I'm using S140 6.0.0 and associated MBR on an nRF52840 with a custom boot loader derived from the nRF5 SDK 15.0.0 examples.
I'd like to perform some custom actions as soon as possible after MCU reset such as setting some GPIO to a known value to control voltage regulators, similar to this post.
As described in the S140 specification, the MBR contains the reset vector and passes control to the boot loader if there is no in-system boot loader update in progress. If there is no update in progress the boot loader main()
is entered quickly after reset where I can add code to control the required GPIO signals.
When there is an in-system boot loader update in progress as a result of using SD_MBR_COMMAND_COPY_BL, the time between a processor reset and entering the boot loader can be multiple seconds. This is because the first item the MBR executes is any pending boot loader copy. The flash erase/program cycles for boot loader programming can easily take over a second, and sometimes multiple seconds if the boot loader is large. Only after this operation is complete does the new boot loader main()
run and we again have control to set GPIO values. This delay is also not ideal sometimes from a user's perspective during an update as it would be nice to be able to indicate that an update is in progress on LED/screen during this time. I don't think a workaround using SD_MBR_COMMAND_VECTOR_TABLE_BASE_SET will work as this only takes effect after any in-system boot loader updates.
What are my options if I'd like to be able to run custom hook code before any time-consuming flash operations on boot?
Here are my suggestions. If there's other ideas on this issue or the ideas below are not feasible, please let me know.
- Manually patch the existing MBR binary to inject hook code into the MBR hex file. It may be possible to replace the existing MBR reset vector to point to the injected hook code (which could reside in the upper part of 0x0-0x1000 MBR page which appears to be unused). The hook code would run any necessary operations the branch to the original reset vector location. If the MBR contains a validated CRC, this will not work. I don't like this option as it involves messy binary patching.
- Obtain the source code for MBR and compile in custom changes. Is it possible to obtain MBR source code?
- Longer term solution. Request a new MBR feature from Nordic to provide an early-boot hook. This could be controlled through use of another UICR.NRFFW[n] register similar to BOOTADDR. If the UICR.NRFFW[n] is set, treat this as a pointer to code which is expected to run and return on boot. As hook code is called from a very low level, it would probably be treated similar to MBR page and never upgraded.