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

Flash Storage not working in ble_evt_handler

My code bluetooth module hangs if I use flash storage functions inside the ble_evt_handler. I am using the functions from the fstorage example in peripheral folder.
I turned on debug, connected to module, updated the value and then it hangs and no matter what I do it does not return to normal, but the debug says that its still running. From the looks it does not even enter the ble_evt_handler (I know this from the Log command).

The code is below:

static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)  //This function here handles any event that comes, just add the event name and fill in what you want to do when the event occurs.
{
    ret_code_t err_code = NRF_SUCCESS;
    NRF_LOG_INFO("Got an Event!"); //To check if it comes here

    switch (p_ble_evt->header.evt_id) 
    {


        case BLE_GATTS_EVT_WRITE:  
        {
			nrf_fstorage_api_t * p_fs_api;
			p_fs_api = &nrf_fstorage_sd;

			#ifdef SOFTDEVICE_PRESENT
				NRF_LOG_INFO("SoftDevice is present.");
				NRF_LOG_INFO("Initializing nrf_fstorage_sd implementation...");
				/* Initialize an fstorage instance using the nrf_fstorage_sd backend.
				 * nrf_fstorage_sd uses the SoftDevice to write to flash. This implementation can safely be
				 * used whenever there is a SoftDevice, regardless of its status (enabled/disabled). */
				p_fs_api = &nrf_fstorage_sd;
			#else
				NRF_LOG_INFO("SoftDevice not present.");
				NRF_LOG_INFO("Initializing nrf_fstorage_nvmc implementation...");
				/* Initialize an fstorage instance using the nrf_fstorage_nvmc backend.
				 * nrf_fstorage_nvmc uses the NVMC peripheral. This implementation can be used when the
				 * SoftDevice is disabled or not present.
				 *
				 * Using this implementation when the SoftDevice is enabled results in a hardfault. */
				p_fs_api = &nrf_fstorage_nvmc;
			#endif

			err_code = nrf_fstorage_init(&fstorage, p_fs_api, NULL);
			APP_ERROR_CHECK(err_code);             

			NRF_LOG_INFO("Initializing nrf_fstorage_sd implementation...");

		   

			/* Let's write to flash. */
			NRF_LOG_INFO("Writing \"%x\" to flash.", p_data);
			err_code = nrf_fstorage_write(&fstorage, 0x3e100, &p_data, length, NULL);
			APP_ERROR_CHECK(err_code);
			
			//Waiting for operation to complete
			wait_for_flash_ready(&fstorage);
			NRF_LOG_INFO("Done.");
			
			//-----------------Testing - Reading----------------------
                char     m_hello_world[] = "hello world";
                err_code = nrf_fstorage_read(&fstorage, 0x3e100, m_hello_world, length);
                APP_ERROR_CHECK(err_code);

                NRF_LOG_INFO("Reading \"%x\" to flash.", m_hello_world);
                wait_for_flash_ready(&fstorage);
			//--------------------------------------------------------
			
		}
		
	}
If I comment out the flash storage function (write and read) it works as it should.

Any leads would greatly be appreciated. (Do lemme know if additional information is required)

Edit 1: If I run this program in the main before the while loop, it works fine but I require it in the run time.

This works fine:

int main(void)
{
    bool erase_bonds;

    log_init();
    timers_init();
    buttons_leds_init(&erase_bonds);
    power_management_init();
    ble_stack_init(); //Here the BLE stack is initialized
    adc_configure();  //ADC for checking the battery
    gap_params_init();
    gatt_init();
    advertising_init();   //Making the iBeacon packet and the Data (major minor UUID etc) into a structure and passing it
    db_discovery_init();  //Commented this AUAK
    services_init();    //Initializing the services
    conn_params_init();
    peer_manager_init();

    //-------------Flash!-----------------------------

    Flash_Test();
   
    //-----------------------------------------

    // Start execution.
    NRF_LOG_INFO("Beacon Start!.");
    advertising_start(erase_bonds);
    tx_power_set();

    // Enter main loop.
    for (;;)
    {   
        
        idle_state_handle();
    }
}

But does not work if I am using it in run-time (also tried to do it via raising a flag and executing the commands in timer but that did not work either.

Parents
  • I agree with Hadi. You shouldn't call fstorage init and especially wait_for_flash_ready() inside the event handler.

    wait_for_flash_ready() is a blocking function and the MCU will stuck inside that event handler waiting for the fstorage event. But the event can't be handled because you are already on the same context priority so the event will not be fetched and you will end up in a dead loop. 

    In stead you should check for the event inside fstorage_evt_handler(). 

Reply
  • I agree with Hadi. You shouldn't call fstorage init and especially wait_for_flash_ready() inside the event handler.

    wait_for_flash_ready() is a blocking function and the MCU will stuck inside that event handler waiting for the fstorage event. But the event can't be handled because you are already on the same context priority so the event will not be fetched and you will end up in a dead loop. 

    In stead you should check for the event inside fstorage_evt_handler(). 

Children
  • No its not working even when i secluded it from the ble_evt_handler.

    Any further information I can provide regarding this for diagnosis?

  • What exactly not working ? How do you call it out side of ble_evt_handler? 

  • I connect and the logger shows me that it is Connected but when I update the value of the characteristic, which will cause the event handler to initiate, the program freezes. But if I remove line 12-56 (of first code pasted) it works fine. This is the same code that handles the flash storage.

    Like even before coming into the evt_handler the code freezes.

  • Please follow the debug guide here. The code never "freezes" it only end up being in a dead loop or it resets. 

    How do you call the function ? Have you removed wait_for_flash_ready()

  • Just by removing the wait_for_flash_ready() function the program worked in the ble_evt_handler.

    This seems to have solved one issue but here comes another one! Smiley

    The read function is not working properly and is not giving the right value. Ideally it should give the same value which I saved but it is not. Is there a specific prerequisite before performing the read function?

    NRF_LOG_INFO("Writing \"%x\" to flash.", p_data);
    err_code = nrf_fstorage_write(&fstorage, 0x3e100, &p_data, length, NULL);
    APP_ERROR_CHECK(err_code);
    
    uint8_t m_hello_world[] = "33333333";
    err_code = nrf_fstorage_read(&fstorage, 0x3e100, &m_hello_world, length);
    
    err_code = nrf_fstorage_read(&fstorage, 0x3e100, &p_data, length);
                    
    NRF_LOG_INFO("Reading p_data \"%02x%02x%02x%02x\" to flash.", p_data[0], p_data[1], p_data[2], p_data[3]);
                    
    NRF_LOG_INFO("Reading \"%02x%02x%02x%02x\" to flash.", m_hello_world[0], m_hello_world[1], m_hello_world[2], m_hello_world[3]);
    APP_ERROR_CHECK(err_code);


    The output I get it:

    <info> app: Initializing nrf_fstorage_sd implementation...
    <info> app: Writing "2003FEC6" to flash.
    <info> app: Reading p_data "00040020" to flash.
    <info> app: Reading "00000000" to flash.
    <info> app: UUID Identified
    <info> app: Storage event handler
    <info> app: --> Event received: wrote 4 bytes at address 0x3E100.

    I can't even get the correct data in p_data.


    Thank you for sticking with me :)

Related