Hi,
I want to use a Due in a hard real time job (oscilloscope) with interrupts. Therefore I made some speed tests with following setup
• On Pin7 (TICPIN) an interrupt pulse is generated
• Pin7 is connected to Pin4
• On Pin6 the interrupt handler generates a pulse
• Pulses are measured with an oscilloscope
volatile uint16_t cnt_hdl=0;
volatile uint32_t tim=0;
void Pin4Intr() {
REG_PIOC_SODR = 0x01000000; // set D6
cnt_hdl++;
REG_PIOC_CODR = 0x01000000; // clear D6
}
//
void setup() {
//
Serial.begin(115200);
REG_PIOC_PER = 0x00800000; // assign TICPIN (7, PC23) to peripheral IO controller PIOC
REG_PIOC_OER = 0x00800000; // set TICPIN for ouput
REG_PIOC_PER = 0x01000000; // assign D6 (PC24) to peripheral IO controller PIOC
REG_PIOC_OER = 0x01000000; // set D6 for ouput
// Test Interrupt timing
// Pin7 generates interrupt signal which is connected to Pin4
attachInterrupt(digitalPinToInterrupt(4), Pin4Intr, RISING);
while (1) {
REG_PIOC_SODR = 0x00800000; // set TICPIN -> Intr.
// here interrupt should fire
// tim++;
REG_PIOC_CODR = 0x00800000; // clear TICPIN
tim += 10;
}
}
Following figure shows the signals on an oscilloscope when interrupts are firing. Channel 2 (yellow) is the signal on Pin7, channel 1 (red) on Pin6 (from interrupt handler Pin4Intr).
- it takes 912 ns from positive edge of the interrupt signal until the code of the interrupt handler (pulse on Pin6) is executed.
- between two interrupt pulses it takes 2500 ns.
- execution of the code of the interrupt- handler takes 176 ns (write register twice and increment a variable).
When interrupts are deactivated the time between interrupt pulses (pin7) is shown in following figure for three different code sequences within the while loop which are shown beneath the images.
Observations (one clock period of a Due with 84 MHz is 12 ns):
• entering and leaving the interrupt handler takes 2016 ns (2500 – 308 – 176) corresponding to 169 clock periods
• incrementing a variable takes 155 ns (pulse widths of cases 1 and 2) corresponding to 13 clock periods
• adding a constant takes 48 ns (pulse widths of cases 2 and 3) corresponding to 4 clock periods
• execution of very short interrupt handler code takes 176 ns corresponding to 15 clock periods
• changing the sequence of statements changes execution time (pulse distances of case 2 and 3)
• overhead of a while loop takes 200 ns (pulse distance – pulse width in case 3) corresponding to 17 clock periods
With a Due I expected to have a speedy controller. The measureing results are disappointing, especially the long interrupt and while loop overheads. I also don't understand how incrementing a variable can take 13 clock periods.
Is there a possibility to speed up the code?