Administrator
发布于 2024-04-11 / 12 阅读
0

硬件 第一篇 2 ESP32第一个程序hello_world - 曲速引擎(Warp Drive)

一、程序模板摸索

打开vscode F1搜索 examples,选择hello_world程序进行学习,映入眼帘的是一大坨C语言,对于我这个10年前学过C语言之后就没有接触过的人,看起来是有点吃力

将esp32开发版插入windows,找到vscode上面的插件按钮,如果没有可以看我第一篇文章,选择COM3,可以在我的电脑-右键-根据计算机管理、设备管理-端口上面看到端口号。

这一排下面几个按钮,分别是编译、选择闪存方法、下载程序到闪存、监控程序

依次点击即可将程序下载到esp32硬件当中,然后点击监控程序(Monitor Device)即可查看看到内部硬件运行情况。可以看到模板程序打印出来Hello_world

二、源代码

/*
 * SPDX-FileCopyrightText: 2010-2022 Espressif Systems (Shanghai) CO LTD
 *
 * SPDX-License-Identifier: CC0-1.0
 */

#include <stdio.h>
#include <inttypes.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_chip_info.h"
#include "esp_flash.h"

void app_main(void)
{
    printf("Hello world!\n");

    /* Print chip information */
    esp_chip_info_t chip_info;
    uint32_t flash_size;
    esp_chip_info(&chip_info);
    printf("This is %s chip with %d CPU core(s), %s%s%s%s, ",
           CONFIG_IDF_TARGET,
           chip_info.cores,
           (chip_info.features & CHIP_FEATURE_WIFI_BGN) ? "WiFi/" : "",
           (chip_info.features & CHIP_FEATURE_BT) ? "BT" : "",
           (chip_info.features & CHIP_FEATURE_BLE) ? "BLE" : "",
           (chip_info.features & CHIP_FEATURE_IEEE802154) ? ", 802.15.4 (Zigbee/Thread)" : "");

    unsigned major_rev = chip_info.revision / 100;
    unsigned minor_rev = chip_info.revision % 100;
    printf("silicon revision v%d.%d, ", major_rev, minor_rev);
    if(esp_flash_get_size(NULL, &flash_size) != ESP_OK) {
        printf("Get flash size failed");
        return;
    }

    printf("%" PRIu32 "MB %s flash\n", flash_size / (uint32_t)(1024 * 1024),
           (chip_info.features & CHIP_FEATURE_EMB_FLASH) ? "embedded" : "external");

    printf("Minimum free heap size: %" PRIu32 " bytes\n", esp_get_minimum_free_heap_size());

    for (int i = 10; i >= 0; i--) {
        printf("Restarting in %d seconds...\n", i);
        vTaskDelay(1000 / portTICK_PERIOD_MS);
    }
    printf("Restarting now.\n");
    fflush(stdout);
    esp_restart();
}

三、代码含义

这段代码是一个ESP-IDF(Espressif IoT Development Framework)项目的主函数示例,用于ESP32等Espressif的微控制器。它展示了如何在应用程序启动时打印出芯片信息、闪存大小、最小空闲堆大小,并在倒计时后重启设备。

这部分代码包含了所需的头文件。stdio.h 和 inttypes.h 是标准C库头文件,分别用于输入输出函数和整数类型格式化。sdkconfig.h 是ESP-IDF的配置文件,FreeRTOS.h 和 task.h 是FreeRTOS实时操作系统的头文件。esp_chip_info.h 和 esp_flash.h 是ESP-IDF提供的用于获取芯片信息和闪存信息的头文件。

#include <stdio.h>
#include <inttypes.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_chip_info.h"
#include "esp_flash.h"

​定义了应用程序的主函数 app_main,这是ESP-IDF项目的入口点。首先打印“Hello world!”。

void app_main(void)
{
    printf("Hello world!\n");

​声明一个 esp_chip_info_t 结构体变量 chip_info 来存储芯片信息,然后调用 esp_chip_info() 函数填充这个结构体,esp_chip_info_t 是一个结构体类型,定义在 ESP-IDF(Espressif IoT Development Framework)框架中,具体位于 esp_chip_info.h 头文件中。这个结构体用于存储ESP芯片的信息,包括CPU核心数、芯片的特性(如是否支持WiFi、蓝牙、BLE等)、芯片模型以及其他相关信息。

    /* Print chip information */
    esp_chip_info_t chip_info;
    uint32_t flash_size;
    esp_chip_info(&chip_info);

​打印芯片类型、CPU核心数和支持的功能(如WiFi、蓝牙、BLE、802.15.4)。

    printf("This is %s chip with %d CPU core(s), %s%s%s%s, ",
           CONFIG_IDF_TARGET,
           chip_info.cores,
           (chip_info.features & CHIP_FEATURE_WIFI_BGN) ? "WiFi/" : "",
           (chip_info.features & CHIP_FEATURE_BT) ? "BT" : "",
           (chip_info.features & CHIP_FEATURE_BLE) ? "BLE" : "",
           (chip_info.features & CHIP_FEATURE_IEEE802154) ? ", 802.15.4 (Zigbee/Thread)" : "");

计算并打印芯片的硅片版本号

    unsigned major_rev = chip_info.revision / 100;
    unsigned minor_rev = chip_info.revision % 100;
    printf("silicon revision v%d.%d, ", major_rev, minor_rev);

尝试获取闪存大小,如果失败则打印错误信息并退出函数

    if(esp_flash_get_size(NULL, &flash_size) != ESP_OK) {
        printf("Get flash size failed");
        return;
    }

打印闪存大小和类型(嵌入式或外部)。 printf("%" PRIu32 "MB %s flash\n",

 printf("%" PRIu32 "MB %s flash\n", flash_size / (uint32_t)(1024 * 1024),
           (chip_info.features & CHIP_FEATURE_EMB_FLASH) ? "embedded" : "external");

打印自系统启动以来记录的最小空闲堆大小

 printf("Minimum free heap size: %" PRIu32 " bytes\n", esp_get_minimum_free_heap_size());

倒计时10秒,每秒打印一次剩余时间,然后延迟1秒

for (int i = 10; i >= 0; i--) {
        printf("Restarting in %d seconds...\n", i);
        vTaskDelay(1000 / portTICK_PERIOD_MS);
    }

打印重启信息,刷新标准输出缓冲区,然后调用 esp_restart() 函数重启设备。​

    printf("Restarting now.\n");
    fflush(stdout);
    esp_restart();
}​​

四、函数来源解释

ESP-IDF特定的库和模块

  • esp_chip_info():

  • 模块: esp_chip_info.h

  • 功能: 获取ESP芯片的详细信息,如CPU核心数、支持的特性(WiFi、BT、BLE等)。

  • 使用场景: 当需要根据芯片的具体能力调整应用行为或输出相应信息时。

  • esp_flash_get_size():

  • 模块: esp_flash.h

  • 功能: 查询ESP设备的闪存大小。

  • 使用场景: 在需要管理或优化存储空间,或者在显示设备信息时使用。

  • esp_get_minimum_free_heap_size():

  • 模块: 无直接对应模块,但函数声明通常在ESP-IDF的堆管理相关的头文件中。

  • 功能: 返回自系统启动以来记录的最小空闲堆内存大小。

  • 使用场景: 用于监控和调试内存使用情况,特别是在资源受限的嵌入式系统中。

  • esp_restart():

  • 模块: 通常在ESP-IDF的系统控制或重启相关的头文件中。

  • 功能: 重启ESP设备。

  • 使用场景: 在需要软件重置设备回到初始状态时使用,如更新配置、应用程序崩溃恢复等情况。

FreeRTOS

  • vTaskDelay():

  • 模块: freertos/task.h

  • 功能: 在任务中创建延时,让出CPU给其他任务或触发调度器。

  • 使用场景: 用于实现非阻塞延时,常见于需要短暂等待的场景,如周期性任务执行间的延时。

标准C库

  • printf()fflush(stdout):

  • 模块: stdio.h

  • 功能: printf() 用于输出格式化的字符串到标准输出。fflush(stdout) 清空输出缓冲区,确保所有输出都被立即打印。

  • 使用场景: printf() 用于打印调试信息、设备状态、错误消息等。fflush(stdout) 在需要确保信息即时显示时使用,特别是在缓冲的输出流上。