# Phase 4a - done, bug with "File not found (bl, app, f_test) fixed
This commit is contained in:
parent
657b3a2e63
commit
3279022829
6 changed files with 108 additions and 112 deletions
|
|
@ -1,81 +0,0 @@
|
||||||
# Gate 4a
|
|
||||||
|
|
||||||
## Case 1
|
|
||||||
|
|
||||||
```bash
|
|
||||||
2026-07-06 10:07:16,955 DEBUG spsdk.mboot.protocol.bulk_protocol IN [1016]: 03, 00, 0C, 00, A0, 00, 00, 02, 00, 00, 00, 00, 11, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00
|
|
||||||
2026-07-06 10:07:16,955 DEBUG spsdk.mboot.mcuboot RX-PACKET: Tag=GenericResponse, Status=Success, Cmd=ConfigureMemory
|
|
||||||
2026-07-06 10:07:16,955 INFO spsdk.mboot.mcuboot CMD: Status: 0 (0x0) Success.
|
|
||||||
2026-07-06 10:07:16,956 INFO spsdk.mboot.mcuboot CMD: FlashEraseAll(mem_id=9)
|
|
||||||
2026-07-06 10:07:16,956 DEBUG spsdk.mboot.mcuboot TX-PACKET: Tag=FlashEraseAll, Flags=0x00, P[0]=0x00000009
|
|
||||||
2026-07-06 10:07:16,956 DEBUG spsdk.mboot.protocol.bulk_protocol OUT[12]: 01, 00, 08, 00, 01, 00, 00, 01, 09, 00, 00, 00
|
|
||||||
2026-07-06 10:07:16,956 DEBUG libusbsio.hidapi.dev HID device 3185030394352 writing[12]: 0x010008000100000109000000
|
|
||||||
2026-07-06 10:07:16,957 DEBUG libusbsio.hidapi.dev HID device 3185030394352 wrote 1016 bytes
|
|
||||||
2026-07-06 10:07:21,297 DEBUG libusbsio.hidapi.dev HID device 3185030394352 read[-1]: None
|
|
||||||
2026-07-06 10:07:21,297 DEBUG spsdk.utils.interfaces.device.usb_device Cannot read from HID device, error=-1
|
|
||||||
2026-07-06 10:07:21,297 DEBUG spsdk.mboot.mcuboot RX-PACKET: No Response, Timeout Error !
|
|
||||||
2026-07-06 10:07:21,298 DEBUG spsdk.mboot.mcuboot RX-PACKET: Tag=0x01, Flags=0x00 [14, 27, 00, 00]
|
|
||||||
2026-07-06 10:07:21,298 INFO spsdk.mboot.mcuboot CMD: Status: 10004 (0x2714) No response packet from target device.
|
|
||||||
2026-07-06 10:07:21,299 INFO libusbsio Loading SIO library: C:\Development\IMXRT\tft_manufacture_test\tools\production\.venv\Lib\site-packages\libusbsio\bin\x64\libusbsio.dll
|
|
||||||
2026-07-06 10:07:21,347 INFO libusbsio HID enumeration[3185065344192]: initialized
|
|
||||||
2026-07-06 10:07:21,347 DEBUG libusbsio HID enumeration[3185065344192]: device #0: USB Receiver
|
|
||||||
2026-07-06 10:07:21,347 DEBUG libusbsio HID enumeration[3185065344192]: device #1: USB Receiver
|
|
||||||
2026-07-06 10:07:21,347 DEBUG libusbsio HID enumeration[3185065344192]: device #2: USB Receiver
|
|
||||||
2026-07-06 10:07:21,347 DEBUG libusbsio HID enumeration[3185065344192]: device #3: USB Receiver
|
|
||||||
2026-07-06 10:07:21,347 DEBUG libusbsio HID enumeration[3185065344192]: device #4: USB Receiver
|
|
||||||
2026-07-06 10:07:21,348 DEBUG libusbsio HID enumeration[3185065344192]: device #5: USB Receiver
|
|
||||||
2026-07-06 10:07:21,348 DEBUG libusbsio HID enumeration[3185065344192]: device #6: HIDI2C Device
|
|
||||||
2026-07-06 10:07:21,348 DEBUG libusbsio HID enumeration[3185065344192]: device #7: USB Receiver
|
|
||||||
2026-07-06 10:07:21,348 DEBUG libusbsio HID enumeration[3185065344192]: device #8: HIDI2C Device
|
|
||||||
2026-07-06 10:07:21,348 DEBUG libusbsio HID enumeration[3185065344192]: device #9: USB Receiver
|
|
||||||
2026-07-06 10:07:21,348 DEBUG libusbsio HID enumeration[3185065344192]: device #10: HIDI2C Device
|
|
||||||
2026-07-06 10:07:21,348 INFO libusbsio HID enumeration[3185065344192]: finished, total 11 devices
|
|
||||||
2026-07-06 10:07:21,348 INFO libusbsio SIO library unloaded
|
|
||||||
2026-07-06 10:07:21,348 INFO spsdk.mboot.mcuboot Closing: identifier='usb', device=USB COMPOSITE DEVICE (0x15A2, 0x0073)path=b'\\\\?\\hid#vid_15a2&pid_0073#7&100c291f&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}' sn=''
|
|
||||||
2026-07-06 10:07:21,348 DEBUG spsdk.utils.interfaces.device.usb_device Closing the Interface: USB COMPOSITE DEVICE (0x15A2, 0x0073)path=b'\\\\?\\hid#vid_15a2&pid_0073#7&100c291f&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}' sn=''
|
|
||||||
2026-07-06 10:07:21,348 INFO libusbsio.hidapi.dev HID device 0x2e5929af1f0 closed
|
|
||||||
2026-07-06 10:07:21,348 DEBUG spsdk.utils.interfaces.device.usb_device Closing the Interface: USB COMPOSITE DEVICE (0x15A2, 0x0073)path=b'\\\\?\\hid#vid_15a2&pid_0073#7&100c291f&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}' sn=''
|
|
||||||
2026-07-06 10:07:21,349 ERROR app.flasher erase_chip: flash_erase_all вернул False (устройство пропало с шины)
|
|
||||||
2026-07-06 10:07:21,351 INFO libusbsio SIO library unloaded
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
## Case 2
|
|
||||||
|
|
||||||
```bash
|
|
||||||
2026-07-06 11:11:37,016 DEBUG spsdk.mboot.protocol.bulk_protocol IN [1016]: 03, 00, 0C, 00, A0, 00, 00, 02, 00, 00, 00, 00, 11, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00
|
|
||||||
2026-07-06 11:11:37,016 DEBUG spsdk.mboot.mcuboot RX-PACKET: Tag=GenericResponse, Status=Success, Cmd=ConfigureMemory
|
|
||||||
2026-07-06 11:11:37,017 INFO spsdk.mboot.mcuboot CMD: Status: 0 (0x0) Success.
|
|
||||||
2026-07-06 11:11:37,018 INFO spsdk.mboot.mcuboot CMD: FlashEraseRegion(address=0x60000000, length=143360, mem_id=0)
|
|
||||||
2026-07-06 11:11:37,018 DEBUG spsdk.mboot.mcuboot TX-PACKET: Tag=FlashEraseRegion, Flags=0x00, P[0]=0x60000000, P[1]=0x00023000, P[2]=0x00000000
|
|
||||||
2026-07-06 11:11:37,018 DEBUG spsdk.mboot.protocol.bulk_protocol OUT[20]: 01, 00, 10, 00, 02, 00, 00, 03, 00, 00, 00, 60, 00, 30, 02, 00, 00, 00, 00, 00
|
|
||||||
2026-07-06 11:11:37,018 DEBUG libusbsio.hidapi.dev HID device 2020961928848 writing[20]: 0x0100100002000003000000600030020000000000
|
|
||||||
2026-07-06 11:11:37,018 DEBUG libusbsio.hidapi.dev HID device 2020961928848 wrote 1016 bytes
|
|
||||||
2026-07-06 11:11:37,301 DEBUG libusbsio.hidapi.dev HID device 2020961928848 read[-1]: None
|
|
||||||
2026-07-06 11:11:37,301 DEBUG spsdk.utils.interfaces.device.usb_device Cannot read from HID device, error=-1
|
|
||||||
2026-07-06 11:11:37,301 DEBUG spsdk.mboot.mcuboot RX-PACKET: No Response, Timeout Error !
|
|
||||||
2026-07-06 11:11:37,301 DEBUG spsdk.mboot.mcuboot RX-PACKET: Tag=0x02, Flags=0x00 [14, 27, 00, 00]
|
|
||||||
2026-07-06 11:11:37,301 INFO spsdk.mboot.mcuboot CMD: Status: 10004 (0x2714) No response packet from target device.
|
|
||||||
2026-07-06 11:11:37,301 INFO libusbsio Loading SIO library: C:\Development\IMXRT\tft_manufacture_test\tools\production\.venv\Lib\site-packages\libusbsio\bin\x64\libusbsio.dll
|
|
||||||
2026-07-06 11:11:37,349 INFO libusbsio HID enumeration[2020961011232]: initialized
|
|
||||||
2026-07-06 11:11:37,349 DEBUG libusbsio HID enumeration[2020961011232]: device #0: USB Receiver
|
|
||||||
2026-07-06 11:11:37,349 DEBUG libusbsio HID enumeration[2020961011232]: device #1: USB Receiver
|
|
||||||
2026-07-06 11:11:37,349 DEBUG libusbsio HID enumeration[2020961011232]: device #2: USB Receiver
|
|
||||||
2026-07-06 11:11:37,349 DEBUG libusbsio HID enumeration[2020961011232]: device #3: USB Receiver
|
|
||||||
2026-07-06 11:11:37,349 DEBUG libusbsio HID enumeration[2020961011232]: device #4: USB Receiver
|
|
||||||
2026-07-06 11:11:37,349 DEBUG libusbsio HID enumeration[2020961011232]: device #5: USB Receiver
|
|
||||||
2026-07-06 11:11:37,349 DEBUG libusbsio HID enumeration[2020961011232]: device #6: HIDI2C Device
|
|
||||||
2026-07-06 11:11:37,349 DEBUG libusbsio HID enumeration[2020961011232]: device #7: USB Receiver
|
|
||||||
2026-07-06 11:11:37,350 DEBUG libusbsio HID enumeration[2020961011232]: device #8: HIDI2C Device
|
|
||||||
2026-07-06 11:11:37,350 DEBUG libusbsio HID enumeration[2020961011232]: device #9: USB Receiver
|
|
||||||
2026-07-06 11:11:37,350 DEBUG libusbsio HID enumeration[2020961011232]: device #10: HIDI2C Device
|
|
||||||
2026-07-06 11:11:37,350 INFO libusbsio HID enumeration[2020961011232]: finished, total 11 devices
|
|
||||||
2026-07-06 11:11:37,350 INFO libusbsio SIO library unloaded
|
|
||||||
2026-07-06 11:11:37,350 INFO spsdk.mboot.mcuboot Closing: identifier='usb', device=USB COMPOSITE DEVICE (0x15A2, 0x0073)path=b'\\\\?\\hid#vid_15a2&pid_0073#7&100c291f&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}' sn=''
|
|
||||||
2026-07-06 11:11:37,350 DEBUG spsdk.utils.interfaces.device.usb_device Closing the Interface: USB COMPOSITE DEVICE (0x15A2, 0x0073)path=b'\\\\?\\hid#vid_15a2&pid_0073#7&100c291f&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}' sn=''
|
|
||||||
2026-07-06 11:11:37,350 INFO libusbsio.hidapi.dev HID device 0x1d68ab7c690 closed
|
|
||||||
2026-07-06 11:11:37,350 DEBUG spsdk.utils.interfaces.device.usb_device Closing the Interface: USB COMPOSITE DEVICE (0x15A2, 0x0073)path=b'\\\\?\\hid#vid_15a2&pid_0073#7&100c291f&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}' sn=''
|
|
||||||
2026-07-06 11:11:37,350 ERROR app.flasher flash: flash_erase_region вернул False (устройство пропало с шины)
|
|
||||||
2026-07-06 11:11:37,354 INFO libusbsio SIO library unloaded
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
@ -64,16 +64,21 @@ class ServiceApp(App):
|
||||||
"""
|
"""
|
||||||
После прошивки:
|
После прошивки:
|
||||||
- firmware_test + успех → PostFlashScreen (промпт смены BootMode)
|
- firmware_test + успех → PostFlashScreen (промпт смены BootMode)
|
||||||
- всё остальное (production/custom, либо ошибка) → WaitingScreen
|
- production/custom + успех → WaitingScreen
|
||||||
- target=None — маркер потери соединения (см. ConnectionWatcherMixin)
|
- target=None — обрыв USB (watcher в простое ИЛИ backend во время
|
||||||
→ WaitingScreen с явной причиной возврата
|
активной операции, см. models.FlashResult, Фаза 4a вариант 2)
|
||||||
|
→ WaitingScreen с причиной (конкретный текст, если есть, иначе
|
||||||
|
общий fallback)
|
||||||
|
|
||||||
|
Логическая ошибка (плата на месте) сюда не долетает вовсе —
|
||||||
|
FlashScreen в этом случае не покидает себя (см. _do_flash/_do_erase).
|
||||||
"""
|
"""
|
||||||
if event.preset is not None:
|
if event.preset is not None:
|
||||||
self._last_flash_preset = event.preset
|
self._last_flash_preset = event.preset
|
||||||
|
|
||||||
if event.target is None and not event.success:
|
if event.target is None and not event.success:
|
||||||
self.switch_screen(
|
WaitingScreen(
|
||||||
WaitingScreen(disconnect_reason="Соединение с платой потеряно")
|
disconnect_reason=event.error_message or "Соединение с платой потеряно"
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ from pathlib import Path
|
||||||
from typing import Awaitable, Callable, Optional
|
from typing import Awaitable, Callable, Optional
|
||||||
|
|
||||||
from . import flash_backend
|
from . import flash_backend
|
||||||
from .models import FcbVariant, FlashProgress, FlashTarget
|
from .models import FcbVariant, FlashProgress, FlashResult, FlashTarget
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
@ -159,13 +159,14 @@ class Flasher:
|
||||||
async_progress_cb: Optional[ProgressCallback],
|
async_progress_cb: Optional[ProgressCallback],
|
||||||
sync_progress_cb: Optional[flash_backend.ProgressCallback],
|
sync_progress_cb: Optional[flash_backend.ProgressCallback],
|
||||||
**kwargs: object,
|
**kwargs: object,
|
||||||
) -> bool:
|
) -> FlashResult:
|
||||||
"""Выполнить flash_backend.flash()/erase_chip() в потоке.
|
"""Выполнить flash_backend.flash()/erase_chip() в потоке.
|
||||||
|
|
||||||
flash_backend поднимает FlashBackendError (включая ConnectionLostError,
|
flash_backend поднимает FlashBackendError (включая ConnectionLostError,
|
||||||
см. Фазу 4) вместо возврата False — здесь это конвертируется обратно
|
см. Фазу 4) вместо возврата False — здесь это конвертируется обратно
|
||||||
в контракт Flasher (bool + событие phase="error"), который был у
|
в контракт Flasher (FlashResult + событие phase="error"). connection_lost
|
||||||
subprocess-версии (ненулевой returncode).
|
транслируется из exc.connection_lost (Фаза 4a, вариант 2) — экран
|
||||||
|
различает физический обрыв от логической ошибки без парсинга текста.
|
||||||
|
|
||||||
Отдельный except Exception — safety net (Фаза 4, согласовано):
|
Отдельный except Exception — safety net (Фаза 4, согласовано):
|
||||||
любое непредвиденное исключение из worker-потока (не только
|
любое непредвиденное исключение из worker-потока (не только
|
||||||
|
|
@ -176,7 +177,7 @@ class Flasher:
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
await asyncio.to_thread(func, *args, progress_cb=sync_progress_cb, **kwargs)
|
await asyncio.to_thread(func, *args, progress_cb=sync_progress_cb, **kwargs)
|
||||||
return True
|
return FlashResult(ok=True)
|
||||||
except flash_backend.FlashBackendError as exc:
|
except flash_backend.FlashBackendError as exc:
|
||||||
logger.error("%s: %s", getattr(func, "__name__", func), exc)
|
logger.error("%s: %s", getattr(func, "__name__", func), exc)
|
||||||
if async_progress_cb is not None:
|
if async_progress_cb is not None:
|
||||||
|
|
@ -185,7 +186,7 @@ class Flasher:
|
||||||
phase="error", percent=0, message=_format_error_message(exc)
|
phase="error", percent=0, message=_format_error_message(exc)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
return False
|
return FlashResult(ok=False, connection_lost=exc.connection_lost)
|
||||||
except Exception as exc: # noqa: BLE001 — safety net, см. docstring
|
except Exception as exc: # noqa: BLE001 — safety net, см. docstring
|
||||||
logger.exception(
|
logger.exception(
|
||||||
"%s: непредвиденная ошибка", getattr(func, "__name__", func)
|
"%s: непредвиденная ошибка", getattr(func, "__name__", func)
|
||||||
|
|
@ -198,19 +199,19 @@ class Flasher:
|
||||||
message=f"Непредвиденная ошибка: {exc}",
|
message=f"Непредвиденная ошибка: {exc}",
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
return False
|
return FlashResult(ok=False, connection_lost=False)
|
||||||
|
|
||||||
# ── Erase ────────────────────────────────────────────────────────────
|
# ── Erase ────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
async def erase_chip(
|
async def erase_chip(
|
||||||
self,
|
self,
|
||||||
progress_cb: Optional[ProgressCallback] = None,
|
progress_cb: Optional[ProgressCallback] = None,
|
||||||
) -> bool:
|
) -> FlashResult:
|
||||||
"""
|
"""
|
||||||
Chip erase Flash через USB SDP (flash_backend.erase_chip).
|
Chip erase Flash через USB SDP (flash_backend.erase_chip).
|
||||||
Занимает ~30 с для W25Q128. FCB будет стёрт.
|
Занимает ~30 с для W25Q128. FCB будет стёрт.
|
||||||
|
|
||||||
:return: True при успехе.
|
:return: FlashResult(ok, connection_lost) — см. models.FlashResult.
|
||||||
"""
|
"""
|
||||||
loop = asyncio.get_running_loop()
|
loop = asyncio.get_running_loop()
|
||||||
sync_cb = _make_sync_progress_cb(progress_cb, loop)
|
sync_cb = _make_sync_progress_cb(progress_cb, loop)
|
||||||
|
|
@ -229,7 +230,7 @@ class Flasher:
|
||||||
bin_path: Optional[Path] = None,
|
bin_path: Optional[Path] = None,
|
||||||
use_dcd: bool = False,
|
use_dcd: bool = False,
|
||||||
fcb_variant: FcbVariant = FcbVariant.W25Q128,
|
fcb_variant: FcbVariant = FcbVariant.W25Q128,
|
||||||
) -> bool:
|
) -> FlashResult:
|
||||||
"""
|
"""
|
||||||
Запустить прошивку через flash_backend.
|
Запустить прошивку через flash_backend.
|
||||||
|
|
||||||
|
|
@ -242,7 +243,7 @@ class Flasher:
|
||||||
при сборке HAB-образа через HabImage.
|
при сборке HAB-образа через HabImage.
|
||||||
:param fcb_variant: Только для CUSTOM — какой явный FCB-блоб (dcd/*_fdcb.bin)
|
:param fcb_variant: Только для CUSTOM — какой явный FCB-блоб (dcd/*_fdcb.bin)
|
||||||
записать в Flash[0x60000000] вместо auto-config.
|
записать в Flash[0x60000000] вместо auto-config.
|
||||||
:return: True при успехе.
|
:return: FlashResult(ok, connection_lost) — см. models.FlashResult.
|
||||||
"""
|
"""
|
||||||
loop = asyncio.get_running_loop()
|
loop = asyncio.get_running_loop()
|
||||||
sync_cb = _make_sync_progress_cb(progress_cb, loop)
|
sync_cb = _make_sync_progress_cb(progress_cb, loop)
|
||||||
|
|
@ -261,20 +262,20 @@ class Flasher:
|
||||||
)
|
)
|
||||||
|
|
||||||
elif target == FlashTarget.PRODUCTION:
|
elif target == FlashTarget.PRODUCTION:
|
||||||
ok = await self._run_flash_op(
|
result = await self._run_flash_op(
|
||||||
flash_backend.flash,
|
flash_backend.flash,
|
||||||
_firmware_hab_path("bootloader"),
|
_firmware_hab_path("bootloader"),
|
||||||
async_progress_cb=progress_cb,
|
async_progress_cb=progress_cb,
|
||||||
sync_progress_cb=sync_cb,
|
sync_progress_cb=sync_cb,
|
||||||
)
|
)
|
||||||
if ok:
|
if result.ok:
|
||||||
ok = await self._run_flash_op(
|
result = await self._run_flash_op(
|
||||||
flash_backend.flash,
|
flash_backend.flash,
|
||||||
_firmware_hab_path("app"),
|
_firmware_hab_path("app"),
|
||||||
async_progress_cb=progress_cb,
|
async_progress_cb=progress_cb,
|
||||||
sync_progress_cb=sync_cb,
|
sync_progress_cb=sync_cb,
|
||||||
)
|
)
|
||||||
return ok
|
return result
|
||||||
|
|
||||||
elif target == FlashTarget.CUSTOM:
|
elif target == FlashTarget.CUSTOM:
|
||||||
if bin_path is None:
|
if bin_path is None:
|
||||||
|
|
@ -283,7 +284,7 @@ class Flasher:
|
||||||
bin_path, use_dcd, fcb_variant, progress_cb, sync_cb
|
bin_path, use_dcd, fcb_variant, progress_cb, sync_cb
|
||||||
)
|
)
|
||||||
|
|
||||||
return False
|
return FlashResult(ok=False)
|
||||||
|
|
||||||
async def _flash_custom(
|
async def _flash_custom(
|
||||||
self,
|
self,
|
||||||
|
|
@ -292,7 +293,7 @@ class Flasher:
|
||||||
fcb_variant: FcbVariant,
|
fcb_variant: FcbVariant,
|
||||||
progress_cb: Optional[ProgressCallback],
|
progress_cb: Optional[ProgressCallback],
|
||||||
sync_cb: Optional[flash_backend.ProgressCallback],
|
sync_cb: Optional[flash_backend.ProgressCallback],
|
||||||
) -> bool:
|
) -> FlashResult:
|
||||||
"""
|
"""
|
||||||
Прошить «сырой» (не-HAB) кастомный бинарник из custom_binaries/.
|
Прошить «сырой» (не-HAB) кастомный бинарник из custom_binaries/.
|
||||||
|
|
||||||
|
|
@ -311,7 +312,9 @@ class Flasher:
|
||||||
raw_bin_path, use_dcd, progress_cb, sync_cb
|
raw_bin_path, use_dcd, progress_cb, sync_cb
|
||||||
)
|
)
|
||||||
if hab_bin is None:
|
if hab_bin is None:
|
||||||
return False
|
# Ошибка сборки HAB — чисто локальная операция (HabImage,
|
||||||
|
# временный файл), к USB-соединению отношения не имеет.
|
||||||
|
return FlashResult(ok=False)
|
||||||
|
|
||||||
fcb_path = flash_backend.fcb_blob_path(fcb_variant.fcb_filename)
|
fcb_path = flash_backend.fcb_blob_path(fcb_variant.fcb_filename)
|
||||||
try:
|
try:
|
||||||
|
|
|
||||||
|
|
@ -135,3 +135,22 @@ class FlashProgress:
|
||||||
# | "reset" | "hab_build" | "done" | "error"
|
# | "reset" | "hab_build" | "done" | "error"
|
||||||
percent: int # 0..100
|
percent: int # 0..100
|
||||||
message: str
|
message: str
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True)
|
||||||
|
class FlashResult:
|
||||||
|
"""Результат Flasher.flash()/erase_chip() (Фаза 4a, вариант 2).
|
||||||
|
|
||||||
|
Раньше публичный API Flasher() возвращал голый bool — экран не мог
|
||||||
|
отличить физический обрыв USB от логической ошибки (файл не найден,
|
||||||
|
битый custom-бинарь, ошибка сборки HAB) и одинаково уводил оператора
|
||||||
|
на WaitingScreen в обоих случаях, хотя при логической ошибке плата
|
||||||
|
остаётся на месте и разумнее остаться на FlashScreen.
|
||||||
|
|
||||||
|
connection_lost транслируется из FlashBackendError.connection_lost
|
||||||
|
(см. flash_backend.py) без парсинга текста сообщения — тот же принцип,
|
||||||
|
что и там.
|
||||||
|
"""
|
||||||
|
|
||||||
|
ok: bool
|
||||||
|
connection_lost: bool = False
|
||||||
|
|
|
||||||
|
|
@ -51,6 +51,18 @@ class FlashScreen(Screen, ConnectionWatcherMixin):
|
||||||
№4 отчёта). Во время самой прошивки/erase мониторинг приостановлен —
|
№4 отчёта). Во время самой прошивки/erase мониторинг приостановлен —
|
||||||
обрыв в этом случае обнаруживает сам flash_backend (SPSDKConnectionError
|
обрыв в этом случае обнаруживает сам flash_backend (SPSDKConnectionError
|
||||||
→ ConnectionLostError, см. Фазу 4) и репортит через #flash-log.
|
→ ConnectionLostError, см. Фазу 4) и репортит через #flash-log.
|
||||||
|
|
||||||
|
FlashResult (Фаза 4a, вариант 2) различает физический обрыв от
|
||||||
|
логической ошибки без парсинга текста — см. models.FlashResult:
|
||||||
|
- connection_lost=True → уходим на WaitingScreen (тот же маркер
|
||||||
|
target=None, что и watcher-детект в простое), текст ошибки
|
||||||
|
прокидывается через FlashDone.error_message, чтобы не терять
|
||||||
|
конкретику ради общего "Соединение с платой потеряно".
|
||||||
|
- connection_lost=False → плата на месте, остаёмся на FlashScreen.
|
||||||
|
Раньше (до варианта 2) любая ошибка уводила на WaitingScreen,
|
||||||
|
который почти мгновенно переоткрывал FlashScreen заново (плата
|
||||||
|
на шине видна) и уничтожал #flash-log раньше, чем оператор
|
||||||
|
успевал прочитать (см. Гейт 4a, п.0 отчёта).
|
||||||
"""
|
"""
|
||||||
|
|
||||||
BINDINGS = [
|
BINDINGS = [
|
||||||
|
|
@ -63,17 +75,24 @@ class FlashScreen(Screen, ConnectionWatcherMixin):
|
||||||
success: bool,
|
success: bool,
|
||||||
target: Optional[FlashTarget] = None,
|
target: Optional[FlashTarget] = None,
|
||||||
preset: Optional[FlashPreset] = None,
|
preset: Optional[FlashPreset] = None,
|
||||||
|
error_message: Optional[str] = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.success = success
|
self.success = success
|
||||||
self.target = target
|
self.target = target
|
||||||
self.preset = preset
|
self.preset = preset
|
||||||
|
# Заполняется только при connection_lost=True — конкретный текст
|
||||||
|
# обрыва вместо общего "Соединение с платой потеряно" в app.py.
|
||||||
|
# При логической ошибке экран никуда не уходит (см. _do_flash),
|
||||||
|
# и это поле не используется.
|
||||||
|
self.error_message = error_message
|
||||||
|
|
||||||
def __init__(self, preset: Optional[FlashPreset] = None, **kwargs) -> None:
|
def __init__(self, preset: Optional[FlashPreset] = None, **kwargs) -> None:
|
||||||
super().__init__(**kwargs)
|
super().__init__(**kwargs)
|
||||||
self._flasher = Flasher()
|
self._flasher = Flasher()
|
||||||
self._flashing = False
|
self._flashing = False
|
||||||
self._preset = preset or FlashPreset()
|
self._preset = preset or FlashPreset()
|
||||||
|
self._last_error_message: Optional[str] = None
|
||||||
|
|
||||||
def compose(self) -> ComposeResult:
|
def compose(self) -> ComposeResult:
|
||||||
with AppFrame(id="flash-frame"):
|
with AppFrame(id="flash-frame"):
|
||||||
|
|
@ -217,10 +236,11 @@ class FlashScreen(Screen, ConnectionWatcherMixin):
|
||||||
async def _do_flash(
|
async def _do_flash(
|
||||||
self, target: FlashTarget, bin_path: Optional[Path], preset: FlashPreset
|
self, target: FlashTarget, bin_path: Optional[Path], preset: FlashPreset
|
||||||
) -> None:
|
) -> None:
|
||||||
|
self._last_error_message = None
|
||||||
self._set_busy(True)
|
self._set_busy(True)
|
||||||
self._show_progress(True)
|
self._show_progress(True)
|
||||||
self._log(f"▶ Прошивка: {target.value}")
|
self._log(f"▶ Прошивка: {target.value}")
|
||||||
ok = await self._flasher.flash(
|
result = await self._flasher.flash(
|
||||||
target=target,
|
target=target,
|
||||||
bin_path=bin_path,
|
bin_path=bin_path,
|
||||||
use_dcd=preset.use_dcd,
|
use_dcd=preset.use_dcd,
|
||||||
|
|
@ -228,19 +248,47 @@ class FlashScreen(Screen, ConnectionWatcherMixin):
|
||||||
progress_cb=self._on_progress,
|
progress_cb=self._on_progress,
|
||||||
)
|
)
|
||||||
self._set_busy(False)
|
self._set_busy(False)
|
||||||
self._finish_progress(ok)
|
self._finish_progress(result.ok)
|
||||||
self._log("✅ Готово" if ok else "❌ Ошибка")
|
self._log("✅ Готово" if result.ok else "❌ Ошибка")
|
||||||
self.post_message(self.FlashDone(success=ok, target=target, preset=preset))
|
|
||||||
|
if result.ok:
|
||||||
|
self.post_message(
|
||||||
|
self.FlashDone(success=True, target=target, preset=preset)
|
||||||
|
)
|
||||||
|
elif result.connection_lost:
|
||||||
|
# Обрыв во время активной прошивки — watcher в это время приглушён
|
||||||
|
# (см. _check_sdp_present), обрыв обнаружил сам backend. Тот же
|
||||||
|
# маркер target=None, что и у watcher-детекта в простое (Гейт 4a).
|
||||||
|
self.post_message(
|
||||||
|
self.FlashDone(
|
||||||
|
success=False,
|
||||||
|
target=None,
|
||||||
|
preset=preset,
|
||||||
|
error_message=self._last_error_message,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
# else: логическая ошибка, плата на месте (вариант 2, Гейт 4a) —
|
||||||
|
# остаёмся на FlashScreen. Сообщение уже в #flash-log (_on_progress),
|
||||||
|
# кнопки уже разблокированы (_set_busy(False) выше).
|
||||||
|
|
||||||
@work(exclusive=True, thread=False)
|
@work(exclusive=True, thread=False)
|
||||||
async def _do_erase(self) -> None:
|
async def _do_erase(self) -> None:
|
||||||
|
self._last_error_message = None
|
||||||
self._set_busy(True)
|
self._set_busy(True)
|
||||||
self._show_progress(True)
|
self._show_progress(True)
|
||||||
self._log("⚠ Очистка памяти (~30 с)...")
|
self._log("⚠ Очистка памяти (~30 с)...")
|
||||||
ok = await self._flasher.erase_chip(progress_cb=self._on_progress)
|
result = await self._flasher.erase_chip(progress_cb=self._on_progress)
|
||||||
self._set_busy(False)
|
self._set_busy(False)
|
||||||
self._finish_progress(ok)
|
self._finish_progress(result.ok)
|
||||||
self._log("✅ Очистка памяти завершена" if ok else "❌ Очистка памяти: ошибка")
|
self._log(
|
||||||
|
"✅ Очистка памяти завершена" if result.ok else "❌ Очистка памяти: ошибка"
|
||||||
|
)
|
||||||
|
if result.connection_lost:
|
||||||
|
self.post_message(
|
||||||
|
self.FlashDone(
|
||||||
|
success=False, target=None, error_message=self._last_error_message
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
# ── Вспомогательные ───────────────────────────────────────────────────────
|
# ── Вспомогательные ───────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
|
@ -273,6 +321,8 @@ class FlashScreen(Screen, ConnectionWatcherMixin):
|
||||||
bar = self.query_one("#flash-progress-bar", ProgressBar)
|
bar = self.query_one("#flash-progress-bar", ProgressBar)
|
||||||
bar.update(total=100, progress=progress.percent)
|
bar.update(total=100, progress=progress.percent)
|
||||||
self._log(progress.message)
|
self._log(progress.message)
|
||||||
|
if progress.phase == "error":
|
||||||
|
self._last_error_message = progress.message
|
||||||
|
|
||||||
def _show_progress(self, visible: bool) -> None:
|
def _show_progress(self, visible: bool) -> None:
|
||||||
"""Показать/скрыть прогресс-бар. Скрыт в простое — без анимации."""
|
"""Показать/скрыть прогресс-бар. Скрыт в простое — без анимации."""
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue