ESP32 — Hello World(芯片信息打印 + FreeRTOS 入门)

ESP32 ESP-IDF Hello World 示例,打印芯片信息和系统状态

ESP32 — Hello World

难度: ⭐(零基础入门)
开发框架: ESP-IDF
源文件: project_test/main/hello_world_main.c


这个实验是干嘛的?

这是 ESP32 的"Hello World"——上电后打印芯片信息,然后倒计时重启。

通过这个实验你将学会:

  • ESP-IDF 项目的基本结构
  • ESP32 的 app_main() 入口函数(不是 main()!)
  • 如何读取芯片信息(型号、核心数、Flash 大小)
  • FreeRTOS 任务的基本用法

硬件准备

  • ESP32 开发板(任意型号)
  • USB 数据线(Micro USB 或 Type-C,看板子)
  • 电脑端串口助手(115200 波特率)

ESP32 与传统 MCU 的区别

特性 传统 MCU(STM32/GD32) ESP32
入口函数 main() app_main()
操作系统 无(裸机)或 FreeRTOS 内置 FreeRTOS
延时函数 delay_ms() vTaskDelay()
编译系统 Keil/IAR CMake + ESP-IDF
WiFi/蓝牙 需外接模块 内置
内存管理 动态内存(heap)

关键区别:ESP32 基于 FreeRTOS,你的代码运行在一个 RTOS 任务里,不是裸机。


完整代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
/*
 * SPDX-FileCopyrightText: 2010-2022 Espressif Systems (Shanghai) CO LTD
 * SPDX-License-Identifier: CC0-1.0
 */

#include <stdio.h>
#include <inttypes.h>
#include "sdkconfig.h"           // SDK 配置(menuconfig 生成)
#include "freertos/FreeRTOS.h"   // FreeRTOS 头文件
#include "freertos/task.h"       // 任务管理
#include "esp_chip_info.h"       // 芯片信息 API
#include "esp_flash.h"           // Flash 信息 API
#include "esp_system.h"          // 系统 API

/* ESP32 的入口函数(不是 main,是 app_main!) */
void app_main(void)
{
    printf("Hello world!\n");

    /* 第一步:读取芯片信息 */
    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,          // CPU 核心数
           (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);

    /* 第三步:读取 Flash 大小 */
    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());

    /* 第五步:倒计时 10 秒后重启 */
    for (int i = 10; i >= 0; i--) {
        printf("Restarting in %d seconds...\n", i);
        vTaskDelay(1000 / portTICK_PERIOD_MS);  // 延时 1 秒
    }
    printf("Restarting now.\n");
    fflush(stdout);
    esp_restart();  // 软件重启
}

代码分段讲解

1. 入口函数

1
void app_main(void)

ESP32 的入口是 app_main(),不是 main()

main() 在 ESP-IDF 内部被 FreeRTOS 使用了,你的代码写在 app_main() 里。ESP-IDF 启动时会自动创建一个 FreeRTOS 任务来运行 app_main()

2. 芯片信息

1
2
esp_chip_info_t chip_info;
esp_chip_info(&chip_info);

esp_chip_info() 返回一个结构体,包含:

  • chip_info.cores — CPU 核心数(ESP32 是 2 核)
  • chip_info.features — 芯片能力标志位(WiFi、蓝牙、BLE 等)
  • chip_info.revision — 芯片版本号

3. FreeRTOS 延时

1
vTaskDelay(1000 / portTICK_PERIOD_MS);

不要用 delay_ms() ESP32 基于 FreeRTOS,必须用 RTOS 的延时函数:

  • vTaskDelay(1000) — 延时 1000 个 tick
  • portTICK_PERIOD_MS — 每个 tick 多少毫秒(通常 1ms)
  • 1000 / portTICK_PERIOD_MS = 延时 1000ms = 1 秒

vTaskDelay非阻塞的,延时期间 CPU 可以运行其他任务。

4. 系统重启

1
esp_restart();

软件重启,相当于按复位键。重启后程序从头开始运行。


实验现象

串口助手(115200 波特率)输出:

1
2
3
4
5
6
7
8
9
Hello world!
This is esp32 chip with 2 CPU core(s), WiFi/BT/BLE, silicon revision v3.0, 
4MB external flash
Minimum free heap size: 287432 bytes
Restarting in 10 seconds...
Restarting in 9 seconds...
...
Restarting in 0 seconds...
Restarting now.

然后芯片自动重启,重复输出。


常见问题

Q: 串口没有输出?

  • 检查 USB 线是否支持数据传输(有些只能充电)
  • 检查串口驱动(CP2102 或 CH340)
  • 波特率设 115200
  • ESP32 上电后会先输出 bootloader 日志,然后才是你的程序

Q: 编译报错找不到 ESP-IDF?

  • 确认已安装 ESP-IDF 并设置了环境变量
  • 运行 source export.sh(Linux)或 export.bat(Windows)

Q: 想用 Arduino 方式写?

  • Arduino IDE 里入口是 setup()loop()
  • setup() 对应 app_main() 的初始化部分
  • loop() 对应 while(1) 主循环

小结

概念 说明
app_main() ESP32 的入口函数(不是 main()
esp_chip_info() 读取芯片型号、核心数、能力
vTaskDelay() FreeRTOS 非阻塞延时
esp_restart() 软件重启
FreeRTOS ESP32 内置的实时操作系统

拓展应用

学了 ESP32 能做什么?最大的优势是自带 WiFi 和蓝牙

项目 原理 难度
智能家居开关 WiFi + MQTT + 继电器 ⭐⭐⭐
物联网温度计 WiFi 上传数据到云平台 ⭐⭐
蓝牙遥控小车 BLE 连接手机控制电机 ⭐⭐⭐
WiFi 遥控器 ESP32 建 Web 服务器,手机浏览器控制 ⭐⭐⭐
网络摄像头 ESP32-CAM + WiFi 视频流 ⭐⭐⭐⭐
天气显示屏 WiFi 获取天气 API,E-ink 显示 ⭐⭐⭐
OTA 远程升级 WiFi 下载新固件,自动更新 ⭐⭐⭐⭐
蓝牙音箱 A2DP 蓝牙音频流 ⭐⭐⭐⭐

核心思路:ESP32 的核心价值是联网能力。传统 MCU 需要外接 WiFi/蓝牙模块才能联网,ESP32 自带。任何需要"联网"的项目,ESP32 都是首选。

世界是你们
使用 Hugo 构建
主题 StackJimmy 设计