But one day, I found another robot has a limit switch toggling the high/low frequently and it restart itself. With some digging I found if xTimerStop() is being called too often too fast would "assert failed: prvProcessReceivedCommands timers.c:858 (xResult)" error.
Code: Select all
assert failed: prvProcessReceivedCommands timers.c:858 (xResult)
Backtrace: 0x40081b4e:0x3ffbb5f0 0x40088cd9:0x3ffbb610 0x4008f52d:0x3ffbb630 0x4008be9a:0x3ffbb750
0x40081b4e: panic_abort at C:/Users/Sam/esp/esp-idf/components/esp_system/panic.c:408
0x40088cd9: esp_system_abort at C:/Users/Sam/esp/esp-idf/components/esp_system/esp_system.c:137
0x4008f52d: __assert_func at C:/Users/Sam/esp/esp-idf/components/newlib/assert.c:85
0x4008be9a: prvProcessReceivedCommands at C:/Users/Sam/esp/esp-idf/components/freertos/timers.c:858
(inlined by) prvTimerTask at C:/Users/Sam/esp/esp-idf/components/freertos/timers.c:600
My code look likes this:
main code start the robot from the end stop
Code: Select all
void robot_start()
{
xTimerStart( xTimerSenChk, 0 );//Set a timer and wait for sensor interrupt from other direction
starMotor(CLEANING_DUTY);
}
Code: Select all
static void IRAM_ATTR gpio_isr_handler(void* arg)
{
uint32_t gpio_num = (uint32_t) arg;
sensorTriggerTime=xTaskGetTickCountFromISR();
xQueueSendFromISR(gpio_evt_queue, &gpio_num, NULL);
}
Code: Select all
static void gpio_task_example(void* arg)
{
uint32_t io_num;
for(;;) {
if(xQueueReceive(gpio_evt_queue, &io_num, 1000/ portTICK_PERIOD_MS)) { //portMAX_DELAY
ESP_LOGD(TAG,"GPIO[%d] intr, val: %d\n", io_num, gpio_get_level(io_num));
leftSensorStatus = gpio_get_level(GPIO_LEFT_SENSOR);
rightSensorStatus = gpio_get_level(GPIO_RIGHT_SENSOR);
ESP_LOGD(TAG,"leftSensorStatus: %d rightSensorStatus: %d", leftSensorStatus, rightSensorStatus);
if(gpio_callback && ((sensorTriggerTime-LastSensorTriggerTime)*1000/configTICK_RATE_HZ>20)){
//code determine if it is the correct sensor released
//if it is the correct sensor we call xTimerStop() to stop the timer
//else timer callback we let us know the sensor is not released
if( correct sensor is released)
{
xTimerStop();
}
}
}
else
{
ESP_LOGI(TAG, "sensor trigger interval <20ms, debouce.");
}
LastSensorTriggerTime=sensorTriggerTime;
}
}
}
Code: Select all
if( correct sensor is released)
{
if(xTimerIsTimerActive() != pdFALSE)//stop timer only when timer is active
{
xTimerStop();
}
}
The problem seems gone after I did the modification. I also look the official document of xTimerStop() https://www.freertos.org/FreeRTOS-timer ... rStop.html It does not mention I could not call it if the timer is already stopped.
So what is the correct practice for it. Thank you in advance for any advice.
enviroment:
esp-idf 4.4.5
FreeRTOS Kernel V10.4.3