-
Notifications
You must be signed in to change notification settings - Fork 1.6k
any timing is lost due interrupt disabling by wifi driver. Please, keep interrupt enabled (GIT8266O-186) #626
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
I think this is related to #240. |
I am trying my best to resolve the problem, but this is so hard because we should modify so much code. When finishing this work, I will pin a note on the issues. |
@donghengqaz |
Hi, void TASK_SW_ATTR xPortSysTickHandle(void *p) {
//extern esp_tick_t g_cpu_ticks;
//extern uint64_t g_os_ticks;
uint32_t missed_ticks = 0;
/* notes:
* A) it is expected no change of _xt_tick_divisor value inside the handler (by NMI)
* B) it is also expected that CCOMPARE is not updated elsewhere.
* TODO: check B against runtime CPU frequency changes (80 <- -> 160Mhz).
* TODO: check the handler with sleep condition.
*/
uint32_t new_ccompare = soc_get_ccompare() + _xt_tick_divisor;
for (;;) {
//OK, even if NMI shot here!
soc_set_ccompare(new_ccompare);
//OK, even if NMI shot here!
uint32_t cpu_ccount = soc_get_ccount();
//OK, even if NMI shot here!
if (((int32_t) (cpu_ccount - new_ccompare) < 0) || (soc_get_int_mask() & (1ul << ETS_MAX_INUM))) {
/*
* case 1 --- no missing ticks.
* A) 1st condition: new_compare is valid and not yet triggered
* B) 2nd condition: new_compare is valid and already triggered (extremely low probability). The caller function will call this function again.
*/
break;
} else if ((cpu_ccount - new_ccompare) < _xt_tick_divisor) {
/*
* case 2: --- single interrupt tick missed,
* to manage situations like: https://github.com/espressif/ESP8266_RTOS_SDK/issues/240 using a small amount of cpu time.
*/
missed_ticks += 1;
new_ccompare += _xt_tick_divisor; //it will be checked in the next loop
} else {
/* case 3: bigger latency (actually expected only by esp_wifi_connect() ),
* to manage situations like: https://github.com/espressif/ESP8266_RTOS_SDK/issues/626
* it is expected that the execution will never return here
* (if extremely long latencies by NMI cannot occur)
*/
uint32_t ticks;
uint32_t cpuTime;
ticks = (cpu_ccount - new_ccompare) / _xt_tick_divisor + 1;
missed_ticks += ticks;
new_ccompare += _xt_tick_divisor * ticks; //it will be checked in the next loop .
}
} //end for
if (missed_ticks) {
/* Apply correction to Freertos. Prerequisite: configUSE_TICKLESS_IDLE != 0
* note: this correction could raise an assert if configASSERT is enabled. TODO: need investigation inside task.c
*/
vTaskStepTick(missed_ticks); //also perform g_os_ticks+=missed_ticks. We will discard the update on g_cpu_ticks
}
g_os_ticks += 1;
g_cpu_ticks = new_ccompare - _xt_tick_divisor; //esp_timer_get_time() expect exactly this value.
//normal freertos duty
if (xTaskIncrementTick() != pdFALSE) {
vTaskSwitchContext();
}
} |
Thanks for your generous sharing, and I am starting to fix the problem, I have planed to solve this at release/3.3. |
Hi @donghengqaz, |
Hi @donghengqaz, It seems to me that the new implementation might produces issues due:
What do you think about it ? |
Hi @donghengqaz, I need the GPIO interrupts to respond within 4 us, and everything works when the wifi is disconnected, but as soon as it tries to connect, massive delays. I tried additional waits up to 40us, still not enough, and then I find this ticket, saying the lag can be up to 900 ms (!). @everyone, the OP post says NONOS pre-3.0.0 did not have this bug. Can anyone confirm whether the current NONOS SDK master has the bug? I think I could rewrite my app for the non-os SDK if it's known to work. |
Hi @clbr, |
Environment
related to: #616
Problem Description
The wifi driver totally disable the level 1 interrupts for a great amount of time, up to 650 - 1500 ms (variable upon project configuration, test condition: STA mode, correct SSID, wrong password).
In such latency g_os_ticks receive one increment only, but esp_timer_get_time expect one increment every 1/CONFIG_FREERTOS_HZ time period instead, so, an incorrect time is returned.
Also freeRtos does not allow missing calls to xTaskIncrementTick() (see port.c), so, freeRtos loose the time coerency and any timed function work erroneusly.
EDIT: further tests are required.
Note: the Arduino framework (NONOS 2.2.1, 2.2.2 and pre 3.0.0) does not disable the interrupts (timer 1 intrrupt work correctly in any condition) so I think about a bug.I'm still working on a workround to mitigate the timing issue, but I think that keep the level1 interrupt enabled is a better solution, due the wifi driver that already suspend the freertos scheduler via the right call.
The attached code detect the system latency using ccount, and show the coerency loss of esp_timer_get_time and xTaskGetTickCount. (I also checked the latency using a logic analyzer. The reported latency is true.)
Debug Logs
The text was updated successfully, but these errors were encountered: