|ARM Technical Support Knowledge Articles|
At Reset, ARMv7-M processors always boot from a vector table at address zero.
With uninitialized memory at address zero (for example, unprogrammed Flash or uninitialized RAM), the processor will read a spurious initial Main Stack Pointer value from address zero and a spurious code entry point (Reset vector) from address 0x4, possibly containing an illegal instruction set state specifier (ESPR.T bit) in bit.
The processor may lock up immediately, or may execute some spurious opcodes, though in the latter case, lock-up remains a possible outcome.
A clean boot-up can be achieved through the actions of a debugger connected to the processor's debug port (assuming that the SoC has implemented Debug features for the processor).
For systems where there is no possibility of damage to the SoC or to the connected systems, the processor could be allowed to exit from Reset, and potentially execute some spurious opcodes, before the debugger takes control; however, where the possibility of damage or undesirable consequences of executing spurious opcodes exists, the SoC should be carefully designed to provide a suitable method of preventing initial execution, such as holding the processor's functional reset, SYSRESETn, asserted after the release of the power-on reset, PORESETn.
While the processor is executing or held in functional reset, the debugger can write to the NVIC to enable Halting Debug (DHCSR.C_DEBUGEN) and set up a vector catch at reset (DEMCR.VC_CORERESET). The processor can then be halted via the vector catch. If the processor is still held in functional reset, this is achieved simply by releasing the reset; if the processor is not currently held in reset, this can be achieved by writing the AIRCR.VECTRESET bit.
The processor is now in a Debug Halt state, having fetched the initial Main Stack Pointer, the Reset Vector, and the EPSR.T bit from uninitialized memory.
The correct and robust procedure from this point is to initialize at least a minimal vector table at address zero. The minimal vector table requires at least the first four entries to be valid, which are the initial Main Stack Pointer, and vectors (all with bit = 1) for the Reset, NMI and Hard Fault handler entry points, as these exceptions cannot be inhibited, and a Reset will always cause the vector table offset to revert to address 0x0. Also remember to download an executable code image to a suitable address in a writable and executable memory region before restarting operation by issuing a further self-reset (VECTRESET) so that the boot procedure starts over, but this time from the now populated vector table at address 0x0.
For use cases such as a simple test case, where there is no desire to fully support continuation of normal execution after the test, and where writing to memory at address zero is cumbersome (for example, requiring Flash erase and reprogramming), a "quick and dirty" alternative exists; the already-fetched values from addresses 0x0 and 0x4 can be fully modified through the DCRSR and DCRDR functions in debug. This requires the Main Stack Pointer to be written with a suitable "top of stack" address in RAM, the DebugReturnAddress (essentially the PC) to be written with the true address of the code entry point, the xPSR to be written with 0x01000000 (setting the ESPR.T bit), and, of course, downloading the executable test code into a suitable (writable and executable) memory region.
Note that for the "quick and dirty" method, there remains no valid vector table at address zero. The debugger or the code image can program the VTOR to point to a valid vector table, for example located in the downloaded code image itself, but if a further reset should occur, the reboot will revert to the (non-existent) vector table at address 0x0.
Did you find this article helpful? Yes No
How can we improve this article?