Bird
Raised Fist0
FreeRTOSprogramming~10 mins

Queue from ISR (xQueueSendFromISR) in FreeRTOS - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - Queue from ISR (xQueueSendFromISR)
ISR triggered
↓
Call xQueueSendFromISR
↓
Check if queue has space
Yes No↓
Add item
↓
Set higher priority task woken flag?
↓
Return success/fail
↓
Exit ISR
When an interrupt occurs, xQueueSendFromISR tries to add an item to the queue without blocking. It checks space, adds item if possible, and may request a context switch.
Execution Sample
FreeRTOS
BaseType_t xQueueSendFromISR(QueueHandle_t xQueue, const void * pvItemToQueue, BaseType_t *pxHigherPriorityTaskWoken);

// Called inside ISR to send item to queue without blocking
This code tries to send an item to a FreeRTOS queue from an ISR and sets a flag if a higher priority task should run.
Execution Table
StepActionQueue Space Available?Item Added?pxHigherPriorityTaskWoken Set?Return Value
1ISR triggers and calls xQueueSendFromISRN/ANoNoN/A
2Check if queue has spaceYesNoNoN/A
3Add item to queueYesYesNoN/A
4Check if higher priority task wokenN/AN/AYesN/A
5Return successN/AN/AN/ApdPASS
6ISR exitsN/AN/AN/AN/A
7If queue full, return failNoNoNoerrQUEUE_FULL
💡 Execution stops after returning success or failure from xQueueSendFromISR.
Variable Tracker
VariableStartAfter Step 2After Step 3After Step 4Final
Queue SpaceDepends on queue stateChecked (Yes or No)Reduced by 1 if item addedNo changeUpdated
Item AddedNoNoYes if space availableYesYes or No
pxHigherPriorityTaskWokenFalseFalseFalseTrue if higher priority task unblockedTrue or False
Return ValueN/AN/AN/AN/ApdPASS or errQUEUE_FULL
Key Moments - 3 Insights
Why can't xQueueSendFromISR block or wait?
Because it runs inside an ISR, blocking would halt interrupts and system responsiveness. The execution_table shows it returns immediately with success or failure.
What does pxHigherPriorityTaskWoken do?
It signals if sending the item unblocked a higher priority task. The ISR can then request a context switch. See step 4 in execution_table where this flag is set.
What happens if the queue is full?
The function returns errQUEUE_FULL immediately without adding the item, as shown in step 7 of the execution_table.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table, at which step is the item actually added to the queue?
AStep 3
BStep 2
CStep 4
DStep 7
💡 Hint
Check the 'Item Added?' column in execution_table rows.
According to variable_tracker, what happens to pxHigherPriorityTaskWoken after step 4?
AIt blocks the ISR
BIt resets to False
CIt becomes True if a higher priority task was woken
DIt causes the queue to overflow
💡 Hint
Look at pxHigherPriorityTaskWoken values in variable_tracker after step 4.
If the queue is full, what does xQueueSendFromISR return according to execution_table?
ApdPASS
BerrQUEUE_FULL
CpdFAIL
DNo return, blocks instead
💡 Hint
See the 'Return Value' column in step 7 of execution_table.
Concept Snapshot
xQueueSendFromISR is used inside ISRs to send items to a FreeRTOS queue without blocking.
It checks if space is available, adds the item if possible, and sets pxHigherPriorityTaskWoken if a higher priority task is unblocked.
Returns pdPASS on success or errQUEUE_FULL if the queue is full.
Never blocks or waits, ensuring ISR responsiveness.
Use pxHigherPriorityTaskWoken to request a context switch after ISR.
Full Transcript
When an interrupt occurs, the ISR calls xQueueSendFromISR to send an item to a queue. The function first checks if there is space in the queue. If space is available, it adds the item and then checks if this action unblocks a higher priority task. If so, it sets the pxHigherPriorityTaskWoken flag to true. The function returns pdPASS to indicate success. If the queue is full, it returns errQUEUE_FULL immediately without blocking. This ensures the ISR runs quickly and does not wait. The pxHigherPriorityTaskWoken flag helps the system decide if a context switch should happen after the ISR finishes.

Practice

(1/5)
1.

What is the primary purpose of xQueueSendFromISR() in FreeRTOS?

easy
A. To send data to a queue safely from an interrupt service routine (ISR)
B. To create a new queue in the system
C. To delete a queue from an ISR
D. To block a task until data is received

Solution

  1. Step 1: Understand the function context

    xQueueSendFromISR() is designed to be called inside an ISR, where normal queue functions that can block are unsafe.
  2. Step 2: Identify the function's role

    It safely sends data to a queue without blocking, allowing communication from ISR to tasks.
  3. Final Answer:

    To send data to a queue safely from an interrupt service routine (ISR) -> Option A
  4. Quick Check:

    Purpose of xQueueSendFromISR = safe queue send from ISR [OK]
Hint: Remember: xQueueSendFromISR is for sending data inside interrupts [OK]
Common Mistakes:
  • Confusing it with queue creation or deletion
  • Thinking it blocks the ISR
  • Using normal queue send functions inside ISR
2.

Which of the following is the correct way to call xQueueSendFromISR()?

BaseType_t xQueueSendFromISR(QueueHandle_t xQueue, const void * pvItemToQueue, BaseType_t *pxHigherPriorityTaskWoken);
easy
A. xQueueSendFromISR(queue, data, NULL);
B. xQueueSendFromISR(queue, &data, NULL);
C. xQueueSendFromISR(&queue, &data, NULL);
D. xQueueSendFromISR(queue, &data);

Solution

  1. Step 1: Check parameter types

    The function expects a queue handle, a pointer to the data, and a pointer to a BaseType_t variable for task wake flag.
  2. Step 2: Match correct call

    xQueueSendFromISR(queue, &data, NULL); passes the queue handle, address of data, and NULL for the last parameter, which is valid if you don't care about task wake.
  3. Final Answer:

    xQueueSendFromISR(queue, &data, NULL); -> Option B
  4. Quick Check:

    Correct parameters and pointers used = xQueueSendFromISR(queue, &data, NULL); [OK]
Hint: Always pass data address and pxHigherPriorityTaskWoken pointer [OK]
Common Mistakes:
  • Passing data instead of its address
  • Passing queue address instead of handle
  • Omitting the third parameter
3.

Given the following code snippet inside an ISR, what will be the value of result after execution?

BaseType_t xHigherPriorityTaskWoken = pdFALSE;
int data = 10;
BaseType_t result = xQueueSendFromISR(myQueue, &data, &xHigherPriorityTaskWoken);

Assume myQueue has space available.

medium
A. pdFAIL (0)
B. pdFALSE (0)
C. pdTRUE (1)
D. pdPASS (1)

Solution

  1. Step 1: Understand return values of xQueueSendFromISR

    The function returns pdPASS (1) if the item was successfully sent to the queue, pdFAIL (0) otherwise.
  2. Step 2: Analyze queue state

    Since myQueue has space, the send will succeed, so result will be pdPASS (1).
  3. Final Answer:

    pdPASS (1) -> Option D
  4. Quick Check:

    Queue has space, send success = pdPASS (1) [OK]
Hint: If queue has space, xQueueSendFromISR returns pdPASS (1) [OK]
Common Mistakes:
  • Confusing pdPASS with pdTRUE
  • Assuming it returns pdFALSE on success
  • Ignoring queue capacity
4.

Identify the error in this ISR code snippet using xQueueSendFromISR():

void ISR_Handler(void) {
    int value = 5;
    BaseType_t xHigherPriorityTaskWoken;
    xQueueSendFromISR(myQueue, &value, &xHigherPriorityTaskWoken);
    if(xHigherPriorityTaskWoken) {
        portYIELD_FROM_ISR();
    }
}
medium
A. value should be a pointer, not an int
B. portYIELD_FROM_ISR() is called incorrectly
C. xHigherPriorityTaskWoken is not initialized before use
D. xQueueSendFromISR() cannot be called inside ISR

Solution

  1. Step 1: Check variable initialization

    xHigherPriorityTaskWoken must be initialized to pdFALSE before calling xQueueSendFromISR() to avoid unpredictable behavior.
  2. Step 2: Verify other parts

    Calling portYIELD_FROM_ISR() conditionally is correct; value is passed by address; calling xQueueSendFromISR() inside ISR is valid.
  3. Final Answer:

    xHigherPriorityTaskWoken is not initialized before use -> Option C
  4. Quick Check:

    Initialize xHigherPriorityTaskWoken = pdFALSE before use [OK]
Hint: Always init xHigherPriorityTaskWoken to pdFALSE before sending [OK]
Common Mistakes:
  • Not initializing xHigherPriorityTaskWoken
  • Misusing portYIELD_FROM_ISR
  • Passing data incorrectly
5.

You want to send multiple sensor readings from an ISR to a task using xQueueSendFromISR(). Which approach correctly ensures the task runs immediately if it has higher priority?

void SensorISR(void) {
    static int sensorData = 0;
    BaseType_t xHigherPriorityTaskWoken = pdFALSE;
    sensorData++;
    xQueueSendFromISR(sensorQueue, &sensorData, &xHigherPriorityTaskWoken);
    // What should be done here?
}
hard
A. Call portYIELD_FROM_ISR(xHigherPriorityTaskWoken); after sending
B. Call vTaskDelay(1); inside the ISR
C. Call taskYIELD(); inside the ISR unconditionally
D. Do nothing; the task will run eventually

Solution

  1. Step 1: Understand task wake mechanism

    After sending data from ISR, if a higher priority task was woken, you must request a context switch immediately.
  2. Step 2: Use correct yield function

    portYIELD_FROM_ISR(xHigherPriorityTaskWoken); triggers a context switch only if needed, which is the correct approach.
  3. Final Answer:

    Call portYIELD_FROM_ISR(xHigherPriorityTaskWoken); after sending -> Option A
  4. Quick Check:

    Use portYIELD_FROM_ISR with xHigherPriorityTaskWoken to yield [OK]
Hint: Use portYIELD_FROM_ISR with flag to yield only if needed [OK]
Common Mistakes:
  • Calling blocking functions like vTaskDelay in ISR
  • Calling taskYIELD unconditionally inside ISR
  • Ignoring portYIELD_FROM_ISR call
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