how can I instruct PIO to link the bootloader such that the storage address (for upload) starts at 0x1FFF F000, but that the address after re-mapping (for operation) starts at 0x0000 0000…? Or is this not required for some reason…?
And further reading the reference manual gives me the impression that you indeed have to set a register bit to either reboot to Bootloader memory (so 0x1fff f000 will be remaped to 0x0) or the app (regular code flash remapped to 0x0)
And that remapping & reboot has to be triggered via the functions described by you already.
The bootloader / IAP program has to be written once at the specified address though, like the chinese PDF says…
将 IAP 程序通过 WCH—LinkUtility 下载到 0x1FFFF000。
→ “Download the IAP program to 0x1FFFF000 via WCH-LinkUtility.”
While we do have the facilities for it to change the start linker address, that’s not needed then because in IAP / Bootloader mode, the memory is remapped and so the app will run from 0x0 and thus should be compiled / linked as if it were at 0x0.
do I understand correctly that both APP and IAP codes are linked for starting address 0x00, but are uploaded to 0x8000000 (APP) or 0x1FFFF000 (IAP)…? Actually that makes much more sense than my initial thought!
But then the next question: how do change the target upload address in PlatformIO for IAP? Apparently the default setting is set to 0x8000000 (APP)…? Thanks a lot in advance!
During an upload, OpenOCD is given the .elf file (upload_target = target_elf), from which it will automatically figure out the upload address based on the start addresses of the to-be-loaded sections, which are determined by the linker script of the application.
In PlatformIO we give it a unified linking script of
where the #flash_start template variables are substituted based on defaults or given platformio.ini values
meaning that, if you would add
board_upload.offset_address = 0x8000000
the application would be linked to be starting at 0x8000000 and the upload program would also try and write to this address.
Note that the default is 0x0 for the flash origin address, because 0x8000000 would be remapped to 0x0 for a normal app run (just like the bootloader would).
…that however results in the pecularity that the flash origin address (linker script) can’t be independently controlled from the upload address, with the current logic they’ll always match. However, if say we want to build + upload the IAP bootloader using PlatformIO, it might be okay to use board_upload.offset_address = 0x1FFFF000 because 1. it will cause the program to be uploaded to the correct address and 2. even if the MCU remaps 0x0 → 0x1FFFF000, I think the memory is also still available, or rather mirrored, at the original 0x1FFFF000, so it happens to work.
** Programming Started **
Info : device id = 0xaa42abcd
Info : flash size = 16kbytes
Warn : no flash bank found for address 0x1ffff000
Warn : no flash bank found for address 0x1ffff878
** Programming Finished **
** Verify Started **
Error: checksum mismatch - attempting binary compare
embedded:startup.tcl:1162: Error: ** Verify Failed **
in procedure 'program'
in procedure 'program_error' called at file "embedded:startup.tcl", line 1223
at file "embedded:startup.tcl", line 1162
*** [upload] Error 1
I noticed that the build log reports a total codesize of ~69kB - mainly due to debug code. But according to the DS the “System Flash” has only 1920B. Can that be the problem?
Can you use the WCH-LinkUtility instead like the chinese docs say? If you have MounRiver IDE installed, it’s C:\MounRiver\MounRiver_Studio\ExTool\SWDTool\WCH-LinkUtility.exe, otherwise, https://file.io/DweYK7WotV7q
IMHO that is because the IAP binary (2176B) is larger than the System Flash size (1920B). To me the below verbose build output seems to indicate that the debug code is responsible for most of that. Is there any way to omit debug code? And while we’re at it, maybe also tell PIO that for this project the flash size is only 1920B, not 16kB…?
after optimizing the example a bit I could add a mode indication by LED (fast blinking). The APP example blinks the same pin slowly. That way I always know which code is actually running
then I seemingly bricked the device:
while playing around with the IAP example I commented the USART code and the mode switching. I figured I can always flash via debug interface
switching to IAP mode worked as expected (LED blinks fast), but now WCH-LinkE can no longer connect (Error: WCH-Link underlying protocol error: 55 ). Power off/on also has no effect, device remains in IAP mode. And since mode switching is commented, I cannot exit IAP mode
To my understanding that means:
boot mode information is indeed stored in flash (see initial post). Else information would be lost after power off
debug not possibly in IAP mode indicates that on µC side debug seems to be via code included in normal applications, which is omitted in IAP example. Is this why a special linker file is required? Or is there another information why the debugger can connect in APP mode, but not in IAP mode?
PS: any idea if/how I can recover my device? I don’t mind the 10ct, but replacing the µC is a pain
Another person also thought they had bricked their ch32v003, but with a bit of timing, you can hold down the RESET button of the board (or power it off), press “Upload”, then when the uploader seems to hang or connect, release reset (or give power). Might need multiple tries.