This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TI Drivers cause interrupt latency



Hi,

I have an application that measures speeds from a trigger input. I have the signal coming in via a gpio pin and I use the HWI dispatcher for the interrupts. I have realized that above speeds of 1.6KHz the ISR is sometimes delayed and this causes errors in the measured speeds.

I have a few tasks writing and reading on the SPI bus and two other tasks doing Mcbsp and Uart communication. The HWI should preempt all these tasks but it looks like the calls to disable_interrupts and restore_interrupts in these drivers are causing the delays in servicing the interrupts. The Uart driver is working in interrupt mode but the other two drivers are working in DMA interrupt mode. I came to this conclusion because when I disable the mcbsp and spi tasks, I can accurately measure speeds up to bout 1.63KHz but with these tasks enabled the inaccuracies start from about 1.5KHz and even occasionally below this speed. I can't disable the uart task since I need that to write out the measured speed. The speed ISR is not reentrant and is set to mask all other interrupts while running. At speeds of 1.6KHz the time period of 0.625ms is long enough to service the interrupt and I haven't seen any evidence of skipped interrupts. What I see is a slight delay (usually in the order of micro seconds) in servicing the ISR that reduces the time between the delayed pulse and the next (on-time) pulse thereby causing a wrong speed.

I am using CCS version 4.2.5.5 with BIOS 5.41.9.34 and PSP 1.30.1. The EDMA 3 dirver is 1.11.3.1.

Is there anything I can do to eliminate this latency?

  • One suggestion would be to try different compiler options/optimizations to see if that makes a difference.

    EDIT:  For libraries the above wouldn't make a difference.

    What does your interrupt map look like?

    Judah

  • Hi Judah,

    Here are the interrupts I have configured.

    HWI_INT 5 - Bank8Isr - this is the speed trigger interrupt and is the highest priority in my application.

    HWI_INT 4,6,13,14 - unused.

    HWI_INT 7,8,9,10 -ECM dispatch.

    HWI_INT 11,12 - HSRTDX_rec.

    HWI_INT 15 - CLK_F_isr.

    There's also another reason why the accuracy improves with some of the tasks disabled. For mcbsp communication I use a buffer pool and queue objects to hold my buffers and data packets respectively. These modules (i.e. BUF and QUE modules) are atomic hence in "putting" and "getting" stuff off of them interrupts are disabled (is this right?). That means when the mcbsp task is not running, the speed interrupt is not disabled at all by these modules and the accuracy improves greatly.

    Is it possible to specify a mask for these modules to use so as to avoid having them disable all interrupts?

    I have tried different compile options and optimizations already but those didn't help. I also avoid running my code on the emulator when testing.

  • 1.  Would it make sense to route some of these interrupts directly to the Interrupt controller instead of going through the ECM (event combiner)?  The Event combiner does add some latency to the interrupt processing but it does allow for more events to be supported.  I see that you have 4 interrrupts not being used.

    2.  Yes, BUF and QUE are atomic so they do disable interrupts for some critical sections but typically this time is very short in the range of 20 cycles or less.  It would be hard to believe these would be the culprit.

    3.  No, you cannot specify a mask for these modules.  You can however specify a mask for your interrupt.  The default is to mask itself, but you can mask other interrupts too.

    4.  Can you tell me what you are doing in your ISRs that are processing mcbsp, uart?

    Judah

  • Hi Judah,

    As far as I know the interrupt is being routed directly to the controller. I use the HWI dispatcher but not the ECM. Or does the dispatcher automatically use the ECM? The speed interrupt masks all other interrupts while running as I explained in the first post.

    The mcbsp and uart drivers are running in tasks and not ISRs and that's why I thought they shouldn't cause any latency in the first place since the hwi will preempt them. In order to read and write mcbsp data I use the SIO issue/reclaim model with read/write callback functions. Buffers are issued and then subsequently reclaimed in the callback functions. On the uart side I use GIO_write to write data out and GIO_submit with a callback function to read data.

    Could it be that some of these objects are disabling interrupts and causing the latencies? I know that when I stop mcbsp and uart communications the accuracy of my measurement improves. Even if some of these objects are blocking calls I think they should only block the tasks and not affect the interrupts.

    Cecil

  • "As far as I know the interrupt is being routed directly to the controller. I use the HWI dispatcher but not the ECM. Or does the dispatcher automatically use the ECM? The speed interrupt masks all other interrupts while running as I explained in the first post."

    But you listed ECM for a few of those interrupts, thats why I thought you were using the ECM_dispatch.  Hwi does not use ECM be default.  If you are doing a HWI_create(), it will route it directly to the interrupt controller.

    So in your ISR's are you simply posting a semaphore that then lets the mcbsp or uart task run?

    Judah

  • All the other interrupts use the ECM except my speed trigger interrupt. So all the BIOS drivers, EDMA etc. that use interrupts will use the ECM.

    Now my mcbsp and uart communications have nothing at all to do with this interrupt. They run in their independent tasks all by themselves and that's why I keep saying they can be preempted when the HWI occurs. Anytime the ISR occurs I read the number of clock ticks into a buffer and later in another periodic SWI I calculate the speed off this value. The ISR completes in less than 10us which is good enough because even at 1.7KHz the pulse period is ~600us giving enough room to complete each interrupt before the next one occurs.

    The original question I had was whether the disable_interrupt calls in some of those drivers could be delaying the ISR running when it is triggerd. You said that delay is in the order of 20 CLK cycles so shouldn't be a problem.

    The ISR I am using is created in the configuration file by the HWI Manager by setting the appropriate parameters of HWI_INT5 and setting its function field to the Bank8Isr which is the ISR I use for the speed trigger.

    Cecil

  • Hi Cecil --

    A couple other ideas:

    (1)  Make sure that you are using -mi10 (or some other value for 10) in your code to make sure that the compiler doesn't generate and non-interruptable loops.   There's an open pipeline on the C6000 and the compiler can generate very fast loops that take advantage of this extra visibility.   The compiler will disable interrupts, do the loop, and reenable interrupts.    This is probably not your problem, but worth noting.

    (2)  Can you make your cache smaller and place the .bios section into L2 memory?   This will put the interrupt dispatcher into L2.  You should put your ISR code into the L2 memory as well.   The L2 memory can be divided into different RAM/cache configurations.   Your added latency might be due to cache misses and having to load the HWI dispatcher and your code from slow external memory into the cache.   You can update your cache settings using the Global and MEM configuration options.

    -Karl-

  • Thanks for the response Karl.

    Actually the ISR already resides in L2 memory but not the .bios section. I guess that'll be something to try.

    Meantime we want to check the hardware to see whether that could be causing the delay we're seeing.

    Thanks

    Cecil