模块间的交互强调高内聚低耦合,需要通过如下手段来实现
一、句柄化设计对外接口
提供不透明指针或抽象整数的句柄,如
typedef void* uart_handle_t; // 句柄(不透明指针)
typedef uint32_t sensor_handle_t; // 用哈希值作为句柄
提供句柄化操作接口,如
sensor_handle_t sensor_create(const char* type)
void sensor_destroy(sensor_handle_t handle)
二、模块功能接口抽象化
见下面实例
i2c_bus.h头文件实现
// i2c_bus.h(抽象接口定义)
typedef struct {
int (*init)(uint32_t bus_id, uint32_t baudrate);
int (*write)(uint32_t bus_id, uint8_t dev_addr, const uint8_t* data, uint32_t len);
int (*read)(uint32_t bus_id, uint8_t dev_addr, uint8_t* data, uint32_t len);
} i2c_bus_ops_t;
// 注册I2C接口(由I2C模块实现)
void i2c_bus_register_ops(const i2c_bus_ops_t* ops);
// 获取I2C接口(供其他模块使用)
const i2c_bus_ops_t* i2c_bus_get_ops(void);
i2c_bus.c实现
// i2c_bus.c(具体实现)
static const i2c_bus_ops_t i2c_ops = {
.init = i2c_hw_init,
.write = i2c_hw_write,
.read = i2c_hw_read,
};
void i2c_bus_init(void) {
i2c_bus_register_ops(&i2c_ops); // 注册接口
}
其它模块调用i2c
// sensor.c(传感器模块调用I2C模块)
#include "i2c_bus.h"
int sensor_init(void) {
const i2c_bus_ops_t* i2c_ops = i2c_bus_get_ops(); // 获取接口(无直接依赖)
if (!i2c_ops) return -1;
return i2c_ops->init(0, 400000); // 调用接口,不关心具体实现
}
三、事件驱动与回调机制
在模块间交互中,事件驱动(Event-Driven)与回调机制(Callback Mechanism) 通过 “发布 - 订阅” 模式实现解耦
事件驱动与回调机制通过以下方式解耦:
- 事件(Event):模块状态变化的抽象描述(如 “按键按下”“数据接收完成”),包含事件类型和相关数据;
- 发布者(Publisher):产生事件的模块(如按键模块),仅负责 “触发事件”,不关心谁会处理;
- 订阅者(Subscriber):关注特定事件的模块(如 LED、蜂鸣器模块),通过 “注册回调函数” 订阅事件;
- 回调函数(Callback):订阅者提供的函数,当事件发生时由发布者调用,实现对事件的响应。
核心逻辑:发布者与订阅者通过 “事件” 间接交互,发布者不知道订阅者的存在,订阅者也无需知道发布者的实现,两者仅依赖 “事件定义” 和 “回调接口”。
1808

被折叠的 条评论
为什么被折叠?



