I have a BLE project using nRF5 SDK on a custom nRF52832 board, which works as a peripheral, collects data, and communicates with a mobile phone. I have created my own APP_ERROR_CHECK function, which saves the error code and the place in main.c file that it occured, in order that when mobile connects, this info is sent to a database. Also, with this function I decide whether a system reset should happen, if the error was critical.
This function is called after every function that I use in main file, and returns err_code, which means that these functions call other functions in other files etc. Therefore, I have also created my own app_error_fault_handler function, which is called only in some cases, after I have decided when it will be important, and this function all it does is to reset.
So, my problems started when I figured a way in my mind to optimize the above error handling functionality, meaning that the original functions APP_ERROR_CHECK and APP_ERROR_HANDLER are called in all other files, in functions that I don't want and shouldn't modify, BUT, these functions end up calling my function app_error_fault_handler, which then causes a reset. So, I would like to save the error information before the reset happens, using the error_info_t structure in app_error.h file, which contains line number, file name, and error code.
In more details:
I call somewhere in the code APP_ERROR_CHECK(7); (specifically when I write something from mobile to the device).
This function then calls app_error_fault_handler
void app_error_fault_handler(uint32_t id, uint32_t pc, uint32_t info) { char strline[8]; char strerror[8]; char error_info_string[20]; uint8_t count = 0; error_info_t * p_info = (error_info_t *)info; NRF_LOG_INFO("Error: %u size %d, File %s, Line Number: %u, size %d",p_info->err_code,sizeof(p_info->err_code), p_info->p_file_name, p_info->line_num, sizeof(p_info->line_num)); uint32_t err_code = p_info->err_code; uint32_t line_num = p_info->line_num; NRF_LOG_INFO("err_code %d, line_num %d ",err_code, line_num); char* string = (char *)p_info->p_file_name; NRF_LOG_INFO("string %s", string); // Extract the first token char * token = strtok(string, "\\"); // loop through the string to extract all other tokens for (int i = 0; i < strlen(string); i++) { if (string[i] == '\\') { count++; } } for(uint8_t j=0; j<count; j++) { token = strtok(NULL, "\\"); } // Convert integers to string snprintf(strerror, sizeof(strerror),"%d", err_code); NRF_LOG_INFO("error %s",strerror); snprintf(strline, sizeof(strline),"%d", line_num); NRF_LOG_INFO("line %s",strline); snprintf(error_info_string, sizeof(error_info_string), "%s,%s,%s", strerror, token, strline); NRF_LOG_INFO("Error info string %s. Size %d",error_info_string, sizeof(error_info_string));
Using the info input argument of the function, and converting it into error_info_t type (as in app_error_weak.c file), I would like to convert the error code and the line number into strings, in order that I create the string "error_info_string" which will be saved in flash and sent to the mobile. I would like it to be a string, since, file name willl be included also, which is a string.
Problem 1:
When I tested these lines of code regarding converting integers error code and line num into strings in main function, it worked fine. When I use these lines (snprintf) in this function app_error_fault_handler it prints some strange characters. How is this possible and how could I solve it?
Problem 2:
When I put Segger in Debug Mode, file name is printed just fine, and therefore I see that I take the last part of the string that contains the file name "main.c" . But when I put it in Release mode, the file name is not printed. So, is this a Logger problem or actually I will face this kind of problems in release mode? And how can I solve this?
Here are the prints in the logger:
Debug mode:
Release mode:
Question 3:
And the point of explaining all these, apart from solving my problems if it is possible,is to ask if this whole idea is an efficient way to save error information and keep track of what happens in the device, or is there another way that you could recommend?
Thank you very much, and I apologize in advance if my problems might be due to Segger settings. I don't really know, I did a search in Segger settings and in my sdk.config.h file but didn't find something that could might help.