

C语言特点:
C语言特点:
├── 过程化编程
├── 函数式设计
├── 手动内存管理
├── 简单直接
└── 性能高效
C++语言特点:
C++语言特点:
├── 面向对象编程
├── 类与对象
├── 自动内存管理
├── 丰富的标准库
└── 更好的代码组织
项目需求分析:
项目需求:
├── 复杂的硬件抽象
├── 多层次的设备管理
├── 音频处理管道
├── 网络协议处理
└── 物联网设备控制
C++优势:
C++优势:
├── 面向对象设计
│ ├── 更好的代码组织
│ ├── 清晰的职责分离
│ └── 易于维护和扩展
├── 丰富的标准库
│ ├── STL容器
│ ├── 智能指针
│ └── 算法库
├── 模板支持
│ ├── 泛型编程
│ ├── 代码复用
│ └── 类型安全
└── 现代C++特性
├── 自动类型推导
├── Lambda表达式
└── 移动语义
面向对象设计:
// 抽象基类设计
class Board {
public:
virtual ~Board() = default;
virtual std::string GetBoardType() = 0;
virtual AudioCodec* GetAudioCodec() = 0;
virtual Display* GetDisplay() = 0;
};
// 具体实现类
class WifiBoard :public Board {
public:
std::string GetBoardType() override {
return"wifi";
}
// 其他实现...
};
智能指针使用:
// 自动内存管理
std::unique_ptr<OpusEncoderWrapper> opus_encoder_;
std::unique_ptr<OpusDecoderWrapper> opus_decoder_;
std::unique_ptr<Protocol> protocol_;
STL容器使用:
// 容器使用
std::list<std::function<void()>> main_tasks_;
std::list<std::vector<uint8_t>> audio_decode_queue_;
std::vector<Thing*> things_;
类的定义:
// 类定义示例
class Led {
public:
// 构造函数
Led(gpio_num_t gpio);
// 析构函数
virtual ~Led() = default;
// 成员函数
virtual void OnStateChanged() = 0;
private:
// 成员变量
gpio_num_t gpio_;
bool state_;
};
对象创建和使用:
// 对象创建
Led* led = new SingleLed(GPIO_NUM_2);
// 对象使用
led->OnStateChanged();
// 对象销毁
delete led;
构造函数类型:
class AudioCodec {
public:
// 默认构造函数
AudioCodec() = default;
// 参数化构造函数
AudioCodec(int sample_rate, int channels)
: sample_rate_(sample_rate), channels_(channels) {
ESP_LOGI(TAG, "AudioCodec created with sample_rate=%d, channels=%d",
sample_rate_, channels_);
}
// 拷贝构造函数
AudioCodec(const AudioCodec& other)
: sample_rate_(other.sample_rate_), channels_(other.channels_) {
ESP_LOGI(TAG, "AudioCodec copied");
}
// 移动构造函数
AudioCodec(AudioCodec&& other) noexcept
: sample_rate_(other.sample_rate_), channels_(other.channels_) {
other.sample_rate_ = 0;
other.channels_ = 0;
ESP_LOGI(TAG, "AudioCodec moved");
}
private:
int sample_rate_;
int channels_;
};
初始化列表:
class Display {
public:
Display(int width, int height, DisplayFonts fonts)
: width_(width), height_(height), fonts_(fonts) {
// 初始化逻辑
Initialize();
}
private:
int width_;
int height_;
DisplayFonts fonts_;
};
析构函数作用:
class Protocol {
public:
Protocol() {
ESP_LOGI(TAG, "Protocol created");
}
virtual ~Protocol() {
ESP_LOGI(TAG, "Protocol destroyed");
// 清理资源
if (websocket_handle_) {
esp_websocket_client_destroy(websocket_handle_);
}
}
private:
esp_websocket_client_handle_t websocket_handle_;
};
虚析构函数:
// 基类使用虚析构函数
class Board {
public:
virtual ~Board() = default; // 虚析构函数
};
// 派生类
class WifiBoard : public Board {
public:
~WifiBoard() override {
ESP_LOGI(TAG, "WifiBoard destroyed");
// 清理WiFi相关资源
}
};
什么是单例模式?
单例模式特点:
├── 确保类只有一个实例
├── 提供全局访问点
├── 延迟初始化
└── 线程安全
单例模式实现方式:
// 方式1:懒汉式(线程不安全)
class Application {
public:
static Application& GetInstance() {
static Application instance;
return instance;
}
private:
Application() = default;
Application(const Application&) = delete;
Application& operator=(const Application&) = delete;
};
小智AI项目中的单例模式:
// Application类单例实现
class Application {
public:
static Application& GetInstance() {
static Application instance;
return instance;
}
// 禁止拷贝和赋值
Application(const Application&) = delete;
Application& operator=(const Application&) = delete;
private:
Application() {
ESP_LOGI(TAG, "Application singleton created");
}
~Application() {
ESP_LOGI(TAG, "Application singleton destroyed");
}
};
资源管理:
class Application {
public:
void Start() {
// 获取单例实例
auto& board = Board::GetInstance();
auto& thing_manager = ThingManager::GetInstance();
// 使用单例实例
board.Initialize();
thing_manager.Initialize();
}
};
全局访问:
// 在任何地方都可以访问Application实例
void SomeFunction() {
auto& app = Application::GetInstance();
app.SetDeviceState(kDeviceStateIdle);
}
Board类单例:
class Board {
public:
static Board& GetInstance() {
static Board* instance = static_cast<Board*>(create_board());
return *instance;
}
};
ThingManager类单例:
class ThingManager {
public:
static ThingManager& GetInstance() {
static ThingManager instance;
return instance;
}
};
vector容器:
// vector 使用示例
std::vector<int> numbers = {1, 2, 3, 4, 5};
// 添加元素
numbers.push_back(6);
// 访问元素
int first = numbers[0];
int last = numbers.back();
// 遍历
for (const auto& num : numbers) {
ESP_LOGI(TAG, "Number: %d", num);
}
list容器:
// list使用示例
std::list<std::function<void()>> tasks;
// 添加任务
tasks.push_back([]() {
ESP_LOGI(TAG, "Task executed");
});
// 执行任务
for (auto& task : tasks) {
task();
}
map容器:
// map使用示例
std::map<std::string, int> device_states;
// 添加键值对
device_states["idle"] = 0;
device_states["listening"] = 1;
device_states["speaking"] = 2;
// 查找值
auto it = device_states.find("idle");
if (it != device_states.end()) {
ESP_LOGI(TAG, "State value: %d", it->second);
}
排序算法:
#include <algorithm>
std::vector<int> numbers = {5, 2, 8, 1, 9};
// 排序
std::sort(numbers.begin(), numbers.end());
// 查找
auto it = std::find(numbers.begin(), numbers.end(), 5);
if (it != numbers.end()) {
ESP_LOGI(TAG, "Found 5 at position: %ld", std::distance(numbers.begin(), it));
}
Lambda 表达式:
// Lambda表达式使用
std::vector<int> numbers = {1, 2, 3, 4, 5};
// 使用Lambda表达式过滤
std::vector<int> even_numbers;
std::copy_if(numbers.begin(), numbers.end(),
std::back_inserter(even_numbers),
[](int n) { return n % 2 == 0; });
unique_ptr:
// unique_ptr使用
std::unique_ptr<OpusEncoderWrapper> opus_encoder_;
// 创建对象
opus_encoder_ = std::make_unique<OpusEncoderWrapper>(16000, 1, 60);
// 使用对象
opus_encoder_->Encode(audio_data, callback);
shared_ptr:
// shared_ptr使用
std::shared_ptr<AudioCodec> codec_;
// 创建对象
codec_ = std::make_shared<Es8311AudioCodec>();
// 共享对象
auto codec_copy = codec_;
步骤1:创建主程序
// main/main.cpp
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "esp_log.h"
#include "esp_system.h"
staticconstchar *TAG = "main";
// LED控制结构体
typedefstruct {
gpio_num_t gpio;
bool active_high;
bool current_state;
} led_control_t;
// LED控制函数
void led_init(led_control_t *led, gpio_num_t gpio, bool active_high) {
led->gpio = gpio;
led->active_high = active_high;
led->current_state = false;
// 配置GPIO
gpio_config_t io_conf = {};
io_conf.intr_type = GPIO_INTR_DISABLE;
io_conf.mode = GPIO_MODE_OUTPUT;
io_conf.pin_bit_mask = (1ULL << gpio);
io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE;
io_conf.pull_up_en = GPIO_PULLUP_DISABLE;
gpio_config(&io_conf);
// 初始状态为关闭
gpio_set_level(gpio, active_high ? 0 : 1);
ESP_LOGI(TAG, "LED control initialized on GPIO %d", gpio);
}
void led_turn_on(led_control_t *led) {
gpio_set_level(led->gpio, led->active_high ? 1 : 0);
led->current_state = true;
ESP_LOGI(TAG, "LED turned ON");
}
void led_turn_off(led_control_t *led) {
gpio_set_level(led->gpio, led->active_high ? 0 : 1);
led->current_state = false;
ESP_LOGI(TAG, "LED turned OFF");
}
void led_toggle(led_control_t *led) {
if (led->current_state) {
led_turn_off(led);
} else {
led_turn_on(led);
}
}
void led_set_state(led_control_t *led, bool state) {
if (state) {
led_turn_on(led);
} else {
led_turn_off(led);
}
}
bool led_get_state(led_control_t *led) {
return led->current_state;
}
void app_main(void) {
ESP_LOGI(TAG, "Starting LED control example");
// 创建LED控制对象
led_control_t led;
led_init(&led, GPIO_NUM_2, true); // GPIO2, 高电平有效
// 测试LED功能
ESP_LOGI(TAG, "Testing LED control...");
// 打开LED
led_turn_on(&led);
vTaskDelay(pdMS_TO_TICKS(1000));
// 关闭LED
led_turn_off(&led);
vTaskDelay(pdMS_TO_TICKS(1000));
// 切换LED状态
led_toggle(&led);
vTaskDelay(pdMS_TO_TICKS(1000));
// 设置LED状态
led_set_state(&led, true);
vTaskDelay(pdMS_TO_TICKS(1000));
// 获取LED状态
bool state = led_get_state(&led);
ESP_LOGI(TAG, "Current LED state: %s", state ? "ON" : "OFF");
// 循环闪烁
ESP_LOGI(TAG, "Starting LED blink loop...");
int count = 0;
while (1) {
led_toggle(&led);
ESP_LOGI(TAG, "LED blink count: %d", count++);
vTaskDelay(pdMS_TO_TICKS(500));
}
}
步骤2:配置项目
# CMakeLists.txt
cmake_minimum_required(VERSION 3.16)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(led_control_example)
步骤3:编译和烧录
# 设置环境
get_idf
# 设置目标芯片
idf.py set-target esp32s3
# 编译项目
idf.py build
# 烧录程序
idf.py -p COM3 flash monitor
步骤4:观察结果
期望输出:
I (1234) main: Starting LED control example
I (1235) led_control: LED control initialized on GPIO 2
I (1236) main: Testing LED control...
I (1237) led_control: LED turned ON
I (2237) led_control: LED turned OFF
I (3237) led_control: LED turned ON
I (4237) led_control: LED turned ON
I (4238) main: Current LED state: ON
I (4239) main: Starting LED blink loop...
I (4240) led_control: LED turned OFF
I (4241) main: LED blink count: 0
I (4741) led_control: LED turned ON
I (4742) main: LED blink count: 1
...
掌握内容:
扩展练习:
对 main.c文件中的每一行代码进行详细解析说明:
#include <stdio.h>
printf、scanf等标准I/O函数(虽然这里没有直接使用,但通常包含以备用)#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
vTaskDelay()#include "driver/gpio.h"
gpio_config()、gpio_set_level()#include "esp_log.h"
ESP_LOGI()#include "esp_system.h"
static const char *TAG = "main";
[main]前缀typedef struct {
gpio_num_t gpio;
bool active_high;
bool current_state;
} led_control_t;
void led_init(led_control_t *led, gpio_num_t gpio, bool active_high) {
led_control_t *led:指向LED控制结构体的指针gpio_num_t gpio:GPIO引脚号bool active_high:LED激活电平 led->gpio = gpio;
led->active_high = active_high;
led->current_state = false;
// 配置GPIO
gpio_config_t io_conf = {};
io_conf.intr_type = GPIO_INTR_DISABLE;
io_conf.mode = GPIO_MODE_OUTPUT;
io_conf.pin_bit_mask = (1ULL << gpio);
io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE;
io_conf.pull_up_en = GPIO_PULLUP_DISABLE;
1ULL << gpio表示第gpio位为1 gpio_config(&io_conf);
// 初始状态为关闭
gpio_set_level(gpio, active_high ? 0 : 1);
ESP_LOGI(TAG, "LED control initialized on GPIO %d", gpio);
void led_turn_on(led_control_t *led) {
gpio_set_level(led->gpio, led->active_high ? 1 : 0);
led->current_state = true;
ESP_LOGI(TAG, "LED turned ON");
}
void led_turn_off(led_control_t *led) {
gpio_set_level(led->gpio, led->active_high ? 0 : 1);
led->current_state = false;
ESP_LOGI(TAG, "LED turned OFF");
}
void led_toggle(led_control_t *led) {
if (led->current_state) {
led_turn_off(led);
} else {
led_turn_on(led);
}
}
void led_set_state(led_control_t *led, bool state) {
if (state) {
led_turn_on(led);
} else {
led_turn_off(led);
}
}
bool state- true表示开启,false表示关闭bool led_get_state(led_control_t *led) {
return led->current_state;
}
void app_main(void) {
ESP_LOGI(TAG, "Starting LED control example");
// 创建LED控制对象
led_control_t led;
led_init(&led, GPIO_NUM_2, true); // GPIO2, 高电平有效
// 测试LED功能
ESP_LOGI(TAG, "Testing LED control...");
// 打开LED
led_turn_on(&led);
vTaskDelay(pdMS_TO_TICKS(1000));
// 关闭LED
led_turn_off(&led);
vTaskDelay(pdMS_TO_TICKS(1000));
// 切换LED状态
led_toggle(&led);
vTaskDelay(pdMS_TO_TICKS(1000));
// 设置LED状态
led_set_state(&led, true);
vTaskDelay(pdMS_TO_TICKS(1000));
// 获取LED状态
bool state = led_get_state(&led);
ESP_LOGI(TAG, "Current LED state: %s", state ? "ON" : "OFF");
// 循环闪烁
ESP_LOGI(TAG, "Starting LED blink loop...");
int count = 0;
while (1) {
led_toggle(&led);
ESP_LOGI(TAG, "LED blink count: %d", count++);
vTaskDelay(pdMS_TO_TICKS(500));
}