heinbali01 wrote on Saturday, May 30, 2015:
I would vote for Tom’s solution:
uint32_t ulTickCount = 0ul;
void a_task( void *pvParameters
{
for( ;; )
{
/* Reading a 32-bit variable in 32-bit memory
should be safe. */
if( ulTickCount != 0ul )
{
taskDISABLE_INTERRUPTS ();
ulTickCount--;
taskENABLE_INTERRUPTS ();
}
}
}
void an_isr()
{
/* The task has protected itself against possible
interrupts. We're not expecting a nested interrupt
that also accesses 'ulTickCount'. */
ulTickCount++;
}
Programmers dislike disabling interrupts, but in the above case I see no better solution. As you’ll know the compiler will create at least 3 instructions for a de- or increment in memory:
ulTickCount--;
ldr r2, [r3] // Load from memory
sub r0, r2, #1 // Decrease with 1
str r0, [r3] // Store in memory
Getting an interrupt in-between these instructions would be fatal, ulTickCount
gets corrupted.
About xSemaphoreGive
:
When you are sharing resources/objects among tasks, a semaphore or a mutex can be very useful. Before using the resource you take
the semaphore, when ready you give
the semaphore:
if( xSemaphoreTake( xUSARTAccessSemaphore, ( TickType_t ) 10 ) )
{
vUSARTWrite( pcMessage, xLength );
xSemaphoreGive( xUSARTAccessSemaphore );
}
About xSemaphoreGiveFromISR
:
Sometime a resource becomes available when an interrupt fires, for instance when data is received or sent.
Suppose a USART receives characters and an ISR stores them into buffers. xSemaphoreGiveFromISR
is called as soon as one buffer is full:
void an_isr()
{
BaseType_t xHigherPriorityTaskWoken = psFALSE;
/* Read a character from the register: */
ucUSARTBUffer[ xUSARTIndex ][ xUSARTHead ] = UDR0;
if( ++xUSARTHead == USART_BUF_LENGTH )
{
xUSARTHead = 0;
if( ++xUSARTIndex == USART_BUF_COUNT )
{
xUSARTIndex = 0;
}
/* As noticed above: the priority of this ISR should not
be higher than configMAX_SYSCALL_INTERRUPT_PRIORITY. */
xSemaphoreGiveFromISR( xUSARTSemaphore, &xHigherPriorityTaskWoken );
}
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
}
Regards,
Hein