Dear All,
I've been trying to use the General Purpose Registers in the System Reset Controller to record some custom information in my application, then cause a software reset and read this information back in the bootloader. Such information would be the cause of the reset, a boot counter, etc. I cause the reset by calling the macro NVIC_SystemReset().
The SDK provides functions to read & write to these registers:
SRC_SetGeneralPurposeRegister (SRC_Type *base, uint32_t index)
SRC_GetGeneralPurposeRegister (SRC_Type *base, uint32_t index, uint32_t value)
which I've been using as such:
SRC_SetGeneralPurposeRegister(SRC, 0, 1) // write 1 to reg 0
SRC_SetGeneralPurposeRegister(SRC, 1, 5) // write 5 to reg 1
but I find when I read the values back after returning to the Bootloader, the values are garbled and not what I set them to. I thought the whole idea was these registers remain unchanged across a reset.
There doesn't seem to be any particular initialisation mentioned by the SDK documentation that needs to be done prior to using these registers and unfortunately there are no examples in the SDK I could find.
Any idea why it doesn't work?
For a workaround, I tried using SRC_GetResetStatusFlags() to give a warm/cold start indication at least, but this always seems to indicate warm start (i.e. a deliberate SW Reset occurred), but I wonder if this will always be the cause when using a debugger (Segger)?
Any other ideas for application -> bootloader handshaking would be welcome, if this is not the right approach.
Regards, Damon
Solved! Go to Solution.
Hi
You can simply save data in SRAM since its content is preserved across resets when not using areas used by the boot loader).
See the uTasker boot loader flow diagram: https://www.utasker.com/docs/iMX/Loader.pdf
It makes use of SRAM to store details about reset causes (boot mailbox to command various boot loader functions), keep count of watchdog resets so that the loader can catch malfunctioning systems and offer recovery options, etc.
Regards
Mark
[uTasker project developer for Kinetis and i.MX RT]
Contact me by personal message or on the uTasker web site to discuss professional training, solutions to problems or rapid product development requirements
For professionals searching for faster, problem-free Kinetis and i.MX RT 10xx developments the uTasker project holds the key: https://www.utasker.com/iMX/RT1064.html
Hi
You can simply save data in SRAM since its content is preserved across resets when not using areas used by the boot loader).
See the uTasker boot loader flow diagram: https://www.utasker.com/docs/iMX/Loader.pdf
It makes use of SRAM to store details about reset causes (boot mailbox to command various boot loader functions), keep count of watchdog resets so that the loader can catch malfunctioning systems and offer recovery options, etc.
Regards
Mark
[uTasker project developer for Kinetis and i.MX RT]
Contact me by personal message or on the uTasker web site to discuss professional training, solutions to problems or rapid product development requirements
For professionals searching for faster, problem-free Kinetis and i.MX RT 10xx developments the uTasker project holds the key: https://www.utasker.com/iMX/RT1064.html
Thank-you for your response. Using RAM will work fine - this was my Plan B. But I am curious, though, as to why the registers don't seem to work as they should. It worries me that other parts of the SDK may not function as expected...
Regards, Damon
Hi @damonb
Thanks for your question!
SRC_GPR register is mainly used for Soc/BootROM, customer can't use it freely.
You also can find the information from the RT reference manual:
But, don't worry, you can use this register: IOMUXC_SNVS_GPR, when you do the software reset, this register still can keep your data.
This is the code for your reference:
bool isp_cleanup_exit(bool *isInfiniteIsp)
{
uint32_t flag = IOMUXC_SNVS_GPR->GPR0;
switch (flag)
{
// SBL_TO_ISP软复位情况下,进入无限超时isp
case CLEANUP_SBL_TO_ISP:
*isInfiniteIsp = true;
flag = 0x0;
break;
// 第一次上电或ISP_TO_SBL软复位情况下,直接退出isp
case CLEANUP_ISP_TO_SBL:
default:
break;
}
IOMUXC_SNVS_GPR->GPR0 = 0x0;
return flag;
}
void isp_cleanup_enter(uint32_t flag)
{
IOMUXC_SNVS_GPR->GPR0 = flag;
NVIC_SystemReset();
}
Please try it on your side!
Wish it helps you!
If you still have questions about it, please kindly let me know.
Best Regards
Kerry