If the watchdog fires and the NMI handler is called, a range of error parameters are collected together in the platform code. However, we cannot attach a debugger at this point in our field deployed products, so we cannot get the error information.
We would like to take the error info and store it somewhere; then do a reboot; then access the error data again so it can be sent off to our host in a message (we do not feel we can still send a message reliably in the NMI handler itself).
Is there any way to persist the error data across reboots, so it can be used later in a message? Power will be retained, but the RST pin will be toggled and the system will reboot over SPI.
Thanks.
Keywords:
Device:
Hi pvmellor,
To be honest, I am not able to understand how the error information are collected from your application, but you could store them in the SPI Flash. So, after the device reboots, you could read them again. Another possible solution for your case is to store the error information in the retention ram since the power will be retained. Generally, after the device resets, the stored data in the retention RAM will be lost. Please check the SystemInit() function, and you will find the SetBits16(PMU_CTRL_REG, RETENTION_MODE, 0xF); , so all the bits of the retention ram are set to So, the zeroing of the retention memory area is something that should be done when the device boots up since the retention area while in deep sleep holds, besides the user data, additional BLE information (BLE heap, stack, etc). After reset the zeroing out function will run again and will wipe out any data that you have in the retention memory area. In order to avoid that what you can do is to know where your “data” reside in the retention memory area and during the initialization you should avoid zeroing them out. You could follow the procedure below in order to do that:
In the scatterfile where the retention memory area is defined for deep sleep allocate a space that will hold your data that should be not initialized.
§ LR_RETENTION_RAM0 0x00080768 (RETRAM_LEN + EXCHANGE_MEMORY_SIZE + SZ_AFT_RST_DATA) {
§ RET_RESET01 0x00080768 UNINIT SZ_AFT_RST_DATA { .ANY (unitialized_data_test)} <- Tag the new area.
所以现在你知道wi的数据ll be tagged with the unitialized_data_test will reside from the address 0x00080768 up to the address 0x00080768 + SZ_AFT_RST_DATA. Since you are aware of that you can go to the SystemInit() function and instruct the function not to zero out the memory between the 0x00080768 and 0x00080768+SZ_AFT_RST_DATA.
// Fill 0x80000 - 0x83000 with zeros
unsigned int *p_retmem = (unsigned int *)0x80000;
for (i = 0xBFF; i >= 0; i--)
{
if((p_retmem > (unsigned int *)0x80768) && (p_retmem < (unsigned int *)(0x80768 + 80)) )
*(volatile unsigned *)p_retmem++;
Else
*(volatile unsigned *)p_retmem++ = 0;
}
This is a possible solution, but you can also store the data into the SPI Flash as it is already mentioned. If I misunderstood what you mean and what you want to accomplish, please let me know!
Thanks, PM_Dialog
PM_Dialog,
Firstly, many thanks for your detailed and helpful reply!
Just to explain myself a little better, we have a PAN1740 unit that contains the DA14580 on our custom board. The board has an ARM M4 MCU as well, and this will exchange messages over SPI with the DA14580. The MCU also boots the DA14580 over an SPI connection. We use SDK 5.0.4. We have no external SPI flash that the DA14580 can access.
The file nmi_handler.c defines a function NMI_HandlerC() that is called if the watchdog fires. It is this funciton that saves debugging data (CPU registers R0/R1/R2/R3/R12/LR/PC/PSR). It currently seems to save them to 0x81850 which is already in the retention ram area.
So I have modified the zeroing routine as per your suggestion to avoid zeroing this data. After the chip has booted and is working properly again, we read the data out and send it off to the MCU over the GTL message transport. Works perfectly!
Many thanks,
Paul.
Hi pvmellor,
Glad that you figured your issue out and thanks for Accepting my answer. Just for your information, in DA14585/6 product family and our new SDK6, you could store uninitialized data in the System-RAM more easily than DA14580 and SDK5. Just you need to use the retention_mem_area_uninit attribute.
uint8_t data __attribute__((section("retention_mem_area_uninit") , zero_init)); //@RETENTION MEMORY
Thanks, PM_Dialog