嵌入式设计模式之策略模式(2)

张开发
2026/6/30 4:47:47 15 分钟阅读
嵌入式设计模式之策略模式(2)
场景描述假设有一个嵌入式设备需要与多种外部传感器通信如温湿度传感器、加速度计、显示屏这些传感器分别使用UART、I2C、SPI协议。设备需要根据当前连接的传感器类型动态选择通信协议。策略模式实现1. 定义策略接口通信协议通用接口// communication_strategy.h typedef struct { int (*init)(void); // 初始化协议 int (*send)(uint8_t *data, uint32_t len); // 发送数据 int (*receive)(uint8_t *buffer, uint32_t len); // 接收数据 void (*deinit)(void); // 释放资源 } CommunicationStrategy;2. 实现具体策略类UART/I2C/SPIUART策略实现// uart_strategy.c #include hal_uart.h static int uart_init(void) { return uart_initialize(115200, UART_PARITY_NONE); // 初始化UART } static int uart_send(uint8_t *data, uint32_t len) { return uart_transmit(data, len); // UART发送数据 } static int uart_receive(uint8_t *buffer, uint32_t len) { return uart_receive(buffer, len); // UART接收数据 } static void uart_deinit(void) { uart_deinitialize(); // 关闭UART } // UART策略对象 const CommunicationStrategy uart_strategy { uart_init, uart_send, uart_receive, uart_deinit };I2C策略实现// i2c_strategy.c #include hal_i2c.h static int i2c_init(void) { return i2c_configure(I2C_SPEED_100KHZ); // 初始化I2C } static int i2c_send(uint8_t *data, uint32_t len) { return i2c_write(SENSOR_ADDRESS, data, len); // I2C发送需设备地址 } static int i2c_receive(uint8_t *buffer, uint32_t len) { return i2c_read(SENSOR_ADDRESS, buffer, len); // I2C接收 } static void i2c_deinit(void) { i2c_disable(); } // I2C策略对象 const CommunicationStrategy i2c_strategy { i2c_init, i2c_send, i2c_receive, i2c_deinit };SPI策略实现// spi_strategy.c #include hal_spi.h static int spi_init(void) { return spi_configure(SPI_MODE_0, 1000000); // 初始化SPI } static int spi_send(uint8_t *data, uint32_t len) { spi_select_device(DEVICE_CS); // 片选使能 int ret spi_transmit(data, len); spi_deselect_device(DEVICE_CS); // 片选禁用 return ret; } static int spi_receive(uint8_t *buffer, uint32_t len) { spi_select_device(DEVICE_CS); int ret spi_receive(buffer, len); spi_deselect_device(DEVICE_CS); return ret; } static void spi_deinit(void) { spi_disable(); } // SPI策略对象 const CommunicationStrategy spi_strategy { spi_init, spi_send, spi_receive, spi_deinit };3. 上下文类通信管理器// communication_manager.c typedef struct { const CommunicationStrategy *strategy; // 当前使用的协议策略 } CommunicationManager; // 设置通信策略 void comm_set_strategy(CommunicationManager *mgr, const CommunicationStrategy *strategy) { if (mgr-strategy) { mgr-strategy-deinit(); // 先释放当前协议资源 } mgr-strategy strategy; mgr-strategy-init(); // 初始化新协议 } // 发送数据委托给当前策略 int comm_send_data(CommunicationManager *mgr, uint8_t *data, uint32_t len) { if (mgr-strategy) { return mgr-strategy-send(data, len); } return -1; // 错误未设置策略 } // 接收数据 int comm_receive_data(CommunicationManager *mgr, uint8_t *buffer, uint32_t len) { if (mgr-strategy) { return mgr-strategy-receive(buffer, len); } return -1; }使用示例int main() { CommunicationManager comm_mgr {0}; uint8_t tx_data[] {0x01, 0x02, 0x03}; uint8_t rx_data[10]; // 场景1连接温湿度传感器使用I2C comm_set_strategy(comm_mgr, i2c_strategy); comm_send_data(comm_mgr, tx_data, sizeof(tx_data)); comm_receive_data(comm_mgr, rx_data, sizeof(rx_data)); // 场景2切换至GPS模块使用UART comm_set_strategy(comm_mgr, uart_strategy); comm_send_data(comm_mgr, tx_data, sizeof(tx_data)); // 场景3连接显示屏使用SPI comm_set_strategy(comm_mgr, spi_strategy); comm_send_data(comm_mgr, tx_data, sizeof(tx_data)); return 0; }策略模式在此场景的优势协议透明性上层应用无需关心底层是UART、I2C还是SPI。运行时动态切换根据外设热插拔或模式变化实时切换协议。易于扩展新增协议如CAN、USB只需实现策略接口无需修改现有代码。资源管理策略切换时自动处理硬件初始化/释放避免资源冲突。典型应用场景多模通信设备如同时支持蓝牙、Wi-Fi、LoRa的物联网网关。传感器融合系统需要交替读取不同协议传感器的数据。协议适配器兼容不同厂家设备的通信协议。这种设计特别适合嵌入式中间件或硬件抽象层HAL的开发

更多文章