Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs

Problem with conversion of integer error code to string and Release/Debug mode

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.

Parents
  • Hi,

    The error handler is different for debug builds (with DEBUG) defined and without it.  You can see that in the definition of APP_ERROR_HANDLER in components/libraries/util/app_error.h.

    (If you want this debug information in your release builds you are free to define DEBUG for the release configuration as well. In that case you may want to adjust the last part of app_error_fault_handler() so that you get a reset even if DEBUG is defined, as that is typically what you want for a product out in the field.)

Reply
  • Hi,

    The error handler is different for debug builds (with DEBUG) defined and without it.  You can see that in the definition of APP_ERROR_HANDLER in components/libraries/util/app_error.h.

    (If you want this debug information in your release builds you are free to define DEBUG for the release configuration as well. In that case you may want to adjust the last part of app_error_fault_handler() so that you get a reset even if DEBUG is defined, as that is typically what you want for a product out in the field.)

Children
  • Ok, thank you. I see that there is a difference in these functions depending on the debug or release mode. 

    Regarding my other question? I know it's mostly about C, but taking into account that when the lines of code using the function snprintf to convert integer to string, are in the main function, then they work as expected, but when I add the lines in the app_error_fault_handler they don't work, and print these strange characters in the photo, make me to want to ask again.

    Maybe there is any configurations I need to make, or maybe you know that snprintf behaviour is unstable for some reason.... Please I would like an answer on that, even if the answer is that you checked my code, and you don't see any error/typo mistake, that I cannot see ..


  • Hi,

    Regarding your use of snprintf() I do not see any obvious problems (I don't understand the purpose of your short error_info_string and why you use strtok() to split it on "\\", but that should also work as far as I can see.

    For a quick test I took your code and just copied in to the default handler in app_error_weak.c, and it worked right out of the box with an example Segger Embedded Studio project from SDK 17.1.0 using SES 5.42a (which is the version that was used for release testing the SDK). Here in debug mode:

    <info> app: Blinky example started.
    <error> app: ERROR 5 [NRF_ERROR_NOT_FOUND] at /home/eith/src/nrf5sdk/nRF5_SDK_17.1.0_ddde560/examples/ble_peripheral/ble_app_blinky/main.c:581
    PC at: 0x0002F299
    <error> app: End of error report
    <info> app: Error: 5 size 4, File /home/eith/src/nrf5sdk/nRF5_SDK_17.1.0_ddde560/examples/ble_peripheral/ble_app_blinky/main.c, Line Number: 581, size 4
    <info> app: err_code 5, line_num 581 
    <info> app: string /home/eith/src/nrf5sdk/nRF5_SDK_17.1.0_ddde560/examples/ble_peripheral/ble_app_blinky/main.c
    <info> app: error 5
    <info> app: line 581
    <info> app: Error info string 5,/home/eith/src/nr. Size 20
    And here in release mode (where you don't get anything sensible printed as the data is not there):

    <info> app: Blinky example started.
    <error> app: Fatal error
    <info> app: Error: 5 size 4, File , Line Number: 0, size 4
    <info> app: err_code 5, line_num 0 
    <info> app: string 
    <info> app: error 5
    <info> app: line 0
    <info> app: Error info string 5,(null),0. Size 20

    There could be a configuration issue on your end, or that there has been a change in SES if you are using a different version. But I am not sure exactly what it would be.

  • I also tested it on ble_app_blinky as you did and it worked fine.

    Looks like that it didn't work because I hadn't added the lines
    __disable_irq();
    NRF_LOG_FINAL_FLUSH();

    that exist in the default handler in app_error_weak.c.
    I was going to call another function after I save the data in flash, that would execute these lines of code and then do NVIC_SystemReset(). However, adding these two lines of code right after the conversions with snprintf etc, solved my problem and now snprintf works properly. I have no idea how this solves my problem, but it does.

    edit: Looks like that is a logger issue.. as sometimes it misses some NRF_LOG_INFO..

    Thank you very much!

Related