Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Bugs in ble_app_hrs_freertos example?

Some bugs in ble_app_hrs_freertos example from the SDK when handling buttons:
(at the end of this listing are same tests but with ble_app_hrs (no rtos) and buttons are handled as expected)
Tests were made with pca10040 / SDK 16.0.0 and SES 4.30b

Could you point where is the problem, please, because I've used some parts of this code as base for one my app and it handles buttons Ok in Release mode, but in Debug mode first pass through the button handler passes, but then the app stalls without reporting any error :(
Thanks
---------------------------------

ble_app_hrs_freertos_pca10040_s132

Turn On the PCA10040 board:
<info> app: HRS FreeRTOS example started.
<info> app: Fast advertising.

Press Btn1: ->Sleep
Press Btn1 or Btn2 or Btn3 or Btn4:
<info> app: HRS FreeRTOS example started.
<info> app: Fast advertising.

While advertising:
Press Btn2:
<error> hardfault: HARD FAULT at 0x00000004
<error> hardfault: R0: 0x200067E4 R1: 0x20006738 R2: 0x200072E0 R3: 0x200072E0
<error> hardfault: R12: 0x20007138 LR: 0x00000004 PSR: 0x6000000E
<error> hardfault: Cause: The processor has attempted to execute an instruction that makes illegal use of the EPSR.
<info> app: HRS FreeRTOS example started.
<info> app: Fast advertising.

Press Btn3 or Btn4:
<error> hardfault: HARD FAULT at 0x00000002
<error> hardfault: R0: 0x20007098 R1: 0x20006FF8 R2: 0x200072E0 R3: 0x200072E0
<error> hardfault: R12: 0x200065D4 LR: 0x00000002 PSR: 0x6000000E
<error> hardfault: Cause: The processor has attempted to execute an instruction that makes illegal use of the EPSR.
<info> app: HRS FreeRTOS example started.
<info> app: Fast advertising.


While Connected (not paired):
<info> app: Connected

Press Btn2:
<error> hardfault: HARD FAULT at 0x00000004
<error> hardfault: R0: 0x200067E4 R1: 0x20006738 R2: 0x200072E0 R3: 0x200072E0
<error> hardfault: R12: 0x20007138 LR: 0x00000004 PSR: 0x6000000E
<error> hardfault: Cause: The processor has attempted to execute an instruction that makes illegal use of the EPSR.
<info> app: HRS FreeRTOS example started.
<info> app: Fast advertising.


<info> app: Connected
Press Btn3 or Btn4:
<error> hardfault: HARD FAULT at 0x00000002
<error> hardfault: R0: 0x20007098 R1: 0x20006FF8 R2: 0x200072E0 R3: 0x200072E0
<error> hardfault: R12: 0x20007138 LR: 0x00000002 PSR: 0x6000000E
<error> hardfault: Cause: The processor has attempted to execute an instruction that makes illegal use of the EPSR.
<info> app: HRS FreeRTOS example started.
<info> app: Fast advertising.

--- When Paired:
restart:
<info> app: HRS FreeRTOS example started.
<info> app: Fast advertising.

Connect:
<info> peer_manager_handler: Peer data updated in flash: peer_id: 0, data_id: Peer rank, action: Update, no change
<info> app: Connected
<info> peer_manager_handler: Connection secured: role: Peripheral, conn_handle: 0, procedure: Encryption
<info> peer_manager_handler: Peer data updated in flash: peer_id: 0, data_id: Peer rank, action: Update, no change
<info> peer_manager_handler: Peer data updated in flash: peer_id: 0, data_id: Local database, action: Update
<info> peer_manager_handler: Peer data updated in flash: peer_id: 0, data_id: Local database, action: Update

Press Btn1 Or Btn2 or Btn3 or Btn4:
For Btn1 and 2 (with some minor diffs in the values):
<error> hardfault: HARD FAULT at 0x00000004
<error> hardfault: R0: 0x200067E4 R1: 0x20006738 R2: 0x200072E0 R3: 0x200072E0
<error> hardfault: R12: 0x20007138 LR: 0x00000004 PSR: 0x6000000E
<error> hardfault: Cause: The processor has attempted to execute an instruction that makes illegal use of the EPSR.
<info> app: HRS FreeRTOS example started.
<info> app: Fast advertising.

For Btn3 and 3 (with some minor diffs in the values):
<error> hardfault: HARD FAULT at 0x00000002
<error> hardfault: R0: 0x20007098 R1: 0x20006FF8 R2: 0x200072E0 R3: 0x200072E0
<error> hardfault: R12: 0x20007138 LR: 0x00000002 PSR: 0x6000000E
<error> hardfault: Cause: The processor has attempted to execute an instruction that makes illegal use of the EPSR.
<info> app: HRS FreeRTOS example started.
<info> app: Fast advertising.


==============================================================================
ble_app_hrs_pca10040_s132: (here everything works Ok so far)

Press Btn1: ->Sleep
Press Btn1:
<info> app_timer: RTC: initialized.
<info> app: Heart Rate Sensor example started.
<info> app: Fast advertising.

Long press Btn2:
<info> app: Fast advertising.

Press Btn1: ->Sleep
Press Btn2:
<info> app_timer: RTC: initialized.
<info> app: Heart Rate Sensor example started.
<info> app: Erase bonds!
<info> peer_manager_handler: All peers deleted.
<info> app: Fast advertising.

Pressing Btn2,Btn3, Btn4 while advertising or connected - no any effect

Parents
  • The problems I posted are from the very original NOT modified anyhow ble_app_hrs_freertos example supplied with SDK16.0.0

  • Hi samsam, 

    I am not seeing any issues running the ble_app_hrs_freertos_pca10040_s132 from SDK 16.0.0 in the Debug configuration. Which logging backend are you using RTT or UART?

  • Hi bjorn-spockeli,

    It should work, but unfortunately doesn't work :( I got also some results, but unfortunately SES debugging doesn't work as suppose to and as soon as I put a breakpoint at any line inside main or try to step after initial breakpoint in debugging and the results/output differ from what is in run mode or debugging without any breakpoint. But using the lamest way with NRF_LOGs what I got so far:

    static void buttons_leds_init(bool * p_erase_bonds)
    {
        ret_code_t err_code;
        bsp_event_t startup_event;
    
        err_code = bsp_init(BSP_INIT_LEDS | BSP_INIT_BUTTONS, bsp_event_handler);
        APP_ERROR_CHECK(err_code);
    NRF_LOG_INFO("4. startup_event %d" , startup_event);
        err_code = bsp_btn_ble_init(NULL, &startup_event);
    NRF_LOG_INFO("5. startup_event %d" , startup_event);
        APP_ERROR_CHECK(err_code);
    
        *p_erase_bonds = (startup_event == BSP_EVENT_CLEAR_BONDING_DATA);
    }
    

    so in ble_app_hrs_freertos  (with #define configTOTAL_HEAP_SIZE (2 * 4096 ) ):

    From Sleep -> awake with Btn1 | Btn2 | 3 | 4
    <info> app: 4. startup_event 16
    <info> app: 5. startup_event 0
    <info> app: HRS FreeRTOS example started.
    <info> app: Fast advertising.

    While in ble_app_hrs:

    From Sleep -> awake with Btn2
    <info> app_timer: RTC: initialized.
    <info> app: 4. startup_event 0
    <info> app: 5. startup_event 2
    <info> app: Heart Rate Sensor example started.
    <info> app: Erase bonds!
    <info> peer_manager_handler: All peers deleted.
    <info> app: Fast advertising.

    From Sleep -> awake with Btn1
    <info> app_timer: RTC: initialized.
    <info> app: 4. startup_event 0
    <info> app: 5. startup_event 11
    <info> app: Heart Rate Sensor example started.
    <info> app: Fast advertising.

    Unfortunately In debug mode (debugging) got those same results for all the buttons 1,2,3,4 if have any breakpoint at any place in main:
    <info> app_timer: RTC: initialized.
    <info> app: 4. startup_event 0
    <info> app: 5. startup_event 0
    <info> app: Heart Rate Sensor example started.
    <info> app: Fast advertising.

    So far I was able to track the problem up to  bsp_btn_ble_init(NULL, &startup_event); which in freertos flavor of hrs example  doesn't assign proper value to the second parameter 'startup_event' as it does in the hrs example without freertos.

    P.S. Let me know if you are able to debug/trace with your edition of SES ble_app_hrs and get same results/output as  in run mode, so I could upgrade my SES and then could dive in bsp_btn_ble_init to try further to identify source of the problem else with NRF_LOGs is quite a waste time.

    Thanks

  • update: so I solve meanwhile part of the problem: in freertos  version of the hrs example there are plenty of stuff loading before call to bsp_btn_ble_init(NULL, &startup_event);  that is why the wake-up buttons must be pressed and HOLD way longer than what is with original hrs example and then could get the correct result - thank you Bjorn for pointing what is the algorithm behind sensing the wake-up conditions - this give me the glimpse where to search for the problem and solution. So I can get now erase_bonds flag, not yet able to get the rest part  for deleting bonds, but work is in progress .... ;)

    <info> app: HRS FreeRTOS example started.

    <info> app: Fast advertising.

    <info> app: 0. erase_bonds 129

    <info> app: 4. startup_event 16

    <info> app: 5. startup_event 2 --> now is Ok 

    <info> app: 1. erase_bonds 1 --> and this is Ok

    <info> app: 2. erase_bonds 1

    <info> app: HRS FreeRTOS example started.

    <info> app: Fast advertising.

  • The freeRTOS example initializes the SoftDevice before the buttons and leds are initialized, which means that you cant start and stop the CPU from executing after ble_stack_init()

    // Configure and initialize the BLE stack.
    ble_stack_init();
    
    // Initialize modules.
    timers_init();
    buttons_leds_init(&erase_bonds);
    gap_params_init();
    gatt_init();
    advertising_init();
    services_init();
    sensor_simulator_init();
    conn_params_init();
    peer_manager_init();
    application_timers_start();

    In the regular ble_app_hrs example the SoftDevice is initialized after buttons_leds_init() is called, so that is why you can debug the issue. 

     

    samsam said:
    So far I was able to track the problem up to  bsp_btn_ble_init(NULL, &startup_event); which in freertos flavor of hrs example  doesn't assign proper value to the second parameter 'startup_event' as it does in the hrs example without freertos.

     Will look into if there is something wrong with the pin assignment in the freeRTOS example. 

    Best regards

    Bjørn

  • Solved: added static to erase_bonds declaration in main
    else erase_bonds get lost before reach nrf_sdh_freertos: Enter softdevice_task.
    Do I need to make it volatile?


    int main(void)
    {
    static bool erase_bonds;

    ...

    Wakeup with Btn2 (longer hold) from sleep:
    <info> app: HRS FreeRTOS example started.
    <debug> nrf_sdh_freertos: Enter softdevice_task.
    <info> app: Fast advertising.
    <debug> nrf_sdh_freertos: Creating a SoftDevice task.
    <info> app: HRS FreeRTOS example started.
    <debug> nrf_sdh_freertos: Enter softdevice_task.
    <info> app: Erase bonds!
    <info> peer_manager_handler: All peers deleted.
    <info> app: Fast advertising.

  • HI Samsam, thanks for providing the update on your investigation. 

    Ok, so you do not need to set the erase_bonds variable as static, you just need to press and hold the button longer than the regular example? Since the erase_bonds variable is used by buttons_leds_init function there should not be a need to set it volatile. 

    Best regards

    Bjørn

Reply Children
  • No, both prerequisites are required in order hrs_freertos example to work: 

    1. Longer press on the Btn2 needs  until program flow reach bsp_button_is_pressed(BTN_ID_WAKEUP)  at which moment local variable in main() erase_bonds is set to whatever is the current state of the button(not the state the button was at wake-up/reset event)  

    2. The actual process for starting delete existing bondings procedure is performed from within the FreeRTOS task  softdevice_task, but unless I change the erase_bonds to static, the correct value that was set for this variable in main() is not seen in the body of the softdevice_task.  Maybe same effect will be if I move erase_bonds variable outside main(), but I didn't try it. 

    The question for the 'volatile' was because I read in a lot of places in the examples where they put volatile in order to secure that the variable will prevent  the compiler to optimize it in such way that might not be available for all the  threads that might  need access to it, so currently my test  with 'static' works fine, but I'm not sure is it enough for 'worst scenario' ... 

    BTW where disappear my last post as I cant see ?

  • samsam said:

    1. Longer press on the Btn2 needs  until program flow reach bsp_button_is_pressed(BTN_ID_WAKEUP)  at which moment local variable in main() erase_bonds is set to whatever is the current state of the button(not the state the button was at wake-up/reset event)  

    2. The actual process for starting delete existing bondings procedure is performed from within the FreeRTOS task  softdevice_task, but unless I change the erase_bonds to static, the correct value that was set for this variable in main() is not seen in the body of the softdevice_task.  Maybe same effect will be if I move erase_bonds variable outside main(), but I didn't try it. 

    The question for the 'volatile' was because I read in a lot of places in the examples where they put volatile in order to secure that the variable will prevent  the compiler to optimize it in such way that might not be available for all the  threads that might  need access to it, so currently my test  with 'static' works fine, but I'm not sure is it enough for 'worst scenario' ... 

     OK, will report that static is missing in our internal issue database. I dont think that volatile is needed here. 

    samsam said:
    BTW where disappear my last post as I cant see ?
    The event log states that your last reply was on 1/24/2020 1:46:05 PM and the second last reply was on 1/23/2020 7:06:42 PM. But I can see your reply on 1/23/20 15:53 in our support view. Could be that its not shown in the public view. Will report this as well. 

     

Related