Skip to content

Commit

Permalink
fix: errors in worker get caught and stops uploader (#11)
Browse files Browse the repository at this point in the history
* fix: errors in worker get caught and stops uploader

* fix: remove test throw error

* chore: bump version
  • Loading branch information
koen1711 authored Apr 22, 2024
1 parent d3c9864 commit d53288a
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 70 deletions.
14 changes: 8 additions & 6 deletions libserial/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC -s ASYNCIFY -O3 --bind -s STANDALONE_WASM=1 -s WASM=1")



add_library(serial STATIC LibSerial.c)

# copy avrdude-worker.js to build directory
add_custom_command(TARGET serial POST_BUILD
add_custom_target(worker
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
COMMAND yarn install
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMAND npx rollup -c --format cjs -i ${CMAKE_CURRENT_SOURCE_DIR}/avrdude-worker.js -o ${CMAKE_CURRENT_BINARY_DIR}/avrdude-worker.js
)

add_library(serial STATIC LibSerial.c)

add_dependencies(serial worker)

# copy avrdude-worker.js to build directory

22 changes: 18 additions & 4 deletions libserial/LibSerial.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ size_t readBufferLen;


void dataCallback(const unsigned char* array, int length) {
// std::vector<int8_t> data(array, array + length);
// readBuffer.insert(readBuffer.end(), data.begin(), data.end());
// add the data to the readBuffer
for (size_t i = 0; i < length; ++i) {
readBuffer[readBufferLen++] = array[i];
}
}

void errorCallback() {
exit(1);
}



Expand All @@ -29,6 +29,10 @@ EM_ASYNC_JS(void, clear_read_buffer, (int timeoutMs), {
window.avrDudeWorker.postMessage({ type: 'clear-read-buffer', timeout: timeoutMs });
await new Promise(resolve => {
window.avrDudeWorker.onmessage = (event) => {
// check if the response type is an error
if (event.data.type === "error") {
window.funcs._errorCallback();
}
resolve();
};
});
Expand All @@ -39,7 +43,10 @@ EM_ASYNC_JS(void, read_data, (int timeoutMs, int length), {
window.avrDudeWorker.postMessage({ type: 'read', timeout: timeoutMs, requiredBytes: length });
const data = await new Promise((resolve, _) => {
window.avrDudeWorker.onmessage = (event) => {
if (event.data.type == "read") {
// check if the response type is an error
if (event.data.type === "error") {
window.funcs._errorCallback();
} else if (event.data.type == "read") {
resolve(event.data);
}
};
Expand Down Expand Up @@ -105,6 +112,9 @@ EM_ASYNC_JS(void, open_serial_port, (int baudRateInt), {
worker.postMessage({ type: 'init', options: serialOpts, port: portNumber });
await new Promise(resolve => {
worker.onmessage = (event) => {
if (event.data.type === "error") {
window.funcs._errorCallback();
}
resolve();
};
});
Expand All @@ -119,6 +129,10 @@ EM_ASYNC_JS(void, close_serial_port, (), {
window.avrDudeWorker.postMessage({ type: 'close' });
await new Promise(resolve => {
window.avrDudeWorker.onmessage = (event) => {
// check if the response type is an error
if (event.data.type === "error") {
window.funcs._errorCallback();
}
resolve();
};
});
Expand Down
123 changes: 65 additions & 58 deletions libserial/avrdude-worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,71 +23,78 @@ const readPromise = (customReader) => new Promise(async () => {


addEventListener('message', async msg => {
const data = msg.data
try {
const data = msg.data

switch (data.type) {
case 'write': {
await writer.write(data.data)
break
}
case 'read': {
const neededBytes = data.requiredBytes
// await available
// available = new Promise(resolve => onData = resolve)
let dataBuffer = new Uint8Array([])
switch (data.type) {
case 'write': {
await writer.write(data.data)
break
}
case 'read': {
const neededBytes = data.requiredBytes
// await available
// available = new Promise(resolve => onData = resolve)
let dataBuffer = new Uint8Array([])

while (dataBuffer.length < neededBytes) {
if (buffer.length > 0) {
// only take the needed bytes
const bytesToTake = Math.min(neededBytes - dataBuffer.length, buffer.length)
dataBuffer = new Uint8Array([...dataBuffer, ...buffer.slice(0, bytesToTake)])
buffer = buffer.slice(bytesToTake)
continue
while (dataBuffer.length < neededBytes) {
if (buffer.length > 0) {
// only take the needed bytes
const bytesToTake = Math.min(neededBytes - dataBuffer.length, buffer.length)
dataBuffer = new Uint8Array([...dataBuffer, ...buffer.slice(0, bytesToTake)])
buffer = buffer.slice(bytesToTake)
continue
}
await available
available = new Promise(resolve => onData = resolve)
}
await available
available = new Promise(resolve => onData = resolve)
}

postMessage({ type: 'read', result: dataBuffer })
break
}
case 'clear-read-buffer': {
const timeoutPromise = new Promise(resolve => setTimeout(resolve, data.timeout))
// await available
// available = new Promise(resolve => onData = resolve)
let result = await Promise.race([timeoutPromise, available])
available = new Promise(resolve => onData = resolve)
buffer = new Uint8Array([])
postMessage({type: 'read', result: dataBuffer})
break
}
case 'clear-read-buffer': {
const timeoutPromise = new Promise(resolve => setTimeout(resolve, data.timeout))
// await available
// available = new Promise(resolve => onData = resolve)
let result = await Promise.race([timeoutPromise, available])
available = new Promise(resolve => onData = resolve)
buffer = new Uint8Array([])

postMessage({ type: 'clear-read-buffer' })
break
}
case 'init': {
if (navigator.serial) {
port = (await navigator.serial.getPorts())[data.port]
} else {
const device = (await navigator.usb.getDevices())[data.port]
port = new WebUSBSerial(device)
postMessage({type: 'clear-read-buffer'})
break
}
case 'init': {
if (navigator.serial) {
port = (await navigator.serial.getPorts())[data.port]
} else {
const device = (await navigator.usb.getDevices())[data.port]
port = new WebUSBSerial(device)
}

await port.open(data.options)
opts = data.options
writer = port.writable.getWriter()
reader = port.readable.getReader()
continuousRead = readPromise(reader)
postMessage({ type: 'ready' })
break
} case 'close': {
writer.releaseLock()
reader.cancel()
reader.releaseLock()
await port.close()
postMessage({ type: 'closed' })
break
}
default: {
console.error('Unknown message type', data.type)
break
await port.open(data.options)
opts = data.options
writer = port.writable.getWriter()
reader = port.readable.getReader()
continuousRead = readPromise(reader)
postMessage({type: 'ready'})
break
}
case 'close': {
writer.releaseLock()
reader.cancel()
reader.releaseLock()
await port.close()
postMessage({type: 'closed'})
break
}
default: {
console.error('Unknown message type', data.type)
break
}
}
} catch (e) {
console.error(e)
postMessage({type: 'error', error: e})
}

})
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@leaphy-robotics/avrdude-webassembly",
"version": "1.6.0",
"version": "1.6.1",
"description": "An port of avrdude to the browser using WebAssembly",
"type": "module",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ target_link_libraries(libavrdude

# check if we are using emscripten
if(EMSCRIPTEN)
set(CMAKE_C_FLAGS ${CMAKE_C_FLAGS} "-fPIC -O3 -s ENVIRONMENT=web -s ERROR_ON_UNDEFINED_SYMBOLS=1 -s WASM=1 -s FORCE_FILESYSTEM -s ASYNCIFY=1 -s INVOKE_RUN=0 -s WASM_BIGINT=1 -s MODULARIZE=1 -s \"EXPORTED_FUNCTIONS=['_startAvrdude','_malloc','_dataCallback']\" --bind -s EXPORTED_RUNTIME_METHODS='[\"cwrap\", \"writeStringToMemory\", \"FS\", \"allocate\"]' -s EXPORT_ES6=1")
set(CMAKE_C_FLAGS ${CMAKE_C_FLAGS} "-fPIC -s EXIT_RUNTIME -O3 -s ENVIRONMENT=web -s ERROR_ON_UNDEFINED_SYMBOLS=1 -s WASM=1 -s FORCE_FILESYSTEM -s ASYNCIFY=1 -s INVOKE_RUN=0 -s WASM_BIGINT=1 -s MODULARIZE=1 -s \"EXPORTED_FUNCTIONS=['_startAvrdude','_malloc','_dataCallback','_errorCallback']\" --bind -s EXPORTED_RUNTIME_METHODS='[\"cwrap\", \"writeStringToMemory\", \"FS\", \"allocate\"]' -s EXPORT_ES6=1")
endif ()

add_executable(avrdude
Expand Down

0 comments on commit d53288a

Please sign in to comment.