最小的延迟“收益率”是多少?

时间:2019-09-07 07:24:18

标签: freertos esp32 esp-idf

Espressif's esp-idf中的入门示例是hello-world和眨眼。 Hello-world输出打印内容,然后调用esp_restart();-这样就在它自己的特殊无限循环中。

眨眼示例(已删除注释)具有此app_main,这也是一个无限循环:

void app_main(void)
{
    gpio_pad_select_gpio(BLINK_GPIO);
    gpio_set_direction(BLINK_GPIO, GPIO_MODE_OUTPUT);
    while(1) {
      printf("Turning off the LED\n");
      gpio_set_level(BLINK_GPIO, 0);
      vTaskDelay(1000 / portTICK_PERIOD_MS);

      printf("Turning on the LED\n");
      gpio_set_level(BLINK_GPIO, 1);
      vTaskDelay(1000 / portTICK_PERIOD_MS);
    }
}

我将眨眼示例复制到我的〜/ esp文件夹中,没有运行makeconfig(因此仅使用默认设置),而是对其进行构建,刷新和监视,并且它可以正常工作-监视器仅显示“关闭LED”和“开启LED'。没有提及看门狗计时器。

我编写了自己的最简单的应用程序,而无需调用vTaskDelay():

void app_main(void) {
  long timeSinceBoot;
  while (1) {
    timeSinceBoot = esp_timer_get_time();
    printf("Helloooo world %ld\n!",timeSinceBoot);
  };
}

这将导致串行监视器定期显示以下输出:

E (20298) task_wdt: Task watchdog got triggered. The following tasks did not reset the watchdog in time:
E (20298) task_wdt:  - IDLE0 (CPU 0)
E (20298) task_wdt: Tasks currently running:
E (20298) task_wdt: CPU 0: main
E (20298) task_wdt: CPU 1: IDLE1

我理解为什么-我需要回叫OS才能完成它需要做的事情。我在其他系统中使用yield语句来完成此操作。

我只想使用一个内核,并且试图避免使用xTaskCreate来使我的代码易于理解。

如果我不想延迟(如眨眼示例一样),将控制权从app_main传递回FreeRTOS以便使其尽快返回的最有效方法是什么?

2 个答案:

答案 0 :(得分:1)

问题不在于将控制权交还给FreeRTOS,而是在eps-idf框架中处理看门狗。

看门狗在IDLE任务中被“喂”,并且APP_MAIN任务的优先级比IDLE高,它永远不会被中断。

如果您不想使用vTaskDelay,则可以使IDLE和MAIN任务的优先级相等。比应同时执行两个任务(但是,如果还有更多任务没有引起足够的重视,则必须小心)。

答案 1 :(得分:0)

除了测试外,我不建议这样做,但是您可以仅对IDLE任务禁用任务看门狗。

menuconfig->组件配置-> Esp32特定的配置->停用任务看门狗

对于生产代码,应遵循最佳实践并使用FreeRTOS功能(例如vTaskDelay),以免占用CPU。