xTaskPriorityDisinherit assert

TL;DR: is there a reason why the design pattern below would cause me to fall foul of the assert configASSERT( pxTCB == pxCurrentTCB ) in xTaskPriorityDisinherit() on a particular platform and, if so, what might I do about it?

My application needs to be able to create and destroy tasks dynamically. In order to organise task creation/deletion I’ve implemented a protocol which goes something like this:

            Main Task                                        Task A
            ---------                                       -------
         creates queue A
         creates mutex A
          creates task A                                  takes mutex A
                                       <does stuff, taking data and commands from queue A>

 sends "terminate" event on queue A
        waits on mutex A
                                            receives the "terminate" event on queue A
                                                          releases mutex A
                                                          destroys itself
        releases mutex A
   yields to idle for clean-up 

This way the main task can know that Task A has been destroyed, everything is nice and organised and it can be repeated as required. It also relies on simple OS primitives so I can run it on any RTOS. This works on Espressif ESP32 (FreeRTOS V8.2.0 with their mods) and Nordic NRF52840 (FreeRTOS V10.0.0).

However I’ve just ported it to STM32F4 (FreeRTOS V10.2.1 and a much faster processor) and I’m now hitting the assert near the top of xTaskPriorityDisinherit():

configASSERT( pxTCB == pxCurrentTCB );

This is happening near the end of the procedure, according to the debugger at the point where the main task is trying to release mutex A. Not always but in certain task/priority/timing combinations which I haven’t yet figured out. The TCBs look perfectly valid when the assert is hit; the two tasks are Task A as pxTCB (which has a higher priority than the main task and, I guess, has not been cleared up yet) and the main task as pxCurrentTCB. All code is task code, no RTOS interrupt stuff going on (at least, not by my code).

Looks valid to me. I wonder if this is a FreeRTOS version issue (should not be, but nothing is ruled out yet).

Does the STM32 have a cache?

Is the assert happening when the mutex is released in Main Task or Task A?

Many thanks for your very swift response and confirming that my approach is valid. Turns out that the specific problem in this case is mine, no need for you to worry. Detail below if anyone is interested.

My init() functions check if they’ve already been initialised and skip doing stuff (like setting up queues) if that’s the case. I am using Unity as a test framework, so when it hits an ASSERT, as it will right now because I am in the middle of integration on a new platform and many of my tests are failing, it will do a longjump and so skips the deinit() calls. This would work fine except that in my tests the queue variable is on the stack (d’oh) and so it’s vapour when the body of stuff gets to run after an init() that thought it had nothing to do. I’m used to clean test runs so hadn’t noticed.

Have now made the queue variable global and all is good.

Thanks, again, for your swift attention.