bmenkveld wrote on Friday, November 21, 2008:
Hello,
I’m working on an application running on an AVR32 UC3A0512 CPU. One of the things the application has to manage is commutation of a stepper motor. This requires accurate output updates at a rate of up to 10KHz.
I set up a timer tick interrupt to operate at a rate of 10KHz, and then poked a spare output in the ISR so I could observer the timing consistency on a scope.
What I found was very large jitter in the timing of the interrupt, with the ISR executing as much as 90us late. That will obviously make for very large disruptions in the control of the stepper motor driver waveforms.
I tried increasing the timer tick interrupt priority from 0 to 3. All other interrupt handlers run at priority 0 (the lowest), so I thought this would solve the problem. Instead, it hardly made any difference. The average jitter did seem to decrease somewhat, but there were still extreme cases of 90us.
Then I got looking at the FreeRTOS kernel code. The vTick() handler for the RTOS timer tick interrupt is in port.c. It encloses its central call to vTaskIncrementTick() in portENTER/EXIT_CRITICAL() calls. When I commented these CRITICAL calls out, the jitter in my 10KHz ISR was reduced to 2us!
The portENTER_CRITICAL() call disables interrupts altogether to ensure the crucial kernel work doesn’t get messed up by an interrupt that might make some kernel call. However, my high priority interrupt handler won’t make any kernel calls.
It seems to me that if my program never makes any kernel calls from any interrupt handler with a higher priority than vTick(), then there should not be a problem with removing the portENTER_CRITICAL() call from vTick(). Is that true?
At http://www.freertos.org/PC/index.html I did find the following under "Can interrupts be nested?":
"In the case that a very fast interrupt response is required for a certain peripheral then the peripheral priority can normally be set to above that of the kernel itself. This means the processing of the peripheral will never be delayed by the action of the kernel. "
That sounds like what I want, but it does not make any mention of removing the portENTER_CRITICAL() call from vTick().
Does anyone know whether it is safe to do that?
On a side note, I was rather surprised to find the kernel taking this long to execute on a processor running at 66MHz.
Thanks in advance for any help.
–
Bert Menkveld