FreeRTOS
A real time operating system for embedded systems
INTERRUPT MANAGEMENT
2
3 Interrupt Management
Topics covered:
Which FreeRTOS API functions can be used from within an interrupt service
routine (ISR).
How a deferred interrupt scheme can be implemented.
How to create and use binary semaphores and counting semaphores.
The differences between binary and counting semaphores.
How to use a queue to pass data into and out of an interrupt service
routine.
3.1 Deferred Interrupt Processing
Binary Semaphores used for Synchronization
A Binary Semaphore can be used to unblock a task each time a particular
interrupt occurs
The majority of the interrupt event processing can be implemented within
the synchronized task.
Only a very fast and short portion remaining directly in the ISR.
The i terrupt pro essi g is said to ha e ee deferred to a ha dler task
The ha dler task uses a lo ki g take all to a se aphore a d e ters the
Blocked state to wait for the event to occur
Whe the e e t o urs, the ISR uses a gi e operatio o the sa e
semaphore to unblock the task
Interrupt and Handler Task
3.1 Deferred Interrupt Processing
In this interrupt Synchronization scenario:
The Binary Semaphore can be considered conceptually as a queue with a
length of one.
By calling xSemaphorTake(), the handler task effectively attempts to read
from the queue with a block time, causing the task to enter the Blocked
state if the queue is empty.
When the event occurs, the ISR uses the xSemaphoreGiveFromISR() to
place a semaphore into the queue, making the queue is full.
This causes the handler task to exit the Blocked state and remove the
semaphore, leaving the queue empty once more.
When the handler task has completed its processing, it once more
attempts to read from the queue, and, finding the queue empty, re-enters
the Blocked state to wait for the next event.
Interrupt and Handler Task
Create a Binary Semaphore
Before a semaphore can be used, it must be created. Use the
vSemaphoreCreateBinary()API function (in fact, macro) to
create a binary semaphore
void vSemaphoreCreateBinary(xSemaphoreHandle xSemaphore);
xSemaphore
The semaphore being created
‘Take’ a Semaphore
Use xSemaphoreTake()to take a se aphore
portBASE_TYPE xSemaphoreTake(xSemaphoreHandle xSemaphore,
portTickType xTicksToWait );
xSemaphore
The se aphore ei g take
xTicksToWait
The maximum amount of time the task should remain in the Blocked state;
Setting xTicksToWait to portMAX_DELAY will cause the task to wait
indefinitely
Return value
pdPASS will only be returned if it was successful in obtaining the
semaphore
pdFALSE if the semaphore was not available
‘Give’ a Semaphore
Use xSemaphoreGive()(xSemaphoreGiveFromISR())to
gi e a se aphore he i a ISR
portBASE_TYPE xSemaphoreGiveFromISR(
xSemaphoreHandle xSemaphore,
portBASE_TYPE *pxHigherPriorityTaskWoken );
xSemaphore
The se aphore ei g gi e
pxHigherPriorityTaskWoken
If the handle task has a higher priority than the currently executing task (the
task that was interrupted), this value will be set to pdTRUE
Return value
pdPASS will only be returned if successful
pdFAIL if a semaphore is already available and cannot be given
Example 12. Using a Binary Semaphore
to Synchronize a Task with an Interrupt
11
xSemaphore()
12
xSemaphoreGiveFromISR()
13
14
15
Sequence of execution
16
17
18
3.2 Counting Semaphores
For Binary Semaphore, when interrupts come at a speed faster
than the handler task can process, events will be lost.
Counting semaphore can be thought of as queues that have a
length of more than one
Ea h ti e a ou ti g se aphore is gi e , a other spa e i its
queue is used, count value is the number of items in the queue.
Counting semaphores are typically used for two things:
Counting events: the count value is the difference between the number of
events that have occurred and the number that have been processed
Resource management: the count value indicates the number of
resources available; a task must first obtains a semaphore before obtains
the control of a resource; a task returns a semaphore when finishing with
the resource
Using a counting semaphore to ‘count’
events
Create a Counting Semaphore
Use xSemaphoreCreateCounting()to create a counting
semaphore
xSemaphoreHandle xSemaphoreCreateCounting(
unsigned portBASE_TYPE uxMaxCount,
unsigned portBASE_TYPE uxInitialCount );
uxMaxCount
The maximum value the semaphore will count to
uxInitialCount
The initial count value of the semaphore after it has been created
Return value
If NULL is returned then the semaphore could not be created because there
was insufficient heap memory available
A non-NULL value being returned indicates that the semaphore was
created successfully. The returned value should be stored as the
handle to the created semaphore.
Example 13. Using a Counting Semaphore to
Synchronize a Task with an Interrupt
22
23
3.4 USING QUEUES WITHIN AN INTERRUPT
SERVICE ROUTINE
• xQueueSendToFrontFromISR(),
xQueueSendToBackFromISR() and
xQueueReceiveFromISR() are versions of
xQueueSendToFront(), xQueueSendToBack()
and xQueueReceive() respectively that are
safe to use within an interrupt service
routine.
• Semaphores are used to communicate
events. Queues are used to both
communicate events and transfer data.
24
Example 14. Sending and Receiving on a
Queue from Within an Interrupt
25
26
27
28
29
Sequence of Execution
30
3.5 INTERRUPT NESTING
• The most recent FreeRTOS ports allow
interrupts to nest.
31
32