Critical section for support of async. events

jonas1978 wrote on Wednesday, November 25, 2009:


Using NEC 16 bit 78K0R-KG3 ~14.7 MHz (uPD78F1166) 256kb Flash / 12 kb RAM with IAR EW 4.62 and Minicube2 on WinXP SP3.

I have consulted the forum earlier regarding time critical issues in relation to handling asynchronous events (RX data to a UART at very high speed without flow control). As I understood it, the problem is inherent using an RTOS like FreeRTOS, and it was suggested to use the build-in DMA controllers to handle the low level data management. So far, so good – I made it work to a certain extend, but was forced to reduce the maximum allowed baudrate to 9600 bps.

Since then, another time critical problem has emerged. The product, I am developing, is required to automatically detect the baudrate of the incoming serial data and re-configure the internal interface. The NEC uC has clever array of timers, that can perform the basic parts of these measurements, but the more logic part of the operation has to be executed in an ISR routine. As one can imagine, the required resolution is a factor 10 higher than the actual baudrate (because I have to synchronize some of the operations within 1-2 bit times) – hence I was back at the original problem.

I have measured the maximum period FreeRTOS disables interrupts (with portENTER/EXIT_CRITICAL) toggling an IO to approximately 500 us – i.e. way more than a bit time for 9600 bps (~100 us). I find it rather difficult to find the actual function, which is responsible for this rather long “outage”.

That was the problem - now for the solution as I image it. Please feel free to comment:

My plan is to “bend” the meaning of portENTER/EXIT_CRITICAL. Instead of executing the assemble instruction “DI/EI” I will selective mask/unmask interrupt sources manually – and never mask my 4-5 ultra time critical interrupts. The interrupts do not in any way use any FreeRTOS API calls and will never require portYIELD_FROM_ISR to be executed.

The system will restore the processor registers and stack after an interrupt – I see no problem in implementing this concept.

I image, that this strategy cannot be implemented as a general behavior in FreeRTOS due to the inherent design differences across the supported micro processor platforms.


Jonas, DK

petermeier wrote on Wednesday, November 25, 2009:

Hi Jonas,

iam running FreeRTOS on a PIC32 and i nearly had the same problems.

You can define the priorities for your tasks and the kernel. ISRs with a higher priority can interrupt other ISRs with a lower priority. Even the function portDISABLE_ INTERRUPTS() which ends up in taskENTER_ CRITICAL() just disables interrupts with a lower priority than the kernel itself.

I guess you should implement the same behaviour on your port as the PIC32 does.


rtel wrote on Friday, November 27, 2009:

> I have measured the maximum period FreeRTOS disables interrupts (with portENTER/EXIT_CRITICAL) toggling an IO to approximately 500 us

This is highly unlikely.  How did you make the measurement.  Note that toggling IO pins within the ENTER/EXIT macros/functions will *NOT* give you an accurate result as each task has its own interrupt flags status.  One task can call ENTER_CRITICAL() then switch to another task, and only call EXIT_CRITICAL when it runs again - which can be some time later.  Or another task can call EXIT_CRITICAL in the mean time - either way the result on the IO pins will be wildly wrong.

I know this sounds strange, but the kernel is designed to work like this.


jonas1978 wrote on Friday, November 27, 2009:

You are absolutely right!
As you suggest I done the measure by patching an IO toggle in the ENTER/LEAVECRITICAL macros – this will not give the right results! I will try to integrate this measuring in the task context switch also (with a slight performance penalty of course).

I have been trying to understand how the kernel works the last couple of days (at least for the NEC 78K0R port). It took me a while to realize how the PSW and PC were saved to the task stack, but the overall strategy seems obvious now. Using the software interrupt BRK when calling YIELD is indeed very clever.

Back to the original problem - somehow I got problems dealing with very time critical events. I will investigate this further! Anyway, I am still aiming to implement a strategy as sketched in the original post.

Who created the port anyway?


Jonas, DK

rtel wrote on Friday, November 27, 2009:

> Who created the port anyway?

Me!  :o)