Non-deterministic behaviour while acquiring data (Interrupts supposedly disabled))
Posted: Tue Jun 27, 2017 1:23 pm
I wish to use the ESP32 chip for acquiring some digital samples at high rates and I detected a suspicious non-deterministic behaviour on delays in some cases. So, I wrote a simple test program trying to understand that strange behaviour.
This is the function loop():The function repeats a million times a loop and takes note of the delays between iterations (using micros()). Interrupts are disabled in the loop and WiFi is stopped.
The funcion PrintResult() shows the delay statistics. This is an example after some time running (percentages are shown in parts per million):97% of iterations spend between 1 and 2 microseconds. 2.46% of iterations spend less than 1 microsecond. And 0.29% of iterations spend between 2 and 3 microseconds. This sounds normal for me.
The strange behaviour belongs to the next delays. A gap is detected between 3 and 6 microseconds and then we discover some "lazy" iterations.
36 ppm needs between 7 and 8 microseconds. Then a remarkable value of 778 ppm needs between 8 and 9 microseconds. 170 ppm are associated to a delay of 9 and even a single occurrence is detected with a delay of 10 microseconds.
The sum of "lazy" iterations is almost a 0.1% of the occurrences. That's a significant percentage. I I wish to acquire data sampling at high rates and this is a serious problem for the quality of the samples. I would like to use a sampling period of 5 microseconds (maybe 10 microseconds), but this non-deterministic behaviour is a big problem for me.
I would like to know the cause of this behaviour. Is a side effect of the second core of the ESP32 blocking my loop during a few microseconds?. Is a problem related to some interrupt not disabled with cli() or noInterrupts()?. I do not know.
Do you know a way to avoid this non-deterministic behaviour?. For example, stopping the second core or disabling more interrupts?.
I would appreciate any help.
This is the function loop():
Code: Select all
...
#define DIM_DELAYS 128
unsigned long delays[DIM_DELAYS];
unsigned long iter;
void loop() {
unsigned long i, m, m1, d;
boolean s;
esp_wifi_stop();
noInterrupts();
m1 = micros();
for (i = 0UL; i< 1000000UL; i++) {
s = digitalRead(PIN);
m = micros();
d = m - m1;
delays[d]++;
iter++;
m1 = m;
}
interrupts();
PrintResults();
delay(2000);
}
The funcion PrintResult() shows the delay statistics. This is an example after some time running (percentages are shown in parts per million):
Code: Select all
delay 0: occurrences 34508900 [24561.50 ppm]
delay 1: occurrences 1365079124 [971586.63 ppm]
delay 2: occurrences 4028051 [2866.94 ppm]
delay 7: occurrences 51208 [36.45 ppm]
delay 8: occurrences 1093190 [778.07 ppm]
delay 9: occurrences 239526 [170.48 ppm]
delay 10: occurrences 1 [0.00 ppm]
The strange behaviour belongs to the next delays. A gap is detected between 3 and 6 microseconds and then we discover some "lazy" iterations.
36 ppm needs between 7 and 8 microseconds. Then a remarkable value of 778 ppm needs between 8 and 9 microseconds. 170 ppm are associated to a delay of 9 and even a single occurrence is detected with a delay of 10 microseconds.
The sum of "lazy" iterations is almost a 0.1% of the occurrences. That's a significant percentage. I I wish to acquire data sampling at high rates and this is a serious problem for the quality of the samples. I would like to use a sampling period of 5 microseconds (maybe 10 microseconds), but this non-deterministic behaviour is a big problem for me.
I would like to know the cause of this behaviour. Is a side effect of the second core of the ESP32 blocking my loop during a few microseconds?. Is a problem related to some interrupt not disabled with cli() or noInterrupts()?. I do not know.
Do you know a way to avoid this non-deterministic behaviour?. For example, stopping the second core or disabling more interrupts?.
I would appreciate any help.