基于stm分发器框架设计(裸机)

发布时间:2026/6/15 12:18:06

基于stm分发器框架设计(裸机) 本期带来的框架是分发器框架什么是分发器框架呢就好比一条只能针对一条任务比如说 0x01 针对的是led的开启的动作 然后可以通过串口发送按键触发等等所有能进行输入的设备都可以对分发器进行一个触发的动作。具体的思路有点类似于注册回调然后判断该指令是否下发做对应的函数功能分发器具体的优点是可扩展性和低耦合,这两个主要的优点可以让所有的动作都加入到指令中去。.h #ifndef __ KEY__H__ #define __ KEY__H__ #include stm32f10x.h #include stdlib.h #include stdio.h #include stdint.h //分发器的状态结构体 typedef enum { CMD_SUCCESS 0, CMD_ERR_INVALID_ID -1, CMD_ERR_INVALID_PAYLOAD -2, CMD_ERR_HANDLER_FAILED -3, }CMD_em; typedef int (*cmd_handler_fn)(const uint8_t *payload, uint16_t payload_len); //分发器的主要数据结构体 typedef struct { uint16_t cmd_id; cmd_handler_fn handler; const char *cmd_name; }cmd_entry_t; //命令处理函数类型定义 /* 分发器接口 */ CMD_em dispatcher_init(const cmd_entry_t *table, uint16_t count); CMD_em dispatcher_handle(uint16_t cmd_id, const uint8_t *payload, uint16_t len); #endif.c #include KEY.h static const cmd_entry_t *cmd_table NULL; static uint16_t cmd_count 0; CMD_em dispatcher_init(const cmd_entry_t *table, uint16_t count) { if (table NULL || count 0) { return CMD_ERR_HANDLER_FAILED; } cmd_table table; cmd_count count; return CMD_SUCCESS; } CMD_em dispatcher_handle(uint16_t cmd_id, const uint8_t *payload, uint16_t len) { if (cmd_table NULL || cmd_count 0) { return CMD_ERR_HANDLER_FAILED; } for (int i 0; i cmd_count; i) { if (cmd_table[i].cmd_id cmd_id) { return cmd_table[i].handler(payload, len); } } return CMD_ERR_HANDLER_FAILED; }可以从.c程序中看出来这个框架的代码量还是比较少的但是可扩展性还是比较强的再优化一下就是可以是一个通用的事件驱动的框架。//主函数 #include stm32f10x.h #include usart.h #include KEY.h #include LED.h #include Delay.h UART_QUEN uart_quen; int LED_callback(const uint8_t *payload,uint16_t payload_len) { printf(LED_callback\r\n); GPIO_WriteBit(GPIOB, GPIO_Pin_0, Bit_RESET); return CMD_SUCCESS; } int KEY_callback(const uint8_t *payload,uint16_t payload_len) { GPIO_WriteBit(GPIOB, GPIO_Pin_0, Bit_SET); printf(KEY_callback\r\n); return CMD_SUCCESS; } cmd_entry_t cmd_table[] { { .cmd_id 1, .handler LED_callback, .cmd_name CMD1 }, { .cmd_id 2, .handler KEY_callback, .cmd_name CMD2 }, }; uint8_t data; int main(void) { SysTick_Config(SystemCoreClock / 1000); UART_init(115200); UART_QUEN_Init(uart_quen); led_init(); dispatcher_init(cmd_table, 2); printf(Stm32 start\r\n); while (1) { if(UART_QUEN_GET(uart_quen,data) UART_QUEN_OK) { dispatcher_handle(data, NULL, 0); } } // key_init(); // event_st event; // printf(Event Start : \r\n); // while(1) // { // /* 从事件队列中取事件 */ // if(quent_pop(key_queue, event) quent_OK) // { // if(event.event_name KEY1_EVENT event.event_flag KEY1_PRESS) // { // printf(key_event START\r\n); // } // } // } } void USART1_IRQHandler(void) { uint8_t rx_data; while (USART_GetITStatus(USART1, USART_IT_RXNE) ! RESET) { rx_data USART_ReceiveData(USART1); while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) RESET); USART_SendData(USART1, rx_data); UART_QUEN_ADD(uart_quen, rx_data); } USART_ClearITPendingBit(USART1, USART_IT_RXNE); if (USART_GetITStatus(USART1, USART_IT_IDLE) ! RESET) { volatile uint32_t tmp USART1-SR; tmp USART1-DR; (void)tmp; USART_ClearITPendingBit(USART1, USART_IT_IDLE); } }从主函数的代码中我们看这里我们创建了两个指令 分别表示 led的开和关 当我们通过串口的接收中断 接收到我们发送给 单片机的指令后 把它加入到环形队列中去然后去环形队列中进行读取 并对读取出来的指令发给分发器的解析函数进行解析 通过查找创建的指令是否于接收的指令相同 相同则成功运行其处理函数。以上是关于分发器框架的具体的一个实现鉴于笔者的能力有限请多多包涵。开源地址https://github.com/yh2004915/STM32-Based-Dispatcher-Framework-Design

相关新闻