Hello, is there a way to get contents in stack and store them into flash when Hard-fault or NMI happen? If it can't write flash in the situation, is there a mechanism to copy them into a block of SRAM which can be kept even when system has been re-started?
Hi Jerry,Thank you for posting your question on our Online Engineering Community.What data exactly are you interested in saving? In which scenario are you facing a Hard Fault or NMI? The RAM cannot be retained if a power off has occurred. Only the data on the SPI Flash will be saved. In order to save data in the SPI Flash please follow our Tutorial here:DA145XX Tutorial SDK6 Peripheral Drivers — DA145XX Tutorial SDK peripherals (renesas.com)Chapter 5. SPI Flash.Kind Regards,OV_Renesas
Hi OV_renesas,
Thank you for your quick reply. I want to save stack info into flash when Hard Fault happens, so I can analyze the info to find out which function caused it.
In function HardFault_HandlerC, I called the interfaces in spi_flash.c to do erase and write operations, but it didn't work, and nothing has been written into flash. These interfaces have already confirmed to work properly in normal process, so I doubt something needs to be taken care of before calling them in HardFault_HandlerC. Could you please give me some instructions about it?
Thanks,
Jerry
Another question: is there a way to output some log from UART2 when Hard Fault happens? I've tried to write some code like dbg_prod_output, but it seemed to not work.
Hi Jerry,Thank you for the reply.When you receive a Hard Fault error the device crashes and you are not going to be able to save the data into the Flash or print them via UART.Please refer on our SDK6 Debugging Tutorial: Tutorial Dialog SDK 6.0.x Debugging — SDK6 Debugging Tutorial (renesas.com)It shows the steps you have to make to understand the Hard Fault Error.If you want you can share your code implementation here, so we can take a look on why you are getting this Hard Fault Error.Kind Regards,OV_Renesas
Hi OV_Renesas,
Thank you for your reply and info, but that can't solve my problem. The Hard Fault happened on my DA14585 device can't be reproduced easily. It needs lots of samples and several days, and then it has the chance to occur on only one device, so it's not easy to connect J-link to catch it. I'm sure DA14683 can have a mechanism to store stack info in a block of RAM, and the contents in the RAM can be kept unchanged during reset. Can DA14585 support the same mechanism as DA14683?
Hi Jerry,Thank you for the reply and the clarifications.The SDK6 does not support the same mechanism as DA14683.However you can print out the Registers for HardFault Errors or NMI so you can see what caused the issue.In order to do that, you will have to do the following:On da1458x_config_advanced.h file:
/****************************************************************************************************************/ /* Output the Hardfault arguments to serial/UART interface. */ /****************************************************************************************************************/ #define CFG_PRODUCTION_DEBUG_OUTPUT
On da1458x_config_basic.h file:
#undef CFG_DEVELOPMENT_DEBUG #undef CFG_PRINTF #define CFG_UART1_SDK
/// Divider for 115200 bits/s #define UART_BAUDRATE_115K2 8 #define UART_FRAC_BAUDRATE_115K2 11 /// Character format enum { /// char format 5 UART_CHARFORMAT_5 = 0, /// char format 6 UART_CHARFORMAT_6 = 1, /// char format 7 UART_CHARFORMAT_7 = 2, /// char format 8 UART_CHARFORMAT_8 = 3 };
// Switch to XTAL16 clock, if necessary if (GetBits16(CLK_CTRL_REG, RUNNING_AT_XTAL16M) == 0) { while ( !GetBits16(SYS_STAT_REG, XTAL16_SETTLED) ); // this takes some mili seconds SetBits16(CLK_CTRL_REG, SYS_CLK_SEL, 0); // select XTAL 16MHz }
if(GetBits16(CLK_CTRL_REG, RUNNING_AT_XTAL32M) == 0) { while ( !GetBits16(SYS_STAT_REG, XTAL32M_SETTLED) ); // this takes some mili seconds }
/***************************************************************************************/ /* Production debug output configuration */ /***************************************************************************************/ #if PRODUCTION_DEBUG_OUTPUT #if defined (__DA14531__) #define PRODUCTION_DEBUG_PORT GPIO_PORT_0 #define PRODUCTION_DEBUG_PIN GPIO_PIN_11 #else #define PRODUCTION_DEBUG_PORT GPIO_PORT_2 #define PRODUCTION_DEBUG_PIN GPIO_PIN_5 #endif #endif
*(uint32_t*)0x07F00000 = 0x90;
It's bad that there isn't a mechanism to save data into flash, but I'll try your demo to output some info from UART. Thank you for sharing the code. Can baudrate 921600 be used? It would be better to know divider values for 921600.
Hi Jerry,Thank you for the reply.Yes, baudrate 921600 can be used.
/// Divider for 921600 bits/s #define UART_BAUDRATE_921K6 1 #define UART_FRAC_BAUDRATE_921K6 1
/// Divider for 1000000 bits/s #define UART_BAUDRATE_1M 1 #define UART_FRAC_BAUDRATE_1M 0 /// Divider for 921600 bits/s #define UART_BAUDRATE_921K6 1 #define UART_FRAC_BAUDRATE_921K6 1 /// Divider for 500000 bits/s #define UART_BAUDRATE_500K 2 #define UART_FRAC_BAUDRATE_500K 0 /// Divider for 460800 bits/s #define UART_BAUDRATE_460K8 2 #define UART_FRAC_BAUDRATE_460K8 3 /// Divider for 230400 bits/s #define UART_BAUDRATE_230K4 4 #define UART_FRAC_BAUDRATE_230K4 5 /// Divider for 115200 bits/s #define UART_BAUDRATE_115K2 8 #define UART_FRAC_BAUDRATE_115K2 11 /// Divider for 57600 bits/s #define UART_BAUDRATE_57K6 17 #define UART_FRAC_BAUDRATE_57K6 6 /// Divider for 38400 bits/s #define UART_BAUDRATE_38K4 26 #define UART_FRAC_BAUDRATE_38K4 1 /// Divider for 28800 bits/s #define UART_BAUDRATE_28K8 34 #define UART_FRAC_BAUDRATE_28K8 12 /// Divider for 19200 bits/s #define UART_BAUDRATE_19K2 52 #define UART_FRAC_BAUDRATE_19K2 1 /// Divider for 14400 bits/s #define UART_BAUDRATE_14K4 69 #define UART_FRAC_BAUDRATE_14K4 7 /// Divider for 9600 bits/s #define UART_BAUDRATE_9K6 104 #define UART_FRAC_BAUDRATE_9K6 3 /// Divider for 2400 bits/s #define UART_BAUDRATE_2K4 416 #define UART_FRAC_BAUDRATE_2K4 11 /// Character format enum { /// char format 5 UART_CHARFORMAT_5 = 0, /// char format 6 UART_CHARFORMAT_6 = 1, /// char format 7 UART_CHARFORMAT_7 = 2, /// char format 8 UART_CHARFORMAT_8 = 3 };