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

Central whitelists with peer manager under FreeRTOS

Hi Nordic,

I've built a ble app with a custom protocol, but am struggling with storing bonds, when running under freeRtos.

What I see:

  • central app crashes (hardfault), when peer manager is passed a non empty white list (loaded from flash)
  • if central gets an empty white list then it pairs, bonds, stores the bond, and runs, but restart the central app and the white list loaded from flash is no longer empty (as expected), and again I see hard faults.
  • if i comment the code which loads the white list (see below), then the central app pairs, bonds, stores the bond, and receives notifications. Everything works well, along side several other busy freeRTOS tasks. I just don't get the white list, which I'd like. This would seem to indicate it is just an issue with peer manager and white lists.
  • if i run the central app, standalone without freertos, everything works, including the white list. So maybe it is an issue with FreeRTOS priorities, or perhaps peer manager + whitelists + freertos.

I would appreciate your thoughts on how to further debug / directions to investigate I get very little info from the hard fault stack trace: freertos start first task -> signal handler call at bad address -> hard fault handler.

All my code is fairly boiler plate example code, as you'll recognise from the white list related snippets below.

static void peer_list_get(pm_peer_id_t * p_peers, uint32_t * p_size)
{
    pm_peer_id_t peer_id;
    uint32_t     peers_to_copy;

    peers_to_copy = (*p_size < BLE_GAP_WHITELIST_ADDR_MAX_COUNT) ?
                     *p_size : BLE_GAP_WHITELIST_ADDR_MAX_COUNT;

    peer_id = pm_next_peer_id_get(PM_PEER_ID_INVALID);
    *p_size = 0;

    while ((peer_id != PM_PEER_ID_INVALID) && (peers_to_copy--))
    {
        p_peers[(*p_size)++] = peer_id;
        peer_id = pm_next_peer_id_get(peer_id);
    }
}

static void whitelist_load()
{
    ret_code_t   ret;
    pm_peer_id_t peers[8];
    uint32_t     peer_cnt;

    memset(peers, PM_PEER_ID_INVALID, sizeof(peers));
    peer_cnt = (sizeof(peers) / sizeof(pm_peer_id_t));

    // Load all peers from flash and whitelist them.
    peer_list_get(peers, &peer_cnt);

    ret = pm_whitelist_set(peers, peer_cnt);
    APP_ERROR_CHECK(ret);

    // Setup the device identies list.
    // Some SoftDevices do not support this feature.
    ret = pm_device_identities_list_set(peers, peer_cnt);
    if (ret != NRF_ERROR_NOT_SUPPORTED)
    {
        APP_ERROR_CHECK(ret);
    }
}





 void scan_start(void)
{

  uint32_t flash_busy;

  // If there is any pending write to flash, defer scanning until it completes.
  (void) fs_queued_op_count_get(&flash_busy);

  if (flash_busy != 0){
    m_memory_access_in_progress = true;
    return;
  }

  // Whitelist buffers.
  ble_gap_addr_t whitelist_addrs[8];
  ble_gap_irk_t  whitelist_irks[8];

  memset(whitelist_addrs, 0x00, sizeof(whitelist_addrs));
  memset(whitelist_irks,  0x00, sizeof(whitelist_irks));

  uint32_t addr_cnt = (sizeof(whitelist_addrs) / sizeof(ble_gap_addr_t));
  uint32_t irk_cnt  = (sizeof(whitelist_irks)  / sizeof(ble_gap_irk_t));

  // Reload the whitelist and whitelist all peers.
  whitelist_load();

  ret_code_t ret;

  // Get the whitelist previously set using pm_whitelist_set().
  ret = pm_whitelist_get(whitelist_addrs, &addr_cnt,
			 whitelist_irks,  &irk_cnt);
  

  
  m_scan_param.active   = 1;
  m_scan_param.interval = SCAN_INTERVAL;
  m_scan_param.window   = SCAN_WINDOW;

  if (((addr_cnt == 0) && (irk_cnt == 0))){
    // Don't use whitelist.
    m_scan_param.use_whitelist  = 0;
    m_scan_param.adv_dir_report = 0;

    m_scan_param.timeout  = 0x0000; // No timeout.
    }else{
    // Use whitelist.

    m_scan_param.use_whitelist  = 1;
    m_scan_param.adv_dir_report = 0;
    m_scan_param.timeout  = 0x001E; // 30 seconds.
  }
    
    
  ret = sd_ble_gap_scan_start(&m_scan_param);
  
  APP_ERROR_CHECK(ret);

}
Related