RT-Thread中mydev_control()函数设计应用与实践
在RT-Thread中,control函数是设备驱动框架中的一个重要接口,用于对设备进行控制。它类似于Linux中的ioctl函数,可以执行一系列设备特定的操作,例如配置设备参数、发送控制命令等。
函数原型:
rt_err_t (*control)(rt_device_t dev, int cmd, void *args);
参数:
dev: 设备句柄
cmd: 控制命令,由设备驱动定义
args: 控制参数,根据不同的命令传入不同的参数
设计mydev_control()函数时,我们需要考虑以下几个方面:
-
命令设计:定义一系列控制命令,通常使用宏定义,并确保每个命令有唯一的整数值。
-
参数设计:对于每个命令,确定其参数类型(可能是一个整数、一个结构体指针等)。
-
错误处理:对于无效命令或参数,返回错误码。
下面是一个示例,假设我们有一个LED设备,我们可以通过控制函数来开关LED、设置亮度、设置闪烁模式等。
步骤:
-
定义控制命令宏。
-
在驱动中实现control函数,根据cmd执行相应的操作。
-
在应用程序中通过rt_device_control()调用这些命令。
一、control()函数的核心地位
1. 在设备框架中的位置
struct rt_device_ops {
rt_err_t (*init)(rt_device_t dev);
rt_err_t (*open)(rt_device_t dev, rt_uint16_t oflag);
rt_err_t (*close)(rt_device_t dev);
rt_ssize_t (*read)(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size);
rt_ssize_t (*write)(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size);
rt_err_t (*control)(rt_device_t dev, int cmd, void *args); // ← 核心控制接口
};
2. 与FreeRTOS的对比
| 系统 | 类似功能 | 特点 |
|---|---|---|
| FreeRTOS | 任务通知、队列消息 | 分散,需要自行封装 |
| RT-Thread | control()函数 |
统一接口,标准化控制 |
二、control()函数设计模式
1. 基础模板
static rt_err_t mydev_control(rt_device_t dev, int cmd, void *args)
{
struct my_device *mydev = (struct my_device *)dev->user_data;
rt_err_t ret = RT_EOK;
RT_ASSERT(dev != RT_NULL);
RT_ASSERT(mydev != RT_NULL);
switch (cmd) {
/* 通用控制命令(所有设备都应支持) */
case RT_DEVICE_CTRL_SUSPEND: /* 挂起设备 */
ret = mydev_suspend(mydev);
break;
case RT_DEVICE_CTRL_RESUME: /* 恢复设备 */
ret = mydev_resume(mydev);
break;
case RT_DEVICE_CTRL_CLOSE: /* 准备关闭 */
ret = mydev_prepare_close(mydev);
break;
/* 设备特定控制命令 */
case MYDEV_CTRL_SET_MODE: /* 设置工作模式 */
ret = mydev_set_mode(mydev, *(uint32_t *)args);
break;
case MYDEV_CTRL_GET_STATUS: /* 获取状态 */
*(uint32_t *)args = mydev_get_status(mydev);
break;
/* 批量配置命令 */
case MYDEV_CTRL_CONFIG: /* 配置多个参数 */
ret = mydev_apply_config(mydev, (struct mydev_config *)args);
break;
default:
ret = -RT_EINVAL; /* 无效命令 */
rt_kprintf("Unknown control command: 0x%X\n", cmd);
break;
}
return ret;
}
2. 命令编码规范
A. 分层命令编码
/* RT-Thread标准命令 (0x00-0x7F) */ #define RT_DEVICE_CTRL_BASE 0x00 #define RT_DEVICE_CTRL_SUSPEND 0x01 #define RT_DEVICE_CTRL_RESUME 0x02 #define RT_DEVICE_CTRL_CLOSE 0x03 #define RT_DEVICE_CTRL_CONFIG 0x04 #define RT_DEVICE_CTRL_SET_BAUDRATE 0x05 #define RT_DEVICE_CTRL_GET_BAUDRATE 0x06 /* 设备类标准命令 (0x80-0xBF) */ #define CHAR_DEVICE_CTRL_BASE 0x80 #define CHAR_CTRL_FLUSH_RX 0x81 #define CHAR_CTRL_FLUSH_TX 0x82 #define BLOCK_DEVICE_CTRL_BASE 0x90 #define BLOCK_CTRL_ERASE_SECTOR 0x91 #define BLOCK_CTRL_GET_SECTOR_SIZE 0x92 /* 具体设备命令 (0xC0-0xFF) */ #define MYDEV_CTRL_BASE 0xC0 #define MYDEV_CTRL_SET_MODE (MYDEV_CTRL_BASE + 0x01) #define MYDEV_CTRL_GET_STATUS (MYDEV_CTRL_BASE + 0x02) #define MYDEV_CTRL_CALIBRATE (MYDEV_CTRL_BASE + 0x03) #define MYDEV_CTRL_SELF_TEST (MYDEV_CTRL_BASE + 0x04)
B. 命令位域设计(高级技巧)
/* 32位命令编码: [类型(8)][子类(8)][操作(8)][参数(8)] */
#define CMD_TYPE_SHIFT 24
#define CMD_SUB_SHIFT 16
#define CMD_OP_SHIFT 8
#define CMD_PARAM_SHIFT 0
/* 构建命令宏 */
#define MAKE_CMD(type, sub, op, param) \
(((type) << CMD_TYPE_SHIFT) | \
((sub) << CMD_SUB_SHIFT) | \
((op) << CMD_OP_SHIFT) | \
((param) << CMD_PARAM_SHIFT))
/* 解码宏 */
#define CMD_TYPE(cmd) (((cmd) >> CMD_TYPE_SHIFT) & 0xFF)
#define CMD_SUB(cmd) (((cmd) >> CMD_SUB_SHIFT) & 0xFF)
#define CMD_OP(cmd) (((cmd) >> CMD_OP_SHIFT) & 0xFF)
#define CMD_PARAM(cmd) ((cmd) & 0xFF)
/* 使用示例 */
#define DEV_TYPE_SENSOR 0x01
#define SENSOR_SUB_TEMP 0x01
#define OP_READ 0x01
#define PARAM_RAW 0x00
#define PARAM_FILTERED 0x01
#define SENSOR_READ_RAW MAKE_CMD(DEV_TYPE_SENSOR, SENSOR_SUB_TEMP, OP_READ, PARAM_RAW)
#define SENSOR_READ_FILTER MAKE_CMD(DEV_TYPE_SENSOR, SENSOR_SUB_TEMP, OP_READ, PARAM_FILTERED)
三、实际应用案例:智能传感器驱动
1. 完整传感器控制接口
/* sensor_driver.h */
#ifndef __SENSOR_DRIVER_H__
#define __SENSOR_DRIVER_H__
#include <rtthread.h>
#include <rtdevice.h>
/* 传感器类型 */
typedef enum {
SENSOR_TYPE_TEMPERATURE = 0x01,
SENSOR_TYPE_HUMIDITY = 0x02,
SENSOR_TYPE_PRESSURE = 0x03,
SENSOR_TYPE_LIGHT = 0x04,
SENSOR_TYPE_ACCEL = 0x05,
SENSOR_TYPE_GYRO = 0x06,
} sensor_type_t;
/* 传感器工作模式 */
typedef enum {
SENSOR_MODE_SLEEP = 0x00, /* 睡眠模式 */
SENSOR_MODE_STANDBY = 0x01, /* 待机模式 */
SENSOR_MODE_NORMAL = 0x02, /* 正常工作 */
SENSOR_MODE_HIGH_PREC = 0x03, /* 高精度模式 */
SENSOR_MODE_LOW_POWER = 0x04, /* 低功耗模式 */
SENSOR_MODE_FAST = 0x05, /* 快速模式 */
} sensor_mode_t;
/* 传感器配置结构 */
struct sensor_config {
sensor_mode_t mode; /* 工作模式 */
uint32_t sample_rate; /* 采样率 (Hz) */
uint32_t filter_coef; /* 滤波器系数 */
uint16_t range; /* 量程 */
uint8_t resolution; /* 分辨率 (位) */
uint8_t oversampling; /* 过采样倍数 */
};
/* 传感器数据 */
struct sensor_data {
float value; /* 测量值 */
float raw_value; /* 原始值 */
uint32_t timestamp; /* 时间戳 */
uint8_t status; /* 状态 */
uint8_t accuracy; /* 精度等级 (0-3) */
};
/* 传感器控制命令 */
#define SENSOR_CTRL_BASE 0xC000
/* 基础控制命令 */
#define SENSOR_CTRL_SET_MODE (SENSOR_CTRL_BASE + 0x01)
#define SENSOR_CTRL_GET_MODE (SENSOR_CTRL_BASE + 0x02)
#define SENSOR_CTRL_SET_SAMPLE_RATE (SENSOR_CTRL_BASE + 0x03)
#define SENSOR_CTRL_GET_SAMPLE_RATE (SENSOR_CTRL_BASE + 0x04)
#define SENSOR_CTRL_SET_RANGE (SENSOR_CTRL_BASE + 0x05)
#define SENSOR_CTRL_GET_RANGE (SENSOR_CTRL_BASE + 0x06)
/* 校准命令 */
#define SENSOR_CTRL_CALIBRATE_ZERO (SENSOR_CTRL_BASE + 0x10)
#define SENSOR_CTRL_CALIBRATE_SPAN (SENSOR_CTRL_BASE + 0x11)
#define SENSOR_CTRL_SAVE_CALIBRATION (SENSOR_CTRL_BASE + 0x12)
#define SENSOR_CTRL_LOAD_CALIBRATION (SENSOR_CTRL_BASE + 0x13)
/* 诊断命令 */
#define SENSOR_CTRL_SELF_TEST (SENSOR_CTRL_BASE + 0x20)
#define SENSOR_CTRL_GET_DIAGNOSTIC (SENSOR_CTRL_BASE + 0x21)
#define SENSOR_CTRL_RESET (SENSOR_CTRL_BASE + 0x22)
/* 高级功能命令 */
#define SENSOR_CTRL_ENABLE_INTERRUPT (SENSOR_CTRL_BASE + 0x30)
#define SENSOR_CTRL_DISABLE_INTERRUPT (SENSOR_CTRL_BASE + 0x31)
#define SENSOR_CTRL_SET_THRESHOLD (SENSOR_CTRL_BASE + 0x32)
#define SENSOR_CTRL_SET_ALARM (SENSOR_CTRL_BASE + 0x33)
/* 批量配置命令 */
#define SENSOR_CTRL_CONFIG_ALL (SENSOR_CTRL_BASE + 0x40)
#define SENSOR_CTRL_GET_CONFIG (SENSOR_CTRL_BASE + 0x41)
#endif /* __SENSOR_DRIVER_H__ */
2. 完整的control()实现
/* sensor_driver.c */
/* 传感器设备私有结构 */
struct sensor_device {
struct rt_device parent; /* 继承设备基类 */
/* 硬件接口 */
struct rt_i2c_bus_device *i2c;
rt_base_t int_pin;
/* 设备状态 */
sensor_mode_t mode;
struct sensor_config config;
rt_bool_t is_calibrated;
rt_bool_t is_initialized;
/* 数据缓冲区 */
struct sensor_data buffer[10];
rt_uint8_t buf_idx;
rt_mutex_t data_lock;
/* 校准数据 */
struct {
float offset;
float scale_factor;
float temperature_coef;
} calibration;
/* 中断处理 */
void (*data_ready_cb)(void *arg);
void *cb_arg;
};
/* 控制函数实现 */
static rt_err_t sensor_control(rt_device_t dev, int cmd, void *args)
{
struct sensor_device *sensor = (struct sensor_device *)dev->user_data;
rt_err_t ret = RT_EOK;
RT_ASSERT(dev != RT_NULL);
RT_ASSERT(sensor != RT_NULL);
switch (cmd) {
/* ========== RT-Thread标准命令 ========== */
case RT_DEVICE_CTRL_SUSPEND: {
/* 挂起设备:进入低功耗模式 */
ret = sensor_enter_sleep_mode(sensor);
if (ret == RT_EOK) {
rt_kprintf("[Sensor] Entered sleep mode\n");
}
break;
}
case RT_DEVICE_CTRL_RESUME: {
/* 恢复设备:唤醒 */
ret = sensor_wakeup(sensor);
if (ret == RT_EOK) {
rt_kprintf("[Sensor] Woke up from sleep\n");
}
break;
}
case RT_DEVICE_CTRL_CLOSE: {
/* 准备关闭:保存状态 */
ret = sensor_save_state(sensor);
break;
}
/* ========== 模式控制命令 ========== */
case SENSOR_CTRL_SET_MODE: {
sensor_mode_t new_mode = *(sensor_mode_t *)args;
if (new_mode >= SENSOR_MODE_SLEEP && new_mode <= SENSOR_MODE_FAST) {
ret = sensor_set_mode(sensor, new_mode);
if (ret == RT_EOK) {
sensor->mode = new_mode;
rt_kprintf("[Sensor] Mode changed to %d\n", new_mode);
}
} else {
ret = -RT_EINVAL;
}
break;
}
case SENSOR_CTRL_GET_MODE: {
*(sensor_mode_t *)args = sensor->mode;
break;
}
/* ========== 采样率控制 ========== */
case SENSOR_CTRL_SET_SAMPLE_RATE: {
uint32_t rate = *(uint32_t *)args;
if (rate >= 1 && rate <= 1000) { /* 1Hz到1000Hz */
rt_mutex_take(sensor->data_lock, RT_WAITING_FOREVER);
sensor->config.sample_rate = rate;
ret = sensor_apply_sample_rate(sensor, rate);
rt_mutex_release(sensor->data_lock);
if (ret == RT_EOK) {
rt_kprintf("[Sensor] Sample rate set to %d Hz\n", rate);
}
} else {
ret = -RT_EINVAL;
}
break;
}
case SENSOR_CTRL_GET_SAMPLE_RATE: {
*(uint32_t *)args = sensor->config.sample_rate;
break;
}
/* ========== 校准命令 ========== */
case SENSOR_CTRL_CALIBRATE_ZERO: {
/* 零位校准:参数为参考值 */
float reference = *(float *)args;
ret = sensor_calibrate_zero(sensor, reference);
if (ret == RT_EOK) {
sensor->is_calibrated = RT_TRUE;
rt_kprintf("[Sensor] Zero calibration completed\n");
}
break;
}
case SENSOR_CTRL_CALIBRATE_SPAN: {
/* 满量程校准 */
struct {
float zero_ref;
float span_ref;
} *cal = (struct { float zero_ref; float span_ref; } *)args;
ret = sensor_calibrate_span(sensor, cal->zero_ref, cal->span_ref);
if (ret == RT_EOK) {
sensor->is_calibrated = RT_TRUE;
rt_kprintf("[Sensor] Span calibration completed\n");
}
break;
}
case SENSOR_CTRL_SAVE_CALIBRATION: {
/* 保存校准数据到非易失存储 */
ret = sensor_save_calibration(sensor);
break;
}
case SENSOR_CTRL_LOAD_CALIBRATION: {
/* 从非易失存储加载校准数据 */
ret = sensor_load_calibration(sensor);
if (ret == RT_EOK) {
sensor->is_calibrated = RT_TRUE;
}
break;
}
/* ========== 诊断命令 ========== */
case SENSOR_CTRL_SELF_TEST: {
/* 自检:返回自检结果 */
uint32_t *result = (uint32_t *)args;
*result = sensor_self_test(sensor);
if (*result == 0) {
rt_kprintf("[Sensor] Self-test PASSED\n");
} else {
rt_kprintf("[Sensor] Self-test FAILED: 0x%08X\n", *result);
}
break;
}
case SENSOR_CTRL_GET_DIAGNOSTIC: {
/* 获取诊断信息 */
struct {
uint32_t error_code;
uint32_t operation_count;
uint32_t uptime;
uint8_t temperature;
} *diag = (struct {
uint32_t error_code;
uint32_t operation_count;
uint32_t uptime;
uint8_t temperature;
} *)args;
diag->error_code = sensor_get_error_code(sensor);
diag->operation_count = sensor_get_op_count(sensor);
diag->uptime = sensor_get_uptime(sensor);
diag->temperature = sensor_get_internal_temp(sensor);
break;
}
case SENSOR_CTRL_RESET: {
/* 软复位设备 */
ret = sensor_soft_reset(sensor);
if (ret == RT_EOK) {
rt_kprintf("[Sensor] Software reset completed\n");
}
break;
}
/* ========== 中断控制 ========== */
case SENSOR_CTRL_ENABLE_INTERRUPT: {
struct {
void (*callback)(void *);
void *arg;
} *int_cfg = (struct {
void (*callback)(void *);
void *arg;
} *)args;
sensor->data_ready_cb = int_cfg->callback;
sensor->cb_arg = int_cfg->arg;
ret = sensor_enable_interrupt(sensor, RT_TRUE);
break;
}
case SENSOR_CTRL_DISABLE_INTERRUPT: {
ret = sensor_enable_interrupt(sensor, RT_FALSE);
sensor->data_ready_cb = RT_NULL;
sensor->cb_arg = RT_NULL;
break;
}
case SENSOR_CTRL_SET_THRESHOLD: {
/* 设置阈值,用于报警 */
struct {
float low_threshold;
float high_threshold;
uint8_t hysteresis;
} *thr = (struct {
float low_threshold;
float high_threshold;
uint8_t hysteresis;
} *)args;
ret = sensor_set_threshold(sensor, thr->low_threshold,
thr->high_threshold, thr->hysteresis);
break;
}
/* ========== 批量配置 ========== */
case SENSOR_CTRL_CONFIG_ALL: {
/* 一次性配置所有参数 */
struct sensor_config *cfg = (struct sensor_config *)args;
if (cfg != RT_NULL) {
rt_mutex_take(sensor->data_lock, RT_WAITING_FOREVER);
/* 验证配置参数 */
if (sensor_validate_config(cfg) != RT_EOK) {
rt_mutex_release(sensor->data_lock);
return -RT_EINVAL;
}
/* 应用新配置 */
rt_memcpy(&sensor->config, cfg, sizeof(struct sensor_config));
ret = sensor_apply_config(sensor);
rt_mutex_release(sensor->data_lock);
if (ret == RT_EOK) {
rt_kprintf("[Sensor] Configuration applied successfully\n");
}
} else {
ret = -RT_EINVAL;
}
break;
}
case SENSOR_CTRL_GET_CONFIG: {
/* 获取当前配置 */
struct sensor_config *cfg = (struct sensor_config *)args;
if (cfg != RT_NULL) {
rt_mutex_take(sensor->data_lock, RT_WAITING_FOREVER);
rt_memcpy(cfg, &sensor->config, sizeof(struct sensor_config));
rt_mutex_release(sensor->data_lock);
} else {
ret = -RT_EINVAL;
}
break;
}
/* ========== 默认处理 ========== */
default: {
/* 尝试处理通用传感器命令 */
if (cmd >= SENSOR_CTRL_BASE && cmd < (SENSOR_CTRL_BASE + 0x100)) {
ret = sensor_handle_generic_command(sensor, cmd, args);
} else {
/* 未知命令 */
rt_kprintf("[Sensor] Unknown control command: 0x%08X\n", cmd);
ret = -RT_ENOSYS; /* 功能未实现 */
}
break;
}
}
/* 记录操作日志(可选) */
if (sensor_log_enabled) {
sensor_log_command(cmd, ret);
}
return ret;
}
3. 应用层调用示例
/* 应用层代码示例 */
/* 示例1:配置传感器 */
void configure_sensor_example(void)
{
rt_device_t sensor = rt_device_find("sensor1");
if (sensor == RT_NULL) return;
/* 打开设备 */
if (rt_device_open(sensor, RT_DEVICE_FLAG_RDWR) != RT_EOK) {
rt_kprintf("Failed to open sensor\n");
return;
}
/* 1. 单个参数配置 */
sensor_mode_t mode = SENSOR_MODE_HIGH_PREC;
rt_device_control(sensor, SENSOR_CTRL_SET_MODE, &mode);
uint32_t sample_rate = 100; /* 100Hz */
rt_device_control(sensor, SENSOR_CTRL_SET_SAMPLE_RATE, &sample_rate);
/* 2. 批量配置 */
struct sensor_config cfg = {
.mode = SENSOR_MODE_NORMAL,
.sample_rate = 50,
.filter_coef = 0x3F,
.range = 1000,
.resolution = 16,
.oversampling = 4,
};
rt_device_control(sensor, SENSOR_CTRL_CONFIG_ALL, &cfg);
/* 3. 校准 */
float zero_ref = 25.0f; /* 25°C参考温度 */
rt_device_control(sensor, SENSOR_CTRL_CALIBRATE_ZERO, &zero_ref);
/* 4. 设置中断回调 */
struct {
void (*callback)(void *);
void *arg;
} int_cfg = {
.callback = sensor_data_ready_callback,
.arg = (void *)sensor,
};
rt_device_control(sensor, SENSOR_CTRL_ENABLE_INTERRUPT, &int_cfg);
/* 5. 诊断 */
uint32_t self_test_result;
rt_device_control(sensor, SENSOR_CTRL_SELF_TEST, &self_test_result);
rt_kprintf("Self-test result: 0x%08X\n", self_test_result);
/* 关闭设备 */
rt_device_close(sensor);
}
/* 示例2:MSH命令行控制 */
static void sensor_cmd(int argc, char **argv)
{
static rt_device_t sensor = RT_NULL;
if (argc < 2) {
rt_kprintf("Usage:\n");
rt_kprintf("sensor open - Open sensor device\n");
rt_kprintf("sensor close - Close sensor device\n");
rt_kprintf("sensor mode <0-5> - Set working mode\n");
rt_kprintf("sensor rate <Hz> - Set sample rate\n");
rt_kprintf("sensor calibrate - Perform calibration\n");
rt_kprintf("sensor test - Run self-test\n");
rt_kprintf("sensor config - Show current config\n");
rt_kprintf("sensor sleep - Enter sleep mode\n");
rt_kprintf("sensor wake - Wake up from sleep\n");
return;
}
if (rt_strcmp(argv[1], "open") == 0) {
sensor = rt_device_find("sensor1");
if (sensor) {
rt_device_open(sensor, RT_DEVICE_FLAG_RDWR);
rt_kprintf("Sensor opened\n");
}
}
else if (rt_strcmp(argv[1], "close") == 0) {
if (sensor) {
rt_device_close(sensor);
rt_kprintf("Sensor closed\n");
}
}
else if (rt_strcmp(argv[1], "mode") == 0 && argc == 3) {
if (sensor) {
sensor_mode_t mode = atoi(argv[2]);
rt_device_control(sensor, SENSOR_CTRL_SET_MODE, &mode);
}
}
else if (rt_strcmp(argv[1], "rate") == 0 && argc == 3) {
if (sensor) {
uint32_t rate = atoi(argv[2]);
rt_device_control(sensor, SENSOR_CTRL_SET_SAMPLE_RATE, &rate);
}
}
else if (rt_strcmp(argv[1], "calibrate") == 0) {
if (sensor) {
float ref = 25.0f;
rt_device_control(sensor, SENSOR_CTRL_CALIBRATE_ZERO, &ref);
}
}
else if (rt_strcmp(argv[1], "test") == 0) {
if (sensor) {
uint32_t result;
rt_device_control(sensor, SENSOR_CTRL_SELF_TEST, &result);
rt_kprintf("Self-test: 0x%08X\n", result);
}
}
else if (rt_strcmp(argv[1], "config") == 0) {
if (sensor) {
struct sensor_config cfg;
rt_device_control(sensor, SENSOR_CTRL_GET_CONFIG, &cfg);
rt_kprintf("Mode: %d, Rate: %dHz, Range: %d\n",
cfg.mode, cfg.sample_rate, cfg.range);
}
}
else if (rt_strcmp(argv[1], "sleep") == 0) {
if (sensor) {
rt_device_control(sensor, RT_DEVICE_CTRL_SUSPEND, RT_NULL);
}
}
else if (rt_strcmp(argv[1], "wake") == 0) {
if (sensor) {
rt_device_control(sensor, RT_DEVICE_CTRL_RESUME, RT_NULL);
}
}
}
MSH_CMD_EXPORT(sensor_cmd, Sensor device control commands);
四、高级控制模式
1. 异步控制模式
/* 异步控制命令处理 */
static rt_err_t sensor_control_async(rt_device_t dev, int cmd, void *args)
{
struct sensor_device *sensor = (struct sensor_device *)dev->user_data;
/* 创建异步控制请求 */
struct async_control_request {
int cmd;
void *args;
rt_completion_t completion;
rt_err_t result;
} *req;
req = rt_malloc(sizeof(struct async_control_request));
if (req == RT_NULL) {
return -RT_ENOMEM;
}
req->cmd = cmd;
req->args = args;
rt_completion_init(&req->completion);
/* 发送到控制队列 */
if (rt_mq_send(sensor->control_queue, &req, sizeof(req)) != RT_EOK) {
rt_free(req);
return -RT_ERROR;
}
/* 等待完成(可设置超时) */
if (rt_completion_wait(&req->completion, 1000) != RT_EOK) {
rt_free(req);
return -RT_ETIMEOUT;
}
rt_err_t result = req->result;
rt_free(req);
return result;
}
/* 控制线程处理异步请求 */
static void sensor_control_thread(void *param)
{
struct sensor_device *sensor = (struct sensor_device *)param;
while (1) {
struct async_control_request *req;
/* 从队列接收请求 */
if (rt_mq_recv(sensor->control_queue, &req, sizeof(req),
RT_WAITING_FOREVER) == RT_EOK) {
/* 同步执行控制命令 */
req->result = sensor_control_sync(&sensor->parent, req->cmd, req->args);
/* 通知完成 */
rt_completion_done(&req->completion);
}
}
}
2. 命令链(Command Chain)模式
/* 批量执行多个命令 */
rt_err_t execute_command_chain(rt_device_t dev,
const struct command_entry *chain,
size_t count)
{
rt_err_t ret = RT_EOK;
for (size_t i = 0; i < count; i++) {
ret = rt_device_control(dev, chain[i].cmd, chain[i].args);
if (ret != RT_EOK) {
rt_kprintf("Command 0x%08X failed: %d\n", chain[i].cmd, ret);
/* 执行回滚命令链 */
if (chain[i].rollback_cmd != 0) {
rt_device_control(dev, chain[i].rollback_cmd, chain[i].rollback_args);
}
return ret;
}
}
return RT_EOK;
}
/* 命令链定义 */
static const struct command_entry sensor_init_chain[] = {
{SENSOR_CTRL_RESET, NULL, 0, NULL},
{SENSOR_CTRL_LOAD_CALIBRATION, NULL, SENSOR_CTRL_RESET, NULL},
{SENSOR_CTRL_SET_MODE, &mode_normal, SENSOR_CTRL_SET_MODE, &mode_sleep},
{SENSOR_CTRL_SET_SAMPLE_RATE, &rate_100hz, 0, NULL},
{SENSOR_CTRL_ENABLE_INTERRUPT, &int_cfg, SENSOR_CTRL_DISABLE_INTERRUPT, NULL},
};
五、实践和注意事项
1. 参数验证策略
static rt_err_t validate_control_parameters(int cmd, void *args)
{
switch (cmd) {
case SENSOR_CTRL_SET_SAMPLE_RATE: {
uint32_t *rate = (uint32_t *)args;
if (rate == RT_NULL) return -RT_EINVAL;
if (*rate < 1 || *rate > 1000) return -RT_EINVAL;
break;
}
case SENSOR_CTRL_SET_MODE: {
sensor_mode_t *mode = (sensor_mode_t *)args;
if (mode == RT_NULL) return -RT_EINVAL;
if (*mode > SENSOR_MODE_FAST) return -RT_EINVAL;
break;
}
/* ... 其他命令验证 */
}
return RT_EOK;
}
2. 线程安全设计
static rt_err_t sensor_control_thread_safe(rt_device_t dev, int cmd, void *args)
{
struct sensor_device *sensor = (struct sensor_device *)dev->user_data;
rt_err_t ret;
/* 根据命令类型选择合适的锁 */
if (cmd & 0x80000000) { /* 关键命令,需要互斥锁 */
rt_mutex_take(sensor->config_lock, RT_WAITING_FOREVER);
ret = sensor_control_internal(dev, cmd, args);
rt_mutex_release(sensor->config_lock);
} else { /* 普通命令,使用读写锁 */
rt_rwlock_rlock(sensor->data_lock);
ret = sensor_control_internal(dev, cmd, args);
rt_rwlock_runlock(sensor->data_lock);
}
return ret;
}
3. 错误码标准化
/* 扩展错误码 */
#define RT_SENSOR_ERROR_BASE 0x1000
#define RT_SENSOR_ERROR_CALIBRATION (RT_SENSOR_ERROR_BASE + 0x01)
#define RT_SENSOR_ERROR_OVER_RANGE (RT_SENSOR_ERROR_BASE + 0x02)
#define RT_SENSOR_ERROR_SELF_TEST (RT_SENSOR_ERROR_BASE + 0x03)
#define RT_SENSOR_ERROR_COMM (RT_SENSOR_ERROR_BASE + 0x04)
static const char* sensor_error_to_string(rt_err_t err)
{
switch (err) {
case RT_SENSOR_ERROR_CALIBRATION:
return "Calibration error";
case RT_SENSOR_ERROR_OVER_RANGE:
return "Measurement over range";
case RT_SENSOR_ERROR_SELF_TEST:
return "Self-test failed";
case RT_SENSOR_ERROR_COMM:
return "Communication error";
default:
return rt_strerror(err);
}
}
六、调试和测试
1. 控制命令日志
static void log_control_command(int cmd, void *args, rt_err_t result)
{
#ifdef SENSOR_DEBUG_CONTROL
static const char* cmd_names[] = {
[SENSOR_CTRL_SET_MODE] = "SET_MODE",
[SENSOR_CTRL_SET_SAMPLE_RATE] = "SET_SAMPLE_RATE",
/* ... */
};
const char* name = "UNKNOWN";
if (cmd >= 0 && cmd < sizeof(cmd_names)/sizeof(cmd_names[0])) {
if (cmd_names[cmd]) name = cmd_names[cmd];
}
rt_kprintf("[CTRL] %s (0x%08X) -> %s\n",
name, cmd,
result == RT_EOK ? "OK" : rt_strerror(result));
#endif
}
2. 自动化测试框架
void test_sensor_control_commands(void)
{
rt_device_t sensor = rt_device_find("sensor1");
TEST_ASSERT_NOT_NULL(sensor);
/* 测试用例1:基本功能 */
TEST_CASE("Basic control commands") {
sensor_mode_t mode;
/* 获取当前模式 */
TEST_CHECK(rt_device_control(sensor, SENSOR_CTRL_GET_MODE, &mode) == RT_EOK);
/* 设置新模式 */
sensor_mode_t new_mode = SENSOR_MODE_NORMAL;
TEST_CHECK(rt_device_control(sensor, SENSOR_CTRL_SET_MODE, &new_mode) == RT_EOK);
/* 验证设置成功 */
sensor_mode_t verify_mode;
rt_device_control(sensor, SENSOR_CTRL_GET_MODE, &verify_mode);
TEST_CHECK(verify_mode == new_mode);
}
/* 测试用例2:错误处理 */
TEST_CASE("Error handling") {
/* 测试无效参数 */
uint32_t invalid_rate = 2000; /* 超出范围 */
rt_err_t ret = rt_device_control(sensor, SENSOR_CTRL_SET_SAMPLE_RATE, &invalid_rate);
TEST_CHECK(ret == -RT_EINVAL);
/* 测试空指针 */
ret = rt_device_control(sensor, SENSOR_CTRL_SET_MODE, RT_NULL);
TEST_CHECK(ret == -RT_EINVAL);
}
}
总结
mydev_control()函数是RT-Thread设备驱动设计的核心,与FreeRTOS相比,它提供了:
-
标准化接口:统一的设备控制范式
-
灵活扩展性:通过命令码分层设计支持无限扩展
-
类型安全:参数通过void指针传递,但可以通过结构体确保类型安全
-
异步支持:可扩展为异步控制模式
对于有FreeRTOS经验的工程师,掌握control()函数的关键是:
-
理解命令编码策略
-
设计合理的参数结构
-
实现线程安全的控制逻辑
-
提供良好的错误处理和调试支持
这种设计模式虽然初期学习成本较高,但长期来看大幅提升了代码的可维护性和可扩展性,特别适合复杂的物联网设备开发。
openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。
更多推荐


所有评论(0)