STMF4 taskyield() help
I found a example code for the F4 Discovery board given by http://ph-elec.com/archives/stm32f4-freertos/. I am new to RTOS, so in the task created vdebugtask, he calls taskyield at the end so the scheduler suspends the task and enters the idle task. So how will this task be called again. i was unable to find any events which are given to wake it up.. please clarify this part of how this task will be run again…..
STMF4 taskyield() help
I’m not going to download at look at somebody elses port, only the official STM32F4 demo is supported (http://www.freertos.org/FreeRTOS-for-STM32F4xx-Cortex-M4F-IAR.html) but will comment on the rest of your post.
Calling taskYIELD() only offers to give up processing time to a task of equal priority, it will not cause the task to be blocked if there are not tasks of equal priority, and will definitely not cause the idle task to run if the task calling taskYIELD() has a priority above the idle priority.
Regards.
STMF4 taskyield() help
Th priorities given is as follows
#define mainTIME_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )
#define mainMEMS_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainDEBUG_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define mainINTEGER_TASK_PRIORITY ( tskIDLE_PRIORITY ) portTASK_FUNCTION( vTimeTask, pvParameters ) {
portTickType xLastWakeTime;
uint8_t i=0; xLastWakeTime = xTaskGetTickCount(); for(;;) {
// Once per second, copy the number of idle ticks and then
// reset the rolling counter.
if ( ++i == 20 ) {
i = 0;
u64IdleTicks = u64IdleTicksCnt;
u64IdleTicksCnt = 0;
} vTaskDelayUntil( &xLastWakeTime, ( 50 / portTICK_RATE_MS ) );
}
} void vApplicationTickHook( void ) {
++u64Ticks;
} portTASK_FUNCTION( vDebugTask, pvParameters ) {
char ch;
portBASE_TYPE xStatus;
//uint16_t u16StackSize; /* The parameters are not used. */
( void ) pvParameters; vDebugString( “Debug task started.rn”); for(;;) {
// As long as there are characters in the queue fifo this code should
// pop them out and send them as quick as possible out the UART.
if( USART_GetFlagStatus( USART2, USART_FLAG_TXE ) ) {
// We don’t want to block forever – need to check on Rx too.
xStatus = xQueueReceive( xDebugQueue, &ch, 10 / portTICK_RATE_MS );
if( xStatus == pdPASS ) USART_SendData( USART2, ch );
}
if ( USART_GetFlagStatus( USART2, USART_FLAG_RXNE ) ) {
ch = USART_ReceiveData( USART2 );
// Handle Debug Console Commands Here.
switch ( ch ) { // Alphabetical list of commands the console debugger responds to. case ‘m’:
vDebugPrintf( “Mems dump Stopped.rn”);
vSetMemsDump( false );
break;
case ‘M’:
vDebugPrintf( “Mems dump Started.rn”);
vSetMemsDump( true );
break; case ‘a’:
vDebugPrintf( “AtoD dump Stopped.rn”);
//vSetAtoDDump( FALSE );
break;
case ‘A’:
vDebugPrintf( “AtoD dump Started.rn”);
//vSetAtoDDump( TRUE );
break; case ‘l’:
vDebugPrintf( “Loop Count Stopped.rn”);
//vSetCntLoops( FALSE );
break;
case ‘L’:
vDebugPrintf( “Loop Count Started.rn”);
//vSetCntLoops( TRUE );
break; // Print out how much stack space remains on each task stack.
case ‘s’:
vDebugPrintf( “Remaining space on Task Stack:rn” );
//u16StackSize = uxTaskGetStackHighWaterMark( hDebugTask );
//vDebugPrintf( “Debugt%drn”, u16StackSize);
//u16StackSize = uxTaskGetStackHighWaterMark( hTimeTask );
//vDebugPrintf( “Timet%drn”, u16StackSize);
//u16StackSize = uxTaskGetStackHighWaterMark( hLCDTask );
//vDebugPrintf( “LCDt%drn”, u16StackSize);
break; // Add general test code here…
case ‘t’:
break; default:
break;
}
} taskYIELD();
}
} i have attached the code above….. i found by profiling that the amount of time spent in vApplicationTickHook is about 35% when the debug task runs for only .1%. But as u mentioned since the debug task is higher the app.hook task shouldn’t it be running all the time and not yielding to the vApplicationTickHook????
#define mainMEMS_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainDEBUG_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define mainINTEGER_TASK_PRIORITY ( tskIDLE_PRIORITY ) portTASK_FUNCTION( vTimeTask, pvParameters ) {
portTickType xLastWakeTime;
uint8_t i=0; xLastWakeTime = xTaskGetTickCount(); for(;;) {
// Once per second, copy the number of idle ticks and then
// reset the rolling counter.
if ( ++i == 20 ) {
i = 0;
u64IdleTicks = u64IdleTicksCnt;
u64IdleTicksCnt = 0;
} vTaskDelayUntil( &xLastWakeTime, ( 50 / portTICK_RATE_MS ) );
}
} void vApplicationTickHook( void ) {
++u64Ticks;
} portTASK_FUNCTION( vDebugTask, pvParameters ) {
char ch;
portBASE_TYPE xStatus;
//uint16_t u16StackSize; /* The parameters are not used. */
( void ) pvParameters; vDebugString( “Debug task started.rn”); for(;;) {
// As long as there are characters in the queue fifo this code should
// pop them out and send them as quick as possible out the UART.
if( USART_GetFlagStatus( USART2, USART_FLAG_TXE ) ) {
// We don’t want to block forever – need to check on Rx too.
xStatus = xQueueReceive( xDebugQueue, &ch, 10 / portTICK_RATE_MS );
if( xStatus == pdPASS ) USART_SendData( USART2, ch );
}
if ( USART_GetFlagStatus( USART2, USART_FLAG_RXNE ) ) {
ch = USART_ReceiveData( USART2 );
// Handle Debug Console Commands Here.
switch ( ch ) { // Alphabetical list of commands the console debugger responds to. case ‘m’:
vDebugPrintf( “Mems dump Stopped.rn”);
vSetMemsDump( false );
break;
case ‘M’:
vDebugPrintf( “Mems dump Started.rn”);
vSetMemsDump( true );
break; case ‘a’:
vDebugPrintf( “AtoD dump Stopped.rn”);
//vSetAtoDDump( FALSE );
break;
case ‘A’:
vDebugPrintf( “AtoD dump Started.rn”);
//vSetAtoDDump( TRUE );
break; case ‘l’:
vDebugPrintf( “Loop Count Stopped.rn”);
//vSetCntLoops( FALSE );
break;
case ‘L’:
vDebugPrintf( “Loop Count Started.rn”);
//vSetCntLoops( TRUE );
break; // Print out how much stack space remains on each task stack.
case ‘s’:
vDebugPrintf( “Remaining space on Task Stack:rn” );
//u16StackSize = uxTaskGetStackHighWaterMark( hDebugTask );
//vDebugPrintf( “Debugt%drn”, u16StackSize);
//u16StackSize = uxTaskGetStackHighWaterMark( hTimeTask );
//vDebugPrintf( “Timet%drn”, u16StackSize);
//u16StackSize = uxTaskGetStackHighWaterMark( hLCDTask );
//vDebugPrintf( “LCDt%drn”, u16StackSize);
break; // Add general test code here…
case ‘t’:
break; default:
break;
}
} taskYIELD();
}
} i have attached the code above….. i found by profiling that the amount of time spent in vApplicationTickHook is about 35% when the debug task runs for only .1%. But as u mentioned since the debug task is higher the app.hook task shouldn’t it be running all the time and not yielding to the vApplicationTickHook????
STMF4 taskyield() help
The Debug task will be spending most of its time suspended in the xQueueReceive(xDebugQueue) call when the output is ready to send a character but your queue doesn’t have anything to send.
It would be much better to make the Serial port interrupt driven where the sender puts the characters in the queue (and kick starts the port if needed), and the serial interrupt pulls the characters out of the queue, and serial input stuffs the characters received into a queue and the receiving task waits on the queue for data.
Having polling loops is normally a sign that you aren’t doing things right. (The exceptions are if you need to busy wait for something that WILL happen very quickly, faster than a context switch, or need to wait on a flag that can’t generate an interrupt).
STMF4 taskyield() help
If so how will the applicationidlehook task, if the higher priority task debug is suspended. But the waiting in the queue is for 10ms only right..
STMF4 taskyield() help
Your question is a bit confusing, but as soon as the higher priority tasks suspends, the next highest available task will start. If this is the Idle task, it will start to run where it left off, which is a loop cleaning up resources from deleted tasks and calling vApplicationIdleHook. There is no “minimum delay” to get to the idle hook, it might run many times in a tick