Author Topic: CH32V003 and Flash alias address  (Read 1349 times)

0 Members and 1 Guest are viewing this topic.

Offline rhodgesTopic starter

  • Frequent Contributor
  • **
  • Posts: 327
  • Country: us
  • Available for embedded projects.
    • My public libraries, code samples, and projects for STM8.
CH32V003 and Flash alias address
« on: August 17, 2024, 04:25:48 pm »
This is not a problem, but a question that has been nagging me for a while.

In the CH32V003 datasheet and reference manual, the address for the 16K of Flash is 0x08000000 and this is the address that I use with wlink to program the Flash. This is also the address area that I use with the 64-byte Flash erase and block program functions. So I would expect that this would be the "normal" address for my code.

But the linker script I am using (I forgot where I found it) gives a flash address of zero:
Code: [Select]
MEMORY
{
        FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 16K
        RAM (xrw)  : ORIGIN = 0x20000000, LENGTH = 2K
}
Both the datasheet state that the area at 0x00000000 is "Aliased to Flash or system memory depending on software configuration". But I can't seem to find any more information on that.

I am not happy with my code "just working fine" because of a configuration setting I can't find. I would like to get advice on whether it would be best to ignore it or change my linker script to 0x08000000 to be sure. Any other opinions on this? Thanks.
Currently developing STM8 and STM32. Past includes 6809, Z80, 8086, PIC, MIPS, PNX1302, and some 8748 and 6805. Check out my public code on github. https://github.com/unfrozen
 

Offline zilp

  • Frequent Contributor
  • **
  • Posts: 329
  • Country: de
Re: CH32V003 and Flash alias address
« Reply #1 on: August 17, 2024, 06:31:25 pm »
I don't think that the remapping is documented anywhere. But it doesn't really matter, the "code flash" is mapped to 0 by default, and gets executed from there on reset, and that's what is relevant for the linker. That there is a second copy in the address space doesn't matter, and what addresses the programmer has to write to the registers of the flash controller is also irrelevant for the linker.
 

Offline ataradov

  • Super Contributor
  • ***
  • Posts: 11710
  • Country: us
    • Personal site
Re: CH32V003 and Flash alias address
« Reply #2 on: August 17, 2024, 10:28:19 pm »
This is a leftover from the system being STM32 clone. In "STM32" version of the design you can select to boot from the bootloader (system) or from the flash. The actual physical address for the flash is 0x08000000. And depending on the BOOTx pin values, either boot ROM or the flash is mapped at 0. The CPU always executes from 0, so it will run either your program or the ROM.
Alex
 

Offline rhodgesTopic starter

  • Frequent Contributor
  • **
  • Posts: 327
  • Country: us
  • Available for embedded projects.
    • My public libraries, code samples, and projects for STM8.
Re: CH32V003 and Flash alias address
« Reply #3 on: August 17, 2024, 10:45:34 pm »
Thank you.

"If the CH32V documentation is unclear, read the STM32 manual..."

UPDATE:
Okay, I see in the CH32V003 manual 16.5 "User option bytes", there is a bit START_MODE to choose between:
0: Boot from user area
1: Boot from BOOT area (default)
Maybe this is part of the answer? But it does not seem right that the default would map the chip BOOT code to zero.
I guess I will leave it alone for now. Thanks again!
« Last Edit: August 17, 2024, 10:56:15 pm by rhodges »
Currently developing STM8 and STM32. Past includes 6809, Z80, 8086, PIC, MIPS, PNX1302, and some 8748 and 6805. Check out my public code on github. https://github.com/unfrozen
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 15220
  • Country: fr
Re: CH32V003 and Flash alias address
« Reply #4 on: August 17, 2024, 10:52:10 pm »
True for a lot of the CH32V MCUs, often you'll find complementary info in the STM32 manuals.

The CH32V003 has a bootloader in ROM and can "boot" either from it or from Flash directly (depending not on a pin on this chip IIRC, but on a config bit). Either is mapped at address zero for execution/read access, but you can't *write* Flash at this address.
 

Offline HwAoRrDk

  • Super Contributor
  • ***
  • Posts: 1561
  • Country: gb
Re: CH32V003 and Flash alias address
« Reply #5 on: August 18, 2024, 09:49:25 am »
True for a lot of the CH32V MCUs, often you'll find complementary info in the STM32 manuals.

Indeed. :) I have resorted to referring to the STM32F103 documentation when the CH32V003 docs weren't clear.

The CH32V003 has a bootloader in ROM and can "boot" either from it or from Flash directly (depending not on a pin on this chip IIRC, but on a config bit).

Actually, the 2K bootloader area is not ROM, but just another flash area. You can write to it with the WCH-LinkUtility. In fact, IIRC it doesn't even come programmed with a bootloader from factory; you have to write it there yourself with their 'IAP' UART bootloader (available from their GitHub) if you want to use the WCHISPTool utility. Or you can write your own bootloader and put it there.
« Last Edit: August 19, 2024, 03:54:17 pm by HwAoRrDk »
 

Offline zilp

  • Frequent Contributor
  • **
  • Posts: 329
  • Country: de
Re: CH32V003 and Flash alias address
« Reply #6 on: August 18, 2024, 11:12:01 am »
The CH32V003 has a bootloader in ROM and can "boot" either from it or from Flash directly (depending not on a pin on this chip IIRC, but on a config bit).

Actually, the 2K bootloader area is not ROM, but just another flash area. You can write to it (but not at runtime).

What does "not at runtime" mean here?! I mean, all the programming is done via the debug interface, and I would guess that the vendor stuff also executes code on the MCU for programming, so ... what exactly determines that it is "not at runtime"?!
 

Offline HwAoRrDk

  • Super Contributor
  • ***
  • Posts: 1561
  • Country: gb
Re: CH32V003 and Flash alias address
« Reply #7 on: August 18, 2024, 12:34:09 pm »
What does "not at runtime" mean here?! I mean, all the programming is done via the debug interface, and I would guess that the vendor stuff also executes code on the MCU for programming, so ... what exactly determines that it is "not at runtime"?!

As in, not in-application. That is, where code running on the MCU is what is re-programming the flash memory - as opposed to programming done via the SWIO debug interface (which does not actually involve, as far as I know, any code executing on the MCU).

However, I take back the statement that bootloader flash cannot be programmed at runtime. Upon checking the reference manual, it seems I was wrong. The reference manual documents a BOOT Key register (FLASH_BOOT_MODEKEYR) that allows you to unlock the bootloader area for writing. So I guess it will work similarly to regular programming of flash, but instead specifying a different address (e.g. 0x1FFFF000).

Edit: No, wait, I might be wrong again (and perhaps correct the first time). It seems the FLASH_BOOT_MODEKEYR register is simply used only to allow the boot mode to be changed - i.e. to specify that at next reset you want to the MCU to alias 0x00000000 to either user flash (0x08000000) or bootloader flash (0x1FFFF000). That is the only thing WCH's HAL code uses it for anyway.
« Last Edit: August 18, 2024, 12:46:06 pm by HwAoRrDk »
 

Offline zilp

  • Frequent Contributor
  • **
  • Posts: 329
  • Country: de
Re: CH32V003 and Flash alias address
« Reply #8 on: August 18, 2024, 01:25:03 pm »
What does "not at runtime" mean here?! I mean, all the programming is done via the debug interface, and I would guess that the vendor stuff also executes code on the MCU for programming, so ... what exactly determines that it is "not at runtime"?!

As in, not in-application. That is, where code running on the MCU is what is re-programming the flash memory - as opposed to programming done via the SWIO debug interface (which does not actually involve, as far as I know, any code executing on the MCU).

I mean, I ultimately have no idea what the vendor stuff does for programming, but at least the available documentation of the debug interface doesn't mention any way to write to the flash without executing code. And also, given that you can write to the flash by executing code via the debug interface, it would seem weird if they made the die larger to add a dedicated flash programming state machine rather than just repurpose the exiting stuff that can do the job already!?

However, I take back the statement that bootloader flash cannot be programmed at runtime. Upon checking the reference manual, it seems I was wrong. The reference manual documents a BOOT Key register (FLASH_BOOT_MODEKEYR) that allows you to unlock the bootloader area for writing. So I guess it will work similarly to regular programming of flash, but instead specifying a different address (e.g. 0x1FFFF000).

Yeah. I mean, I haven't tried it, and the documentation obviously isn't always entirely correct, but that's also part of why I was surprised that you couldn't program the boot flash "at runtime" specifically.

No, wait, I might be wrong again (and perhaps correct the first time). It seems the FLASH_BOOT_MODEKEYR register is simply used only to allow the boot mode to be changed - i.e. to specify that at next reset you want to the MCU to alias 0x00000000 to either user flash (0x08000000) or bootloader flash (0x1FFFF000). That is the only thing WCH's HAL code uses it for anyway.

Haha ... well, yeah, the documentation isn't exactly clear, I guess one would have to just try ...
« Last Edit: August 18, 2024, 01:31:28 pm by zilp »
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 15220
  • Country: fr
Re: CH32V003 and Flash alias address
« Reply #9 on: August 18, 2024, 08:18:57 pm »

Actually, the 2K bootloader area is not ROM, but just another flash area. You can write to it with the WCH-LinkUtility. In fact, IIRC it doesn't even come programmed with a bootloader from factory;

Ah, so it's like the CH32V3xx. The latter has 28KB flash dedicated to the bootloader. It does come preprogrammed from factory, though, and yes, you can reprogram this area. Can't tell for the CH32V003.
 

Offline rhodgesTopic starter

  • Frequent Contributor
  • **
  • Posts: 327
  • Country: us
  • Available for embedded projects.
    • My public libraries, code samples, and projects for STM8.
Re: CH32V003 and Flash alias address
« Reply #10 on: August 18, 2024, 10:39:54 pm »
I just dumped the boot code, but objdump won't disassemble a binary. Does anyone have a disassembler handy?
Argh. The forum won't let me post with a .bin file, so I renamed it .hex
Currently developing STM8 and STM32. Past includes 6809, Z80, 8086, PIC, MIPS, PNX1302, and some 8748 and 6805. Check out my public code on github. https://github.com/unfrozen
 

Offline zilp

  • Frequent Contributor
  • **
  • Posts: 329
  • Country: de
Re: CH32V003 and Flash alias address
« Reply #11 on: August 18, 2024, 10:51:54 pm »
I just dumped the boot code, but objdump won't disassemble a binary. Does anyone have a disassembler handy?

Code: [Select]
riscv64-unknown-elf-objdump -b binary -m riscv -D boot_code.hex
 
The following users thanked this post: rhodges

Offline HwAoRrDk

  • Super Contributor
  • ***
  • Posts: 1561
  • Country: gb
Re: CH32V003 and Flash alias address
« Reply #12 on: August 19, 2024, 03:53:07 pm »
It does come preprogrammed from factory, though, and yes, you can reprogram this area. Can't tell for the CH32V003.

Ah, you're right, it is pre-programmed. Don't remember why I had the idea it wasn't. I just dumped the bootloader from a CH32V003 that I've never touched the boot area on, and it matches what rhodges dumped.

The command line that zilp posted will perform the disassembly. But one note: I suspect unless you are using objdump from MounRiver-supplied toolchain, it will not correctly decode WCH's proprietary XW instruction set extension. So all those instructions (and there are quite a few) will mistakenly come out as floating-point operations (which the CH32V003 obviously doesn't have!). I found a decoder for XW instructions here: https://xw.macyler.moe/
 
The following users thanked this post: SiliconWizard

Offline rhodgesTopic starter

  • Frequent Contributor
  • **
  • Posts: 327
  • Country: us
  • Available for embedded projects.
    • My public libraries, code samples, and projects for STM8.
Re: CH32V003 and Flash alias address
« Reply #13 on: August 19, 2024, 04:46:08 pm »
I was wondering about those FP instructions in the listing. "This must be data embedded in code? What is this?"
Thanks for pointing that out.

I saw the pointer to the USART in there, as well as the unlock codes, FWIW.
Currently developing STM8 and STM32. Past includes 6809, Z80, 8086, PIC, MIPS, PNX1302, and some 8748 and 6805. Check out my public code on github. https://github.com/unfrozen
 

Offline HwAoRrDk

  • Super Contributor
  • ***
  • Posts: 1561
  • Country: gb
Re: CH32V003 and Flash alias address
« Reply #14 on: August 20, 2024, 02:19:42 pm »
I have been nerd-sniped into some reverse engineering of the disassembly of the bootloader. ;D

A question to those more in-the-know: the "zext.b" instruction (zero-extend byte?) is part of the 'B' RISC-V extension (specifically, Zbb), correct? Which the CH32V003 (i.e. QingKe V2) does not support. So therefore any such instructions present in the disassembly have been mis-interpreted and should instead (as far as I can tell) be "andi rd, rs, 255"? That is, an instruction to truncate/mask a word in a register to the LSB?
 
The following users thanked this post: pardo-bsso

Offline HwAoRrDk

  • Super Contributor
  • ***
  • Posts: 1561
  • Country: gb
Re: CH32V003 and Flash alias address
« Reply #15 on: August 20, 2024, 03:17:47 pm »
From what little I have seen so far I can say right now that the 'IAP' bootloader on WCH's GitHub (https://github.com/openwch/ch32v003/tree/main/EVT/EXAM/USART_IAP/CH32V003_IAP) is not exactly the same as the 'factory' bootloader that I pulled off one of my CH32V003F4P6 (TSSOP20) chips. There are similarities, but they don't have the same behaviour. For instance:

- 'IAP' checks pin PC0 and resets straight into user code if pin is low; factory bootloader doesn't do anything at all with GPIOC.
- Different UART baud rates - 'IAP' runs at 460800, factory appears to be 115384 (??? unsure about this, USART_BRR = 0xD0).
- Factory bootloader seems to read the CHIPID for some purpose, 'IAP' doesn't appear to.

I wonder if newer chips contain changed bootloader code and I just have early chips (date code 4123). I don't see any kind of version number in the flash - unless the four zero bytes after the watermark ASCII string "MCU ISP & WCH.CN" at the end of bootloader flash is a version number of zero... :)
 

Offline westfw

  • Super Contributor
  • ***
  • Posts: 4293
  • Country: us
Re: CH32V003 and Flash alias address
« Reply #16 on: August 21, 2024, 02:38:13 am »
Quote
Different UART baud rates - 'IAP' runs at 460800, factory appears to be 115384
115384 is about 0.2% away from 115200...  (closer than the built-in oscillator is likely to be?)

 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 15220
  • Country: fr
Re: CH32V003 and Flash alias address
« Reply #17 on: August 21, 2024, 04:09:27 am »
I have been nerd-sniped into some reverse engineering of the disassembly of the bootloader. ;D

A question to those more in-the-know: the "zext.b" instruction (zero-extend byte?) is part of the 'B' RISC-V extension (specifically, Zbb), correct? Which the CH32V003 (i.e. QingKe V2) does not support. So therefore any such instructions present in the disassembly have been mis-interpreted and should instead (as far as I can tell) be "andi rd, rs, 255"? That is, an instruction to truncate/mask a word in a register to the LSB?

zext.b and andi rd, rs, 255 are the same instruction indeed:
https://github.com/riscvarchive/riscv-code-size-reduction/issues/101

So "misinterpreted" is up to... interpretation. You can consider in this particular case that zext.b is a pseudo-instruction.
 

Online brucehoult

  • Super Contributor
  • ***
  • Posts: 4442
  • Country: nz
Re: CH32V003 and Flash alias address
« Reply #18 on: August 21, 2024, 04:33:25 am »
A question to those more in-the-know: the "zext.b" instruction (zero-extend byte?) is part of the 'B' RISC-V extension (specifically, Zbb), correct?

No. Zbb adds only sext.b, sext.h, and zext.h. The zext.b you found is just an assembler alias of andi, which of course the CH32V003's RV32E has, not an extension.

(and zext.w as an alias of Zba's add.uw)

Try running objdump -Mno-aliases
« Last Edit: August 21, 2024, 04:37:18 am by brucehoult »
 

Online brucehoult

  • Super Contributor
  • ***
  • Posts: 4442
  • Country: nz
Re: CH32V003 and Flash alias address
« Reply #19 on: August 21, 2024, 04:48:07 am »
I have been nerd-sniped into some reverse engineering of the disassembly of the bootloader. ;D

A question to those more in-the-know: the "zext.b" instruction (zero-extend byte?) is part of the 'B' RISC-V extension (specifically, Zbb), correct? Which the CH32V003 (i.e. QingKe V2) does not support. So therefore any such instructions present in the disassembly have been mis-interpreted and should instead (as far as I can tell) be "andi rd, rs, 255"? That is, an instruction to truncate/mask a word in a register to the LSB?

zext.b and andi rd, rs, 255 are the same instruction indeed:
https://github.com/riscvarchive/riscv-code-size-reduction/issues/101

So "misinterpreted" is up to... interpretation. You can consider in this particular case that zext.b is a pseudo-instruction.

I took the "I found a Zbb instruction in CH32V003 code" to mean "It can't possibly actually be zext.b, so it must be some WCH custom instruction, and the code would have to have used an andi if it wanted to zero extend a byte".

Which is wrong on two levels. Both that zext.b is an alias for andi, but also that no manufacturer should be putting custom instructions into opcode space reserved for standard extensions and therefore no WCH (or any other) custom extension should be mistakenly disassembled as something like a Zbb instruction.

The one exception to this is the political decision to call XTHeadVector a "custom extension" when in fact it is binary compatible with (uses the same opcode space and in fact 99% the same opcodes as) the official RVV 1.0 for a lot of interesting code. This was demonstrated once again when someone blogged about writing a tolower() function in AVX-512 and I wrote the equivalent in RVV and ran exactly the same binary on the RVV 1.0 BananaPi F3 and the XTHeadVector LicheePi 4A and Milk-V Duo.

https://lobste.rs/s/bfgsh6/tolower_with_avx_512
 

Offline HwAoRrDk

  • Super Contributor
  • ***
  • Posts: 1561
  • Country: gb
Re: CH32V003 and Flash alias address
« Reply #20 on: August 21, 2024, 12:24:27 pm »
115384 is about 0.2% away from 115200...

That's what I thought - supposed to be nominally 115200. Especially as the WCHISPTool apparently only allows setting a choice between 115200, 1M, and 2M for baud rate. Although, it's a fractional baud rate generator, so why couldn't they make it a value that gives exactly 115200? :-//

No. Zbb adds only sext.b, sext.h, and zext.h.

Ah, I see now. I was referring to the RISC-V Wikipedia article and now I look again it only mentions zext.h - must've skim-read too quickly. :) So I guess that technically zext.b isn't part of Zbb because it's just an alias for andi, but the alias was added to 'B' extension for completeness.

I took the "I found a Zbb instruction in CH32V003 code" to mean "It can't possibly actually be zext.b, so it must be some WCH custom instruction, and the code would have to have used an andi if it wanted to zero extend a byte".

No, it wasn't so much that I thought it can't be zext.b - I realised it's an alias for andi - by "misinterpreted" I meant that I thought the disassembler should have output the un-aliased andi instruction because I hadn't told it that the architecture supported 'B' extension. But if zext.b is fine for RV32EC and is just a matter of nomenclature, then I suppose it doesn't really matter.
« Last Edit: August 21, 2024, 02:26:24 pm by HwAoRrDk »
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf