I am looking at the APP_ERROR_CHECK and find out it finally goes to the app_error_save_and_stop method. I couldn't understand from the code, that where the error info saved and how I can look in those errors?
Thanks,
I am looking at the APP_ERROR_CHECK and find out it finally goes to the app_error_save_and_stop method. I couldn't understand from the code, that where the error info saved and how I can look in those errors?
Thanks,
Have you looked at the source code?
The documentation says it just enters an infinite loop:
Got it. It says: Function for saving the parameters and entering an eternal loop, for debug purposes. So, where those parameters saved?
Thanks
Again,
Have you looked at the source code?
If you are talking about these codes as following, yes I did, but don't understand. Can u explain? Thanks,
void app_error_save_and_stop(uint32_t id, uint32_t pc, uint32_t info)
{
/* static error variables - in order to prevent removal by optimizers */
static volatile struct
{
uint32_t fault_id;
uint32_t pc;
uint32_t error_info;
assert_info_t * p_assert_info;
error_info_t * p_error_info;
ret_code_t err_code;
uint32_t line_num;
const uint8_t * p_file_name;
} m_error_data = {0};
// The following variable helps Keil keep the call stack visible, in addition, it can be set to
// 0 in the debugger to continue executing code after the error check.
volatile bool loop = true;
UNUSED_VARIABLE(loop);
m_error_data.fault_id = id;
m_error_data.pc = pc;
m_error_data.error_info = info;
switch (id)
{
case NRF_FAULT_ID_SDK_ASSERT:
m_error_data.p_assert_info = (assert_info_t *)info;
m_error_data.line_num = m_error_data.p_assert_info->line_num;
m_error_data.p_file_name = m_error_data.p_assert_info->p_file_name;
break;
case NRF_FAULT_ID_SDK_ERROR:
m_error_data.p_error_info = (error_info_t *)info;
m_error_data.err_code = m_error_data.p_error_info->err_code;
m_error_data.line_num = m_error_data.p_error_info->line_num;
m_error_data.p_file_name = m_error_data.p_error_info->p_file_name;
break;
}
UNUSED_VARIABLE(m_error_data);
// If printing is disrupted, remove the irq calls, or set the loop variable to 0 in the debugger.
__disable_irq();
while(loop);
__enable_irq();
}
If you are talking about these codes as following, yes I did, but don't understand. Can u explain? Thanks,
void app_error_save_and_stop(uint32_t id, uint32_t pc, uint32_t info)
{
/* static error variables - in order to prevent removal by optimizers */
static volatile struct
{
uint32_t fault_id;
uint32_t pc;
uint32_t error_info;
assert_info_t * p_assert_info;
error_info_t * p_error_info;
ret_code_t err_code;
uint32_t line_num;
const uint8_t * p_file_name;
} m_error_data = {0};
// The following variable helps Keil keep the call stack visible, in addition, it can be set to
// 0 in the debugger to continue executing code after the error check.
volatile bool loop = true;
UNUSED_VARIABLE(loop);
m_error_data.fault_id = id;
m_error_data.pc = pc;
m_error_data.error_info = info;
switch (id)
{
case NRF_FAULT_ID_SDK_ASSERT:
m_error_data.p_assert_info = (assert_info_t *)info;
m_error_data.line_num = m_error_data.p_assert_info->line_num;
m_error_data.p_file_name = m_error_data.p_assert_info->p_file_name;
break;
case NRF_FAULT_ID_SDK_ERROR:
m_error_data.p_error_info = (error_info_t *)info;
m_error_data.err_code = m_error_data.p_error_info->err_code;
m_error_data.line_num = m_error_data.p_error_info->line_num;
m_error_data.p_file_name = m_error_data.p_error_info->p_file_name;
break;
}
UNUSED_VARIABLE(m_error_data);
// If printing is disrupted, remove the irq calls, or set the loop variable to 0 in the debugger.
__disable_irq();
while(loop);
__enable_irq();
}
So there you can see where the stuff is!
Thanks for the tip. But still you are answering me. I am still not clear. Can't you just give a direct answer?
Here:
static volatile struct { uint32_t fault_id; uint32_t pc; uint32_t error_info; assert_info_t * p_assert_info; error_info_t * p_error_info; ret_code_t err_code; uint32_t line_num; const uint8_t * p_file_name; } m_error_data = {0};
How do I access it? just printf m_error_data?
Well, if you're in that place it means your system is in a mess; so printing may well be "disrupted" - as the comment says.
You could try it to see if it works.
If not, put a breakpoint in that function and examine the data using the debugger.
Failing that, save the data in a "safe" area of RAM that will survive a reboot. Then reboot, and print the info at startup.
How to setup a "safe" area of RAM that will survive a reboot depends on what tools you're using - which you haven't mentioned.
But these are pretty standard debugging techniques - not specific to Nordic - so some general googling should find the answer ...
EDIT
Here's an example for SES (also mentions IAR):