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

Using FDS with BLE and Scheduler

Hey guys,

I'm trying to make the FDS work with BLE and the scheduler. But something doesn't right when I use the Softdevice and scheduler with the FDS.

Must I register something in my ble_stack_init(), I read something about sys_evt_dispatch() to softdevice_sys_evt_handler_set():.

I'm using SDK 14.1 with the Softdevice S132 v5.0.0 on a NRF52832.

I hope you guys can help me.

Here is a part of my code:

fds_evt_handler()

static void fds_evt_handler(fds_evt_t const * p_evt)
{
    NRF_LOG_INFO("Event: %s received (%s)",
                  fds_evt_str[p_evt->id],
                  fds_err_str[p_evt->result]);

    switch (p_evt->id)
    {
        case FDS_EVT_INIT:
				{
            if (p_evt->result == FDS_SUCCESS)
            {
								NRF_LOG_INFO("FDS_EVT_INIT");
                m_fds_initialized = true;
            }
				} break;

        case FDS_EVT_WRITE:
        {
            if (p_evt->result == FDS_SUCCESS)
            {
								NRF_LOG_INFO("FDS_EVT_WRITE");
            }
        } break;

        case FDS_EVT_DEL_RECORD:
        {
            if (p_evt->result == FDS_SUCCESS)
            {
                NRF_LOG_INFO("FDS_EVT_DEL_RECORD");
            }
        } break;

        default:
            break;
    }
}

fds_write()

void ncs_record_write(uint32_t fid, uint32_t key, void const * p_data, uint32_t len)
{
		ret_code_t err_code;
	
    fds_record_t const rec =
    {
        .file_id           = fid,
        .key               = key,
        .data.p_data       = p_data,
        .data.length_words = (len + 3) / sizeof(uint32_t)
    };

    NRF_LOG_INFO("Writing record to flash...\r\n"
                 "file: 0x%x, key: 0x%x, \"%s\", len: %u bytes\r\n",
                 fid, key, p_data, len);

    err_code = fds_record_write(NULL, &rec);
		
    if (err_code != FDS_SUCCESS)
    {
        NRF_LOG_INFO("Error: ncs_record_write() returned %s.\r\n",
                     fds_err_str[err_code]);
    }
}

fds_read()

void ncs_record_read(uint32_t fid, uint32_t key)
{
		ret_code_t err_code;
	
		fds_flash_record_t			config = {0};
		fds_record_desc_t 			desc = {0};
    fds_find_token_t  			ftok = {0};
		
    if (fds_record_find(fid, key, &desc, &ftok) == FDS_SUCCESS)
    {		
				/* Open the record and read its contents. */
				err_code = fds_record_open(&desc, &config);
				APP_ERROR_CHECK(err_code);
				
				memcpy(&_ncs_settings.buffer, config.p_data, sizeof(config.p_data));
			
				NRF_LOG_INFO("Record found: %u", _ncs_settings.buffer);
				
				/* Close the record when done reading. */
				err_code = fds_record_close(&desc);
				APP_ERROR_CHECK(err_code);
		}
		else
		{
				NRF_LOG_INFO("Record not found!");
		}
}

fds_setup()

static ret_code_t fds_setup(void)
{
		ret_code_t err_code;
	
		err_code = fds_register(fds_evt_handler);
		APP_ERROR_CHECK(err_code);
		
		err_code = fds_init();
		APP_ERROR_CHECK(err_code);

		return NRF_SUCCESS;
}

wait_for_fds_ready()

static void wait_for_fds_ready(void)
{
    while (!m_fds_initialized)
    {
        power_manage();
    }
}

scheduler_fds_write()

static void scheduler_fds_write(void * p_event_data, uint16_t event_size)
{
    UNUSED_PARAMETER(p_event_data);
    UNUSED_PARAMETER(event_size);
	
		ncs_record_write(ncs_settings.file, ncs_settings.key, 
											(void *)ncs_settings.buffer, sizeof(ncs_settings.buffer));

    NRF_LOG_INFO("FDS data written!");
}

scheduler_fds_read()

static void scheduler_fds_read(void * p_event_data, uint16_t event_size)
{
    UNUSED_PARAMETER(p_event_data);
    UNUSED_PARAMETER(event_size);
	
    ncs_record_read(ncs_settings.file, ncs_settings.key);
	
		NRF_LOG_INFO("FDS data readed!");
}

main()

int main(void)
{
    ret_code_t	err_code;
	bool			erase_bonds;
		
    // Initialize
    log_init();
    timers_init();
    buttons_leds_init(&erase_bonds);
	ble_stack_init();
    scheduler_init();	
    gap_params_init();
    gatt_init();
	peer_manager_init();
	services_sr_init();
	advertising_init();
	db_discovery_init();
	services_init();
    conn_params_init();
	gpiote_init();
	saadc_init();
	twi_init(SCL_PIN, SDA_PIN);

	err_code = fds_setup();
	APP_ERROR_CHECK(err_code);
		
	wait_for_fds_ready();
		
	// Reading Battery first time
	err_code = nrf_drv_saadc_sample();
    APP_ERROR_CHECK(err_code);
		

ncs_settings.sync = 5;
ncs_settings.buffer = ncs_settings.sync;
	ncs_settings.file = 1;
	ncs_settings.key = 1;
				
	err_code = app_sched_event_put(NULL, 0, scheduler_fds_write);
	APP_ERROR_CHECK(err_code);

//		err_code = app_sched_event_put(NULL, 0, scheduler_fds_read);
//		read_error(err_code);
//		APP_ERROR_CHECK(err_code);
	
    // Start execution
    NRF_LOG_INFO("nxta Cube started.");
	
    advertising_start(erase_bonds);
				
		err_code = app_timer_start(m_battery_timer_id, BATTERY_LEVEL_MEAS_INTERVAL, NULL);
		APP_ERROR_CHECK(err_code);

    // Enter main loop
    for (;;)
    {
        app_sched_execute();
			
        if (NRF_LOG_PROCESS() == false)
        {
            power_manage();
        }
				
				if(m_cur_conn_handle != BLE_CONN_HANDLE_INVALID)
				{
						if(nxtaEvent.pending)
						{
								handle_nxtaEvent(&nxtaEvent);
						}
				}		
    }
}

Thanks in advance :)

UPDATE 22.12.2017 I updated the code a little bit

  • Hey Jørgen, did you found what I'm doing wrong in my code? Thanks for you help

  • I can't see anything wrong with your code. I commented in call to ncs_s_file_setup() in your main.c file (as this was the only reference, except peer_manager, I could find in your code to fds_init() function). This is the output I see on RTT:

     0> <info> app: log_init
     0> <info> app: timers_init
     0> <info> app: buttons_leds_init
     0> <info> app: ble_stack_init
     0> <info> app: scheduler_init
     0> <info> app: gap_params_init
     0> <info> app: gatt_init
     0> <info> app: peer_manager_init
     0> <info> app: services_sr_init
     0> <info> app: advertising_init
     0> <info> app: db_discovery_init
     0> <info> app: services_init
     0> <info> app: conn_params_init
     0> <info> app: gpiote_init
     0> <info> app: saadc_init
     0> <info> app: twi_init
     0> <info> ncs_s_file_m: FDS initialization success.
    

    I am able to see the device advertising, and connect to it. What is the issue?

  • Yes sorry I forget to uncomment:

    //		err_code = fds_setup();
    //		APP_ERROR_CHECK(err_code);
    

    Can you try to write and read something by uncomment this lines:

    //		ncs_settings.sync = 5;
    //		ncs_settings.buffer = ncs_settings.sync;
    //		ncs_settings.file = 1;
    //		ncs_settings.key = 1;
    //				
    //		err_code = app_sched_event_put(NULL, 0, scheduler_fds_write);
    //		read_error(err_code);
    //		APP_ERROR_CHECK(err_code);
    //	
    //		err_code = app_sched_event_put(NULL, 0, scheduler_fds_read);
    //		read_error(err_code);
    //		APP_ERROR_CHECK(err_code);
    

    This doesn't work and after fds_setup() the NRF_LOG_INFO() function doesnt work right.

    Thanks for your affort

  • Hi,

    I don't think the code on GitHub that you linked is updated. It only have scheduler_ncs_s_file_update, which will end in FDS_ERR_NOT_FOUND error in the FDS event handler. I changed the code to schedule ncs_s_file_create() instead, and this seems to work. However, I get a FDS_ERR_NOT_FOUND error code from the scheduled call to ncs_s_file_read() right after.

    You do not have any mechanism to make sure the record is written before reading it. Note that FDS writes are asynchronous, meaning that it will schedule the write/erase event between softdevice/BLE events. You must wait until for the FDS_EVT_WRITE/FDS_EVT_UPDATE event in the FDS event handler before you can read the record.

    Best regards,

    Jørgen

  • Hey Jørgen, I uploaded my code again. If I only want to write a FDS record, the FDS handler I initialize never gave a something back.

     case FDS_EVT_WRITE:
        {
            if (p_evt->result == FDS_SUCCESS)
            {
    							NRF_LOG_INFO("FDS_EVT_WRITE");
            }
        } break;
    

    For me it seems, that the events are not called right from the schedueler. I know that I did something from, but I can't figure out what...

    And thank you again for your effort to help me!

    Kevin

Related