mutex between task and ISR

richpainter wrote on Monday, June 30, 2008:

Running 5.0.0…

I need to be able to protect atomic writing and reading a 32-bit type on a dspic33 which has a native word length of 16 bits. Thus I need a mutex.

The web manual for xSemaphoreTake says one must use xQueueReceiveFromISR() from within the ISR.

If one looks at the manual for xQueueReceiveFromISR() it does not specify how to call this for the mutex when calling this in the ISR.

For example, the mutex has no "data returned" so what is one to use for the pvBuffer parameter? Also, does one need the pxTaskWoken parameter in this case?

It would be helpful to explain this mutex use of xQueueReceiveFromISR() and an example in the manual.


davedoors wrote on Monday, June 30, 2008:

It is not common to take a semaphore from within an interrupt. The interrupt cannot block should the semaphore not be available.

If you need to guard the variable from concurrent access by a task and interrupt then you could add a critical region around the access in the task. This would prevent an interrupt from executing while the critical region was in place so you have your mutual exclusion. Just keep the critical section as short as possible.

richpainter wrote on Monday, June 30, 2008:

OK. I have implemented the taskENTER_CRITICAL() and exit.  I assume then I can call these from a task or an ISR.

A documentation note… the web manual pages for this class of functions do not specify they are functions. I suggest that you add parens () to the document.

Once I added the taskENTER_CRITICAL() and exit I’m now having Stack Errors and Address Errors. To diagnose, I have removed ALL of my task create calls and I still get this problem the instant the vApplicationTickHook(void)
gets called (stack screws up at the function’s preamble code before my code gets executed).

I have no clue why this is now happening. Maybe this is the Microchip C30 3.10 raising its ugly head. This is so frustrating that with small changes the entire system rolls over. I had long ago given rtos a huge stack (18000) and before implementing the mutex (and now replace with the taskENTER_CRITICAL()) my application worked well with several tasks. Now even without creating any tasks it gets a stack error OR an address error.

Any suggestions would be welcomed.

Running FreeRTOS 5.0.0, MPLAB 8.10, C30 3.10

edwards3 wrote on Monday, June 30, 2008:

taskENTER_CRITICAL() is already implemented you just have to call it but you must not call it from an interrupt. From what Dave said you do not need to call it from the interrupt, just the task. 

If you guard the data using a critical section in the task then you know an interrupt cannot simultaneously access the data. When you are in the interrupt then you know a task is not running.  Therefore the data is accessed by only one thing at a time.

THe critical section is only required in the task, not the interrupt.

richpainter wrote on Monday, June 30, 2008:

I likely made a mistake by putting the calls for taskENTER_CRITICAL() and exit in the vApplicationTickHook(void).

I removed these and now only have them in the task that protects the updating variable.

This stopped the stack error but I’m still not fully working yet. I will continue to look for the problem.