Skip to content

Commit 8279984

Browse files
Restart the WASM module when stopping/starting/panicking (#51)
Fixes panic HAL calls so the device is no longer operable afterwards. - Use the same logic for a normal stop/start. - Cache the WASM to avoid downloading and compiling it for each module instantiation. - Prefer using the _foo functions on the module vs cwrap. - Incidental fix to the radio message handling in demo.html Co-authored-by: Robert Knight <[email protected]>
1 parent d7a68ab commit 8279984

21 files changed

+324
-289
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ build:
99
dist: build
1010
mkdir -p $(BUILD)/build
1111
cp -r $(SRC)/*.html $(SRC)/term.js src/examples $(BUILD)
12-
cp $(SRC)/build/micropython.js $(SRC)/build/firmware.wasm $(BUILD)/build/
12+
cp $(SRC)/build/firmware.js $(SRC)/build/simulator.js $(SRC)/build/firmware.wasm $(BUILD)/build/
1313

1414
watch: dist
1515
fswatch -o -e src/build src | while read _; do $(MAKE) dist; done

README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,19 @@ The following sections documents the messages supported via postMessage.
151151
<td>Radio output (sent from the user's program) as bytes.
152152
If you send string data from the program then it will be prepended with the three bytes 0x01, 0x00, 0x01.
153153

154+
<tr>
155+
<td>internal_error
156+
<td>
157+
158+
```javascript
159+
{
160+
"kind": "internal_error",
161+
"error": new Error()
162+
}
163+
```
164+
165+
<td>A debug message sent for internal (unexpected) errors thrown by the simulator. Suitable for application-level logging. Please raise issues in this project as these indicate a bug in the simulator.
166+
154167
</table>
155168

156169
## Messages supported by the iframe

src/Makefile

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Makefile to build micropython.js
1+
# Makefile to build WASM and simulator JS.
22

33
# Build upon the codal_port code.
44
CODAL_PORT = $(abspath ../lib/micropython-microbit-v2/src/codal_port)
@@ -44,9 +44,11 @@ COPT += -O3 -DNDEBUG
4444
endif
4545

4646
JSFLAGS += -s ASYNCIFY
47-
JSFLAGS += -s EXPORTED_FUNCTIONS="['_mp_js_main','_mp_js_request_stop','_microbit_hal_audio_ready_callback','_microbit_hal_audio_speech_ready_callback','_microbit_hal_gesture_callback','_microbit_hal_level_detector_callback','_microbit_radio_rx_buffer']"
47+
JSFLAGS += -s EXIT_RUNTIME
48+
JSFLAGS += -s MODULARIZE=1
49+
JSFLAGS += -s EXPORT_NAME=createModule
50+
JSFLAGS += -s EXPORTED_FUNCTIONS="['_mp_js_main','_microbit_hal_audio_ready_callback','_microbit_hal_audio_speech_ready_callback','_microbit_hal_gesture_callback','_microbit_hal_level_detector_callback','_microbit_radio_rx_buffer','_mp_js_force_stop','_mp_js_request_stop']"
4851
JSFLAGS += -s EXPORTED_RUNTIME_METHODS="['ccall', 'cwrap']" --js-library jshal.js
49-
JSFLAGS += --pre-js $(BUILD)/pre.js
5052

5153
ifdef DEBUG
5254
JSFLAGS += -g
@@ -136,14 +138,13 @@ $(MBIT_VER_FILE): FORCE
136138
$(PYTHON) $(TOP)/py/makeversionhdr.py $(MBIT_VER_FILE).pre
137139
$(CAT) $(MBIT_VER_FILE).pre | $(SED) s/MICROPY_/MICROBIT_/ > $(MBIT_VER_FILE)
138140

139-
$(BUILD)/micropython.js: $(OBJ) jshal.js main.js pre-js
141+
$(BUILD)/micropython.js: $(OBJ) jshal.js simulator-js
140142
$(ECHO) "LINK $(BUILD)/firmware.js"
141143
$(Q)emcc $(LDFLAGS) -o $(BUILD)/firmware.js $(OBJ) $(JSFLAGS)
142-
cat main.js $(BUILD)/firmware.js > $@
143144

144-
pre-js:
145-
npx esbuild ./pre.ts --bundle --outfile=$(BUILD)/pre.js --loader:.svg=text
145+
simulator-js:
146+
npx esbuild ./simulator.ts --bundle --outfile=$(BUILD)/simulator.js --loader:.svg=text
146147

147148
include $(TOP)/py/mkrules.mk
148149

149-
.PHONY: pre-js
150+
.PHONY: simulator-js

src/board/accelerometer.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ export class Accelerometer {
4848

4949
setValue(id: StateKeys, value: any) {
5050
this.state[id].setValue(value);
51-
if (id === "gesture") {
52-
this.gestureCallback!(
51+
if (id === "gesture" && this.gestureCallback) {
52+
this.gestureCallback(
5353
convertAccelerometerStringToNumber(this.state.gesture.value)
5454
);
5555
}
@@ -71,11 +71,9 @@ export class Accelerometer {
7171
});
7272
}
7373

74-
initialize(gestureCallback: GestureCallback) {
74+
initializeCallbacks(gestureCallback: GestureCallback) {
7575
this.gestureCallback = gestureCallback;
7676
}
7777

78-
dispose() {
79-
this.gestureCallback = undefined;
80-
}
78+
dispose() {}
8179
}

src/board/audio/index.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,10 @@ export class Audio {
2323

2424
constructor() {}
2525

26-
initialize({ defaultAudioCallback, speechAudioCallback }: AudioOptions) {
26+
initializeCallbacks({
27+
defaultAudioCallback,
28+
speechAudioCallback,
29+
}: AudioOptions) {
2730
this.context = new AudioContext({
2831
// The highest rate is the sound expression synth.
2932
sampleRate: 44100,

src/board/buttons.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,6 @@ export class Button {
115115
return result;
116116
}
117117

118-
initialize() {}
119-
120118
dispose() {
121119
this._presses = 0;
122120
}

src/board/compass.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,5 @@ export class Compass {
2727
return Math.sqrt(x * x + y * y + z * z);
2828
}
2929

30-
initialize() {}
31-
3230
dispose() {}
3331
}

src/board/conversions.ts

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,22 +12,10 @@ import {
1212
MICROBIT_HAL_ACCELEROMETER_EVT_TILT_LEFT,
1313
MICROBIT_HAL_ACCELEROMETER_EVT_TILT_RIGHT,
1414
MICROBIT_HAL_ACCELEROMETER_EVT_TILT_UP,
15-
MICROBIT_HAL_MICROPHONE_EVT_THRESHOLD_HIGH,
16-
MICROBIT_HAL_MICROPHONE_EVT_THRESHOLD_LOW,
1715
MICROBIT_HAL_MICROPHONE_SET_THRESHOLD_HIGH,
1816
MICROBIT_HAL_MICROPHONE_SET_THRESHOLD_LOW,
1917
} from "./constants";
2018

21-
export function convertAudioBuffer(source: number, target: AudioBuffer) {
22-
const channel = target.getChannelData(0);
23-
const heap = window.HEAPU8;
24-
for (let i = 0; i < channel.length; ++i) {
25-
// Convert from uint8 to -1..+1 float.
26-
channel[i] = (heap[source + i] / 255) * 2 - 1;
27-
}
28-
return target;
29-
}
30-
3119
export function convertSoundThresholdNumberToString(
3220
value: number
3321
): "low" | "high" {
@@ -106,3 +94,16 @@ export function convertAccelerometerNumberToString(value: number): string {
10694
throw new Error(`Invalid value ${value}`);
10795
}
10896
}
97+
98+
export const convertAudioBuffer = (
99+
heap: Uint8Array,
100+
source: number,
101+
target: AudioBuffer
102+
) => {
103+
const channel = target.getChannelData(0);
104+
for (let i = 0; i < channel.length; ++i) {
105+
// Convert from uint8 to -1..+1 float.
106+
channel[i] = (heap[source + i] / 255) * 2 - 1;
107+
}
108+
return target;
109+
};

src/board/display.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,6 @@ export class Display {
7373
}
7474
}
7575

76-
initialize() {}
77-
7876
dispose() {
7977
this.clear();
8078
}

0 commit comments

Comments
 (0)