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

why the fs_sys_event_handler() can't be called--when use fstorage to write flash?

SDK11, NRF51822

#include "fstorage.h"
#include "section_vars.h"

#define NUM_PAGES 6
static uint8_t fs_callback_flag;

static void fs_evt_handler(fs_evt_t const * const evt, fs_ret_t result)
{
	if (result != FS_SUCCESS)
	{
		//bsp_indication_set(BSP_INDICATE_FATAL_ERROR);
	}
	else
	{
		NRF_LOG_PRINTF("    fstorage command successfully completed   \n\r");
		fs_callback_flag = 0;
	}
}

FS_REGISTER_CFG(fs_config_t fs_config) =
{
	.callback  = fs_evt_handler, // Function for event callbacks.
	.num_pages = NUM_PAGES, 	 // Number of physical flash pages required.
	.priority  = 0xFE			 // Priority for flash usage.
};

void init_fstorage(void)
{
		fs_ret_t ret = fs_init();
		if (ret != FS_SUCCESS)
		{
				//bsp_indication_set(BSP_INDICATE_FATAL_ERROR);
			NRF_LOG_PRINTF("FS init failed!\n");
		}
		else
		{
			NRF_LOG_PRINTF("FS init ok!\n");
		}
		
}

//----------------------------
void feed_wdt(void)
{
	uint32_t err_code = sd_app_evt_wait();
    APP_ERROR_CHECK(err_code);
}
//-----------------------------

void fstorage_test(void)
{
		static uint32_t data;
		uint32_t flash_data[4];
		fs_ret_t ret;

		// Erase one page (page 0).
		NRF_LOG_PRINTF("Erasing a flash page at address 0x%X\r\n", (uint32_t)fs_config.p_start_addr);
		fs_callback_flag = 1;
		ret = fs_erase(&fs_config, fs_config.p_start_addr, 1);
		while(fs_callback_flag == 1)  { feed_wdt(); }
		
		//ret = fs_erase(&fs_config, fs_config.p_start_addr+1024, 1);
		//while(fs_callback_flag == 1)  { power_manage(); }
		//Read the first 4 words of the page
		NRF_LOG_PRINTF("Data read from flash address 0x%X: ", (uint32_t)fs_config.p_start_addr);
		for(int i=0; i<4; i++)
		{
			flash_data[i] = *(fs_config.p_start_addr + i);
			NRF_LOG_PRINTF("%X ", flash_data[i]);
		}
		NRF_LOG_PRINTF("\r\n");
		
		data = 0xAAAAAAAA;
		NRF_LOG_PRINTF("Writing data 0x%X to address 0x%X\r\n", data, (uint32_t)fs_config.p_start_addr);
		fs_callback_flag = 1;
		ret = fs_store(&fs_config, fs_config.p_start_addr, &data, 1);      //Write data to memory address 0x0003F00. Check it with command: nrfjprog --memrd 0x0003F000 --n 16
		if (ret != FS_SUCCESS)
		{
				//bsp_indication_set(BSP_INDICATE_FATAL_ERROR);
		}
		while(fs_callback_flag == 1)  {feed_wdt(); }
		
		data = 0xBBBBBBBB;
		NRF_LOG_PRINTF("Writing data 0x%X to address 0x%X\r\n", data, (uint32_t)fs_config.p_start_addr + 4);
		fs_callback_flag = 1;
		ret = fs_store(&fs_config, fs_config.p_start_addr + 1, &data, 1);      //Write data to memory address 0x0003F000. Check it with command: nrfjprog --memrd 0x0003F000 --n 16
		if (ret != FS_SUCCESS)
		{
				//bsp_indication_set(BSP_INDICATE_FATAL_ERROR);
		}
		while(fs_callback_flag == 1)  { feed_wdt(); }
		
		data = 0xCCCCCCCC;
		NRF_LOG_PRINTF("Writing data 0x%X to address 0x%X\r\n", data, (uint32_t)fs_config.p_start_addr + 8);
		fs_callback_flag = 1;
		ret = fs_store(&fs_config, fs_config.p_start_addr + 2, &data, 1);      //Write data to memory address 0x0003F000. Check it with command: nrfjprog --memrd 0x0003F000 --n 16
		if (ret != FS_SUCCESS)
		{
				//bsp_indication_set(BSP_INDICATE_FATAL_ERROR);
		}
		while(fs_callback_flag == 1)  {feed_wdt(); }
		//Read the first 4 words of the page
		NRF_LOG_PRINTF("Data read from flash address 0x%X: ", (uint32_t)fs_config.p_start_addr);
		for(int i=0; i<4; i++)
		{
				flash_data[i] = *(fs_config.p_start_addr + i);
				NRF_LOG_PRINTF("%X ", flash_data[i]);
		}
		NRF_LOG_PRINTF("\r\n");
		//================================================
		// Erase one page (page 0).
		NRF_LOG_PRINTF("Erasing a flash page at address 0x%X\r\n", (uint32_t)fs_config.p_start_addr);
		fs_callback_flag = 1;
		ret = fs_erase(&fs_config, fs_config.p_start_addr+0x100, 1);
		while(fs_callback_flag == 1)  { feed_wdt();}
		
		//ret = fs_erase(&fs_config, fs_config.p_start_addr+1024, 1);
		//while(fs_callback_flag == 1)  { power_manage(); }
		//Read the first 4 words of the page
		NRF_LOG_PRINTF("Data read from flash address 0x%X: ", (uint32_t)fs_config.p_start_addr+0x100);
		for(int i=0; i<4; i++)
		{
				flash_data[i] = *(fs_config.p_start_addr +0x100+ i);
				NRF_LOG_PRINTF("%X ", flash_data[i]);
		}
		NRF_LOG_PRINTF("\r\n");
		
		data = 0xAAAAAAAA;
		NRF_LOG_PRINTF("Writing data 0x%X to address 0x%X\r\n", data, (uint32_t)fs_config.p_start_addr+0x100);
		fs_callback_flag = 1;
		ret = fs_store(&fs_config, fs_config.p_start_addr+0x100, &data, 1);      //Write data to memory address 0x0003F00. Check it with command: nrfjprog --memrd 0x0003F000 --n 16
		if (ret != FS_SUCCESS)
		{
				//bsp_indication_set(BSP_INDICATE_FATAL_ERROR);
		}
		while(fs_callback_flag == 1)  {feed_wdt(); }
		NRF_LOG_PRINTF("Data read from flash address 0x%X: ", (uint32_t)fs_config.p_start_addr+0x100);
		for(int i=0; i<4; i++)
		{
				flash_data[i] = *(fs_config.p_start_addr+0x100 + i);
				NRF_LOG_PRINTF("%X ", flash_data[i]);
		}
		NRF_LOG_PRINTF("\r\n");
}


void sys_evt_dispatch(uint32_t sys_evt) //
{
	//pstorage_sys_event_handler(sys_evt);
    fs_sys_event_handler(sys_evt);
	ble_advertising_on_sys_evt(sys_evt);
}

static void ble_stack_init(void)
{
    uint32_t err_code;
    
    nrf_clock_lf_cfg_t clock_lf_cfg = NRF_CLOCK_LFCLKSRC;
    
    // Initialize SoftDevice.
    SOFTDEVICE_HANDLER_INIT(&clock_lf_cfg, NULL);
    
    ble_enable_params_t ble_enable_params;
    err_code = softdevice_enable_get_default_config(CENTRAL_LINK_COUNT,
                                                    PERIPHERAL_LINK_COUNT,
                                                    &ble_enable_params);
    APP_ERROR_CHECK(err_code);
        
    //Check the ram settings against the used number of links
    CHECK_RAM_START_ADDR(CENTRAL_LINK_COUNT,PERIPHERAL_LINK_COUNT);
    // Enable BLE stack.
    err_code = softdevice_enable(&ble_enable_params);
    APP_ERROR_CHECK(err_code);
	
    // Subscribe for BLE events.
    err_code = softdevice_ble_evt_handler_set(ble_evt_dispatch);
    APP_ERROR_CHECK(err_code);
	
		// Register with the SoftDevice handler module for BLE events.
    err_code = softdevice_sys_evt_handler_set(sys_evt_dispatch);
    APP_ERROR_CHECK(err_code);
}
//-------------------------------------------
void application_init(void)
{
    uint32_t err_code;
    
    APP_TIMER_INIT(APP_TIMER_PRESCALER, APP_TIMER_OP_QUEUE_SIZE, false);
    system_gpios_init();
    dx_ble_app_init(); 
  
    app_pwms_init();
    
    err_code = param_data_init();
    APP_ERROR_CHECK(err_code);
    
    battery_check_init();
    button_check_init();
    wdt_init();
	init_fstorage();
	//fstorage_test(); //here run OK
    err_code = app_timer_create(&m_app_assist_timer_id,
                                APP_TIMER_MODE_REPEATED,
                                app_assist_meas_timeout_handler);
    APP_ERROR_CHECK(err_code);
    
}
//-------------------------------------------
int main(void)
{

    NRF_LOG_INIT();
	application_init();
	
    NRF_LOG_PRINTF("system start......\r\n");	
    
    // Enter main loop.
    for (;;)
    {
        power_manage();
    }
}

if I use the fstorage_test at the applicaiton_init(void), then runs ok.

but on my product, I use a key to power the system, if I use the fstorage_test() in the   power on function(), then the fs_sys_event_handler() can't be called, code as following:

static void power_key_long_press_proc(void)
{

		NRF_LOG_PRINTF("power on\r\n");
	
		app_timer_start(m_app_assist_timer_id, APP_ASSIST_MEAS_INTERVAL, NULL);
		fstorage_test(); // if at here, the function run failed.
       
        get_toy_ble_mac(app_system_param.dec_addr);
        POWER_ON(POWER_MASK); 
		ble_advertising_start(BLE_ADV_MODE_FAST);

}

static void bottun_event_handler(void * p_context)
{
    //some code here...
    
    if(long_press == 1) 
	{
        power_key_long_press_proc();
    }

    
}

Can someone help me?

Parents
  • Hi,

    It seems like fs_sys_event_handler() has a lower interrupt priority than fstorage_test() and therefore is never called. You can try to use app_scheduler to call fstorage_test() from main context. Take a look at the schedule handling library.

    Best regards,

    Marjeris

  • Hi,

    First of all you need to declare fs_callback_flag volatile:

    static volatile uint8_t fs_callback_flag;

    You also need to move the call to fstorage_test() out of interrupt context. Now it is called through a button event handler, which means it is called from an interrupt. This will block all interrupts of same or lower priority for as long as the function runs. Please have a look at the schedule handling library as suggested by .

    Regards,
    Terje

  • It's can't be set volatile, for every time before store or erase ,it's should be set 1 by user. I wonder how to use schedule handling library, Is there any example?

  • Hi,

    I do not know if it is an error in translation, but what I meant by "declare volatile" is you must define the variable with the "volatile" keyword. This tells the compiler that the value must be read from and written to memory every time it is used. If it is not "volatile", the compiler may hold the value in a CPU register or even optimize the code in such a way that the variable is never used. When you set and clear a flag in one context, and check for the flag in another context, you must always use a volatile variable for that flag.

    Please have a look at the Schedule handling library documentation. In nRF5 SDK v11, it is used for instance in the HID Keyboard and Mouse examples and in the Eddystone example.

    Regards,
    Terje

  • tesc, thank you very much! first i Misunderstanding the volatile, now I fixed it , and I use schedule to try it, code as follow:

    APP_TIMER_DEF(led1_timer); 
    
    void write_flash(void *p_event_data, uint16_t event_size)
    {
    	 #if 1
    	 NRF_LOG_PRINTF("write_flash %X\n ", 0x88888888); //here can't be called!
    	 #else
    //		static uint32_t data;
    //		uint32_t flash_data[4];
    //		fs_ret_t ret;
    //		
    //		// Erase one page (page 0).
    //		NRF_LOG_PRINTF("Erasing a flash page at address 0x%X\r\n", (uint32_t)fs_config.p_start_addr);
    //		fs_callback_flag = 1;
    //		ret = fs_erase(&fs_config, fs_config.p_start_addr, 1);
    //		while(fs_callback_flag == 1)  { power_manage(); }
    //		
    //		//Read the first 4 words of the page
    //		NRF_LOG_PRINTF("Data read from flash address 0x%X: ", (uint32_t)fs_config.p_start_addr);
    //		for(int i=0; i<4; i++)
    //		{
    //				flash_data[i] = *(fs_config.p_start_addr + i);
    //				NRF_LOG_PRINTF("%X ", flash_data[i]);
    //		}
    //		NRF_LOG_PRINTF("\r\n");
    //		
    //		data = 0xAAAAAAAA;
    //		NRF_LOG_PRINTF("Writing data 0x%X to address 0x%X\r\n", data, (uint32_t)fs_config.p_start_addr);
    //		fs_callback_flag = 1;
    //		ret = fs_store(&fs_config, fs_config.p_start_addr, &data, 1);      //Write data to memory address 0x0003F00. Check it with command: nrfjprog --memrd 0x0003F000 --n 16
    //		if (ret != FS_SUCCESS)
    //		{
    //				//bsp_indication_set(BSP_INDICATE_FATAL_ERROR);
    //		}
    //		while(fs_callback_flag == 1)  { power_manage(); }
    //		
    //		//Read the first 4 words of the page
    //		NRF_LOG_PRINTF("Data read from flash address 0x%X: ", (uint32_t)fs_config.p_start_addr);
    //		for(int i=0; i<4; i++)
    //		{
    //				flash_data[i] = *(fs_config.p_start_addr + i);
    //				NRF_LOG_PRINTF("%X ", flash_data[i]);
    //		}
    //		NRF_LOG_PRINTF("\r\n");
    	#endif
    }
    
    
    
    void led_timer_handler(void *p_contex)
    {
    		write_event a={5, 0x11223344};
    		app_sched_event_put(&a, sizeof(write_event), write_flash);//can run here.
    }
    
    void led_timer_init(void)
    {
           //创建定时器
           app_timer_create(&led1_timer,APP_TIMER_MODE_REPEATED,led_timer_handler);
    }
    
    
    //启动定时器
    
    void led_timer_start(void)
    {
    
           app_timer_start(led1_timer,
    
                                       APP_TIMER_TICKS(1000, APP_TIMER_PRESCALER),
    
                                       NULL);  
    
          
    
    }
    //--------------------------------------------------
    void application_init(void)
    {
        uint32_t err_code;
        
        APP_TIMER_INIT(APP_TIMER_PRESCALER, APP_TIMER_OP_QUEUE_SIZE, false);
        system_gpios_init();
        dx_ble_app_init(); 
      
        app_pwms_init();
    
        battery_check_init();
        button_check_init();
        wdt_init();
     
        err_code = app_timer_create(&m_app_assist_timer_id,
                                    APP_TIMER_MODE_REPEATED,
                                    app_assist_meas_timeout_handler);
        APP_ERROR_CHECK(err_code);
        
    }
    //-----------------------------------------------------
    /**@brief Application main function.
     */
    
    int main(void)
    {
    
        NRF_LOG_INIT();
    	
    	application_init();//
    	init_fstorage();
    
    	APP_SCHED_INIT(4,10);
        NRF_LOG_PRINTF("system start......\r\n");	
    	led_timer_init();
        led_timer_start();
        // Enter main loop.
        for (;;)
        {
    		app_sched_execute();
            power_manage();
        }
    }

    this time I found app_sched_event_put can be execute, but the function write_flash() can't be called, I don't know any question occur here. can you help me, thanks again!

  • OK, I solved it. it's the function app_sched_event_put return  NRF_ERROR_INVALID_LENGTH. I redefine the parameters of APP_SCHED_INIT();and now is ok!Thank you,tesc, thank you ,msromero! 

Reply Children
No Data
Related