This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Add FreeRTOS to do a lot of caculation and BLE data data transmission in MutilRole device

Hi,

I got the example github.com/.../nrf52-ble-multi-link-multi-role and I have added FreeRTOS to the example refer to ble_app_hrs_freertos in SDK v15.2.0 with S140 v6.1.0.

We want to do a game project. One 52840 works in mutilrole(central_and_peripheral) and another one just work in peripheral. APP,peripheral and mutilrole device would exchane data each other and also the devie would have a lot of data to cacaulate using FPU.

static void BLEAppTask(void * pvParameter)
{	
		if (pdPASS != xTimerStart(m_battery_timer, OSTIMER_WAIT_FOR_QUEUE))
		{
				APP_ERROR_HANDLER(NRF_ERROR_NO_MEM);
		}		
			
		while(1)
		{
			  process_ble_commands();
			  send_device_status();
			  flash_operate(fs_event_num);
			  taskYIELD();		
		}
}

static void ble_task(void *arg)
{		
		advertising_start(); 	
		scan_start();                          // Start scanning for peripherals and initiate connection to devices which  advertise.	
}	
static void app_task_demo(void *arg)
{		
		if (pdPASS != xTimerStart(m_master_receive_timer, OSTIMER_WAIT_FOR_QUEUE))
		{
				APP_ERROR_HANDLER(NRF_ERROR_NO_MEM);
		}
		uart_printf("app_task_demo start.\n");
		vTaskSuspend(NULL);	
}	
static void run_task(void)
{
	nrf_sdh_freertos_init(ble_task, NULL);	                                 // Create a FreeRTOS task for the BLE stack.

    if (pdPASS != xTaskCreate(BLEAppTask, "BLEAppTask", 256, NULL, 2, &m_app_thread))
    {
        uart_printf("Failed to create BLEAppTask.\n");
    }
    else
    {
        uart_printf("BLEAppTask FreeRTOS created.\n");
    }
		
		
    if (pdPASS != xTaskCreate(app_task_demo, "TaskDemo", 256, NULL, 1, &m_demo_thread))
    {
        uart_printf("Failed to create TaskDemo task.\n");
    }
    else
    {
        uart_printf("TaskDemo FreeRTOS created.\n");
    }				
}	
int main(void)
{
    .....
    .....
	run_task();
    vTaskStartScheduler();		
	uart_printf("MutilRole application start %s\n",FIRM_WARE_REVERSION);
    for (;;)
    {	
		APP_ERROR_HANDLER(NRF_ERROR_FORBIDDEN);
    }
		
}

void send_device_status(void)
{
	uint8_t dev_info[10];
	if(DeviceStaChanged)
	{
			DeviceStaChanged = false;
			uart_printf("send_device_status\n");	
			dev_info[0] = APP_PACKET_TAG;
			dev_info[1] = 1;
			dev_info[2] = MODULE_EVENT_TYPE;
			dev_info[3] = 0;
			dev_info[4] = 4;
			dev_info[5] = 7;
			dev_info[6] = 0;
			dev_info[7] = 1;
			if(m_service_discovery_conn_handle!= BLE_CONN_HANDLE_INVALID)
				dev_info[8] = 1;        // connected status
			else
				dev_info[8] = 0;        // disconnected status
			dev_info[9] = Crc8(dev_info,9);		
			BLE_peripheral_send(dev_info,10);
			
	}
}	

 

In the BLEAppTask, process_ble_commands() is used to send data to APP or peripheral and it's OK now.

send_device_status() is used to send the link status to APP between center and peripheral . But I found that it would send data to APP even though it has run into send_device_status function and have printf send_device_status log. I'm also sure BLE_peripheral_send function is good.

It seems that CPU has been rob by other task so that it couldn't send data to APP. I set the priority of BLEAppTask to 2 and it is the same as nrf_sdh_freertos_init(ble_task, NULL);

If I set the priority to 1 for the BLEAppTask ,the  BLEAppTask couldn't run well. For example, mutilrole could connect to peripheral but it wouldn't advertise after center connect to peripheral .

So could you give me some advice about it? Thanks.

Another question, I also want to do some data caculation in the app_task_demo, but I have not done caculation now. The task creation is OK.

I hope the task wouldn't affect BLE data transmission. 

I have start a timer in the app_task_demo task and it  would invert a LED on the development kit. But the task has not run becasuse the LED could not blink.

Best regards,

Bruse

Parents
  • Hi,

    Have you done any bench marking of the various tasks you have? Sounds as you are running out of CPU time and would need to optimize some function or adapt you app to handle that in some way.

    As for raising app priorities to a higher level, this could disturb the SD behavior and is not recommended. If you use the app high level for some of  your tasks you need to make sure the sd has some time to run tasks in SD low priority as well, or it will not able to funciton properly.

  • Hi

    How to do bench marking of the various tasks?

    Now I just have two task. One task(BLEAppTask) mainly is used for  BLE data transmission. Another task(app_task_demo) is just used to start a timer to toggle a LED.

    Should I merge BLEAppTask into the task which's created by nrf_sdh_freertos_init(). I have tried to do it as follow, but it  couldn't funciton properly. 

    static void ble_task(void *arg)
    {		
    		advertising_start(); 	
    		scan_start();                          // Start scanning for peripherals and initiate connection to devices which  advertise.	
    	
    		while(1)
    		{
    			  process_ble_commands();				
    			flash_operate(fs_event_num);
    			taskYIELD();
    		}
    }
    
    nrf_sdh_freertos_init(ble_task, NULL);

    I see some issues about nRF52 SDK on https://devzone.nordicsemi.com/f/nordic-q-a/34155/what-are-sdk-15-x-0-known-issues. Would these issues cause my issue?

    Best regards,

    Bruse

  • Hi,
    Please try to add the workaround for the issue to your code to see if that helps. Since there is a known issue, it's probably better to test that first, before starting to benchmark other functions.

    One way to do the benchmarking is to add gpio toggling to parts of your code that you want to check run time for, then observe that using a logic analyzer.

Reply
  • Hi,
    Please try to add the workaround for the issue to your code to see if that helps. Since there is a known issue, it's probably better to test that first, before starting to benchmark other functions.

    One way to do the benchmarking is to add gpio toggling to parts of your code that you want to check run time for, then observe that using a logic analyzer.

Children
  • I also try to lock when flash is erasing like this:

    			taskENTER_CRITICAL();
        		flash_clear();				
    			taskEXIT_CRITICAL();

    However,the code still would die and it couldn't run any more when it runs to flash_clear unless I reset or power up again.

    Is there any solutions for this issue? Thanks.

Related