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

  • Bruse said:
    However, if I commen out if (pdPASS != xTaskCreate(app_task_demo, "TaskDemo", 256, NULL, 1, &m_demo_thread)), that is to say, the task app_task_demo has not been created, the flash erasing and writing is all OK.

    It does not sound to me that the taskCreate function was successful and it looks like your application is not handling that fault correctly. I would first advise you to find out the error code for that failure in xtaskCreate function and if it is due to insufficient heap memory, then you need to increase the heap size in configTOTAL_HEAP_SIZE in your FreeRTOSConfig.h file. 

    Bruse said:
    But I meet other issue. I need to write some data to flash which is receive from UART. When it runs nrf_fstorage_erase() function, the code is dead and it couldn't run any more. 

    There is no such thing as the code is dead, the PC of the CPU still needs to execute something so you need to figure out the context in which your program counter (PC) is still executing. Start your application in debugger after compiling it without any debug optimizations and when the error occurs, then halt the debugger to check the context in which your code is being executed. It could be a loop, app_error_check handler or an hardfault. Once you figured out why your code seems dead to you (most likely because it might be looping somewhere) then you can try to understand the nature of your problem.

  • Hi 

    I have solved the issue causing by flash erasing. I use the queue mechanism like this:

    		while(1)
    		{				
    			if(xQueueReceive(ble_task_handle,&ble_task_msg,portMAX_DELAY)==pdTRUE)							
    			{					
    				switch(ble_task_msg.task_id)
    				{
    					case APP_COMMAND_QUEUE_ID:				
    							 process_ble_commands();	
    					break;
    					
    					case WRITE_FLASH_QUEUE_ID:
    							 flash_operate(fs_event_num);		
    					break;
    											
    				}
    				ble_task_msg.task_id = 0;
    			}			
    		}

Related