小工具知识网

当前位置: 首页 > 行业知识 > 30-ESP32-S3-WIFI篇-01 FreeRTOS

行业知识

30-ESP32-S3-WIFI篇-01 FreeRTOS

2026-11-11 08:24:43 来源:互联网转载

ESP32-S3-WIFI-FreeRTOS 任务

介绍

FreeRTOS

FreeRTOS是一个开源的实时操作系统(RTOS)内核,以模块化的方式与ESP-IDF集成。这意味着所有的ESP-IDF应用程序和各种ESP-IDF组件都建立在FreeRTOS框架之上。FreeRTOS内核已经被移植到ESP芯片的所有CPU架构上,包括Xtensa和RISC-V。

在ESP32中,WIFI的操作与FreeRTOS的多任务紧密相连,并且彼此之间存在相互依赖的关系。实际上,FreeRTOS作为一种用于实时操作系统的开源软件,它提供了任务调度和管理的功能。而ESP32作为一款集成了WIFI功能的芯片,充分利用了FreeRTOS的多任务处理机制来实现同时处理多个WIFI连接和数据传输的能力。因此,了解和熟悉FreeRTOS的多任务编程模型对于有效地操作和管理ESP32的WIFI功能至关重要。通过合理的任务分配和调度,能够充分利用ESP32的资源,提高WIFI的性能和稳定性。同时,合理处理WIFI任务与其他任务的并行执行,能够确保系统的整体响应性和吞吐量。

显示当前所有的任务

在开始前让我们先看看不进行任何操作,ESP3都有哪些任务

首先在 menuconfig中修改打开下面设置

然后运行以下程序

/** * @brief 显示当前所有的任务 *  */void task_list(){    char ptrTaskList[250];    vTaskList(ptrTaskList);    printf("********************************************\n");    printf("Task          State     Prio    Stack     Num\n");    printf("********************************************\n");    printf(ptrTaskList);    printf("********************************************\n");}void app_main(void){    task_list();}

效果如下

以下是将FreeRTOS任务列表用表格表示的结果:

任务名称状态优先级剩余堆栈空间 (字节)任务编号功能描述
mainX120364应用主任务,通常用于启动其他任务和初始化系统。
IDLE1R08126空闲任务之一,通常在系统空闲时执行,一般进行喂狗。
IDLE0R010085空闲任务之二,通常在系统空闲时执行,一般进行喂狗。
esp_timerB2233523定时器服务任务,处理系统定时器事件。
ipc1S245242进程间通信任务之一,用于处理高优先级的IPC操作。
Tmr SvcB113207定时器服务任务,管理应用程序定时器回调函数的执行。
ipc0S245121进程间通信任务之二,用于处理高优先级的IPC操作。

各个字段含义:

  • 任务名称 (Task): 任务的名称。
  • 状态 (State): 任务的状态。
    • X: 未知状态
    • R: 运行中 (Running)
    • B: 阻塞中 (Blocked)
    • S: 挂起 (Suspended)
    • 优先级 (Prio): 任务的优先级,数值越大优先级越高。
    • 剩余堆栈空间 (Stack): 任务剩余的堆栈空间大小,以字节为单位。
    • 任务编号 (Num): 任务的编号。

      带有WIFI功能时的任务

      我们将WIFI扫描的功能加入到app_main中

      #include #include #include "esp_log.h"#include "nvs_flash.h"#include "esp_wifi.h"#include "freertos/FreeRTOS.h"#include "freertos/task.h"/** * @brief WIFI扫描 *  */void wifi_scan(){    ESP_LOGI("WIFI", "0. 初始化NVS存储");    ESP_ERROR_CHECK(nvs_flash_init());                   // 对NVS默认的区域进行初始化    ESP_LOGI("WIFI", "1. WIFI 初始化阶段");    esp_netif_init();                    // 1.1 创建一个 LwIP 核心任务    esp_event_loop_create_default();             // 1.2 创建一个系统事件任务    esp_netif_create_default_wifi_sta(); // 1.3.1 创建有 TCP/IP 堆栈的默认网络接口实例    wifi_init_config_t wifi_config = WIFI_INIT_CONFIG_DEFAULT();    esp_wifi_init(&wifi_config);             // 1.3.2 创建 Wi-Fi 驱动程序任务    ESP_LOGI("WIFI", "2. WIFI 配置阶段");    esp_wifi_set_mode(WIFI_MODE_STA);       // 2 将 Wi-Fi 模式配置为 station    ESP_LOGI("WIFI", "3. WIFI 启动阶段");    esp_wifi_start();                        // 3.1 启动 Wi-Fi 驱动程序    ESP_LOGI("WIFI", "4. WIFI 扫描");    //在所有信道中扫描全部 AP(前端)    wifi_country_t country_config = {        .cc = "CN",        .schan = 1,        .nchan = 13,    };    esp_wifi_set_country(&country_config); // 4.1 扫描配置国家代码    wifi_scan_config_t scan_config = {        .show_hidden = true               // 显示隐藏    };    esp_wifi_scan_start(&scan_config,true); // 4.2 配置扫描信息 true表示当这个任务执行的时候,回进入阻塞状态等待扫描    //得到扫描的AP数量    uint16_t ap_num =0;    ESP_ERROR_CHECK(esp_wifi_scan_get_ap_num(&ap_num));     ESP_LOGI("WIFI","AP Count : %d",ap_num);    //获取具体的AP信息    uint16_t max_aps=20;    wifi_ap_record_t ap_records[max_aps];    memset(ap_records,0,sizeof(ap_records));    uint16_t aps_count =max_aps;    ESP_ERROR_CHECK(esp_wifi_scan_get_ap_records(&aps_count,ap_records));    //打印信息    ESP_LOGI("WIFI","AP Count: %d",aps_count);    printf("%30s %3s %3s %3s\n","SSID","频道","强度","MAC地址");    for(int i=0;i        printf("%30s %4d %4d %02X-%02X-%02X-%02X-%02X-%02X\n",        ap_records[i].ssid,        ap_records[i].primary,        ap_records[i].rssi,        ap_records[i].bssid[0],        ap_records[i].bssid[1],        ap_records[i].bssid[2],        ap_records[i].bssid[3],        ap_records[i].bssid[4],        ap_records[i].bssid[5]);    }}/** * @brief 显示当前所有的任务 *  */void task_list(){    char ptrTaskList[250];    vTaskList(ptrTaskList);    printf("********************************************\n");    printf("Task          State     Prio    Stack     Num\n");    printf("********************************************\n");    printf(ptrTaskList);    printf("********************************************\n");}void app_main(void){    wifi_scan();    task_list();    for(;;){        vTaskDelay(1000/portTICK_PERIOD_MS);    }}    ESP_LOGI("app_task","App Task创建成功");    vTaskDelete(NULL);}xTaskCreate(app_task,"App Task",1024*12,NULL,1,NULL);   //1.4 创建app_task任务    // 事件处理程序逻辑    ESP_LOGE("event_handle", "事件处理程序 base: %s, id: %d", base, id);}// 应用任务void app_task(void* pt) {    ESP_LOGI("app_task", "App Task创建成功");    // 注册事件处理程序    esp_err_t err = esp_event_handler_register(ESP_EVENT_ANY_BASE, ESP_EVENT_ANY_ID, run_on_event, NULL);    if (err != ESP_OK) {        ESP_LOGE("app_task", "事件处理程序注册失败: %s", esp_err_to_name(err));    } else {        ESP_LOGI("app_task", "事件处理程序注册成功");    }    // 删除任务    ESP_LOGI("app_task", "删除App Task");    vTaskDelete(NULL);}// 主函数void app_main(void) {    // 创建应用任务    xTaskCreate(app_task, "app_task", 2048, NULL, 5, NULL);}    ESP_LOGI("WIFI", "4. WIFI 扫描");    //在所有信道中扫描全部 AP(前端)    wifi_country_t country_config = {        .cc = "CN",        .schan = 1,        .nchan = 13,    };    esp_wifi_set_country(&country_config); // 4.1 扫描配置国家代码    wifi_scan_config_t scan_config = {        .show_hidden = true               // 显示隐藏    };    esp_wifi_scan_start(&scan_config,true); // 4.2 配置扫描信息 true表示当这个任务执行的时候,回进入阻塞状态等待扫描    vTaskDelete(NULL);}/** * @brief 显示扫描的ap信息 *  * @param pd  */void wifi_show_task(void* pd){    //得到扫描的AP数量    uint16_t ap_num =0;    ESP_ERROR_CHECK(esp_wifi_scan_get_ap_num(&ap_num));     ESP_LOGI("WIFI","AP Count : %d",ap_num);    //获取具体的AP信息    uint16_t max_aps=20;    wifi_ap_record_t ap_records[max_aps];    memset(ap_records,0,sizeof(ap_records));    uint16_t aps_count =max_aps;    ESP_ERROR_CHECK(esp_wifi_scan_get_ap_records(&aps_count,ap_records));    //打印信息    ESP_LOGI("WIFI","AP Count: %d",aps_count);    printf("%30s %3s %3s %3s\n","SSID","频道","强度","MAC地址");    for(int i=0;i        printf("%30s %4d %4d %02X-%02X-%02X-%02X-%02X-%02X\n",        ap_records[i].ssid,        ap_records[i].primary,        ap_records[i].rssi,        ap_records[i].bssid[0],        ap_records[i].bssid[1],        ap_records[i].bssid[2],        ap_records[i].bssid[3],        ap_records[i].bssid[4],        ap_records[i].bssid[5]);    }    vTaskDelete(NULL);}// 定义事件处理程序void run_on_event(void* handler_arg, esp_event_base_t base, int32_t id, void* event_data){    // 事件处理程序逻辑    //ESP_LOGE("event_handle","事件处理程序 base: %s , id: %d",base,id);    switch(id){    case WIFI_EVENT_STA_START:        ESP_LOGE("EVENT_HANDLE","WIFI_EVENT_STA_START");         xTaskCreate(wifi_scan_task,"WIFI_scan Task",1024*12,NULL,1,NULL);        break;    case WIFI_EVENT_SCAN_DONE:        ESP_LOGE("EVENT_HANDLE","WIFI_EVENT_SCAN_DONE");        xTaskCreate(wifi_show_task,"WIFI_show Task",1024*12,NULL,1,NULL);    default:    }}/** * @brief 用户自定义app_task任务用于捕捉wifi_task的消息 *  * @param pt  */void app_task(void* pt){    ESP_LOGI("app_task","App Task创建成功");    esp_event_handler_register(ESP_EVENT_ANY_BASE,ESP_EVENT_ANY_ID,run_on_event,NULL);    vTaskDelete(NULL);}

上一篇:探索QQ时间轴,数字足迹中的美好回忆之旅!

下一篇:libswift