embeddedrtoscmsis

CMSIS RTOS2 behaviour upon kernel lock


I am working on CMSIS-POSIX port to CMSIS RTOS2, and I am trying to understand how APIs should behave after osKernelLock was called.

My guess it is like in ISR and just functions that can be called from ISR are allowed (all non blocking functions), but the documentation is not clear as I show below.

According to its documentation, it lock all task switches.

Another things I found are:


Solution

  • The osThreadSuspend restriction is explicitly documented, you can assume that if there is no explicit documentation that a call is invalid during a kernel lock, then it is not invalid. That is not to say however that it makes semantic sense in all circumstances, but that is a design rather then an API issue.

    A locked scheduler is not "like an ISR" at all - blocking functions for example are valid in a locked thread since the event waited on may be issued by an ISR rather then a task context.

    If you were to block waiting on some IPC or synchronisation from another task thread during a kernel lock then that thread will not run, you would wait forever, so it would be a bug. However such a call is permitted because interrupts still run and the IPC/sync may legitimately come from an ISR. If you were to lock the scheduler and disable interrupts, then waiting for an event from an interrupt handler thread would also be a bug.

    osThreadYield is benign, essentially a zero length delay, any delay would be supported, but no task threads will run during that delay, reducing the delay to a "busy-wait". Again if you were to disable interrupts before the delay, the system tick would not run and you would wait indefinitely. A yield in an ISR just makes no sense, interrupts run to completion, and may only be preempted by a higher priority interrupt, yielding has no meaning in that context.

    With respect to osThreadSuspend, that is only invalid if you attempt to suspend the current thread during a kernel lock. That is clearly documented:

    This function must not be called to suspend the running thread when the kernel is locked, i.e. osKernelLock.

    Suspending the only task that can run would always be an error - there are no circumstances where that would be useful. You can of course suspend other threads during a lock, and they will not run after the kernel lock is released.