Bird
Raised Fist0
FreeRTOSprogramming~10 mins

Semaphore for ISR-to-task signaling in FreeRTOS - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - Semaphore for ISR-to-task signaling
ISR triggers event
↓
Give semaphore from ISR
↓
Task waiting on semaphore
↓
Semaphore received
↓
Task resumes and processes event
The ISR signals a task by giving a semaphore, which the task waits to take before continuing.
Execution Sample
FreeRTOS
void ISR_Handler() {
  BaseType_t xHigherPriorityTaskWoken = pdFALSE;
  xSemaphoreGiveFromISR(xSemaphore, &xHigherPriorityTaskWoken);
  portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}

void Task(void *pvParameters) {
  for(;;) {
    xSemaphoreTake(xSemaphore, portMAX_DELAY);
    // Process event
  }
}
ISR gives a semaphore to unblock a task waiting on it, allowing safe signaling from interrupt to task.
Execution Table
StepContextActionSemaphore StateTask StateOutput
1TaskWaiting on semaphoreEmptyBlockedNo output
2ISRGive semaphore from ISRGivenBlockedNo output
3ISRCheck if higher priority task wokenGivenBlockedNo output
4ISRYield to higher priority task if neededGivenReady to runNo output
5TaskTake semaphoreTakenRunningProcess event
6TaskFinish processingEmptyRunningEvent processed
7EndNo more eventsEmptyRunningIdle
💡 Task takes semaphore and resumes; ISR signaling complete.
Variable Tracker
VariableStartAfter ISR GiveAfter Task TakeFinal
xSemaphoreEmptyGivenTakenEmpty
Task StateBlockedBlockedRunningRunning
xHigherPriorityTaskWokenpdFALSEpdTRUE or pdFALSEN/AN/A
Key Moments - 3 Insights
Why do we use xSemaphoreGiveFromISR instead of xSemaphoreGive in the ISR?
Because xSemaphoreGiveFromISR is safe to call inside an ISR and handles special ISR context, as shown in execution_table step 2.
What does portYIELD_FROM_ISR do after giving the semaphore?
It requests a context switch if a higher priority task was woken, allowing immediate task execution (execution_table step 4).
Why does the task block on xSemaphoreTake before the ISR gives the semaphore?
Because the semaphore is initially empty, so the task waits until the ISR signals it by giving the semaphore (execution_table step 1).
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table at step 2, what happens to the semaphore?
ASemaphore is taken by task
BSemaphore is given from ISR
CSemaphore remains empty
DSemaphore is deleted
💡 Hint
Check the 'Semaphore State' column at step 2 in execution_table.
At which step does the task resume running after being blocked?
AStep 1
BStep 3
CStep 5
DStep 7
💡 Hint
Look at 'Task State' column to see when it changes to Running.
If portYIELD_FROM_ISR was not called, what would likely happen?
ATask might remain blocked until next scheduler run
BSemaphore would not be given
CTask would immediately run
DISR would block
💡 Hint
Refer to key_moments about portYIELD_FROM_ISR and execution_table step 4.
Concept Snapshot
Semaphore for ISR-to-task signaling:
- ISR uses xSemaphoreGiveFromISR to signal task safely.
- Task waits on semaphore with xSemaphoreTake.
- portYIELD_FROM_ISR triggers immediate task switch if needed.
- Ensures safe communication from interrupt to task context.
Full Transcript
This example shows how an ISR signals a task using a semaphore in FreeRTOS. The task starts blocked, waiting on the semaphore. When the ISR occurs, it calls xSemaphoreGiveFromISR to give the semaphore safely from interrupt context. Then it calls portYIELD_FROM_ISR to request a context switch if a higher priority task was woken. The task then takes the semaphore and resumes running to process the event. This method ensures safe and efficient signaling between ISR and task without race conditions or blocking in the ISR.

Practice

(1/5)
1. What is the main purpose of using a semaphore in FreeRTOS for ISR-to-task signaling?
easy
A. To disable interrupts during task execution
B. To create a new task inside an ISR
C. To safely notify a task from an interrupt service routine (ISR)
D. To allocate memory dynamically in an ISR

Solution

  1. Step 1: Understand semaphore role in FreeRTOS

    Semaphores are synchronization tools used to signal between tasks or between ISRs and tasks.
  2. Step 2: Identify ISR-to-task signaling purpose

    In FreeRTOS, semaphores let an ISR notify a task safely without blocking or complex synchronization.
  3. Final Answer:

    To safely notify a task from an interrupt service routine (ISR) -> Option C
  4. Quick Check:

    Semaphore signals task from ISR = A [OK]
Hint: Semaphores signal tasks from ISRs safely [OK]
Common Mistakes:
  • Thinking semaphores create tasks
  • Confusing semaphores with disabling interrupts
  • Using semaphores for memory allocation
2. Which FreeRTOS function is used inside an ISR to give a semaphore to a task?
easy
A. xSemaphoreGiveFromISR()
B. xSemaphoreTakeFromISR()
C. xSemaphoreCreateFromISR()
D. xSemaphoreGive()

Solution

  1. Step 1: Recall ISR-safe semaphore functions

    FreeRTOS provides special functions for ISR context to avoid blocking and ensure safety.
  2. Step 2: Identify the correct ISR semaphore give function

    The function to give a semaphore from an ISR is xSemaphoreGiveFromISR().
  3. Final Answer:

    xSemaphoreGiveFromISR() -> Option A
  4. Quick Check:

    Give semaphore from ISR = xSemaphoreGiveFromISR() [OK]
Hint: ISR uses xSemaphoreGiveFromISR() to signal tasks [OK]
Common Mistakes:
  • Using xSemaphoreGive() inside ISR (not safe)
  • Confusing take and give functions
  • Assuming xSemaphoreCreateFromISR() exists
3. Given the code snippet below, what will be the output printed by the task?
SemaphoreHandle_t xSemaphore;

void ISR_Handler() {
    BaseType_t xHigherPriorityTaskWoken = pdFALSE;
    xSemaphoreGiveFromISR(xSemaphore, &xHigherPriorityTaskWoken);
}

void TaskFunction(void *pvParameters) {
    if (xSemaphoreTake(xSemaphore, portMAX_DELAY) == pdTRUE) {
        printf("Semaphore received\n");
    }
}
medium
A. Semaphore received twice
B. No output
C. Runtime error
D. Semaphore received

Solution

  1. Step 1: Analyze ISR giving semaphore

    The ISR calls xSemaphoreGiveFromISR() which releases the semaphore.
  2. Step 2: Analyze task waiting on semaphore

    The task waits indefinitely with xSemaphoreTake() and prints "Semaphore received" when it gets the semaphore.
  3. Final Answer:

    Semaphore received -> Option D
  4. Quick Check:

    Task prints after semaphore take = C [OK]
Hint: Task prints after successful semaphore take [OK]
Common Mistakes:
  • Thinking semaphore is given twice
  • Assuming no output if ISR runs
  • Expecting runtime error without initialization
4. Identify the error in the following ISR code snippet for giving a semaphore:
void ISR_Handler() {
    xSemaphoreGive(xSemaphore);
}
medium
A. xSemaphoreGive() cannot be called from an ISR
B. Semaphore must be taken before giving
C. ISR must not use semaphores
D. xSemaphoreGive() requires a pointer argument

Solution

  1. Step 1: Check function suitability for ISR

    xSemaphoreGive() is not safe to call inside an ISR because it may block or cause race conditions.
  2. Step 2: Identify correct ISR function

    Use xSemaphoreGiveFromISR() inside ISRs to safely give semaphores.
  3. Final Answer:

    xSemaphoreGive() cannot be called from an ISR -> Option A
  4. Quick Check:

    Use xSemaphoreGiveFromISR() in ISR, not xSemaphoreGive() [OK]
Hint: Use xSemaphoreGiveFromISR() inside ISR, not xSemaphoreGive() [OK]
Common Mistakes:
  • Calling xSemaphoreGive() inside ISR
  • Ignoring ISR context restrictions
  • Assuming semaphore must be taken before giving
5. You want a task to respond immediately when a hardware interrupt occurs. Which sequence correctly uses a semaphore for ISR-to-task signaling in FreeRTOS?
hard
A. Create counting semaphore; task calls xSemaphoreGive(); ISR calls xSemaphoreTakeFromISR()
B. Create binary semaphore; ISR calls xSemaphoreGiveFromISR(); task calls xSemaphoreTake() with portMAX_DELAY
C. Create mutex; ISR calls xSemaphoreGive(); task calls xSemaphoreTake() with zero timeout
D. Create binary semaphore; task calls xSemaphoreGiveFromISR(); ISR calls xSemaphoreTake()

Solution

  1. Step 1: Identify correct semaphore type and usage

    Binary semaphore is suitable for signaling events from ISR to task.
  2. Step 2: Confirm correct function calls and order

    ISR must call xSemaphoreGiveFromISR() to signal; task waits with xSemaphoreTake() blocking indefinitely (portMAX_DELAY) until signaled.
  3. Final Answer:

    Create binary semaphore; ISR calls xSemaphoreGiveFromISR(); task calls xSemaphoreTake() with portMAX_DELAY -> Option B
  4. Quick Check:

    Binary semaphore + ISR give + task take = A [OK]
Hint: ISR gives semaphore, task takes with infinite wait [OK]
Common Mistakes:
  • Using mutex instead of semaphore
  • Calling give in task and take in ISR
  • Using zero timeout causing missed signals
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard