ARMmbed / ARMmbed/DAPLink

Windows on arm (arm64) issues with WebUSB

Open
#1,111 8 comments 0 reactions 0 assignees View on GitHub
Dominant language
C
Stars
2.8k
Forks
1.1k
Avg merge
3d 12h
Merged PRs (30d)
1

Description

As far as I've found, this does not look like an issue in the DAPLink firmware, but this is the best place to collect the findings so far.

## Issue Summary

When trying to use WebUSB with the BBC micro:bit (I assume the same is true of other DAPLink devices, although I have not tested more yet) all WebUSB editors and tools fail.
This includes the [MakeCode Editor](https://makecode.microbit.org/), [Python Editor](https://python.microbit.org/v/3), [micro:bit hex download tool](https://microbit.org/tools/webusb-hex-download-tool/), and [DAPjs WebUSB Flash Demo](https://armmbed.github.io/dapjs/examples/daplink-flash/web.html).

## Symptoms

The main issue seems to be that all these systems time out.

MakeCode output using `?dbg=1` flag:
```
[...]
pxtapp.js:1 dap 86892: next page 384: [5d00, 5d3e] (885kb left)
pxtapp.js:1 dap 02509: error: abort
pxtapp.js:1 dap 02515: reset on error
editor.js:3641 timeout
pxtapp.js:1 hideloading: hiddeploy
pxtapp.js:1 cmds: hid error undefined
pxtapp.js:1 timeout
```

Click here to see full log

```
cmds: [CLIENT]: starting reconnect
pxtapp.js:1 packetio: init
pxtapp.js:1 dap 31562: reconnect
pxtapp.js:1 dap 31565: cancelling connection 1
pxtapp.js:1 dap 31789: alloc dap
pxtapp.js:1 webusb: reconnect
pxtapp.js:1 webusb: get devices
pxtapp.js:1 webusb: trying to connect (1 devices)
pxtapp.js:1 webusb: connect device: Arm BBC micro:bit CMSIS-DAP
pxtapp.js:1 webusb: serial number: uXTwBAAAAIjRvAfP
pxtapp.js:1 webusb: open device
pxtapp.js:1 webusb: select configuration
pxtapp.js:1 webusb: got 6 interfaces
pxtapp.js:1 webusb: 2 matching interfaces; picking #5
pxtapp.js:1 webusb: using dedicated endpoints
pxtapp.js:1 webusb: claim interface
pxtapp.js:1 webusb: device ready
pxtapp.js:1 dap 33377: daplink version: 2.1.0
dap 33593: bin name: mbcodal-binary.hex v:99053602000528333b46d98c9fec3268000000006e052820
pxtapp.js:1 dap 33812: baud rate already set to 115200
editor.js:2415 Connecting...
editor.js:2446 Connected
editor.js:1129 6 hardware breakpoints, 4 literal comparators
editor.js:535 Found an ARM Cortex-M4
pxtapp.js:1 dap 38710: reset cortex
pxtapp.js:1 dap 40906: page size 4096, num pages 128
pxtapp.js:1 dap 41129: cortex state: halted
pxtapp.js:1 dap 42795: jacdac: finding xchg address (retry 1)
dap 43746: jacdac: finding xchg address (retry 2)
pxtapp.js:1 dap 44683: jacdac: finding xchg address (retry 3)
pxtapp.js:1 cmds: [CLIENT]: starting reconnect
compiling...
pxtapp.js:1 dap 45636: jacdac: exchange address 0x?; 4 retries; 3849ms
pxtapp.js:1 dap 45637: jacdac: xchg address not found
pxtapp.js:1 dap 45640: start read serial 2
pxtapp.js:1 sim: stop (autorun true)
pxtapp.js:1 hideloading: attempting-connection
pxtapp.js:1 building: core, microphone, radio, Untitled
pxtapp.js:1 app variant: mbdal
pxtapp.js:1 Using cached extinfo
pxtapp.js:1 app variant: undefined
pxtapp.js:1 get hex info: 8e76592a9cb06b299cd74ce547ef7a0f701f2aacd15646ccbfa1ba0f22c726ad
pxtapp.js:1 app variant: mbcodal
pxtapp.js:1 Using cached extinfo
pxtapp.js:1 app variant: undefined
pxtapp.js:1 get hex info: 22204ac874977e7f341ae512133a0fd9812fb83074c8b43203d5dbd31e302f6f
pxtapp.js:1 showloading: hexcloudcompiler
pxtapp.js:1 hideloading: hexcloudcompiler
pxtapp.js:1 [Violation] 'setTimeout' handler took 76ms
pxtapp.js:1 worker op: compile
pxtapp.js:1 worker op done: compile
pxtapp.js:1 sim: start run (autorun true, first false)
pxtapp.js:1 cmds: hid deploy
pxtapp.js:1 packetio: init
pxtapp.js:1 building: core, microphone, radio, Untitled
pxtapp.js:1 app variant: mbdal
Using cached extinfo
pxtapp.js:1 app variant: undefined
pxtapp.js:1 app variant: mbcodal
pxtapp.js:1 Using cached extinfo
pxtapp.js:1 app variant: undefined
pxtapp.js:1 showloading: hiddeploy
pxtapp.js:1 dap 47143: reflash
pxtapp.js:1 dap 00000: cancelling connection 2
pxtapp.js:1 worker op: compile
pxtapp.js:1 dap 00007: stopped serial reader 2
pxtapp.js:1 worker op done: compile
pxtapp.js:1 sim: run
editor.js:2415 Connecting...
editor.js:2446 Connected
editor.js:1129 6 hardware breakpoints, 4 literal comparators
editor.js:535 Found an ARM Cortex-M4
dap 08053: cortex state: halted
pxtapp.js:1 dap 08496: uicr: ff (ffffffff)
pxtapp.js:1 dap 08506: full flash
pxtapp.js:1 dap 08727: daplinkflash open: 8a00
pxtapp.js:1 dap 08728: bin file mbcodal-binary.hex in yotta.json, codal.json, mbdal-binary.asm, mbdal-binary.hex, mbcodal-binary.asm, mbcodal-binary.hex, binary.hex, 908379b
pxtapp.js:1 dap 08738: hex 908379b, ~14651 chunks of 62b
pxtapp.js:1 dap 08753: next page 0: [0, 3e] (909kb left)
dap 36860: next page 128: [1f00, 1f3e] (901kb left)
pxtapp.js:1 dap 58857: next page 256: [3e00, 3e3e] (893kb left)
pxtapp.js:1 dap 86892: next page 384: [5d00, 5d3e] (885kb left)
pxtapp.js:1 dap 02509: error: abort
pxtapp.js:1 dap 02515: reset on error
editor.js:3641 timeout
pxtapp.js:1 hideloading: hiddeploy
pxtapp.js:1 cmds: hid error undefined
pxtapp.js:1 timeout
error @ pxtapp.js:1
e.error @ pxtapp.js:1
e.reportException @ pxtapp.js:1
e.reportException @ pxtapp.js:1
S @ main.js:1
pxtapp.js:1 cmds: saving microbit-Untitled.hex
pxtapp.js:1 trigger download
```


And in the micro:bit hex download tool, the timeout during reset do end up causing other issues on the re-attempts:

Click here to view output

Image


## Timings

So I've added additional debug info to this DAPJs WebUSB flash demo:
- Branch: https://github.com/ARMmbed/dapjs/compare/master...microbit-carlos:dapjs:debug-console
- Deployment: https://microbit-carlos.github.io/dapjs/examples/daplink-flash/web.html

If we flash this hex file on Windows on Arm vs any other platform, we can see that each packet of 64 bytes instead of **~0.2-0.3ms**, takes around **~100-120ms**, and a file that normally flashes in 12 seconds takes around **45min**:

[MICROBIT.hex.zip](https://github.com/user-attachments/files/25802366/MICROBIT.hex.zip)

| Windows on Arm | macOS arm64 |
|--------|--------|
| Image | Image |

For WebUSB, we find slow CPUs to be a bottleneck, so as a test, I used the dev tools to simulatre a x20 CPU slowdown and timings changes were:
- Windows on arm goes from ~100-120ms to 400-700ms, so aroun x5 slowdon (and the timings per packet differ a lot more)
- macOS goes from ~0.2-0.3ms to ~3-5ms, and a full flash went from 12 seconds to 3min, so x15 slowdown (closer to the expected x20)

## Tests carried out

These systems replicate the issue:
- Used micro:bit V1 DAPLink 0249, and micro:bit V2 DAPLink 0256
- I've tested this on these systems, and they behave the same:
- Windows 11 on Arm running inside a VM in a Macbook Pro
- A native Surface laptop with a Snapdragon CPU
- I've replicated this issue in the following browsers:
- Edge 145 arm64,
- Chrome arm64
- Chrome beta arm64
- Brave 146 x64
- I wasn't able to find a way to install Chrome x86_64 (the Google Chrome Enterprise Bundle didn't install successfully, the Chrome online installers for x86_64 ends up installing the arm64 version, and could not find another Chrome offline installer). However, I was able to get a Brave offline installer for x86_64 from their GitHub: https://github.com/brave/brave-browser/releases/tag/v1.90.7
- Using the WebUSB serial example also shows in and out transfers taking around 120ms

Using a different MCU USB stack and WebUSB demo shows the same problem, as described in:
- https://github.com/ARMmbed/DAPLink/issues/1111#issuecomment-4083698081

These other DAPLink features work correctly:
- Drag & drop a .hex file into the MSD drive on Windows on Arm works correctly.
- Using `node examples/daplink-flash/usb.js MICROBIT.hex` on Windows on Arm does work as well.
- This was tested with node v24 for arm64 and for x64 (emulated).
- Web Serial works correctly, tested with [webserialterminal.com](https://webserialterminal.com/).
- "Standard" serial terminal, like TeraTerm works as expected too

node-HID issue:
- Using `node examples/daplink-flash/hid.js MICROBIT.hex` on Windows on Arm:
- nodejs arm64: Also has slow reads
- nodejs x64 (emulated): Fast read and writes.
- Described in https://github.com/ARMmbed/DAPLink/issues/1111#issuecomment-4042966106

Other things tested:
- Tried to replace the winusb drivers with Zadig, but this is not possible due to issue https://github.com/pbatard/libwdi/issues/289

## Related issues

Raised in the Chrome tracker:
- https://issues.chromium.org/issues/494543570

Contributor guide

Open the contributing guide

Research direction

Reproduce the timing difference with the DAPjs WebUSB flash demo and compare it with examples/daplink-flash/usb.js and examples/daplink-flash/hid.js on Windows on Arm. Read the linked Chromium tracker and related DAPLink comments to determine whether the fault is in DAPLink, WebUSB, or the host stack. Done means identifying a confirmed cause and a validated path that avoids the packet timeouts.

Written by the indexing model from the issue text.

Assessment

Tech stack
node.js
Domain
devtools, embedded-iot
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Needs clarification
Newbie friendliness
28/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.