upgrade problems from 8.0.1 to 8.1.0

ksoldavin wrote on Wednesday, August 27, 2014:

I have recently upgraded to 8.1.0 from 8.0.1 and I am having an issue I have never seen before. My code seems to freezing up immediately on a call to configASSERT( pxCurrentTCB->uxMutexesHeld ) in vTaskDecrementMutexHeldCount. When I paused the code and looked at pxCurrentTCB, it says it from the Idle task. I have the idle task defined but I am not doing anything in it.

Any thoughts on why this is happening?

BTW I am using this on a STM32F407 processor using the CodeSourcery Lite tool chain.


rtel wrote on Wednesday, August 27, 2014:

Hmm. I wonder if you have hit on a snag here.

Are you giving a mutex from an interrupt? If so then it will be checking the mutex held count of whichever task is running at the time, which will assert if the task is not holding a mutex and generally mess things up if the task is holding the mutex. It was never intended to use mutexes from interrupts as logically it does not make sense - an interrupt cannot own a mutex use a resource then give the mutex back again. However I have written driver code myself which does just that where a task obtains a mutex to get access to a peripheral, then the interrupt gives the mutex back again when an interrupt driven access completes.


ksoldavin wrote on Wednesday, August 27, 2014:

That seemed to be the problem. I had a few Mutexes that were being given in an ISR in my USART library. Once I changed them to semaphores the code worked correctly again.

Thanks for the prompt help!

rtel wrote on Wednesday, August 27, 2014:

Ok - that is good. While it is not normally expected to give a mutex from an interrupt there is I think a small change I can make to make it possible in V8.1.0. I may provide you with a patch to try.


gespin wrote on Wednesday, August 27, 2014:

I had the same problem. In the ASF library code freertos_uart_serial.c local_uart_handler() has:

/** If the driver is supporting multi-threading, then return the access mutex */
if (tx_dma_control[uart_index].peripheral_access_mutex != NULL) {

Which is created in freertos_peripheral_control.c create_peripheral_control_semaphores():
/** If the tx driver is to be thread aware then create an access control
mutex. An Rx access mutex is not created in this function as half duplex
peripherals need only use a single access mutex, and the Tx mutex is used
for the purpose. Full duplex peripherals have extra configuration steps
that are performed separately. */
if ((options_flags & USE_TX_ACCESS_MUTEX) != 0) {
tx_dma_control->peripheral_access_mutex = xSemaphoreCreateMutex();

USE_TX_ACCESS_MUTEX should be true:

 * \ingroup freertos_service_group
 * ...  When this bit is set the
 * FreeRTOS peripheral driver will use a mutex (internally within the driver) to
 * ensure only one FreeRTOS task can perform a write to the peripheral at any
 * one time.  Examples use cases are provided in the FreeRTOS peripheral control 
 * examples that are included in the Atmel ASF distribution, in the application
 * not that accompanies the FreeRTOS peripheral control drivers, and in the 
 * quick start references for the FreeRTOS peripheral control initialization 
 * functions in this online documentation.
#define USE_TX_ACCESS_MUTEX		0x01

rtel wrote on Wednesday, August 27, 2014:

Yes - apologies for this. I think I have a simple change that will allow mutexes to be used in interrupts again. I’m just trying it now and will post it here for you to try later.


rtel wrote on Thursday, August 28, 2014:

Attached you will find a modified kernel version - I have not included the port layer just the core code. It re-introduces (I hope) the possibility to give a mutex from an interrupt. Please try it and report back your findings.


gespin wrote on Thursday, August 28, 2014:

All systems go. Works fine. Thanks!


rtel wrote on Saturday, August 30, 2014:

This is now V8.1.1.


blacknine wrote on Thursday, September 04, 2014:

If you give a mutex from an ISR there is still an issue which can lead to an FreeRTOS crash. It occurs when a task tries to take a mutex a second time.
See https://sourceforge.net/p/freertos/bugs/84/

rtel wrote on Friday, September 05, 2014:

It occurs when a task tries to take a mutex a second time.

I tried testing that scenario but found (as mentioned when the bug report was first raised) I couldn’t. You can see the [aborted] attempt at re-creating the scenario in the standard demo GenQTest.c which introduce a test giving the mutex from an ISR.

In a nutshell the scenario starts:

Task A holds a mutex, task B attempts to take the mutex causing task A to inherit its priority, task A takes the mutex again.

However, if Task a holds the mutex already it cannot take the mutex again.

Did I miss something?

I do have a test where a task receives a semaphore from an interrupt and then takes a separate semaphore, but it can’t retake the same semaphore. That too is implemented in the GenQTest file, but it is not checked in. I might check it in for good measure but it doesn’t do anything over and above the tests that are already checked in.


blacknine wrote on Friday, September 19, 2014:

Sorry that it takes so long, but finally I made a demo project where this issue will occur.

rtel wrote on Friday, September 19, 2014:

I can build your project, but not run it, as I am using the simulator and the tick interrupt is not firing (I could set up the IAR triggers, but that would take some time).

However, the first thing I looked at was the idle hook, which is calling ReleaseMutexFromISR(), which in turn is calling xSemaphoreGiveFromISR(). I suspect this is your problem as the code is not running in an ISR. Please use xSemaphoreGive() instead.


blacknine wrote on Monday, September 22, 2014:

In my project an ISR occurs while the idle Task is running. In this ISR I use xSemaphoreGiveFromISR(). In the demo project I was too lazy to implement an ISR that fires in the right moment. I thought it shouldn’t make a big difference.
But if you thing this should make a big difference I can implement an ISR in the demo project.

rtel wrote on Monday, September 22, 2014:

I would be interested to see the project as you are actually using it, but it is hard to do anything with interrupts in the simulator so I will probably not be able to replicate it.


blacknine wrote on Monday, September 22, 2014:

In the project as I am using it the problem occurs only rarely. So it isn’t well suited to demonstrate the issue. The demo project shows what happens when the problem occurs.

I changed the demo project so that xSemaphoreGiveISR() is called by an ISR.

If you are using the simulator you can use Forced Interrupts (Simulator / Forced Interrupts). The tick is triggered with TIMER0_B0_VECTOR and the ISR for the mutex is triggered with TIMER0_A0_VECTOR. You can use this sequence:
FreeRTOS is now stuck in vListInsert().