Support latest PXT with GC (#1798)

* Enable gc and basic compilation fixes

* Add missing GC stuff

* Set microbit-dal version

* Disable jacdac in servo

* UTF fixes

* TS build fixes

* Auto-generated files update

* We only seem to have that much

* Fix for new new compiler

* Account for uninitialized scheduler

* Intialize memory allocator

* bump references

* updated package

* Set image tag, requires https://github.com/Microsoft/pxt/pull/5262

* updated project summaries

* Fixing block tests
This commit is contained in:
Michał Moskal 2019-02-21 15:41:32 -08:00 committed by GitHub
parent 040b699a27
commit 71d98822ae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 330 additions and 124 deletions

View File

@ -1,57 +1,83 @@
# Projects # Projects
Here are some cool projects that you can build with your @boardname@!
## Categories
```codecard ```codecard
[{ [
{
"name": "Tutorials", "name": "Tutorials",
"url": "/tutorials", "url": "/tutorials",
"imageUrl": "/static/mb/projects/a1-display.png" "imageUrl": "/static/mb/projects/a1-display.png",
}, { "largeImageUrl": "/static/mb/projects/flashing-heart/sim.gif"
},
{
"name": "Games", "name": "Games",
"url":"/projects/games", "url": "/projects/games",
"imageUrl":"/static/mb/projects/a4-motion.png" "imageUrl": "/static/mb/projects/a4-motion.png"
}, { },
{
"name": "Radio Games", "name": "Radio Games",
"url":"/projects/radio-games", "url": "/projects/radio-games",
"imageUrl":"/static/mb/projects/fireflies.png" "imageUrl": "/static/mb/projects/multi-dice.png"
}, { },
{
"name": "Fashion", "name": "Fashion",
"url":"/projects/fashion", "url": "/projects/fashion",
"imageUrl":"/static/mb/projects/wallet.png" "imageUrl": "/static/mb/projects/wallet.png"
}, { },
{
"name": "Music", "name": "Music",
"url":"/projects/music", "url": "/projects/music",
"imageUrl":"/static/mb/projects/a6-music.png" "imageUrl": "/static/mb/projects/a6-music.png"
},{ },
{
"name": "Toys", "name": "Toys",
"url":"/projects/toys", "url": "/projects/toys",
"imageUrl":"/static/mb/projects/inchworm.jpg" "imageUrl": "/static/mb/projects/inchworm.jpg"
}, { },
{
"name": "Science", "name": "Science",
"url":"/projects/science", "url": "/projects/science",
"imageUrl":"/static/mb/projects/timegate.jpg" "imageUrl": "/static/mb/projects/timegate.jpg"
}, { },
{
"name": "Tools", "name": "Tools",
"url": "/projects/tools", "url": "/projects/tools",
"imageUrl": "/static/mb/projects/light-level-meter.png" "imageUrl": "/static/mb/projects/plot-acceleration.png"
}, { },
{
"name": "Turtle", "name": "Turtle",
"url": "/projects/turtle", "url": "/projects/turtle",
"imageUrl":"/static/mb/projects/turtle-square.png" "imageUrl": "/static/mb/projects/turtle-square.png"
}] },
{
"name": "Blocks To JavaScript",
"url": "/courses/blocks-to-javascript",
"imageUrl": "/static/courses/blocks-to-javascript/hello-javascript.png"
},
{
"name": "Courses",
"url": "/courses",
"imageUrl": "/static/courses/csintro.jpg"
},
{
"name": "Behind the MakeCode Hardware",
"url": "/behind-the-makecode-hardware",
"imageUrl": "/static/mb/behindhardware/leds.jpg"
}
]
``` ```
## See Also ## See Also
[Tutorials](/tutorials), [Tutorials](/tutorials),
[Games](/projects/games), [Games](/projects/games),
[Radio games](/projects/radio-games), [Radio Games](/projects/radio-games),
[Fashion](/projects/fashion) [Fashion](/projects/fashion),
[Music](/projects/music), [Music](/projects/music),
[Toys](/projects/toys), [Toys](/projects/toys),
[Science](/projects/science), [Science](/projects/science),
[Tools](/projects/tools), [Tools](/projects/tools),
[Turtle](/projects/turtle) [Turtle](/projects/turtle),
[Blocks To JavaScript](/courses/blocks-to-javascript),
[Courses](/courses),
[Behind the MakeCode Hardware](/behind-the-makecode-hardware)

86
docs/projects/SUMMARY.md Normal file
View File

@ -0,0 +1,86 @@
# Projects
* [Tutorials](/tutorials)
* [Flashing Heart](/projects/flashing-heart)
* [Name Tag](/projects/name-tag)
* [Smiley Buttons](/projects/smiley-buttons)
* [Dice](/projects/dice)
* [Love Meter](/projects/love-meter)
* [Micro Chat](/projects/micro-chat)
* [Games](/projects/games)
* [Rock Paper Scissors](/projects/rock-paper-scissors)
* [Coin Flipper](/projects/coin-flipper)
* [Reaction Time](/projects/reaction-time)
* [Magic Button Trick](/projects/magic-button-trick)
* [Snap the dot](/projects/snap-the-dot)
* [Salute!](/projects/salute)
* [Karel the LED](/projects/karel)
* [Crashy bird](/projects/crashy-bird)
* [Radio Games](/projects/radio-games)
* [Multi Dice](/projects/multi-dice)
* [Mood Radio](/projects/mood-radio)
* [Tele-potato](/projects/tele-potato)
* [Fireflies](/projects/fireflies)
* [Hot or Cold](/projects/hot-or-cold)
* [Red Light Green Light](/projects/red-light-green-light)
* [Voting Machine](/projects/voting-machine)
* [Rock Paper Scissors Teams](/projects/rps-teams)
* [Micro:Coin](/projects/micro-coin)
* [Infection](/projects/infection)
* [Fashion](/projects/fashion)
* [Duct Tape Wallet](/projects/wallet)
* [Watch](/projects/watch)
* [Stopwatch](/projects/stopwatch)
* [Step counter](/projects/step-counter)
* [Duct Tape Watch](/projects/duct-tape-watch)
* [Music](/projects/music)
* [Hack Your Headphones](/projects/hack-your-headphones)
* [Banana Keyboard](/projects/banana-keyboard)
* [Guitar](/projects/guitar)
* [Toys](/projects/toys)
* [Inchworm](/projects/inchworm)
* [Milk Carton Robot](/projects/milk-carton-robot)
* [Milky Monster](/projects/milky-monster)
* [Railway Crossing](/projects/railway-crossing)
* [Kitronik RC Car Hack](/projects/rc-car)
* [Science](/projects/science)
* [Timing Gates](/projects/timing-gates)
* [Soil Moisture](/projects/soil-moisture)
* [Plant Watering](/projects/plant-watering)
* [States of Matter](/projects/states-of-matter)
* [Tools](/projects/tools)
* [Plot Acceleration](/projects/plot-acceleration)
* [Light Level Meter](/projects/light-level-meter)
* [Analog Pin Tester](/projects/analog-pin-tester)
* [Servo Calibrator](/projects/servo-calibrator)
* [Radio Bridge](/projects/radio-bridge)
* [Turtle](/projects/turtle)
* [Square](/projects/turtle-square)
* [Spiral](/projects/turtle-spiral)
* [Scanner](/projects/turtle-scanner)
* [Blocks To JavaScript](/courses/blocks-to-javascript)
* [Hello JavaScript](/courses/blocks-to-javascript/hello-javascript)
* [Starter Blocks](/courses/blocks-to-javascript/starter-blocks)
* [Writing Code](/courses/blocks-to-javascript/writing-code)
* [Complex Conditionals](/courses/blocks-to-javascript/complex-conditionals)
* [Conditional Loops](/courses/blocks-to-javascript/conditional-loops)
* [Command Responder](/courses/blocks-to-javascript/command-responder)
* [Writing Functions](/courses/blocks-to-javascript/writing-functions)
* [Courses](/courses)
* [Intro to CS](/courses/csintro)
* [Science Experiments](/courses/ucp-science)
* [Learn All About micro:bit](https://goo.gl/XTPYpP)
* [Discover JavaScript Blocks](https://microbit.org/en/2017-03-07-javascript-block-resources/)
* [Networking with the micro:bit](https://microbit.nominetresearch.uk/networking-book/)
* [SparkFun Videos](https://youtu.be/kaNtg1HGXbY?list=PLBcrWxTa5CS0mWJrytvii8aG5KUqMXvSk)
* [Blocks to JavaScript](/courses/blocks-to-javascript)
* [SparkFun Inventor's Kit](https://learn.sparkfun.com/tutorials/sparkfun-inventors-kit-for-microbit-experiment-guide/introduction-to-the-sparkfun-inventors-kit-for-microbit)
* [Kitronik Inventor Kit](https://www.kitronik.co.uk/blog/inventors-kit-experiment-1-help)
* [micro:bit of Things](https://sites.google.com/view/microbitofthings)
* [A-Z Robotics](https://tinkerspark.teachable.com/)
* [Behind the MakeCode Hardware](/behind-the-makecode-hardware)
* [LEDs](https://youtu.be/qqBmvHD5bCw)
* [Buttons](https://youtu.be/t_Qujjd_38o)
* [Accelerometer](https://youtu.be/byngcwjO51U)
* [Light Sensor](https://youtu.be/TKhCr-dQMBY)
* [Temperature Sensor](https://youtu.be/_T4N8O9xsMA)

View File

@ -19,11 +19,11 @@ let index = 0
turtle.setPosition(0, 0) turtle.setPosition(0, 0)
turtle.turnRight() turtle.turnRight()
basic.forever(() => { basic.forever(() => {
for (let index = 0; index <= 4; index++) { for (index = 0; index <= 4; index++) {
turtle.forward(4 - index) turtle.forward(4 - index)
turtle.turnRight() turtle.turnRight()
} }
for (let index = 0; index <= 4; index++) { for (index = 0; index <= 4; index++) {
turtle.turnLeft() turtle.turnLeft()
turtle.back(index) turtle.back(index)
} }

View File

@ -191,7 +191,7 @@ namespace pxt.editor {
} else { } else {
const forceHexDownload = /forceHexDownload/i.test(window.location.href); const forceHexDownload = /forceHexDownload/i.test(window.location.href);
const isUwp = !!(window as any).Windows; const isUwp = !!(window as any).Windows;
if (Cloud.isLocalHost() && Cloud.localToken && !forceHexDownload || isUwp) if (BrowserUtils.isLocalHost() && Cloud.localToken && !forceHexDownload || isUwp)
r = true r = true
} }
return r; return r;

View File

@ -17,7 +17,7 @@ namespace bluetooth {
void __log(String msg) { void __log(String msg) {
if (NULL == pHF2) if (NULL == pHF2)
pHF2 = new BLEHF2Service(*uBit.ble); pHF2 = new BLEHF2Service(*uBit.ble);
pHF2->sendSerial(msg->data, msg->length, false); pHF2->sendSerial(msg->getUTF8Data(), msg->getUTF8Size(), false);
} }
/** /**

View File

@ -4,10 +4,14 @@
"AcceleratorRange.OneG": "The accelerator measures forces up to 1 gravity", "AcceleratorRange.OneG": "The accelerator measures forces up to 1 gravity",
"AcceleratorRange.TwoG": "The accelerator measures forces up to 2 gravity", "AcceleratorRange.TwoG": "The accelerator measures forces up to 2 gravity",
"Array": "Add, remove, and replace items in lists.\n\nAdd, remove, and replace items in lists.", "Array": "Add, remove, and replace items in lists.\n\nAdd, remove, and replace items in lists.",
"Array.concat": "Concatenates the values with another array.",
"Array.concat|param|arr": "The other array that is being concatenated with",
"Array.every": "Tests whether all elements in the array pass the test implemented by the provided function.", "Array.every": "Tests whether all elements in the array pass the test implemented by the provided function.",
"Array.every|param|callbackfn": "A function that accepts up to two arguments. The every method calls the callbackfn function one time for each element in the array.", "Array.every|param|callbackfn": "A function that accepts up to two arguments. The every method calls the callbackfn function one time for each element in the array.",
"Array.fill": "Fills all the elements of an array from a start index to an end index with a static value. The end index is not included.",
"Array.filter": "Return the elements of an array that meet the condition specified in a callback function.", "Array.filter": "Return the elements of an array that meet the condition specified in a callback function.",
"Array.filter|param|callbackfn": "A function that accepts up to two arguments. The filter method calls the callbackfn function one time for each element in the array.", "Array.filter|param|callbackfn": "A function that accepts up to two arguments. The filter method calls the callbackfn function one time for each element in the array.",
"Array.find": "Returns the value of the first element in the array that satisfies the provided testing function. Otherwise undefined is returned.",
"Array.forEach": "Call a defined callback function on each element of an array.", "Array.forEach": "Call a defined callback function on each element of an array.",
"Array.forEach|param|callbackfn": "A function that accepts up to two arguments. The forEach method calls the callbackfn function one time for each element in the array.", "Array.forEach|param|callbackfn": "A function that accepts up to two arguments. The forEach method calls the callbackfn function one time for each element in the array.",
"Array.get": "Get the value at a particular index", "Array.get": "Get the value at a particular index",
@ -17,6 +21,7 @@
"Array.indexOf|param|item": "The value to locate in the array.", "Array.indexOf|param|item": "The value to locate in the array.",
"Array.insertAt": "Insert the value at a particular index, increases length by 1", "Array.insertAt": "Insert the value at a particular index, increases length by 1",
"Array.insertAt|param|index": "the zero-based position in the list to insert the value, eg: 0", "Array.insertAt|param|index": "the zero-based position in the list to insert the value, eg: 0",
"Array.isArray": "Check if a given object is an array.",
"Array.join": "joins all elements of an array into a string and returns this string.", "Array.join": "joins all elements of an array into a string and returns this string.",
"Array.join|param|sep": "the string separator", "Array.join|param|sep": "the string separator",
"Array.length": "Get or set the length of an array. This number is one more than the index of the last element the array.", "Array.length": "Get or set the length of an array. This number is one more than the index of the last element the array.",
@ -58,6 +63,7 @@
"Buffer.shift|param|start": "start offset in buffer. Default is 0.", "Buffer.shift|param|start": "start offset in buffer. Default is 0.",
"Buffer.slice": "Return a copy of a fragment of a buffer.", "Buffer.slice": "Return a copy of a fragment of a buffer.",
"Buffer.toHex": "Convert a buffer to its hexadecimal representation.", "Buffer.toHex": "Convert a buffer to its hexadecimal representation.",
"Buffer.toString": "Convert a buffer to string assuming UTF8 encoding",
"Buffer.write": "Write contents of `src` at `dstOffset` in current buffer.", "Buffer.write": "Write contents of `src` at `dstOffset` in current buffer.",
"EventCreationMode": "How to create the event.", "EventCreationMode": "How to create the event.",
"EventCreationMode.CreateAndFire": "MicroBitEvent is initialised, and its event handlers are immediately fired (not suitable for use in interrupts!).", "EventCreationMode.CreateAndFire": "MicroBitEvent is initialised, and its event handlers are immediately fired (not suitable for use in interrupts!).",
@ -160,6 +166,7 @@
"Math.trunc": "Returns the number with the decimal part truncated.", "Math.trunc": "Returns the number with the decimal part truncated.",
"Math.trunc|param|x": "A numeric expression.", "Math.trunc|param|x": "A numeric expression.",
"Number.toString": "Returns a string representation of a number.", "Number.toString": "Returns a string representation of a number.",
"Object.keys": "Return the field names in an object.",
"String": "Combine, split, and search text strings.\n\nCombine, split, and search text strings.", "String": "Combine, split, and search text strings.\n\nCombine, split, and search text strings.",
"String.charAt": "Return the character at the specified index.", "String.charAt": "Return the character at the specified index.",
"String.charAt|param|index": "The zero-based index of the desired character.", "String.charAt|param|index": "The zero-based index of the desired character.",
@ -178,6 +185,11 @@
"String.indexOf|param|start": "optional start index for the search", "String.indexOf|param|start": "optional start index for the search",
"String.isEmpty": "Returns a value indicating if the string is empty", "String.isEmpty": "Returns a value indicating if the string is empty",
"String.length": "Returns the length of a String object.", "String.length": "Returns the length of a String object.",
"String.slice": "Return a substring of the current string.",
"String.slice|param|end": "one-past-last character index",
"String.slice|param|start": "first character index; can be negative from counting from the end, eg:0",
"String.split": "Splits the string according to the separators",
"String.split|param|separator": "@param limit ",
"String.substr": "Return a substring of the current string.", "String.substr": "Return a substring of the current string.",
"String.substr|param|length": "number of characters to extract", "String.substr|param|length": "number of characters to extract",
"String.substr|param|start": "first character index; can be negative from counting from the end, eg:0", "String.substr|param|start": "first character index; can be negative from counting from the end, eg:0",
@ -195,7 +207,7 @@
"basic.showArrow|param|direction": "the direction of the arrow", "basic.showArrow|param|direction": "the direction of the arrow",
"basic.showArrow|param|interval": "the amount of time (milliseconds) to show the icon. Default is 600.", "basic.showArrow|param|interval": "the amount of time (milliseconds) to show the icon. Default is 600.",
"basic.showIcon": "Draws the selected icon on the LED screen", "basic.showIcon": "Draws the selected icon on the LED screen",
"basic.showIcon|param|icon": "the predifined icon id", "basic.showIcon|param|icon": "the predefined icon id",
"basic.showIcon|param|interval": "the amount of time (milliseconds) to show the icon. Default is 600.", "basic.showIcon|param|interval": "the amount of time (milliseconds) to show the icon. Default is 600.",
"basic.showLeds": "Draws an image on the LED screen.", "basic.showLeds": "Draws an image on the LED screen.",
"basic.showLeds|param|interval": "time in milliseconds to pause after drawing", "basic.showLeds|param|interval": "time in milliseconds to pause after drawing",
@ -214,6 +226,8 @@
"control": "Runtime and event utilities.", "control": "Runtime and event utilities.",
"control.assert": "If the condition is false, display msg on serial console, and panic with code 098.", "control.assert": "If the condition is false, display msg on serial console, and panic with code 098.",
"control.createBuffer": "Create a new zero-initialized buffer.", "control.createBuffer": "Create a new zero-initialized buffer.",
"control.createBufferFromUTF8": "Create a new buffer with UTF8-encoded string",
"control.createBufferFromUTF8|param|str": "the string to put in the buffer",
"control.createBuffer|param|size": "number of bytes in the buffer", "control.createBuffer|param|size": "number of bytes in the buffer",
"control.deviceName": "Make a friendly name for the device based on its serial number", "control.deviceName": "Make a friendly name for the device based on its serial number",
"control.deviceSerialNumber": "Derive a unique, consistent serial number of this device from internal data.", "control.deviceSerialNumber": "Derive a unique, consistent serial number of this device from internal data.",

View File

@ -213,6 +213,7 @@
"Note.GSharp4|block": "G#4", "Note.GSharp4|block": "G#4",
"Note.GSharp5|block": "G#5", "Note.GSharp5|block": "G#5",
"Note.GSharp|block": "G#", "Note.GSharp|block": "G#",
"Object|block": "Object",
"PinEvent.Fall|block": "fall", "PinEvent.Fall|block": "fall",
"PinEvent.PulseHigh|block": "pulse high", "PinEvent.PulseHigh|block": "pulse high",
"PinEvent.PulseLow|block": "pulse low", "PinEvent.PulseLow|block": "pulse low",
@ -389,6 +390,7 @@
"{id:category}Msgpack": "Msgpack", "{id:category}Msgpack": "Msgpack",
"{id:category}Music": "Music", "{id:category}Music": "Music",
"{id:category}Number": "Number", "{id:category}Number": "Number",
"{id:category}Object": "Object",
"{id:category}Pins": "Pins", "{id:category}Pins": "Pins",
"{id:category}PwmOnlyPin": "PwmOnlyPin", "{id:category}PwmOnlyPin": "PwmOnlyPin",
"{id:category}Serial": "Serial", "{id:category}Serial": "Serial",

View File

@ -37,14 +37,14 @@ namespace basic {
void showString(String text, int interval = 150) { void showString(String text, int interval = 150) {
if (interval <= 0) if (interval <= 0)
interval = 1; interval = 1;
int l = text ? text->length : 0; int l = text ? text->getUTF8Size() : 0;
if (l == 0) { if (l == 0) {
uBit.display.clear(); uBit.display.clear();
fiber_sleep(interval * 5); fiber_sleep(interval * 5);
} else if (l > 1) { } else if (l > 1) {
uBit.display.scroll(MSTR(text), interval); uBit.display.scroll(MSTR(text), interval);
} else { } else {
uBit.display.printChar(text->data[0], interval * 5); uBit.display.printChar(text->getUTF8Data()[0], interval * 5);
} }
} }

View File

@ -8,7 +8,7 @@
<block type="device_play_note"> <block type="device_play_note">
<value name="note"> <value name="note">
<shadow type="device_note"> <shadow type="device_note">
<field name="note">175</field> <field name="name">175</field>
</shadow> </shadow>
</value> </value>
<value name="duration"> <value name="duration">
@ -20,7 +20,7 @@
<block type="device_ring"> <block type="device_ring">
<value name="note"> <value name="note">
<shadow type="device_note"> <shadow type="device_note">
<field name="note">147</field> <field name="name">147</field>
</shadow> </shadow>
</value> </value>
<next> <next>
@ -38,7 +38,7 @@
<field name="NUM">0</field> <field name="NUM">0</field>
</shadow> </shadow>
<block type="device_note"> <block type="device_note">
<field name="note">466</field> <field name="name">466</field>
</block> </block>
</value> </value>
<next> <next>

View File

@ -241,7 +241,7 @@
<block type="device_play_note"> <block type="device_play_note">
<value name="note"> <value name="note">
<shadow type="device_note"> <shadow type="device_note">
<field name="note">220</field> <field name="name">220</field>
</shadow> </shadow>
</value> </value>
<value name="duration"> <value name="duration">
@ -253,7 +253,7 @@
<block type="device_ring"> <block type="device_ring">
<value name="note"> <value name="note">
<shadow type="device_note"> <shadow type="device_note">
<field name="note">659</field> <field name="name">659</field>
</shadow> </shadow>
</value> </value>
<next> <next>
@ -432,7 +432,7 @@
<field name="SLIDER">255</field> <field name="SLIDER">255</field>
</shadow> </shadow>
<block type="device_note"> <block type="device_note">
<field name="note">440</field> <field name="name">440</field>
</block> </block>
</value> </value>
<next> <next>

View File

@ -8,15 +8,13 @@ PXT_ABI(__aeabi_dsub)
PXT_ABI(__aeabi_ddiv) PXT_ABI(__aeabi_ddiv)
PXT_ABI(__aeabi_dmul) PXT_ABI(__aeabi_dmul)
extern "C" void target_panic(int error_code) extern "C" void target_panic(int error_code) {
{
// wait for serial to flush // wait for serial to flush
wait_us(300000); wait_us(300000);
microbit_panic(error_code); microbit_panic(error_code);
} }
extern "C" void target_reset() extern "C" void target_reset() {
{
microbit_reset(); microbit_reset();
} }
@ -76,6 +74,7 @@ void registerWithDal(int id, int event, Action a, int flags) {
void fiberDone(void *a) { void fiberDone(void *a) {
decr((Action)a); decr((Action)a);
unregisterGCPtr((Action)a);
release_fiber(); release_fiber();
} }
@ -101,6 +100,7 @@ void forever_stub(void *a) {
void runForever(Action a) { void runForever(Action a) {
if (a != 0) { if (a != 0) {
incr(a); incr(a);
registerGCPtr(a);
create_fiber(forever_stub, (void *)a); create_fiber(forever_stub, (void *)a);
} }
} }
@ -108,6 +108,7 @@ void runForever(Action a) {
void runInParallel(Action a) { void runInParallel(Action a) {
if (a != 0) { if (a != 0) {
incr(a); incr(a);
registerGCPtr(a);
create_fiber((void (*)(void *))runAction0, (void *)a, fiberDone); create_fiber((void (*)(void *))runAction0, (void *)a, fiberDone);
} }
} }
@ -129,31 +130,24 @@ unsigned afterProgramPage() {
return ptr; return ptr;
} }
int current_time_ms() { int current_time_ms() {
return system_timer_current_time(); return system_timer_current_time();
} }
static void logwriten(const char *msg, int l) static void logwriten(const char *msg, int l) {
{ uBit.serial.send((uint8_t *)msg, l);
uBit.serial.send((uint8_t*)msg, l);
} }
static void logwrite(const char *msg) static void logwrite(const char *msg) {
{
logwriten(msg, strlen(msg)); logwriten(msg, strlen(msg));
} }
static void writeNum(char *buf, uint32_t n, bool full) {
static void writeNum(char *buf, uint32_t n, bool full)
{
int i = 0; int i = 0;
int sh = 28; int sh = 28;
while (sh >= 0) while (sh >= 0) {
{
int d = (n >> sh) & 0xf; int d = (n >> sh) & 0xf;
if (full || d || sh == 0 || i) if (full || d || sh == 0 || i) {
{
buf[i++] = d > 9 ? 'A' + d - 10 : '0' + d; buf[i++] = d > 9 ? 'A' + d - 10 : '0' + d;
} }
sh -= 4; sh -= 4;
@ -161,35 +155,27 @@ static void writeNum(char *buf, uint32_t n, bool full)
buf[i] = 0; buf[i] = 0;
} }
static void logwritenum(uint32_t n, bool full, bool hex) static void logwritenum(uint32_t n, bool full, bool hex) {
{
char buff[20]; char buff[20];
if (hex) if (hex) {
{
writeNum(buff, n, full); writeNum(buff, n, full);
logwrite("0x"); logwrite("0x");
} } else {
else
{
itoa(n, buff); itoa(n, buff);
} }
logwrite(buff); logwrite(buff);
} }
void vdebuglog(const char *format, va_list ap) void vdebuglog(const char *format, va_list ap) {
{
const char *end = format; const char *end = format;
while (*end) while (*end) {
{ if (*end++ == '%') {
if (*end++ == '%')
{
logwriten(format, end - format - 1); logwriten(format, end - format - 1);
uint32_t val = va_arg(ap, uint32_t); uint32_t val = va_arg(ap, uint32_t);
switch (*end++) switch (*end++) {
{
case 'c': case 'c':
logwriten((const char *)&val, 1); logwriten((const char *)&val, 1);
break; break;
@ -220,8 +206,7 @@ void vdebuglog(const char *format, va_list ap)
logwrite("\n"); logwrite("\n");
} }
void debuglog(const char *format, ...) void debuglog(const char *format, ...) {
{
va_list arg; va_list arg;
va_start(arg, format); va_start(arg, format);
vdebuglog(format, arg); vdebuglog(format, arg);
@ -232,7 +217,57 @@ void sendSerial(const char *data, int len) {
logwriten(data, len); logwriten(data, len);
} }
#ifdef PXT_GC
ThreadContext *getThreadContext() {
if (!currentFiber)
return NULL;
return (ThreadContext *)currentFiber->user_data;
}
void setThreadContext(ThreadContext *ctx) {
currentFiber->user_data = ctx;
}
static void *threadAddressFor(Fiber *fib, void *sp) {
if (fib == currentFiber)
return sp;
return (uint8_t *)sp + ((uint8_t *)fib->stack_top - (uint8_t *)fib->tcb.stack_base);
}
void gcProcessStacks(int flags) {
// check scheduler is initialized
if (!currentFiber) {
// make sure we allocate something to at least initalize the memory allocator
void * volatile p = xmalloc(1);
xfree(p);
return;
}
int numFibers = list_fibers(NULL);
Fiber **fibers = (Fiber **)xmalloc(sizeof(Fiber *) * numFibers);
int num2 = list_fibers(fibers);
if (numFibers != num2)
oops(12);
int cnt = 0;
for (int i = 0; i < numFibers; ++i) {
auto fib = fibers[i];
auto ctx = (ThreadContext *)fib->user_data;
if (!ctx)
continue;
for (auto seg = &ctx->stack; seg; seg = seg->next) {
auto ptr = (TValue *)threadAddressFor(fib, seg->top);
auto end = (TValue *)threadAddressFor(fib, seg->bottom);
if (flags & 2)
DMESG("RS%d:%p/%d", cnt++, ptr, end - ptr);
// VLOG("mark: %p - %p", ptr, end);
while (ptr < end) {
gcProcess(*ptr++);
}
}
}
xfree(fibers);
}
#endif
} // namespace pxt } // namespace pxt

View File

@ -318,6 +318,6 @@ namespace control {
//% //%
void __log(String text) { void __log(String text) {
if (NULL == text) return; if (NULL == text) return;
pxt::sendSerial(text->data, text->length); pxt::sendSerial(text->getUTF8Data(), text->getUTF8Size());
} }
} }

View File

@ -22,13 +22,8 @@
} }
declare const enum ValType { declare const enum PerfCounters {
Undefined = 0, GC = 0,
Boolean = 1,
Number = 2,
String = 3,
Object = 4,
Function = 5,
} }
declare namespace images { declare namespace images {
} }

View File

@ -1,7 +1,6 @@
#include "pxt.h" #include "pxt.h"
PXT_VTABLE_BEGIN(RefMImage, 0, 0) PXT_VTABLE(RefMImage)
PXT_VTABLE_END
RefMImage::RefMImage(ImageData *d) : PXT_VTABLE_INIT(RefMImage), img(d) { RefMImage::RefMImage(ImageData *d) : PXT_VTABLE_INIT(RefMImage), img(d) {
img->incr(); img->incr();
@ -22,6 +21,12 @@ void RefMImage::makeWritable() {
} }
} }
void RefMImage::scan(RefMImage *t) {}
unsigned RefMImage::gcsize(RefMImage *t) {
return (sizeof(*t) + 3) >> 2;
}
/** /**
* Creation, manipulation and display of LED images. * Creation, manipulation and display of LED images.
*/ */
@ -64,8 +69,8 @@ void plotImage(Image i, int xOffset = 0) {
* @param xOffset column index to start displaying the image * @param xOffset column index to start displaying the image
*/ */
//% help=images/show-image weight=80 blockNamespace=images //% help=images/show-image weight=80 blockNamespace=images
//% blockId=device_show_image_offset block="show image %sprite(myImage)|at offset %offset" blockGap=8 //% blockId=device_show_image_offset block="show image %sprite(myImage)|at offset %offset"
//% parts="ledmatrix" async //% blockGap=8 parts="ledmatrix" async
void showImage(Image sprite, int xOffset, int interval = 400) { void showImage(Image sprite, int xOffset, int interval = 400) {
uBit.display.print(MicroBitImage(sprite->img), -xOffset, 0, 0, interval); uBit.display.print(MicroBitImage(sprite->img), -xOffset, 0, 0, interval);
} }

View File

@ -17,9 +17,11 @@ class RefMImage : public RefObject {
void makeWritable(); void makeWritable();
static void destroy(RefMImage *map); static void destroy(RefMImage *map);
static void print(RefMImage *map); static void print(RefMImage *map);
static void scan(RefMImage *t);
static unsigned gcsize(RefMImage *t);
}; };
#define MSTR(s) ManagedString((s)->data, (s)->length) #define MSTR(s) ManagedString((s)->getUTF8Data(), (s)->getUTF8Size())
static inline String PSTR(ManagedString s) { static inline String PSTR(ManagedString s) {
return mkString(s.toCharArray(), s.length()); return mkString(s.toCharArray(), s.length());
@ -28,7 +30,7 @@ static inline String PSTR(ManagedString s) {
typedef uint32_t ImageLiteral_; typedef uint32_t ImageLiteral_;
static inline ImageData *imageBytes(ImageLiteral_ lit) { static inline ImageData *imageBytes(ImageLiteral_ lit) {
return (ImageData*)ptrOfLiteral(lit); return (ImageData *)lit;
} }
typedef RefMImage *Image; typedef RefMImage *Image;
@ -39,16 +41,20 @@ extern MicroBitEvent lastEvent;
MicroBitPin *getPin(int id); MicroBitPin *getPin(int id);
static inline int min_(int a, int b) { static inline int min_(int a, int b) {
if (a < b) return a; if (a < b)
else return b; return a;
else
return b;
} }
static inline int max_(int a, int b) { static inline int max_(int a, int b) {
if (a > b) return a; if (a > b)
else return b; return a;
else
return b;
} }
} } // namespace pxt
using namespace pxt; using namespace pxt;

View File

@ -18,6 +18,8 @@
"pxt-helpers.ts", "pxt-helpers.ts",
"helpers.ts", "helpers.ts",
"pinscompat.ts", "pinscompat.ts",
"configkeys.h",
"gc.cpp",
"codal.cpp", "codal.cpp",
"images.cpp", "images.cpp",
"basic.cpp", "basic.cpp",
@ -50,6 +52,7 @@
"yotta": { "yotta": {
"optionalConfig": { "optionalConfig": {
"microbit-dal": { "microbit-dal": {
"fiber_user_data": 1,
"bluetooth": { "bluetooth": {
"private_addressing": 0, "private_addressing": 0,
"advertising_timeout": 0, "advertising_timeout": 0,

View File

@ -10,6 +10,11 @@ namespace pxt {
void debuglog(const char *format, ...); void debuglog(const char *format, ...);
} }
// #define GC_GET_HEAP_SIZE() device_heap_size(0)
#define xmalloc malloc
#define xfree free
#define GC_BLOCK_SIZE 1000
#define DMESG NOLOG #define DMESG NOLOG

17
libs/core/shims.d.ts vendored
View File

@ -39,8 +39,8 @@ declare interface Image {
* @param xOffset column index to start displaying the image * @param xOffset column index to start displaying the image
*/ */
//% help=images/show-image weight=80 blockNamespace=images //% help=images/show-image weight=80 blockNamespace=images
//% blockId=device_show_image_offset block="show image %sprite(myImage)|at offset %offset" blockGap=8 //% blockId=device_show_image_offset block="show image %sprite(myImage)|at offset %offset"
//% parts="ledmatrix" async interval.defl=400 shim=ImageMethods::showImage //% blockGap=8 parts="ledmatrix" async interval.defl=400 shim=ImageMethods::showImage
showImage(xOffset: int32, interval?: int32): void; showImage(xOffset: int32, interval?: int32): void;
/** /**
@ -898,6 +898,12 @@ declare interface Buffer {
//% start.defl=0 length.defl=-1 shim=BufferMethods::shift //% start.defl=0 length.defl=-1 shim=BufferMethods::shift
shift(offset: int32, start?: int32, length?: int32): void; shift(offset: int32, start?: int32, length?: int32): void;
/**
* Convert a buffer to string assuming UTF8 encoding
*/
//% shim=BufferMethods::toString
toString(): string;
/** /**
* Convert a buffer to its hexadecimal representation. * Convert a buffer to its hexadecimal representation.
*/ */
@ -928,6 +934,13 @@ declare namespace control {
*/ */
//% shim=control::createBuffer //% shim=control::createBuffer
function createBuffer(size: int32): Buffer; function createBuffer(size: int32): Buffer;
/**
* Create a new buffer with UTF8-encoded string
* @param str the string to put in the buffer
*/
//% shim=control::createBufferFromUTF8
function createBufferFromUTF8(str: string): Buffer;
} }
// Auto-generated. Do not edit. Really. // Auto-generated. Do not edit. Really.

View File

@ -92,13 +92,13 @@ namespace radio {
} }
uint8_t copyStringValue(uint8_t* buf, String data, uint8_t maxLength) { uint8_t copyStringValue(uint8_t* buf, String data, uint8_t maxLength) {
uint8_t len = min_(maxLength, data->length); uint8_t len = min_(maxLength, data->getUTF8Size());
// One byte for length of the string // One byte for length of the string
buf[0] = len; buf[0] = len;
if (len > 0) { if (len > 0) {
memcpy(buf + 1, data->data, len); memcpy(buf + 1, data->getUTF8Data(), len);
} }
return len + 1; return len + 1;
} }
@ -136,7 +136,7 @@ namespace radio {
uBit.serial.send(s); uBit.serial.send(s);
if ((tp == PACKET_TYPE_STRING || tp == PACKET_TYPE_VALUE) && NULL != m) { if ((tp == PACKET_TYPE_STRING || tp == PACKET_TYPE_VALUE) && NULL != m) {
uBit.serial.send(",\"n\":\""); uBit.serial.send(",\"n\":\"");
uBit.serial.send((uint8_t*)m->data, m->length); uBit.serial.send((uint8_t*)m->getUTF8Data(), m->getUTF8Size());
uBit.serial.send("\""); uBit.serial.send("\"");
} }
if (tp == PACKET_TYPE_BUFFER && NULL != b) { if (tp == PACKET_TYPE_BUFFER && NULL != b) {
@ -152,7 +152,7 @@ namespace radio {
uBit.serial.send(",\"v\":"); uBit.serial.send(",\"v\":");
TNumber td = fromDouble(dv); TNumber td = fromDouble(dv);
String sd = numops::toString(td); String sd = numops::toString(td);
uBit.serial.send((uint8_t*)sd->data, sd->length); uBit.serial.send((uint8_t*)sd->getUTF8Data(), sd->getUTF8Size());
decrRC(sd); decrRC(sd);
} }
uBit.serial.send("}\r\n"); uBit.serial.send("}\r\n");

View File

@ -1,5 +1,5 @@
{ {
"servos.Servo.run": "Set the throttle on a continuous servo", "servos.Servo.run": "Set the throttle on a continuous servo",
"servos.Servo.run|param|speed": "the throttle of the motor from -100% to 100%", "servos.Servo.run|param|speed": "the throttle of the motor from -100% to 100%",
"servos.Servo.setAngle": "set the servo angle" "servos.Servo.setAngle": "Set the servo angle"
} }

View File

@ -5,6 +5,7 @@
"servos.Servo.run|block": "continuous %servo run at %speed=speedPicker \\%", "servos.Servo.run|block": "continuous %servo run at %speed=speedPicker \\%",
"servos.Servo.setAngle|block": "set %servo angle to %degrees=protractorPicker °", "servos.Servo.setAngle|block": "set %servo angle to %degrees=protractorPicker °",
"servos.Servo.setPulse|block": "set %servo pulse to %micros μs", "servos.Servo.setPulse|block": "set %servo pulse to %micros μs",
"servos.Servo.stop|block": "stop %servo",
"{id:category}Servos": "Servos", "{id:category}Servos": "Servos",
"{id:group}Servos": "Servos" "{id:group}Servos": "Servos"
} }

View File

@ -1,3 +1,13 @@
{ {
"additionalFilePath": "../../node_modules/pxt-common-packages/libs/servo" "additionalFilePath": "../../node_modules/pxt-common-packages/libs/servo",
"files": [
"README.md",
"servo.ts",
"ns.ts",
"targetoverrides.ts"
],
"public": true,
"dependencies": {
"core": "file:../core"
}
} }

View File

@ -42,7 +42,7 @@
"@types/web-bluetooth": "0.0.4" "@types/web-bluetooth": "0.0.4"
}, },
"dependencies": { "dependencies": {
"pxt-common-packages": "0.25.10", "pxt-common-packages": "6.3.3",
"pxt-core": "4.4.10" "pxt-core": "5.5.13"
} }
} }

View File

@ -36,6 +36,9 @@
"flashCodeAlign": 1024, "flashCodeAlign": 1024,
"floatingPoint": true, "floatingPoint": true,
"taggedInts": true, "taggedInts": true,
"utf8": false,
"gc": true,
"imageRefTag": 9,
"patches": { "patches": {
"0.0.0 - 1.0.0": [ "0.0.0 - 1.0.0": [
{ {
@ -218,7 +221,7 @@
"yottaTarget": "bbc-microbit-classic-gcc", "yottaTarget": "bbc-microbit-classic-gcc",
"yottaCorePackage": "microbit", "yottaCorePackage": "microbit",
"githubCorePackage": "lancaster-university/microbit", "githubCorePackage": "lancaster-university/microbit",
"gittag": "v2.1.1", "gittag": "pxtgc-0",
"serviceId": "microbit", "serviceId": "microbit",
"dockerImage": "pext/yotta:latest" "dockerImage": "pext/yotta:latest"
}, },

View File

@ -138,6 +138,7 @@ namespace pxsim {
}; };
const viewHost = new visuals.BoardHost(pxsim.visuals.mkBoardView({ const viewHost = new visuals.BoardHost(pxsim.visuals.mkBoardView({
visual: boardDef.visual, visual: boardDef.visual,
boardDef: boardDef,
highContrast: msg.highContrast highContrast: msg.highContrast
}), opts); }), opts);

View File

@ -79,6 +79,7 @@ namespace pxsim {
raiseEvent(id: number, eventid: number) { raiseEvent(id: number, eventid: number) {
Runtime.postMessage(<SimulatorEventBusMessage>{ Runtime.postMessage(<SimulatorEventBusMessage>{
type: "eventbus", type: "eventbus",
broadcast: true,
id, id,
eventid, eventid,
power: this.power, power: this.power,