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

Parents
  • 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

Reply
  • 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

Children
Related