这几个嵌入式软件架构,能胜任90%的项目了。

原创 无际单片机编程 2025-03-27 07:50

关注公众号,回复“入门资料”获取单片机入门到高级开挂教程

 开发板带你入门,我们带你飞

文 | 无际(微信:2777492857)

全文约4501字,阅读大约需要 15 分钟

雷猴啊~我是无际。

我还记得当年刚踏入嵌入式开发领域的时候,对软件架构完全没有概念。写代码想到哪写到哪,最后拼凑成一个能跑的程序。

          

但随着项目越来越复杂,代码也越来越臃肿,维护起来简直就是一场噩梦。改动一个小功能,都要提心吊胆,生怕把其他地方搞崩了。

          

工作大概4年左右,有幸接接手了大牛做的项目维护,感觉他的功底深不可测,能把复杂的系统拆解成一个个清晰的模块,而且封装得也挺复杂,当时看还挺复杂,挺不解,写这么复杂干吊?看起来头疼。

          

后面自己独立做复杂点的项目,才发现他的架构是真香,因此吸收了很多他的思路和架构。

          

          

如果你也想提升自己的代码质量,那么这篇文章就是为你准备的!我会用最通俗易懂的语言,带你了解嵌入式软件开发中常见的几种架构模式,让你摆脱“面向过程编程”的原始状态,掌握“面向架构编程”的高级技巧。

          

无论你是初入茅庐的新手,还是想进阶提升的老鸟,这篇文章都能帮你打造更清晰、更稳定、更易维护的嵌入式系统。

          

好了,废话不多说,我们直接进入主题。

          

    

1. 轮询(Polling)架构:简单直接,但容易阻塞

轮询架构是最简单、最基础的架构模式,就像一个不知疲倦的“巡逻员”,不停地循环检查各个任务的状态,哪个任务需要执行就执行哪个。

          

基本原理:

轮询架构的核心是一个无限循环(while(1)),在循环中按照一定的顺序依次执行各个任务模块。每个任务模块通常是一个函数,执行完成后立即返回,继续执行下一个任务。

          

代码示例:

void task1() {  // 任务1的代码}void task2() {  // 任务2的代码}int main() {  while (1  {    task1();    task2();    // ... 其他任务  }  return 0;}


适用场景:

任务比较简单,实时性要求不高。

系统资源非常有限,无法支持更复杂的架构。

初学者学习和理解嵌入式编程的入门架构。

          

优缺点:

优点: 简单易懂,易于实现,代码量少。

缺点: 响应速度慢,所有任务共享CPU时间,容易出现“任务饥饿”现象(某个任务一直得不到执行);如果某个任务执行时间过长,会阻塞其他任务的执行。

          

实战避坑

尽量让每个任务的执行时间短,避免长时间占用CPU。

可以调整任务的执行顺序,将优先级较高的任务放在前面执行,以提高响应速度。

轮询架构适合简单的控制逻辑和数据采集,但不适合复杂的实时系统。

          

2. 中断(Interrupt)架构:快速响应,但需要谨慎管理

中断架构是一种基于事件驱动的简易架构模式,当外部事件发生时,会触发中断,CPU暂停当前任务,立即执行中断服务程序(ISR)。

          

基本原理:    

中断架构将任务分为“前台任务”和“后台任务”。后台任务在主循环中执行,前台任务(即中断服务程序)在中断发生时执行。

          

代码示例:

// 中断服务程序void EXTI0_IRQHandler() {  if (EXTI_GetITStatus(EXTI_Line0) != RESET)   {    // 处理中断事件    EXTI_ClearITPendingBit(EXTI_Line0);  }}int main() {  // 初始化中断  // ...  while (1  {    // 后台任务  }  return 0;}

          

适用场景:

需要快速响应外部事件,如按键按下、传感器数据变化等。

系统有严格的实时性要求。

外部设备需要实时监控,例如串口接收数据。    

          

优缺点:

优点: 响应速度快,能及时处理紧急事件;CPU利用率高,可以在后台执行其他任务。

缺点: 中断服务程序应该尽可能短,避免长时间占用CPU;中断嵌套管理复杂,容易导致中断优先级反转等问题。

          

实战避坑:

中断服务程序要“短小精悍”,只做最必要的工作,其他耗时操作交给后台任务处理。

合理设置中断优先级,避免高优先级的中断被低优先级的中断阻塞。

避免在中断服务程序中使用阻塞函数,如delay(),printf()等。

          

3. 状态机(State Machine)架构:逻辑清晰,但容易“状态爆炸”

          

状态机架构是一种将系统划分为多个状态,并根据输入事件在不同状态之间进行转换的架构模式。

          

基本原理:

状态机将系统抽象成有限个状态,每个状态下有特定的行为和转移条件。通过状态转移图或表来管理状态间的转换。

          

代码示例:

typedef enum {  STATE_IDLE,  STATE_RUNNING,  STATE_ERROR} State_t;State_t currentState = STATE_IDLE;void stateMachine() {  switch (currentState)   {    case STATE_IDLE:      if (startCondition)       {        currentState = STATE_RUNNING;      }      break;    case STATE_RUNNING:      if (errorCondition)       {        currentState = STATE_ERROR;      }      break;    case STATE_ERROR:      // 处理错误      break;  }}int main() {  while (1  {    stateMachine();    // ... 其他任务  }  return 0;}

          

适用场景:

系统有明显的“状态”概念,如通信协议、控制系统、用户界面、不同的模式等。

逻辑比较复杂,需要清晰的状态管理。

需要明确的流程控制,例如按键检测,电梯运行等。

          

优缺点:

优点: 逻辑清晰,易于维护和扩展;能有效管理复杂的状态转移。

缺点: 状态过多时,代码量会急剧增加,维护成本高;状态转移逻辑错误容易导致“死循环”等问题。

          

实战避坑:

在编写代码之前,先画好状态转移图,明确每个状态的行为和转移条件。

尽量减少状态的数量,避免“状态爆炸”。

可以使用状态机框架或工具来简化开发,例如UML状态机图。

          

4. 实时操作系统(RTOS)架构:多任务并行,但需要更多资源

实时操作系统(RTOS)是一种专门用于嵌入式系统的操作系统,它提供了任务调度、任务间通信、资源管理等功能,让开发者可以像编写PC程序一样编写嵌入式软件。

          

基本原理:

RTOS提供任务调度器,可以将系统划分为多个独立的任务(线程),每个任务都有自己的优先级和栈空间。RTOS负责调度这些任务,让它们并行执行。

          

代码示例(以FreeRTOS为例):

#include "FreeRTOS.h"#include "task.h"void task1(void *pvParameters) {  while (1  {    // 任务1的代码    vTaskDelay(100 / portTICK_PERIOD_MS); // 延时100ms  }}void task2(void *pvParameters) {  while (1  {    // 任务2的代码    vTaskDelay(200 / portTICK_PERIOD_MS); // 延时200ms  }}int main() {  xTaskCreate(task1, "Task1"128NULL1NULL);  xTaskCreate(task2, "Task2"128NULL2NULL);  vTaskStartScheduler();  return 0;}


          

适用场景:

系统功能复杂,需要多个任务并行执行。

对实时性和响应速度有较高要求。

需要复杂的任务管理和资源管理。

          

优缺点:

优点: 任务管理灵活,易于实现复杂功能;提高系统响应速度;可以有效利用CPU资源。

缺点: 资源消耗较大,不适合资源受限的单片机;学习成本高;需要考虑任务同步和互斥等问题。

          

实战避坑:

根据项目和应用场景选择合适的RTOS,如FreeRTOS、uC/OS等。

合理分配任务优先级和栈空间,避免任务冲突和栈溢出。

使用信号量、互斥锁等机制进行任务间通信和资源保护。

避免在中断服务程序中调用RTOS API。

          

5. 混合架构:灵活应对,但需要精心设计

在实际开发中,单一的架构模式往往难以满足所有需求,因此经常会采用混合架构,将多种架构模式结合起来使用。例如,“轮询 + 中断”、“状态机 + RTOS”等。

          

这次我们以一个简单的温度监控系统为例,该系统需要:

实时监控温度传感器: 需要中断来快速响应温度变化。

根据温度进行状态切换: 需要状态机来管理不同的工作模式(例如:正常、高温报警、低温报警)。

定期进行数据记录: 需要轮询来定期保存温度数据到存储器。

// 1. 定义状态typedef enum {    STATE_NORMAL,    STATE_HIGH_TEMP_ALARM,    STATE_LOW_TEMP_ALARM} TemperatureState_t;TemperatureState_t currentTemperatureState = STATE_NORMAL;// 2. 定义全局变量volatile float temperature = 25.0// 当前温度,volatile 确保中断和主循环都能访问bool newDataAvailable = false// 新数据标志// 3. 温度传感器中断服务程序 (假设通过ADC读取)void ADC_IRQHandler(){    if (ADC_GetITStatus(ADC1, ADC_IT_EOC) != RESET)    {        // 读取ADC值        uint16_t adcValue = ADC_GetConversionValue(ADC1);        // 转换成温度值 (简化计算)        temperature = (float)adcValue * 0.1// 假设每0.1代表1摄氏度        newDataAvailable = true// 设置新数据标志        // 清除中断标志位        ADC_ClearITPendingBit(ADC1, ADC_IT_EOC);    }}// 4. 状态机函数void temperatureStateMachine(){    switch (currentTemperatureState)    {        case STATE_NORMAL:            if (temperature > 35.0)            {                currentTemperatureState = STATE_HIGH_TEMP_ALARM;                // 启动风扇                GPIO_SetBits(FAN_PORT, FAN_PIN);                printf("High Temperature Alarm!\n");            }            else if (temperature < 10.0)            {                currentTemperatureState = STATE_LOW_TEMP_ALARM;                // 启动加热器                GPIO_SetBits(HEATER_PORT, HEATER_PIN);                printf("Low Temperature Alarm!\n");            }            break;        case STATE_HIGH_TEMP_ALARM:            if (temperature <= 30.0)            {                currentTemperatureState = STATE_NORMAL;                // 关闭风扇                GPIO_ResetBits(FAN_PORT, FAN_PIN);                printf("Normal Temperature.\n");            }            break;        case STATE_LOW_TEMP_ALARM:            if (temperature >= 15.0)            {                currentTemperatureState = STATE_NORMAL;                // 关闭加热器                GPIO_ResetBits(HEATER_PORT, HEATER_PIN);                printf("Normal Temperature.\n");            }            break;    }}// 5. 数据记录任务 (轮询方式)void dataLoggingTask(){    static uint32_t lastLogTime = 0;    uint32_t currentTime = HAL_GetTick(); // 获取当前时间 (需要HAL库支持)    if (currentTime - lastLogTime >= 5000// 每5秒记录一次    {        lastLogTime = currentTime;        // 将温度数据记录到存储器 (这里简化成打印)        printf("Logging: Temperature = %.2f, State = %d\n", temperature, currentTemperatureState);        // 实际应用中,需要写入Flash或者SD卡    }}// 6. 主函数int main(){    // 初始化 ADC,GPIO,中断    // ... (初始化代码略)    HAL_Init();    SystemClock_Config();    MX_GPIO_Init();    MX_ADC1_Init();    // 启动ADC转换并使能中断    HAL_ADC_Start_IT(&hadc1);    // 主循环    while (1)    {        // 1. 状态机处理        temperatureStateMachine();        // 2. 数据记录 (轮询)        dataLoggingTask();        // 3. 其他任务 (可以添加更多任务)        // ...        // 4. 降低功耗 (可选)        // HAL_PWR_EnterSleepMode(PWR_LOWPOWERREGULATOR_ON, ADC_IRQn);    }}


          

代码说明:

温度传感器中断: 使用ADC读取温度,并在每次读取后设置newDataAvailable标志。volatile关键字确保主循环能及时读取到最新的温度数据。

          

状态机:temperatureStateMachine() 函数根据温度值,切换系统状态,并控制风扇或加热器的开启/关闭。

          

数据记录任务:dataLoggingTask() 函数每隔5秒记录一次温度数据和系统状态。

          

混合架构的优势:

实时响应: 中断确保系统能及时响应温度变化。

状态管理: 状态机负责管理系统的工作模式,并根据温度进行切换。

数据记录: 轮询确保数据能够被定期记录。

          

这个例子虽然简单,但已经展示了混合架构的基本思想:将不同的架构模式结合起来,充分发挥各自的优势,以满足复杂的系统需求。

          

适用场景:

系统既有实时性要求,又有复杂的逻辑。

资源有限,需要在性能和复杂度之间进行平衡。

各个模块的功能特性不同,需要采用不同的架构模式。

          

优缺点:

优点: 灵活性高,可以针对具体问题选择最佳解决方案。

缺点: 架构设计难度较大,需要经验丰富的工程师;架构间的接口和通信需要精心设计,避免出现“缝合怪”现象。

          

我们从事了10年,就喜欢用自己设计的架构,采用了多种混合架构,缝合了不同框架的优势,相对RTOS更精简更节省资源,很多51单片机也能用。

          

比如我们无际单片机的项目3和项目6,就是把轮询架构加了一层封装,让它们在管理任务时更加灵活方便,以轮询作为主框架,其余有状态机、表驱动之类的架构配合,具体可以看我前面几篇文章。

          

关于这个轮询架构我也在2018年录了个全面的教程,目前开源,无际粉丝可找我安排。

          

实战避坑:

在设计混合架构之前,先分析系统需求,明确各个模块的功能和性能要求。

确定核心架构,例如使用RTOS作为主框架,然后根据需要添加其他架构模块。

定义清晰的接口规范,确保各个模块之间的通信和数据交换顺畅。

          

6. 选择架构:没有最好的,只有最合适的

          

选择哪种架构模式,并没有绝对的答案,关键是要根据具体的项目需求和资源情况进行选择。

          

如果任务简单,实时性要求不高,资源有限,那么轮询架构是一个不错的选择。

如果需要快速响应外部事件,或者有严格的实时性要求,那么中断架构是必不可少的。

如果系统逻辑复杂,有明显的状态概念,那么状态机架构可以帮助你更好地管理代码。

如果系统功能复杂,需要多个任务并行执行,那么RTOS架构可以提高系统效率和响应速度。

如果以上几种架构都不能满足你的需求,那么可以考虑采用混合架构,将多种架构模式结合起来使用。

          

7. 总结

嵌入式软件架构是单片机开发的“灵魂”,它决定了你的代码是“豆腐渣工程”还是“艺术品”。

          

掌握这些常见的架构模式,你就能更好地组织你的代码,构建更清晰、更稳定、更易维护的嵌入式系统。

          

希望这篇文章能帮助你摆脱“代码搬运工”的身份,起到抛砖引玉的作用,助你成为一名真正的嵌入式软件架构师!好的架构不仅能提高开发效率,还能让你在开发复杂项目时游刃有余。


end


下面是更多无际原创个人成长经历、行业经验、技术干货

1.电子工程师是怎样的成长之路?10年5000字总结

2.如何快速看懂别人的代码和思维

3.单片机开发项目全局变量太多怎么管理?

4.C语言开发单片机为什么大多数都采用全局变量的形式

5.单片机怎么实现模块化编程?实用程度让人发指!

6.c语言回调函数的使用及实际作用详解

7.手把手教你c语言队列实现代码,通俗易懂超详细!

8.c语言指针用法详解,通俗易懂超详细!

无际单片机编程 单片机编程、全栈孵化。
评论 (0)
  • 在不久前发布的《技术实战 | OK3588-C开发板上部署DeepSeek-R1大模型的完整指南》一文中,小编为大家介绍了DeepSeek-R1在飞凌嵌入式OK3588-C开发板上的移植部署、效果展示以及性能评测,本篇文章不仅将继续为大家带来关于DeepSeek-R1的干货知识,还会深入探讨多种平台的移植方式,并介绍更为丰富的交互方式,帮助大家更好地应用大语言模型。1、移植过程1.1 使用RKLLM-Toolkit部署至NPURKLLM-Toolkit是瑞芯微为大语言模型(LLM)专门开发的转换
    飞凌嵌入式 2025-03-31 11:22 222浏览
  • 北京贞光科技有限公司作为紫光同芯产品的官方代理商,为客户提供车规安全芯片的硬件、软件SDK销售及专业技术服务,并且可以安排技术人员现场支持客户的选型和定制需求。在全球汽车电子市场竞争日益激烈的背景下,中国芯片厂商正通过与国际领先企业的深度合作,加速融入全球技术生态体系。近日,紫光同芯与德国HighTec达成的战略合作标志着国产高端车规芯片在国际化道路上迈出了关键一步,为中国汽车电子产业的发展注入了新的活力。全栈技术融合:打造国际化开发平台紫光同芯与HighTec共同宣布,HighTec汽车级编译
    贞光科技 2025-03-31 14:44 120浏览
  • 提到“质量”这两个字,我们不会忘记那些奠定基础的大师们:休哈特、戴明、朱兰、克劳士比、费根堡姆、石川馨、田口玄一……正是他们的思想和实践,构筑了现代质量管理的核心体系,也深远影响了无数企业和管理者。今天,就让我们一同致敬这些质量管理的先驱!(最近流行『吉卜力风格』AI插图,我们也来玩玩用『吉卜力风格』重绘质量大师画象)1. 休哈特:统计质量控制的奠基者沃尔特·A·休哈特,美国工程师、统计学家,被誉为“统计质量控制之父”。1924年,他提出世界上第一张控制图,并于1931年出版《产品制造质量的经济
    优思学院 2025-04-01 14:02 104浏览
  •        在“软件定义汽车”的时代浪潮下,车载软件的重要性日益凸显,软件在整车成本中的比重逐步攀升,已成为汽车智能化、网联化、电动化发展的核心驱动力。车载软件的质量直接关系到车辆的安全性、可靠性以及用户体验,因此,构建一套科学、严谨、高效的车载软件研发流程,确保软件质量的稳定性和可控性,已成为行业共识和迫切需求。       作为汽车电子系统领域的杰出企业,经纬恒润深刻理解车载软件研发的复杂性和挑战性,致力于为O
    经纬恒润 2025-03-31 16:48 79浏览
  • 升职这件事,说到底不是单纯靠“干得多”或者“喊得响”。你可能也看过不少人,能力一般,甚至没你努力,却升得飞快;而你,日复一日地拼命干活,升职这两个字却始终离你有点远。这种“不公平”的感觉,其实在很多职场人心里都曾经出现过。但你有没有想过,问题可能就藏在一些你“没当回事”的小细节里?今天,我们就来聊聊你升职总是比别人慢,可能是因为这三个被你忽略的小细节。第一:你做得多,但说得少你可能是那种“默默付出型”的员工。项目来了接着干,困难来了顶上去,别人不愿意做的事情你都做了。但问题是,这些事情你做了,却
    优思学院 2025-03-31 14:58 98浏览
  • 在智能交互设备快速发展的今天,语音芯片作为人机交互的核心组件,其性能直接影响用户体验与产品竞争力。WT588F02B-8S语音芯片,凭借其静态功耗<5μA的卓越低功耗特性,成为物联网、智能家居、工业自动化等领域的理想选择,为设备赋予“听得懂、说得清”的智能化能力。一、核心优势:低功耗与高性能的完美结合超低待机功耗WT588F02B-8S在休眠模式下待机电流仅为5μA以下,显著延长了电池供电设备的续航能力。例如,在电子锁、气体检测仪等需长期待机的场景中,用户无需频繁更换电池,降低了维护成本。灵活的
    广州唯创电子 2025-04-02 08:34 46浏览
  • 引言在语音芯片设计中,输出电路的设计直接影响音频质量与系统稳定性。WT588系列语音芯片(如WT588F02B、WT588F02A/04A/08A等),因其高集成度与灵活性被广泛应用于智能设备。然而,不同型号在硬件设计上存在关键差异,尤其是DAC加功放输出电路的配置要求。本文将从硬件架构、电路设计要点及选型建议三方面,解析WT588F02B与F02A/04A/08A的核心区别,帮助开发者高效完成产品设计。一、核心硬件差异对比WT588F02B与F02A/04A/08A系列芯片均支持PWM直推喇叭
    广州唯创电子 2025-04-01 08:53 143浏览
  • 引言随着物联网和智能设备的快速发展,语音交互技术逐渐成为提升用户体验的核心功能之一。在此背景下,WT588E02B-8S语音芯片,凭借其创新的远程更新(OTA)功能、灵活定制能力及高集成度设计,成为智能设备语音方案的优选。本文将从技术特性、远程更新机制及典型应用场景三方面,解析该芯片的技术优势与实际应用价值。一、WT588E02B-8S语音芯片的核心技术特性高性能硬件架构WT588E02B-8S采用16位DSP内核,内部振荡频率达32MHz,支持16位PWM/DAC输出,可直接驱动8Ω/0.5W
    广州唯创电子 2025-04-01 08:38 133浏览
  • 据先科电子官方信息,其产品包装标签将于2024年5月1日进行全面升级。作为电子元器件行业资讯平台,大鱼芯城为您梳理本次变更的核心内容及影响:一、标签变更核心要点标签整合与环保优化变更前:卷盘、内盒及外箱需分别粘贴2张标签(含独立环保标识)。变更后:环保标识(RoHS/HAF/PbF)整合至单张标签,减少重复贴标流程。标签尺寸调整卷盘/内盒标签:尺寸由5030mm升级至**8040mm**,信息展示更清晰。外箱标签:尺寸统一为8040mm(原7040mm),提升一致性。关键信息新增新增LOT批次编
    大鱼芯城 2025-04-01 15:02 151浏览
  • REACH和RoHS欧盟两项重要的环保法规有什么区别?适用范围有哪些?如何办理?REACH和RoHS是欧盟两项重要的环保法规,主要区别如下:一、核心定义与目标RoHS全称为《关于限制在电子电器设备中使用某些有害成分的指令》,旨在限制电子电器产品中的铅(Pb)、汞(Hg)、镉(Cd)、六价铬(Cr6+)、多溴联苯(PBBs)和多溴二苯醚(PBDEs)共6种物质,通过限制特定材料使用保障健康和环境安全REACH全称为《化学品的注册、评估、授权和限制》,覆盖欧盟市场所有化学品(食品和药品除外),通过登
    张工13144450251 2025-03-31 21:18 102浏览
  • 职场之路并非一帆风顺,从初入职场的新人成长为团队中不可或缺的骨干,背后需要经历一系列内在的蜕变。许多人误以为只需努力工作便能顺利晋升,其实核心在于思维方式的更新。走出舒适区、打破旧有框架,正是让自己与众不同的重要法宝。在这条道路上,你不只需要扎实的技能,更需要敏锐的观察力、不断自省的精神和前瞻的格局。今天,就来聊聊那改变命运的三大思维转变,让你在职场上稳步前行。工作初期,总会遇到各式各样的难题。最初,我们习惯于围绕手头任务来制定计划,专注于眼前的目标。然而,职场的竞争从来不是单打独斗,而是团队协
    优思学院 2025-04-01 17:29 87浏览
  • 文/Leon编辑/cc孙聪颖‍步入 2025 年,国家进一步加大促消费、扩内需的政策力度,家电国补政策将持续贯穿全年。这一利好举措,为行业发展注入强劲的增长动力。(详情见:2025:消费提振要靠国补还是“看不见的手”?)但与此同时,也对家电企业在战略规划、产品打造以及市场营销等多个维度,提出了更为严苛的要求。在刚刚落幕的中国家电及消费电子博览会(AWE)上,家电行业的竞争呈现出胶着的态势,各大品牌为在激烈的市场竞争中脱颖而出,纷纷加大产品研发投入,积极推出新产品,试图提升产品附加值与市场竞争力。
    华尔街科技眼 2025-04-01 19:49 73浏览
  • 文/郭楚妤编辑/cc孙聪颖‍不久前,中国发展高层论坛 2025 年年会(CDF)刚刚落下帷幕。本次年会围绕 “全面释放发展动能,共促全球经济稳定增长” 这一主题,吸引了全球各界目光,众多重磅嘉宾的出席与发言成为舆论焦点。其中,韩国三星集团会长李在镕时隔两年的访华之行,更是引发广泛热议。一直以来,李在镕给外界的印象是不苟言笑。然而,在论坛开幕前一天,李在镕却意外打破固有形象。3 月 22 日,李在镕与高通公司总裁安蒙一同现身北京小米汽车工厂。小米方面极为重视此次会面,CEO 雷军亲自接待,小米副董
    华尔街科技眼 2025-04-01 19:39 69浏览
我要评论
0
0
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦