行业知识
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任务列表用表格表示的结果:
| 任务名称 | 状态 | 优先级 | 剩余堆栈空间 (字节) | 任务编号 | 功能描述 |
|---|---|---|---|---|---|
| main | X | 1 | 2036 | 4 | 应用主任务,通常用于启动其他任务和初始化系统。 |
| IDLE1 | R | 0 | 812 | 6 | 空闲任务之一,通常在系统空闲时执行,一般进行喂狗。 |
| IDLE0 | R | 0 | 1008 | 5 | 空闲任务之二,通常在系统空闲时执行,一般进行喂狗。 |
| esp_timer | B | 22 | 3352 | 3 | 定时器服务任务,处理系统定时器事件。 |
| ipc1 | S | 24 | 524 | 2 | 进程间通信任务之一,用于处理高优先级的IPC操作。 |
| Tmr Svc | B | 1 | 1320 | 7 | 定时器服务任务,管理应用程序定时器回调函数的执行。 |
| ipc0 | S | 24 | 512 | 1 | 进程间通信任务之二,用于处理高优先级的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);}
下一篇:libswift