Pumpkin, Inc.

Pumpkin User Forums

Interrupt Latency

For issues specific to Microchip's PICmicro® MCUs, including compilers (e.g. HI-TECH PICC & PICC-18, Microchip MPLAB®-C18) and IDEs (e.g. Microchip MPLAB®).

Interrupt Latency

Postby larsbn » Mon Mar 21, 2011 8:11 am

I use Salvo Lite on a PIC18 controller (works great, by the way :D ). At some point I started worrying about the interrupt latency of Salvo and I decided to measure it. I used an external interrupt source and measured the time between the interrupt edge and the execution of the first line in the ISR. The order of the interrupt latency seems to be very good (good enough for me, anyway). However, when I measured the latency, I noticed that the interrupt latency varied randomly (between approximately 10 and 12 microseconds). (I used a 4 MHz crystal.)

Why is that? Where does the randomness come from? My tasks are really simple, the only OS-service they are calling is the OS_Yield command (and I of course also call the OSSched() in the main program).

In the manual I saw that Salvo disables interrupts during some "critical code sections". Does that include OS_Yield and OSSched()? That would explain the randomness in the interrupt latency I guess.

Am I right? Do you have another explanation?

While I was at it I also measured the context switching latency. It turned out to be 15-20 times larger than the interrupt latency. I was surprised by the big difference.
Sincerly, L
Posts: 18
Joined: Mon Mar 10, 2008 11:00 pm
Location: Gothenburg, Sweden

Re: Interrupt Latency

Postby aek » Mon Mar 21, 2011 9:28 am

Interrupt latency is affected by any code that disables (and then re-enables) interrupts.

Salvo (like most RTOSes) has critical sections. These are sections of code that access global shared variables. In order to prevent crashes, interrupts must be disabled during critical sections, so that interrupt (i.e., foreground) code that accesses the same global variables does not do so when mainline (i.e., background) code has already begun the process of doing so.

For example, the scheduler OSSched() (background code, called from main()) has to act on timers timing out. Similarly, OSTImer() (normally foreground code, called from an ISR) affects timers as well. Once OSSched()'s "timer processing code" begins, it must prevent OSTimer() from being called -- this is a critical section in OSSched(). This is done in OSSched() by disabling interrupts, so that e.g. OSTImer() will not be called.

If the timer interrupt whose ISR calls OSTimer() occurs during a critical section, the interrupt will not be serviced -- and OSTimer() will not be called) -- until the critical section is over, and interrupts are re-enabled.

So, the interrupt latency you see is a function of the longest critical section. Any time the Salvo code is in a critical section, interrupts will be disabled, thereby adding to interrupt latency.

You're using Salvo Lite for PICmicro(R) MCUs, a version 3 of Salvo. In Salvo v3, all libraries are built with a default response to critical sections -- namely, that interrupts are disabled globally. So regardless of how many of your ISRs call Salvo services, all interrupts will be disabled during critical sections.

Salvo Pro for PICmicro(R) MCU users can reconfigure Salvo's control of interrupts. The preferred way to do this is to run the PIC18 with high (GIEH) and low (GIEL) interrupts enabled, to put all the Salvo-related ISRs on the low priority tree, and have Salvo (via OSPIC18_INTERRUPT_MASK) disable only the low-priority interrupts. This yields zero interrupt latency for high-priority interrupts, and standard Salvo latencies for low-priority ones. Of course, with this configuration, high-priority ISRs must not call Salvo services, or the application will crash.

Salvo 4 made this sort of fine-tuning possible to all users (from Salvo Lite up to Salvo Pro), by changing the interrupt control to be a set of user-definable hooks. They still default to control of global interrupts (because this is simpler and safer for novices), but have as much targeted interrupt control as the user desires. Unfortunately, Salvo for PICmicro(R) MCUs has not yet been ported to the Salvo 4 codebase.

Randomness will be due partially to PIC18 hardware, and also due to the fact that Salvo's priority resolver is queue-based, not array-based. This has benefits (e.g., when dealing with multiple delayed tasks) and drawbacks (i.e., the algorithm is not constant-time, but is a function of the task in question's priority, and the priority of other tasks in the queue in question).

Botom line is that if/when zero interrupt latency is required, Salvo can be configured to deliver that, with the caveat that zero-interrupt-latency ISRs (e.g., an ISR to handle incoming high-speed serial data or an ISR to handle high-speed DAC output from a table) will not be able to call Salvo directly services. Generally speaking, this is not a problem.
Posts: 1888
Joined: Sat Aug 26, 2000 11:00 pm

Return to PICmicro MCUs

Who is online

Users browsing this forum: No registered users and 1 guest