taskENTER_CRITICAL issue on 5.0.0.3

richpainter wrote on Tuesday, August 05, 2008:

I am using Microchip C dspic 3.11 (just released) and the latest FreeRTOS 5.0.3. on a dspic33fj256gp710.

In a uart input interrupt routine I bump a count for every read byte.

In a task I update (decrement) this like this:

taskENTER_CRITICAL();
   count -= numread;
taskEXIT_CRITICAL();

The problem is that this is not preventing the interrupt routine from changing it while it is in the critical section.

To check this I modified this as follows:
taskENTER_CRITICAL();
   count -= numread;
   if(count == 0)
       HALT();
taskEXIT_CRITICAL();

Where HALT is a macro that will cause the microchip debugger to halt on the spot.

When this HALT is hit and the count is displayed with the Microchip debugger the count is 1 which should not be possible.

I have carefully checked to be sure the count is only updated in these 2 places (incremented in the interrupt routine and decremented in the task).

It appears that either the critical section code is not working in some way in the task or it is not preventing the interrupt routine from running during this time.

Any ideas?

thanks,
rich

picmeup wrote on Tuesday, August 05, 2008:

The critical section disables interrupts to the priority set in freertosconfig.h as configKERNEL_INTERRUPT_PRIORITY. I guess you set the uart above this?

richpainter wrote on Wednesday, August 06, 2008:

I have determined why the use of the critical section macro did not work as I had expected.

By default the interrupt priority of the RTOS is 1, a very low priority where level 0 is lower.

The enter and exit critical section macros modify the "current" interrupt priority level.

This is not what is needed to provide mutual exclusion between a task and an interrupt handler for say a uart.

To do this I in the task code disable the uart interrupt for the direction of interest (transmit or receive), perform the count update and then re-enable the uart interrupt.

This solved the problem.

So, the task critical macros should only be used when trying to create fast mutual exclusion between TASKS.

An alternative would be to raise the processor’s IPL to that of 7. There are Microchip chip include file macros to do this. However, this would block all user interrupts and may not be desirable when only the single uart interrupt is needed.

rich

davedoors wrote on Wednesday, August 06, 2008:

or run your UART at the same priority level as the RTOS, which I expect is the intended method. Can this be done on a PIC?

fanlex wrote on Wednesday, January 14, 2009:

hi,

I’m using FreeRTOS 5.0.2 with GCC on an AT91sam7x512.
Many characters are lost when receiving under interrupt on uart1 (38400 bauds), depending on what happens on other ports( ethernet, uart0).

I think that there is a lot of time spent between vPortEnterCritical and vPortExitCritical, while which interrupts are disabled : I have measured (using timer1 as counter) approximately 1ms when sending some html pages to the webserver task, sometimes it can go up to 3.5 ms, sometimes more.
a usual value is arround 0.3mS, when starting the target and having only the uart1 transmitting and receiving (half duplex).

And of course, when transmitting a frame, it happens that some characters are delayed for the same kind of time. This can be a problem in my applications. Time is very critical between frames, and since I have another uart working at 115200 bauds, if there is such delays, the remote machine can fall in timeout.

My uart interrrupt priority level is 6.

what can be done to avoid this ?

thanks
J.L.

fanlex wrote on Wednesday, January 14, 2009:

sorry, I have made a new thread with my post. it was not the right place.