This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

nRF52840 combining ble_app_blinky + ble_app_buttonless_dfu

I am working with an nRF52840 on a custom board. Our device has a number of sensor attached in various ways including spim, twim, uart. I've used the ble_app_blinky as a starting point, and have a app that is doing things periodically, but has integrated a number of custom ble services which interact with a ble app. For testing, I've been typically been using nRF Connect on an Android tablet. The app has morphed over a period of a few weeks, but is functional. However, I've also been using the open bootloader and usb to update the firmware.

Recently, I've adapted the ble_app_buttonless_dfu to work on our custom board. I've also adapted the secure_bootloader project for our board. Along these lines, I've been able to use the DFU tool in the nRF toolbox app for Android to update the device firmware.

The next step was to integrate the buttonless dfu into our previously working app. I've ran into some trouble, and need some advice on how to proceed.

I have made a few clones of the app so I can experiment, and describe the behavior I am seeing. It appears much of the base code in ble_app_blinky and ble_app_buttonless_dfu is similar. The primary difference I see is the advertising mechanism. I have one version using the advertising scheme from the buttonless dfu app. When I run this version, after the  advertising_start() function, the app will report:

<error> app: Fatal error
<warning> app: System reset

and then reboot. This process repeats continually.

A second clone of the app uses the advertising scheme from the ble_app_blinky project. The calls are very different as are the data structures. When I run the app in this case, it gets through all the initialization code, and appears to run correctly. However, when I try to "connect" using a nrf connect, the app will immediately report the same fatal error and reset. The app will run just fine right until I try to connect.

The sdk_config.h files for each project is based on the base project's files, but have been modified to make the code run. The ble_app_blinky version is much more complex. I've attempted to use that one as the starting point, and have added the missing parts so the project compiles and runs. This is the place I've usually needed to edit to make things work in other projects.

I also made a third clone, but this time used the buttonless_dfu's sdk_config.h as the starting point, and added the missing content from the ble_app_blinky's config file. This project is currently failing much earlier. I have code which uses a button to trigger some code. The call to ble_lbs_init() is causing immediate failure and reboot.

Sorry for the long message, but been stumped on making any progress on this.

  • Hello,

    Some general hints:

    Add DEBUG to your preprocessor definitions. If you are not sure how to add definitions to your preprocessor definitions, please let me know what IDE you are using. When DEBUG is added, the log should say what APP_ERROR_CHECK(err_code) that caught the error instead of just printing "Fatal error".

    So to the problem. After you add DEBUG to your preprocessor definitions, you will know what function call that returner an error, and what error that was. My guess (but you have to confirm this using the DEBUG definition and log. I cannot stress that enough) is that you need to increase the NRF_SDH_BLE_VS_UUID_COUNT by one. I would think it is 1 right now, and you should set it to 2. Then, when you program with this change, the log will probably say something about RAM settings, and then crash later. Apply the changes suggested in the log, and then it should work. Let me know if it doesn't.

    Best regards,

    Edvin

  • I've added the DEBUG to the relevant projects. I made a few minor code changes from yesterday, so now both clone projects seem to start running on boot the same, and now they both fail exactly the same.

    <error> app: ERROR 4 [NRF_ERROR_NO_MEM] at ../../../main.c:1150
    PC at: 0x00030B4D
    <error> app: End of error report

    static void conn_params_error_handler(uint32_t nrf_error)
    {
       APP_ERROR_HANDLER(nrf_error);
    }

    The failure occurs right when I attempt to connect. The function above is the line referenced.

    There are a couple of values in the sdk_config.h that I've modified previously.

    #define NRF_SDH_BLE_GATTS_ATTR_TAB_SIZE 1600/*1408*/
    #define NRF_SDH_BLE_VS_UUID_COUNT 14/*10*/
    Most of the DK ble projects have the top one set to 1408. I had increased this somewhat. I'm not sure how to know how large to make it, or if I should even touch it? The bottom value I've also increased a few times as I've added more services to the app. Based on the comment in the sdk_config.h, I've made this value track the number of custom services, and the number of characteristics total. So for example, I have an imu service which has a UUID, and then three characteristics, so it counts as 4?
    I experimented by incrementing the uuid count several times, but the same error happened each time. I also had to edit the projects `.ld` file to match the ram start and length per the debug output.
    I also made a clone today where I kept those values the same, but removed all my custom services. This project also produces the same exact error on connection.
  • Sorry for the late reply. I have been out of office due to Easter Holidays.

    The NRF_SDH_BLE_VS_UUID_COUNT should reflect the number of custom services. You can have several characteristics in that service without changing this value. Look at how the ble_app_uart example has this set to 1, although it has two characeristics. 

    The NRF_SDH_BLE_GATTS_ATTR_TAB_SIZE is a bit more difficult to predict exactly how large to set. Usually I go by trial and error. If your application is able to initalize all your services/characteristics without any errors, then you can try lowering it if you prefer. It is just a number indicating how much memory that is set aside for the softdevice. 

     

     

    fe-hadella said:

    <error> app: ERROR 4 [NRF_ERROR_NO_MEM] at ../../../main.c:1150
    PC at: 0x00030B4D
    <error> app: End of error report

    static void conn_params_error_handler(uint32_t nrf_error)
    {
       APP_ERROR_HANDLER(nrf_error);
    }

    Did this go away when you changed the definitions that you mentioned? I assume that line 1150 is the APP_ERROR_HANDLER() inside conn_params_error_handler()?

    Does the log say anything else before this? Can you paste in the entire log? I am particularly curious whether it says anything regarding RAM sizes.

  • The relevant lines in sdk_config.h were modified to be:

    #ifndef NRF_SDH_BLE_GATT_MAX_MTU_SIZE
    #define NRF_SDH_BLE_GATT_MAX_MTU_SIZE 247
    #endif

    #ifndef NRF_SDH_BLE_GATTS_ATTR_TAB_SIZE
    #define NRF_SDH_BLE_GATTS_ATTR_TAB_SIZE 2816//1408
    #endif

    #ifndef NRF_SDH_BLE_VS_UUID_COUNT
    #define NRF_SDH_BLE_VS_UUID_COUNT 6
    #endif

    I need to add NUS in future, so I made the value match the ble_app_uart value.

    I made the UUID match the number of services used. Three are nordic standard services, DFU, DIS, LBS, and three are custom ones I wrote.

    When I ran the version after this update, I see the output:

    <info> app: Setting vector table to bootloader: 0x000F8000
    <info> app: Setting vector table to main app: 0x00027000
    <info> app: power_management_init()
    <info> app: leds_init()
    <info> app: user_button_init()
    <info> app: ble_stack_init()
    <warning> nrf_sdh_ble: Insufficient RAM allocated for the SoftDevice.
    <warning> nrf_sdh_ble: Change the RAM start location from 0x200024A0 to 0x200030B8.
    <warning> nrf_sdh_ble: Maximum RAM size for application is 0x3CF48.
    <error> nrf_sdh_ble: sd_ble_enable() returned NRF_ERROR_NO_MEM.
    <error> app: ERROR 4 [NRF_ERROR_NO_MEM] at ../../../main.c:666
    PC at: 0x0002CA15
    <error> app: End of error report

    I update the project's `.ld` file, updating the RAM.

    MEMORY
    {
    FLASH (rx) : ORIGIN = 0x27000, LENGTH = 0xc9000
    RAM (rwx) : ORIGIN = 0x200030b8, LENGTH = 0x3cf48
    uicr_bootloader_start_address (r) : ORIGIN = 0x10001014, LENGTH = 0x4
    }

    When I run it again, things seem to work right until I attempt to connect bluetooth to my tablet. This is same behavior I described last time. This is true for either advertising scheme, or for the minimal version without any of my services. In the last test run, I updated the attr size to 5632. I don't know how to gauge this?

    <info> app: Setting vector table to bootloader: 0x000F8000
    <info> app: Setting vector table to main app: 0x00027000
    <info> app: power_management_init()
    <info> app: leds_init()
    <info> app: user_button_init()
    <info> app: ble_stack_init()
    <info> app: gap_params_init()
    <info> app: gatt_init()
    <info> app: services_init()
    <info> app: ~~ nrf_ble_qwr_init()
    <info> app: ~~ ble_dfu_buttonless_init()
    <info> app: ~~ ble_lbs_init()
    <info> app: ~~ ble_dis_init()
    <info> app: ~~ ble_time_service_init()
    <info> app: ~~ ble_lidar_service_init()
    <info> app: advertising_init()
    <info> app: conn_params_init()
    <info> app: init_uart()
    <info> app: init_sensors()
    <info> app: advertising_start()
    <info> app: ~~ advertising start end...
    <info> app: entering main loop...
    <info> app: sd_ble_gatts_hvx result: NRF_ERROR_INVALID_STATE.

    LIDAR: distance = 0.030 m, board temp = 0 C, soc temp = 41 C

    Tue Apr 6 21:40:43 2021

    <info> app: sd_ble_gatts_hvx result: NRF_ERROR_INVALID_STATE.

    <info> app: sd_ble_gatts_hvx result: NRF_ERROR_INVALID_STATE.

    LIDAR: distance = 0.030 m, board temp = 41 C, soc temp = 41 C

    Tue Apr 6 21:40:53 2021

    <info> app: sd_ble_gatts_hvx result: NRF_ERROR_INVALID_STATE.

    <error> app: ERROR 4 [NRF_ERROR_NO_MEM] at ../../../main.c:1154
    PC at: 0x0002E23F
    <error> app: End of error report

    During operation, I have a internal real time clock which interrupts every 10 seconds, grabbing some data from sensors and updating the dsplay. This will work indefinitely right until I attempt to connect. The version without DFU enabled has been working for quite some time.

    Many of my test projects were based on the ble_app_blinky from the start, and I'm trying to integrate the DFU updates into it. I may take another approach since this is taking so long and go the other way and try to integrate my content into the buttonless dfu example. There are parts of this which refer to buttons which may exist on the dk. I don't have those on my board.

    Is any of this output helpful at all? I dont' see any <debug> lines, so that might not be enabled in the sdk_config.h. I'll add it and update this ticket if I get any additional data...

  • I added the logging debug output. Right before the error, the output changed to:

    <debug> nrf_ble_gatt: Requesting to update ATT MTU to 247 bytes on connection 0x0.

    <debug> nrf_ble_gatt: Updating data length to 251 on connection 0x0.
    <error> app: ERROR 4 [NRF_ERROR_NO_MEM] at ../../../main.c:1149
    PC at: 0x00030C0F
    <error> app: End of error report

Related