5.22 Camera设备
2026/7/20大约 6 分钟设备驱动驱动Camera摄像头ESP32传感器
5.22 Camera设备
📚 本节导读
学习时长: 约 40 分钟
难度级别: ⭐⭐⭐⭐☆
前置知识: C 语言基础、摄像头基础知识、5.1 设备驱动框架
🎯 学习目标
- 理解 OneOS Camera 设备驱动的架构设计(SAL 传感器抽象层 + 驱动层)
- 掌握
camera_config_t配置结构体的各项参数 - 掌握帧缓冲
camera_fb_t的获取与归还机制 - 理解
sensor_t传感器抽象层的多态设计 - 掌握摄像头初始化、拍照、参数保存的完整流程
一、概述
Camera 摄像头设备是 OneOS 提供的图像采集驱动框架,基于 ESP32 摄像头驱动,支持 JPEG、RGB565、YUV422、Grayscale 等多种像素格式。驱动源码位于 drivers/camera/ 目录下,核心头文件为 camera.h,传感器抽象层位于 driver/include/sensor.h。
Camera 设备框架的特点:
- SAL 传感器抽象层:
sensor_t结构体封装了 28 个函数指针,实现多态传感器驱动 - 多格式支持:支持 JPEG、RGB565、YUV422、Grayscale 四种像素格式
- 帧缓冲管理:通过
camera_fb_t实现帧缓冲的获取与归还,支持多缓冲队列 - 双缓冲模式:
fb_count配置帧缓冲数量,支持双缓冲提高帧率 - NVS 持久化:支持将摄像头配置保存到 NVS(Non-Volatile Storage),实现参数持久化
二、核心数据结构
2.1 摄像头配置结构体 camera_config_t
typedef struct {
int pin_pwdn; /* 摄像头电源关闭引脚 */
int pin_reset; /* 摄像头复位引脚 */
int pin_xclk; /* 主时钟 XCLK 引脚 */
int pin_sscb_sda; /* SCCB (类I2C) SDA 引脚 */
int pin_sscb_scl; /* SCCB (类I2C) SCL 引脚 */
char *sscb_name; /* 命名的 I2C 总线名称 */
int pin_d7; /* 8位并行数据总线 D7 */
int pin_d6; /* D6 */
int pin_d5; /* D5 */
int pin_d4; /* D4 */
int pin_d3; /* D3 */
int pin_d2; /* D2 */
int pin_d1; /* D1 */
int pin_d0; /* D0 */
int pin_vsync; /* 垂直同步信号 */
int pin_href; /* 水平参考信号 */
int pin_pclk; /* 像素时钟 */
int xclk_freq_hz; /* XCLK 频率(Hz),如 20000000 */
pixformat_t pixel_format; /* 像素格式 */
framesize_t frame_size; /* 帧尺寸 */
int jpeg_quality; /* JPEG 质量(0-63,越小质量越高) */
size_t fb_count; /* 帧缓冲数量 */
camera_fb_location_t fb_location; /* 帧缓冲存储位置 */
camera_grab_mode_t grab_mode; /* 帧抓取模式 */
} camera_config_t;| 字段 | 说明 |
|---|---|
pin_pwdn / pin_reset | 摄像头电源与复位控制引脚 |
pin_xclk | 主时钟输出,典型值 20MHz |
pin_sscb_sda/scl | SCCB 配置接口(兼容 I2C 协议) |
pin_d7~d0 | 8 位并行数据总线 |
pin_vsync/href/pclk | 同步信号(垂直/水平/像素时钟) |
xclk_freq_hz | 主时钟频率,典型值 20000000 |
pixel_format | 像素格式枚举 |
frame_size | 帧尺寸枚举 |
jpeg_quality | JPEG 质量 0-63 |
fb_count | 帧缓冲数量,>1 启用双缓冲 |
fb_location | 缓冲区位置(PSRAM 或 DRAM) |
grab_mode | 抓取模式 |
2.2 抓取模式枚举
typedef enum {
CAMERA_GRAB_WHEN_EMPTY, /* 缓冲区为空时填充(省资源) */
CAMERA_GRAB_LATEST /* 始终保留最新的 fb_count 帧 */
} camera_grab_mode_t;2.3 帧缓冲位置枚举
typedef enum {
CAMERA_FB_IN_PSRAM, /* 帧缓冲位于外部 PSRAM */
CAMERA_FB_IN_DRAM /* 帧缓冲位于内部 DRAM */
} camera_fb_location_t;2.4 帧缓冲结构体 camera_fb_t
typedef struct {
uint8_t * buf; /* 像素数据指针 */
size_t len; /* 缓冲区长度(字节) */
size_t width; /* 图像宽度(像素) */
size_t height; /* 图像高度(像素) */
pixformat_t format; /* 像素格式 */
struct timeval timestamp; /* 帧时间戳 */
} camera_fb_t;| 字段 | 说明 |
|---|---|
buf | 指向像素数据的指针 |
len | 缓冲区字节长度 |
width/height | 图像分辨率 |
format | 像素格式 |
timestamp | 帧时间戳(自启动以来的时间) |
2.5 传感器抽象层 sensor_t
sensor_t 结构体封装了 28 个函数指针,实现多态传感器驱动,不同型号的摄像头传感器(如 OV2640、OV3660、OV5640 等)各自实现此接口。关键函数指针包括:
| 函数指针 | 说明 |
|---|---|
init / deinit | 传感器初始化与反初始化 |
set_pixformat | 设置像素格式(JPEG/RGB565/YUV422/Grayscale) |
set_framesize | 设置帧尺寸(QVGA/VGA/SVGA/XGA 等) |
set_contrast | 设置对比度 |
set_brightness | 设置亮度 |
set_saturation | 设置饱和度 |
set_quality | 设置 JPEG 质量 |
set_whitebal | 使能/禁用白平衡 |
set_gain_ctrl | 使能/禁用增益控制 |
set_exposure_ctrl | 使能/禁用曝光控制 |
set_hmirror / set_vflip | 水平镜像 / 垂直翻转 |
set_special_effect | 设置特殊效果(负片/灰度/棕褐色等) |
set_wb_mode | 设置白平衡模式(自动/晴天/阴天/荧光灯等) |
三、关键 API
3.1 摄像头初始化
os_err_t esp_camera_init(const camera_config_t* config);- config: 摄像头配置参数
- 返回:
OS_SUCCESS初始化成功
此函数通过 I2C 接口检测并配置摄像头,分配帧缓冲和 DMA 缓冲区,初始化并行 I2S 输入,设置 DMA 描述符。
3.2 摄像头反初始化
os_err_t esp_camera_deinit(void);3.3 获取帧缓冲
camera_fb_t* esp_camera_fb_get(void);- 返回: 帧缓冲指针,失败返回
NULL
3.4 归还帧缓冲
void esp_camera_fb_return(camera_fb_t * fb);3.5 获取传感器控制句柄
sensor_t * esp_camera_sensor_get(void);3.6 保存/加载配置到 NVS
os_err_t esp_camera_save_to_nvs(const char *key);
os_err_t esp_camera_load_from_nvs(const char *key);四、使用示例
4.1 摄像头初始化与拍照
#include <camera.h>
#include <device.h>
static camera_config_t camera_config = {
.pin_pwdn = 32,
.pin_reset = -1,
.pin_xclk = 0,
.pin_sscb_sda = 26,
.pin_sscb_scl = 27,
.pin_d7 = 35, .pin_d6 = 34, .pin_d5 = 39, .pin_d4 = 36,
.pin_d3 = 21, .pin_d2 = 19, .pin_d1 = 18, .pin_d0 = 5,
.pin_vsync = 25,
.pin_href = 23,
.pin_pclk = 22,
.xclk_freq_hz = 20000000,
.pixel_format = PIXFORMAT_JPEG,
.frame_size = FRAMESIZE_SVGA,
.jpeg_quality = 10,
.fb_count = 2,
.grab_mode = CAMERA_GRAB_WHEN_EMPTY,
};
void camera_capture_task(void *arg)
{
/* 1. 初始化摄像头 */
os_err_t ret = esp_camera_init(&camera_config);
if (ret != OS_SUCCESS)
{
os_kprintf("camera init failed!\r\n");
return;
}
/* 2. 获取传感器句柄,配置图像参数 */
sensor_t *sensor = esp_camera_sensor_get();
sensor->set_vflip(sensor, 1); /* 垂直翻转 */
sensor->set_hmirror(sensor, 1); /* 水平镜像 */
sensor->set_brightness(sensor, 2); /* 亮度 +2 */
while (1)
{
/* 3. 获取一帧图像 */
camera_fb_t *fb = esp_camera_fb_get();
if (fb == NULL)
{
os_kprintf("camera capture failed!\r\n");
os_task_msleep(100);
continue;
}
os_kprintf("Frame: %dx%d, format=%d, size=%d\r\n",
fb->width, fb->height, fb->format, fb->len);
/* 4. 处理图像数据(保存、发送等) */
process_image(fb->buf, fb->len);
/* 5. 归还帧缓冲 */
esp_camera_fb_return(fb);
os_task_msleep(1000); /* 每秒拍一张 */
}
}4.2 保存摄像头配置到 NVS
void camera_save_settings(void)
{
os_err_t ret = esp_camera_save_to_nvs("camera_config");
if (ret == OS_SUCCESS)
{
os_kprintf("camera settings saved to NVS\r\n");
}
}
void camera_load_settings(void)
{
/* 先加载 NVS 中的配置,再初始化摄像头 */
esp_camera_load_from_nvs("camera_config");
esp_camera_init(&camera_config);
}📝 本节小结
本节介绍了 OneOS 中 Camera 摄像头设备驱动的使用方法,包括:
- SAL 传感器抽象层:
sensor_t封装 28 个函数指针,实现多态传感器驱动 - 配置结构体:
camera_config_t涵盖硬件引脚、像素格式、帧尺寸、JPEG 质量等全部配置参数 - 帧缓冲机制:
esp_camera_fb_get()获取帧,esp_camera_fb_return()归还,支持多缓冲 - NVS 持久化:
esp_camera_save_to_nvs()/esp_camera_load_from_nvs()实现配置持久化
Camera 设备驱动框架适用于需要图像采集的嵌入式 IoT 设备,如智能摄像头、人脸识别终端、条码扫描器等。