Skip to main content
Visitor II
October 5, 2021
Question

Resum Task from ISR: CMSIS osThreadResume does not use xTaskResumeFromISR , how can that be solved?

  • October 5, 2021
  • 8 replies
  • 3599 views

Hello,

for acquiring Data I run a timer that does a I2CRead with DMA transfer and using a ISR for averaging

HAL_TIM_PeriodElapsedCallback -> HAL_I2C_Mem_Read_DMA

HAL_I2C_MemRxCpltCallback -> "Ava-Function"/Lowpassfilter

"AvgCnt ==16" -> "Schedule a Task"

After 16 Averages I'd like to schedule a task(resume a suspended task) to do further calculation. For that purpose I think a task would solve the issue by using xTaskResumeFromISR  buth that is not used in the osThreadResume, it presents an error of called from an ISR.

osStatus_t osThreadResume (osThreadId_t thread_id) {
 TaskHandle_t hTask = (TaskHandle_t)thread_id;
 osStatus_t stat;
 
 if (IS_IRQ()) {
 stat = osErrorISR;
 }
 else if (hTask == NULL) {
 stat = osErrorParameter;
 }
 else {
 stat = osOK;
 vTaskResume (hTask);
 }
 
 return (stat);
}
#endif /* (configUSE_OS2_THREAD_SUSPEND_RESUME == 1) */

Why is that and how can that be resolved using the CMSIS abstraction-layer? Or did I miss something in the CMCIS?

Thanks a lot for the help.

Best regards, Seppel

    This topic has been closed for replies.

    8 replies

    Super User
    October 5, 2021

    Don't know why that is, it may make porting the CMSIS layer to other RTOSes simpler. You seem to use CMSIS v2 API, v1 supports it.

    Anyway, I would use a semaphore, i.e. osSemaphoreRelease in the ISR and osSemaphoreAcquire in the task. Or a message queue.

    Suspending a task does not give you control on where in the task loop excatly the suspended task will stop, and later continue.

    Visitor II
    October 6, 2021

    Hello,

    interesting, do you know why it was removed from CMSIS V2?

    To give you more inside information, the processing takes longer than one ISR-Interval triggered by the timer. The Averaging is very simple, so it can be done in the ISR. The processing takes longer, it cannot be done within the ISR. That is why I need to do it in a high priority task.

    I use a queue, but as far as I'm aware there is no "Task-Scheduling" attached, no resuming of tasks when a queue has new elements. This means a Task may be delayed/"suspended by a timer" and would have to asynchronously poll for values in the queue. However, I'd like to synchronize the value-processing so I get a better Realtime behavior. 

    To have some loose synchronization, within the Task itself is suspending the task. If the ISR is executed, it put values into the queue and then resume the task. The task will run and process the data and suspends itself once it is finished all elements in the queue. Even if the Task-execution takes longer, resuming it a 2nd time will not be a problem and the values of the following ISR's that may occur simultaneously will just be put into the queue.

    Maybe there are better ways, I must admit I'm not a FreeRTOS-expert.

    Thanks a lot.

    Best Regards, Seppel

    P.S. What is very interesting is that the STM32CubeIDE has a checkbox for "xTaskResumeFromISR", however ARM's CMSIS V2 does not use it.

    0693W00000FBZywQAH.png 

    Super User
    October 6, 2021

    > I use a queue, but as far as I'm aware there is no "Task-Scheduling" attached

    It should. In the implementation of osMessageQueuePut there are lines

     if (xQueueSendToBackFromISR (hQueue, msg_ptr, &yield) != pdTRUE) {
     stat = osErrorResource;
     } else {
     portYIELD_FROM_ISR (yield);
     }

    If a task waiting for the queue is unblocked by xQueueSendToBackFromISR , yield is set to 1 and portYIELD_FROM_ISR will set the scheduler interrupt pending, such that the scheduler will run after the (all) interrupts finished. This is in accordance to the docs https://www.freertos.org/xQueueSendToBackFromISR.html

    hth

    KnarfB

    Visitor II
    October 6, 2021

    Hello @KnarfB​ ,

    what is "yield" actually, I do not know that from other OS'es. So far I was out of luck to find a good explainaition/tutorial on what it really is, how it should be used, etc. .

    Thanks a lot, Best Regards, Seppel

    Visitor II
    October 6, 2021

    Hello,

    there is a good article: https://stackoverflow.com/questions/58631246/freertos-why-to-call-taskyield-from-isr-method-within-the-isrhandler

    As far as I understand it, by calling taskYIELD_FROM_ISR at the end of the ISR, the scheduler is called and checks the priorities of the tasks, so the context can immediately switch from the ISR to the highest priority task that is ready to run.

    Did I get that right?

    I still struggle on "portYield", "taskYield",... what does port mean, what is a port in an RTOS?

    Best Regards,

    Best Regards, Seppel

    Super User
    October 7, 2021

    > Did I get that right?

    Yes, that's it. Nice article.

    port... means here ported to a certain MCU architecture like ARMv7 Cortex-M. The macros implement the interface to architecture specific code like assembly code or fiddling with the interrupt controller. Most of the FreeRTOS source code is architecture agnostic.

    My first contact with yield was in Windows 3.11 :) which didn't use preemption for task switching but cooperative multitasking. I.e. a task called yield (or similar functions) to indicate that it is ready to be descheduled. Like a yield sign indicates that you should be ready to stop if required by the traffic (scheduler) rules.

    For preemptive multitasking, IMHO yield shouldn't be used in user code.

    BTW: For real-time tracing of scheduling events, I revived a tool used for another processor years ago: https://gitlab.com/KnarfB/timedoctor. Maybe you want to try it out.

    hth

    KnarfB

    Graduate II
    October 10, 2021
    Visitor II
    November 13, 2021

    Hello,

    sorry for the late reply, I have found a solution that works, I have it running with two I2C's:

    0693W00000GXU9SQAX.gif 

    I do a avery simple PT1 average in the "TransferComplete" and every 32 averages I fill the Queue. If I have more time I will write a small documentation/tutorial.

    Thanks eveyone in the forum supporting, great community.

    Best Regards, Seppel