Hello team,
We are using FreeRtos on TDA4vm board of TI.
Here we are using the TaskP_sleepInMsecs() to generate a delay in ms using the ticks .
But our functionality needs delay in microseconds say. 500-800us .
Is there any way to achieve sleep in us.
Kindly help.
Welcome to the forums @Ketaki04! This question is a good one and comes up time and time again.
There are loads of other discussion you can find if you search for ‘microseconds’ on these forums if you want even more opinions…but I’ll chip in here with mine.
I’d listen to the guidance from @hs2. A hardware timer with a corresponding interrupt is the best way to go. Not only will the hardware timer be more accurate, but it will also avoid any issues with the context switch of FreeRTOS eating into performance. In short - the faster the TickISR executes, the less time between each context switch which means your task is executing less as the context switches eat into that time.
Your task could simply sleep/block/wait between the interrupt so other tasks can execute. This is probably only a good strategy if your task is long running. If your function is quick, I’d just leave it as the interrupt service routine (ISR).
Actually, we are currently working on a Evalution board, using the Ti sdk 8.2 freeRTOS, so we are using the APIs available for our function to work. Can I get some help in how to use the Hardware timer.
I agree with @hs2 and @kstribrn. For such a short duration, it might be best to use hardware timer since it would provide you with accurate timing and also eliminate the overhead of context switching. Note that for greater duration of wait (in milliseconds), you should consider using vTaskDelay as that will be more efficient and will allow other tasks to run.
You can download the technical reference manual of the TI TDA4VM SoC here.
Looking at the above manual, it seems that there are 10 ‘MCU’ timers and 20 ‘Main’ timers. Depending on the core you are using for running FreeRTOS, you can choose to use any one of them to generate an interrupt. Below I show how can this be done using pseudo code.
volatile uint32_t globalFlag;
void task( void * arg )
{
for( ;; )
{
configPRINTF( "Next print after 5000us\n" );
globalFlag = 0;
/* Configure and Start MCU timer 3 to generate an interrupt every 1000us. */
/* NOTE: this is pseudo code. There is no such function and you would need
* to write one looking at the data sheet. */
MCU_TIMER_Config( TIMER3, interruptHandler, 1000 /* us */ );
/* Busy wait while the flag becomes greater than 5 (since we are
* incrementing it every 1000us and we want to wait for 5000us). Hint: look
* at the Interrupt handler below. */
while( globalFlag < 5 ); /* Here, you can also use Semaphores/task
notifications to wait. No compulsion to busy
wait. */
/* Stop the timer. Note that this is also pseudo code. */
MCU_TIMER_Stop( TIMER3 );
}
}
/* Handler which will be called at every 1000us by the timer interrupt. */
void interruptHandler( void )
{
/* Increment the flag per invocation indicating the passing of 1000us. */
globalFlag++;
}