This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

How does uVision start executing M3 flash OS from RAM?

It seems the flash programming algorithm is a piece of code that is downloaded into the SRAM and executes from there.

But how does it get started if there is nothing yet in the vector table at 0? If the flash is erased then everything in the vector table at zero will be 0xFFFFFFFF, so how does it start executing the algorithm in RAM? (which is at 0x20000000 for example)

I want to know because I want to be able to boot from RAM as well.

Parents
  • The JTAG interface allows the processor to be controlled. So the JTAG interface can manually put bytes of data into RAM. And the JTAG interface can give a suitable value to PC to make the processor run the code that was downloaded into RAM.

    So no need for any reset vector when you have a JTAG adapter connected.

    So no - you can't normally boot from RAM. Just that some processors have an internal boot loader that can (depending on configuration) retrieve a boot image from some non-volatile interface, like an SD card or an USB thumb drive, and copy into RAM and then have that program continue with any further startup actions.

    When debugging using the Keil tools, you normally have an init file for the debugger with a line that tells the debugger what PC value to use after your program have been downloaded into RAM. So same method as used when programming the chip, but instead used to let you debug applications directly from RAM without involvement of any boot loader.

Reply
  • The JTAG interface allows the processor to be controlled. So the JTAG interface can manually put bytes of data into RAM. And the JTAG interface can give a suitable value to PC to make the processor run the code that was downloaded into RAM.

    So no need for any reset vector when you have a JTAG adapter connected.

    So no - you can't normally boot from RAM. Just that some processors have an internal boot loader that can (depending on configuration) retrieve a boot image from some non-volatile interface, like an SD card or an USB thumb drive, and copy into RAM and then have that program continue with any further startup actions.

    When debugging using the Keil tools, you normally have an init file for the debugger with a line that tells the debugger what PC value to use after your program have been downloaded into RAM. So same method as used when programming the chip, but instead used to let you debug applications directly from RAM without involvement of any boot loader.

Children
  • That sounds reasonable but I can't get it to work.

    I have tried compiling the code so the IRAM and IROM are in the system RAM space (starting at 0x20000000) and I see that the image is built correctly with the vector table at 0x20000000 and loaded correctly by uVision (this is in simulation mode).

    But I can't get the G command to work (I tried G 0x20000100, the reset vector), it seems determined to load the vector table from 0 and the G command causes a fault *** error 65: access violation at 0xFFFFFFF4 : no 'write' permission

    I tried setting the VTOR register but that seems to be useless since any kind of reset resets the VTOR register so the vector table offset is immediately lost.

  • You can't reset your processor when debugging in RAM. Or more specifically: You can't reset it and expect it to be able to start your program a second time.

    You can have the debugger set the PC to the correct start address. And you can then have your own startup code configure the VTOR (I assume it stands for something like Vector Table Offset Register for your specific processor) to tell the core exactly where the interrupt vector table is.

    So as long as both code + data fits in your RAM, you can debug in RAM. But the debugger must be involved to fix an initial PC value if you try to reset the processor.

    Note that not all processors allows execution from all RAM memory ranges. Some RAM may be located on a separate memory bus intended for DMA transfers to/from peripherial hardware. The processor pipeline and any code cache needs integration with used RAM regions to make sure everything works as intended.

  • With STM32 parts you have to drive the BOOT0/1 pins to map the boot memory to zero when you reset, other M3 cores presumably have similar mechanics.

    Unless there is a compelling reason to enter via reset, a loader can simply pass control to RAM based code by jumping to it.

  • Mine doesn't have that BOOT0/1 feature

    But going back to the original question. None of these answers explain how a vanilla M3 microcontroller is first flashed. Initially the flash is all F's. To attach JTAG and fiddle with the PC to make it point to the flash programming algorithm downloaded in SRAM you have to first take it out of reset. But by then it has already started executing the erased flash, so it fetches a stack pointer of FFFFFFFF and a reset vector of FFFFFFFF both of which will probably make it go off in the weeds. Now maybe the debugger can use JTAG to recover from the fault but this seems a very messy way of doing the most fundamental thing to start using a flash-based M3.

  • Starting a device via JTAG is a messy process. If the processor is starting from a blank flash it's going to fault very quickly. Code can be injected into RAM, PC/SP set up, breakpoints/watchpoints set, it doesn't need to be reset again. JTAG can modify the internal state of the processor.

    Most devices have an Internal ROM which can be mapped at zero.

  • -> Mine doesn't have that BOOT0/1 feature <-

    What M3 MCU do you use?

  • It's an M3 embedded in a much larger ASIC, not a stand-alone MCU chip