Interrupts being disabled for extended period

Hello everyone, I am currently running FreeRTOS on a Atmel AT91SAM7S256.  We use FreeRTOS Queues and Semaphores for inter-thread communications as well as ISR communications. The problem I am having is, during heavy application loading, I miss TWI interrupts; hence overflows.  Further investigations point at xQueueReceive, xQueueSend causing this.  My hypothesis is that because queue activity (hence semaphore activity) causes the interrupts to be disabled for 240us, this causes it to miss the TWI RxRdy interrupt; eventually causing the overflow of the hardware. The Oscilloscope trace of the TWI overflow and associated signals has been captured and is viewable here:   http://www.flickr.com/photo_zoom.gne?id=285266143&size=o To capture this, I toggled IO lines on different events. The signal descriptions are as follows (listed down the right hand edge in the image): Label    Signal name                -——————————————————————————————————————————– A2     TWI Clock                A1     TWI Data                7     Idle Activity task (Every time around the loop)                6     EnterCritical – Exit Critical timings (Note that I am forcing this pin low at portRESTORE_CONTEXT) 5     USB interrupt time (Logic 1 at start of USB interrupt, 0 at end of interrupt)        4     TWI comms Interrupt (Logic 1 at start of TWI interrupt, 0 at end of interrupt)        3     NA 2     QueueRecive activity (xQueueReceive but clearing this before any possible context switching) 1     QueueSend activity (xQueueSend but clearing this before any possible context switching) 0     RTOS Interrupt     ( vTaskIncrementTick, vTaskSwitchContext ) As you can seen the periodic TWI_RxRdy interrupt occurs approx every 200us and CANNOT be invoked while queues are being manipulated.  Hence the next TWI interrupt after Interrupts are re-enabled is for the TWI overflow. ===============

Questions:

1. Is it possible to ONLY disable the PIT timer interrupt while queues are being manipulated & context switching ? 2. Is there any variations of the queue implementation  (even commercial ones) , that do not disable the interrupts, that I could use in FreeRTOS ? 3. Is there any other solutions to this problem ? ===============

Misc information.

The application that uses the following:   – USB (HID class, custom pipes and custom host app)   – TWI   – Serial Comms   – DBGU Comms   – SPI   – Timer Interrupt   + 5 threads at different priority levels (including idle priority)

Interrupts being disabled for extended period

I’m using the same CPU as well – congrats! Anyway, what immediately springs to mind – what about turning the TWI into a FIQ and setting FIQs as higher priorities? Then just disabling IRQs?

Interrupts being disabled for extended period

Congrats to you as well! :) If I hack the FreeRTOS code I probably could get the FIQ for TWI working.  The current implementation uses "__disable_interrupt()" library function.  That disables IRQ and FIRQ on the CPSR register on the ARM7TDMI.  I think that Idea has merit if I decide to hack FreeRTOS.  Worst thing is AT91SAM7S256 does not allow DMA access to TWI or USB either! :{

Interrupts being disabled for extended period

In my port, which is Keil, the disable interrupt is a short assembler macro, where the bits to set in the control register are specified. There it would be easy to leave the FIRQ enabled through OS operations. 240 us sounds like a long time for irq to be disabled. Did you try to measure that (e g some debug pin set/clear when enterring and leaving disabled state)? I guess you run 48MHz?

Interrupts being disabled for extended period

> We use FreeRTOS Queues and Semaphores for inter-thread communications as well > as ISR communications. > The problem I am having is, during heavy application loading, I miss TWI interrupts; > hence overflows.  Further investigations point at xQueueReceive, xQueueSend > causing this.  My hypothesis is that because queue activity (hence semaphore > activity) causes the interrupts to be disabled for 240us, this causes it to > miss the TWI RxRdy interrupt; eventually causing the overflow of the hardware. 240us seems a long time.  Are you sending a lot of data, or making lots of calls to send small amounts of data?  There maybe a more efficient alternative. Also, you may be able to use scheduler locking instead of disabling interrupts.  When the scheduler is locked interrupts remain enabled, but context switches cannot occur. <snip> > 1. Is it possible to ONLY disable the PIT timer interrupt while queues are being > manipulated & context switching ? Any interrupt that can read or write to the queue being manipulated needs to be disabled if the queue is accessed both from a task and an ISR. > 2. Is there any variations of the queue implementation  (even commercial ones) > , that do not disable the interrupts, that I could use in FreeRTOS ? FreeRTOS uses the scheduler locking mechanism to ensure interrupt remain enabled while data is being actually copied to the queue (the part that could potentially take the most time).  Most commercial implementations would just disable interrupts, so may perform worse.  The downside is that interrupts are then disabled briefly while the scheduler is being unlocked again. > 3. Is there any other solutions to this problem ? There may be a more efficient way of doing whatever it is you are doing.  For example, using a circular buffer instead of a queue, and waking the the task using a vTaskResume() once there is data in the buffer, rather than letting the task wake automatically on the queue event.  The use of the FIQ is the best option if the TWI interrupt does not itself cause a context switch.

Interrupts being disabled for extended period

Comrades. Thanks for the responses. I do run at ~48Mhz. I do measure the IRQ lockout time using debug pin Set/Clear.  However I should note that this is not easy as it context switches in middle of queue write/read functions and I had to put some assembler code in the context switching area to get accurate timings (It stores/pulls out CPSR during context switches). In the IAR compiler I can put some assembler code to leave FIRQs enabled, however I don’t know what the effect on the RTOS will be.  Thats why I said it will be a FreeRTOS hack. I am sending a lot of data through the queues (specially for USB). At least Twice every 100mS I send chunks of USB data (30 bytes each). In addition to this, there are other intra tread communications between the 5 threads. I think alternative queuing/semaphore mechanisms, vTaskResume and scheduler locking has a lot of merit.  I am investigating those now. > Any interrupt that can read or write to the queue being manipulated needs to be disabled > if the queue is accessed both from a task and an ISR. Makes sense.  This means I have to lock down specific interrupts when accessing specific queues in my implementation. I will be glad to hear any more suggestions/insights/solutions.  Thanks and Cheers.