Fatal Error after sending notification

Hey Guys,
currently, I am working on my masterthesis. I have to develop an mobile application which comminicates with the nordic board via BLE. I know that there is an existing application from nordic but I had to implement some extra features. The example I use is the ble_peripheral_uart example. According to measure my traffic I am using Docklight. 

My issue is that always when I try to send a notification with docklight to my application (Notification is enabled) my embedded studio crashes and I get a fatal error. Writing messages from the app to the board is possible. I can see this on docklight. 

The confusing point is that when I started to write messages and send notifications it worked. But one day I tried it again and this error appeared, which is really annoying because I haven´t changed a single line of C-Code from the example. I tried to run a new version from the code, I tried to use different versions from my android studios code, I ran the code on several computers I changed the eval board, I changed the UART-Module I am using, I reinstalled the software - nothing worked.

I noticed that it is possible to send notification as long as I send only one letter or number. When I send more letters or numbers or add \n my code crashes. Obviously, it is a memory issue but I don´t understand why it worked at the beginning. 

Can you give my some advices?

Kind Regards,
Thomas

Parents
  • Hi Thomas,

    My issue is that always when I try to send a notification with docklight to my application (Notification is enabled) my embedded studio crashes and I get a fatal error.

    Is this Segger Embedded Studio(?) that has a fatal error and crashes, or is it that you see a fatal error in the log from the nRF? If it is the latter, then this is likely from an APP_ERROR_CHECK. In that case, testing a debug build (select "Debug" from the build configuration dropdown menu) will give you more information. With this you should see file name, line number and error code, and that will give us much more to go on.

  • Yes, I am using Embedded Studio. These are the error codes I get when I try to send a notification. But I have to add, that I made a mistake in my explanation. I can send more than one sign as long as I don´t add "\n". The point is that I need \n because without it, I have to send several packages until my app gets the packages. 
    Is it possible that it is something like a cache problem? Because no matter on which device I ran my C-Code, first it worked and after a few trys I got this error.

  • To be honest these are the only two error code lines that appeared after debugging. 
    Here is the function where the error code has guided me to:

    void app_error_handler(ret_code_t error_code, uint32_t line_num, const uint8_t * p_file_name)
    {
        __ASM volatile(
    
        "push {lr}                      \n"
    
        /* reserve space on stack for error_info_t struct - preserve 8byte stack aligment */
        "sub sp, sp, %0                 \n"
    
        /* prepare error_info_t struct */
        "str r0, [sp, %1]               \n"
        "str r1, [sp, %3]               \n"
        "str r2, [sp, %2]               \n"
    
        /* prepare arguments and call function: app_error_fault_handler */
        "ldr r0, =%4                    \n"
        "mov r1, lr                     \n"
        "mov r2, sp                     \n"
        "bl  %5                         \n"
    
        /* release stack */
        "add sp, sp, %0                 \n"
    
        "pop {pc}                       \n"
        ".ltorg                         \n"
    
        : /* Outputs */
        : /* Inputs */
        "I" (APP_ERROR_ERROR_INFO_SIZE_ALIGNED_8BYTE),
        "I" (APP_ERROR_ERROR_INFO_OFFSET_ERR_CODE),
        "I" (APP_ERROR_ERROR_INFO_OFFSET_P_FILE_NAME),
        "I" (APP_ERROR_ERROR_INFO_OFFSET_LINE_NUM),
        "X" (NRF_FAULT_ID_SDK_ERROR),
        "X" (app_error_fault_handler)
        : /* Clobbers */
        "r0", "r1", "r2"
        );
    }


    Here is the copied log:
    Reset: Halt core after reset via DEMCR.VC_CORERESET.
    Reset: Reset device via AIRCR.SYSRESETREQ.
    Downloading ‘s132_nrf52_7.2.0_softdevice.hex’ to J-Link
    Programming 2.7 KB of addresses 00000000 — 00000aff
    Programming 146.3 KB of addresses 00001000 — 0002596b
    J-Link: Flash download: Bank 0 @ 0x00000000: 1 range affected (126976 bytes)
    J-Link: Flash download: Total: 3.005s (Prepare: 0.490s, Compare: 0.042s, Erase: 0.071s, Program & Verify: 2.266s, Restore: 0.135s)
    J-Link: Flash download: Program & Verify speed: 55 KB/s
    Download successful
    Downloading ‘ble_app_uart_pca10040_s132.elf’ to J-Link
    Programming 59.7 KB of addresses 00026000 — 00034f16
    Programming 0.1 KB of addresses 00034f18 — 00034fbb
    J-Link: Flash download: Bank 0 @ 0x00000000: Skipped. Contents already match
    Download successful
    

  • Hi,

    This is not the relevant log. This is from programming the device, and what we are after is the log from the device, which where there are printouts from the error handler. And the code in your snippet is from the error handler, and that runs because of the error. The relevant log is from your previous screenshot, specifically in the left par of it, where you see the debug log printed by your application running in the nRF. This log contains all information we need to start looking into this, when combined with the file it points to (probably your main.c, but could also be something else).

    I strongly suggest that you spend time understanding the error handling in the nrF5 SDK by the link in my previous post. This will surly save you time in the long run.

  • <info> app_timer: RTC: initialized.
    <info> app: Debug logging for UART over RTT started.
    <info> app: Connected
    <info> app: Data len is set to 0xF4(244)
    <error> app: ERROR 4 [NRF_ERROR_NO_MEM] at C:\Users\loratho\Desktop\Projektordner_Thomas_Loran\Masterthesis\BLEtoUART\Nordic\nRF5_SDK_BLEtoUART\examples\ble_peripheral\ble_app_uart\main.c:581
    PC at: 0x0002F8E3
    <error> app: End of error report
    
    
    
    
    Thank you for the Link. I am read it and try to understand it. Here is the left part of the screen, you metioned

  • Good. Did you also check what happens around line 581 in your main.c file?

Reply Children
  • void uart_event_handle(app_uart_evt_t * p_event)
    {
        static uint8_t data_array[BLE_NUS_MAX_DATA_LEN];
        static uint8_t index = 0;
        uint32_t       err_code;
    
        switch (p_event->evt_type)
        {
            case APP_UART_DATA_READY:
                UNUSED_VARIABLE(app_uart_get(&data_array[index]));
                index++;
                rx_uart_data = data_array[index];
                if (rx_uart_data == 'h')
                {
                     bsp_board_led_on(CONNECTED_LED_3);
                     nrf_delay_ms(1000);
                     bsp_board_led_off(CONNECTED_LED_3);
                }
    
                if ((data_array[index - 1] == '\n') ||
                    (data_array[index - 1] == '\r') ||
                    (index >= m_ble_nus_max_data_len))
                {
                    if (index > 1)
                    {
                        NRF_LOG_DEBUG("Ready to send data over BLE NUS");
                        NRF_LOG_HEXDUMP_DEBUG(data_array, index);
    
                        do
                        {
                            uint16_t length = (uint16_t)index;
                            err_code = ble_nus_data_send(&m_nus, data_array, &length, m_conn_handle);
                            if ((err_code != NRF_ERROR_INVALID_STATE) &&
                                (err_code != NRF_ERROR_RESOURCES) &&
                                (err_code != NRF_ERROR_NOT_FOUND))
                            {
                                APP_ERROR_CHECK(err_code);
                            }
                        } while (err_code == NRF_ERROR_RESOURCES);
                    }
    
                    index = 0;
                }
                break;
    
            case APP_UART_COMMUNICATION_ERROR:
                APP_ERROR_HANDLER(p_event->data.error_communication);
                break;
    
            case APP_UART_FIFO_ERROR:
                APP_ERROR_HANDLER(p_event->data.error_code);
                break;
    
            default:
                break;
        }
    }

    its a switch case. Seems like I get in the wrong state of my uart_event_handler. I get in the state APP_UART_COMMUNICATION_ERROR The error also shows that I have a memory issue.

  • Good, you are getting closer. Just so I know as well Which line in this code snippet represents line 581?

  •     case APP_UART_COMMUNICATION_ERROR:
                APP_ERROR_HANDLER(p_event->data.error_communication);
                break;

    it is this one. 

    here is the definition of the used enums in file app_uart.h

    typedef enum
    {
        APP_UART_DATA_READY,          /**< An event indicating that UART data has been received. The data is available in the FIFO and can be fetched using @ref app_uart_get. */
        APP_UART_FIFO_ERROR,          /**< An error in the FIFO module used by the app_uart module has occured. The FIFO error code is stored in app_uart_evt_t.data.error_code field. */
        APP_UART_COMMUNICATION_ERROR, /**< An communication error has occured during reception. The error is stored in app_uart_evt_t.data.error_communication field. */
        APP_UART_TX_EMPTY,            /**< An event indicating that UART has completed transmission of all available data in the TX FIFO. */
        APP_UART_DATA,                /**< An event indicating that UART data has been received, and data is present in data field. This event is only used when no FIFO is configured. */
    } app_uart_evt_type_t;
    
    /**@brief Struct containing events from the UART module.
     *
     * @details The app_uart_evt_t is used to notify the application of asynchronous events when data
     * are received on the UART peripheral or in case an error occured during data reception.
     */
    typedef struct
    {
        app_uart_evt_type_t evt_type; /**< Type of event. */
        union
        {
            uint32_t error_communication; /**< Field used if evt_type is: APP_UART_COMMUNICATION_ERROR. This field contains the value in the ERRORSRC register for the UART peripheral. The UART_ERRORSRC_x defines from nrf5x_bitfields.h can be used to parse the error code. See also the \nRFXX Series Reference Manual for specification. */
            uint32_t error_code;          /**< Field used if evt_type is: NRF_ERROR_x. Additional status/error code if the error event type is APP_UART_FIFO_ERROR. This error code refer to errors defined in nrf_error.h. */
            uint8_t  value;               /**< Field used if evt_type is: NRF_ERROR_x. Additional status/error code if the error event type is APP_UART_FIFO_ERROR. This error code refer to errors defined in nrf_error.h. */
        } data;
    } app_uart_evt_t;

  • I see. The APP_UART_COMMUNICATION_ERROR means that there was an error in the UART communication. The API doc indicates how you can know more about this error:

        APP_UART_COMMUNICATION_ERROR, /**< An communication error has occured during reception. The error is stored in app_uart_evt_t.data.error_communication field. */
    

    This is the number you provide to APP_ERROR_HANDLER, and from the printout we see it is 4. In this case, this does not mean NRF_ERROR_NO_MEM but that is printed as that is the standard meaning of error codes in the nRF5 SDK. In this case, the number is from the ERRORSRC register in the UART peripheral, as we see form the API documentation for error_communication you found:

            uint32_t error_communication; /**< Field used if evt_type is: APP_UART_COMMUNICATION_ERROR. This field contains the value in the ERRORSRC register for the UART peripheral. The UART_ERRORSRC_x defines from nrf5x_bitfields.h can be used to parse the error code. See also the \nRFXX Series Reference Manual for specification. */

    Looking at the UARTE chapter in the product specification you can see that 4 in ERRORSRC is FRAMING:

    Framing error occurred. A valid stop bit is not detected on the serial data input after all bits in a character have been received.

    There are several reasons you could get framing errors. Assuming everything is OK with the other UART device and there is no logical error, it could for instance be simply that you are using HFINT instead of HFXO, and that will not be accurate enough. If that is the case you would typically see the issue more with longer packets or higher baud rates. And the fix is to request the HFXO before doing UART communication.

  • So a solution could be to change HFINT to HFOX. As I have read in my research I have to set this up in file nrf_drv_clock.c. But I  don`t understand how. I read that I have to set NRF_CLOCK->TASKS_CTART=1 and NRF_CLOCK->TASKS_LFCLKSTART=1 but this is not correct, I guess. It did not work...

Related