当前位置: 首页 > news >正文

嵌入式软件的几种程序架构

嵌入式软件的程序架构是其设计的核心,它决定了代码的组织方式、可维护性、可扩展性以及资源利用效率。下面详细介绍几种主流的嵌入式软件程序架构,从简单到复杂,并分析其优缺点和适用场景。

一、前后台系统(超级循环架构)

这是最简单、最常见的嵌入式程序架构,尤其适用于资源极度受限的单片机系统。

实现方式:

int main(void) {// 初始化    init_all();while(1) {// 前台任务       task1();task2();task3();// 后台中断处理        // 由硬件中断自动完成    }
}

优点:

  • 简单直观,易于理解和实现

  • 资源占用极少,无额外开销

  • 适合逻辑简单的控制任务

缺点:

  • 任务之间无优先级,响应性差

  • 长时间任务会阻塞整个系统

  • 可维护性差,任务耦合度高

适用场景:

  • 8位、16位单片机

  • 任务量少、逻辑简单的系统

  • 对成本极度敏感的场合

二、时间片轮询架构

在超级循环的基础上引入了简单的时间片调度,提高了任务执行的合理性。

实现方式:

typedef struct {void (*task)(void); // 任务函数   uint32_t interval;  // 执行间隔   uint32_t last_run;  // 上次执行时间task_t;task_t tasks[] = { {task1, 10, 0}, {task2, 20, 0}, {task3, 50, 0}};void scheduler(void) {uint32_t current_time = get_tick_count();for (int i = 0; i < TASK_COUNT; i++) {if(current_time - tasks[i].last_run >= tasks[i].interval) {tasks[i].task();tasks[i].last_run = current_time;}}}

优点:

  • 相对简单,资源开销小

  • 任务调度更加合理

  • 可以控制任务执行频率

缺点:

  • 仍然无法实现真正的优先级

  • 实时性有限

  • 长时间任务仍会影响其他任务

适用场景:

  • 任务执行周期相对固定的系统

  • 对实时性要求不高的场合

  • 资源有限的32位单片机

三、实时操作系统(RTOS)架构

使用实时操作系统进行任务调度,是嵌入式开发的重要发展方向。

基于FreeRTOS的实现:

void task1(void *params) {while(1) {// 任务1处理vTaskDelay(100 / portTICK_PERIOD_MS);}
}void task2(void *params) {while(1) {// 任务2处理vTaskDelay(200 / portTICK_PERIOD_MS);}
}int main(void) {// 初始化init_all();// 创建任务xTaskCreate(task1, "Task1", 128, NULL, 2, NULL);xTaskCreate(task2, "Task2", 128, NULL, 1, NULL);// 启动调度器vTaskStartScheduler();return 0;
}

优点:

  • 真正的多任务,支持优先级

  • 优秀的实时响应特性

  • 提高代码的可维护性和可扩展性

缺点:

  • 需要额外的资源开销(ROM、RAM)

  • 学习曲线相对陡峭

  • 增加了系统复杂度

适用场景:

  • 复杂的多任务系统

  • 对实时性要求高的场合

  • 资源相对丰富的32位单片机

四、事件驱动架构

基于状态机或事件队列的架构,适合处理大量的异步事件。

状态机实现示例:

typedef enum {STATE_IDLE,STATE_RUNNING,STATE_PAUSED,STATE_ERROR
} system_state_t;typedef enum {EVT_START,EVT_STOP,EVT_PAUSE,EVT_RESUME,EVT_ERROR
} event_t;void state_machine(event_t event) {static system_state_t current_state = STATE_IDLE;switch(current_state) {case STATE_IDLE:if(event == EVT_START) {start_operation();current_state = STATE_RUNNING;}break;case STATE_RUNNING:if(event == EVT_STOP) {stop_operation();current_state = STATE_IDLE;} else if(event == EVT_PAUSE) {pause_operation();current_state = STATE_PAUSED;}break;// 其他状态处理...}
}

优点:

  • 适合处理复杂的异步事件

  • 状态清晰,易于调试

  • 资源利用率高

缺点:

  • 状态过多时复杂度高

  • 需要仔细设计状态转换

适用场景:

  • 通信协议处理

  • 用户界面交互

  • 复杂的业务流程控制

五、面向对象/组件化架构

这是一种设计思想,可以与上述任何一种架构结合使用,尤其是在中大型嵌入式项目中。

核心思想:使用 C 语言的结构体和函数指针来模拟 C++ 的类和对象,将硬件和外设抽象成独立的、可复用的“驱动”或“组件”。

实现方式

定义一个结构体,包含该“对象”的数据(属性)和操作这些数据的函数指针(方法)。通过创建该结构体的实例(对象)来使用它。

// led.h - LED "类"的定义
typedef struct {GPIO_TypeDef *port;uint16_t pin;void (*on)(void);void (*off)(void);void (*toggle)(void);
} Led_TypeDef;// 构造函数
void Led_Init(Led_TypeDef *led, GPIO_TypeDef *port, uint16_t pin);// led.c
static void _led_on(Led_TypeDef *this) {HAL_GPIO_WritePin(this->port, this->pin, GPIO_PIN_SET);
}
// ... 其他静态函数void Led_Init(Led_TypeDef *led, GPIO_TypeDef *port, uint16_t pin) {led->port = port;led->pin = pin;led->on = _led_on;led->off = _led_off;led->toggle = _led_toggle;
}// main.c
Led_TypeDef led1, led2;
int main(void) {// ... 初始化Led_Init(&led1, GPIOA, GPIO_PIN_5);Led_Init(&led2, GPIOC, GPIO_PIN_13);while (1) {led1.toggle(); // 使用对象的方法led2.on();HAL_Delay(500);}
}

优点

  • 高内聚、低耦合:代码模块化程度高,易于复用和维护。

  • 隐藏实现细节:使用者只需关心接口,无需了解底层硬件操作。

  • 易于测试:可以方便地进行单元测试和模拟。

缺点

  • 代码结构稍复杂:引入了间接的函数调用。

  • 需要良好的设计:设计不当会导致过度工程化。

适用场景

中大型项目、产品线需要硬件平台迁移或驱动复用的场合。

六、如何选择合适的程序架构

考虑因素一:硬件资源

资源极度受限(Flash < 16KB,RAM < 2KB):
推荐使用前后台系统或简单的时间片轮询,避免RTOS带来的额外开销。

资源中等(Flash 16-64KB,RAM 2-8KB):
可以根据复杂度选择时间片轮询或轻量级RTOS,如FreeRTOS、μC/OS等。

资源丰富(Flash > 64KB,RAM > 8KB):
优先考虑RTOS架构,提高系统的可维护性和扩展性。

考虑因素二:实时性要求

实时性要求不高:
前后台系统或时间片轮询可以满足需求。

有硬实时要求:
必须使用RTOS,并合理设置任务优先级。

考虑因素三:系统复杂度

简单控制系统:
选择前后台系统,快速开发。

中等复杂度:
时间片轮询或简单RTOS。

复杂系统:
RTOS配合状态机或事件驱动架构。

考虑因素四:团队能力和开发周期

团队经验不足、周期紧张:
选择熟悉的简单架构,降低风险。

团队技术能力强、周期充足:
可以选择更先进的架构,为后续维护和扩展打好基础。

七、实际项目中的混合架构

在实际项目中,经常采用混合架构来平衡各种需求:

// RTOS + 状态机的混合架构示例
void high_priority_task(void *params) {// 高优先级实时任务while(1) {// 处理紧急事件}
}void state_machine_task(void *params) {// 状态机任务while(1) {process_events();vTaskDelay(10 / portTICK_PERIOD_MS);}
}void background_tasks(void *params) {// 低优先级后台任务while(1) {// 数据处理、日志记录等vTaskDelay(1000 / portTICK_PERIOD_MS);}
}

八、总结

架构复杂度实时性资源占用适用场景
前后台系统极低简单控制、8/16位MCU、成本敏感
时间片轮询中低任务周期固定、执行时间短
RTOS中高复杂多任务、高实时性、32位MCU
面向对象/组件化设计思想取决于底层架构略有增加中大型项目、强调可维护性和复用性
  1. 先评估项目需求:任务数量、实时性要求、硬件资源(CPU主频、RAM、Flash)、团队技术栈、项目工期。

  2. “杀鸡勿用牛刀”:对于简单应用,前后台或时间片轮询是最经济高效的选择。

  3. 拥抱复杂性:当系统需要处理多个不相关且时序要求严格的事件时,RTOS 是必然选择。

  4. 考虑长期维护:对于需要长期开发和维护的产品,采用组件化设计思想,即使是在 RTOS 或时间片轮询之上,也会带来巨大好处。

在实际项目中,这些架构也常常是混合使用的。例如,在 RTOS 中,每个任务内部可能使用一个小型的状态机;整个软件的驱动层采用组件化设计,而应用层则使用 RTOS 的任务进行管理。

http://www.dtcms.com/a/564978.html

相关文章:

  • 网站开发适合女生吗网页设计程序代码
  • 某游戏大厂的常用面试问题解析:Netty 与 NIO
  • 网站建设去哪可接单做押韵句子的网站
  • Memos:一款不打扰的笔记工具,使用cpolar远程后体验再升级
  • Uni APP中关于Android原生插件UniComponent的使用
  • Hadess零基础学习,如何管理Docker制品
  • 石家庄购物网站排名网站检测器
  • 《嵌入式硬件(二十):基于IMX6ULL的LCD操作》
  • 日志系统设计 与 策略模式实现
  • 电子规划书商务网站建设城市分站cms
  • 【android驱动开发十三】内核常见的十种死机类型
  • Flutter 移动端性能优化指南:内存、电量与 UI 渲染
  • 广告网站建设网wordpress登录更改域名后
  • 【JUnit实战3_25】第十五章:表现层测试(上)—— HtmlUnit 在网页测试中的用法
  • OpenComic,一款跨平台的漫画阅读器
  • 基于springboot的社区疫情物资管理系统的设计与实现(代码+数据库+LW)
  • 3.3V与5V电平转换方法、电路原理分析
  • python mysql-connector、PyMySQL基础
  • 【Javascript】如何硬拷贝一个数组?
  • 少儿编程不止学技术:6 大学习习惯的蜕变与思维能力的跃迁
  • 自动驾驶运动规划 | 基于自行车模型的运动学模型和横向动力学模型详细推导图解
  • 软文营销的技巧有哪些网站建设和优化内容最重要性
  • 我局在网站建设方面wordpress 搜索没反应
  • C语言基础之函数指针4
  • 深入浅出 Java 虚拟机之进阶部分
  • 医疗保健|医疗养老|基于Java+vue的医疗保健系统(源码+数据库+文档)
  • 网站建设方案书组网方案网站攻击
  • Python循环
  • 基于自适应傅里叶分解(AFD)及其改进算法的信号分解与重构实现
  • Linux Shell awk