嵌入式软件裸机开发—常用的软件架构

嵌入式软件裸机开发

嵌入式软件裸机开发是指在没有操作系统支持的情况下,直接对硬件进行编程,以实现特定功能的开发过程。这种开发方式适用于资源受限、实时性要求高或对系统开销敏感的应用场景。在裸机开发中,设计合理的软件架构对于保证程序的可读性、可维护性、可扩展性和可靠性至关重要。

具体实例

以下是几种常见的嵌入式软件裸机开发架构及其详细说明:

循环-查询(Polling)架构

原理与结构:循环查询架构是最基础的嵌入式软件架构之一,其核心思想是在主循环中不断检查各个外设状态或事件标志,根据状态变化执行相应的处理逻辑。整个程序通常由初始化模块、主循环模块和外设驱动模块组成。

示例:

int main(void) {// 初始化模块:配置硬件、设置中断、初始化变量等init_hardware();init_variables();while (1) {// 主循环模块:循环查询外设状态并执行相应操作if (check_uart_rx()) {process_uart_data();}if (check_timer_interrupt()) {handle_timer_event();}// ...其他外设的查询与处理// 可能存在的空闲处理或低功耗模式切换idle_processing();}}

优缺点:

优点:实现简单,易于理解;适用于外设数量较少、事件响应不频繁的场景。
缺点:CPU占用率高,实时性取决于查询周期;不适合复杂系统和大量并发事件处理。
中断驱动(Interrupt-Driven)架构

原理与结构:中断驱动架构基于硬件中断机制,当特定事件(如外设数据就绪、定时器溢出等)发生时,CPU暂停当前任务,转而执行预先注册的中断服务程序(ISR)。主程序通常仅负责初始化和一些非实时性任务,大部分实时处理工作在ISR中完成。系统包括初始化模块、主循环模块、外设驱动模块(含ISR)和可能的中断优先级管理模块。

示例:

cvoid UART_IRQHandler(void) {// UART ISR:快速处理接收到的数据,避免阻塞中断read_uart_data();set_uart_event_flag();}int main(void) {// 初始化模块:配置硬件、注册中断服务程序、初始化变量等init_hardware();enable_UART_IRQ(UART_IRQHandler);init_variables();while (1) {// 主循环模块:响应已发生的事件if (is_uart_event_flag_set()) {clear_uart_event_flag();process_uart_data();}// ...其他事件的响应// 可能存在的空闲处理或低功耗模式切换idle_processing();}}

优缺点:

优点:实时性强,CPU利用率高;适用于事件密集、实时响应要求高的系统。
缺点:需谨慎处理中断嵌套和优先级问题,避免中断延迟和死锁;ISR应保持短小精悍,避免影响中断响应时间。
前后台(Bare-Metal RTOS-Like)架构

原理与结构:前后台架构模仿实时操作系统(RTOS)的设计理念,将系统划分为前台(中断服务程序)和后台(主循环)两部分。前台负责快速响应实时事件,后台执行非实时任务和管理任务队列。系统包括初始化模块、主循环(任务调度)模块、外设驱动模块(含ISR)、任务队列管理模块和任务(函数指针)结构体。

示例:

   typedef void (*task_t)(void);struct task_queue {task_t* tasks;uint8_t head, tail, count;};void add_task(struct task_queue* queue, task_t task) {// 将任务添加到队列尾部// ...实现细节省略}void UART_IRQHandler(void) {// UART ISR:快速处理接收到的数据,将数据处理任务放入队列read_uart_data();add_task(&task_queue, process_uart_data);}int main(void) {// 初始化模块:配置硬件、注册中断服务程序、初始化变量和任务队列等init_hardware();enable_UART_IRQ(UART_IRQHandler);init_variables();init_task_queue(&task_queue);while (1) {// 主循环模块:执行任务队列中的任务if (!is_task_queue_empty(&task_queue)) {task_t current_task = get_and_remove_task(&task_queue);current_task();} else {// 可能存在的空闲处理或低功耗模式切换idle_processing();}}}

优缺点:

优点:兼顾实时性和任务管理,易于扩展和调整任务优先级;适用于中等复杂度、有一定任务调度需求的系统。
缺点:实现相对复杂,需要手动管理任务队列和调度逻辑;相比RTOS,缺乏内建的线程同步原语和高级调度策略。
有限状态机(FSM)架构

原理与结构:有限状态机是一种行为型软件设计模式,特别适用于处理具有多个状态且状态间转换依赖于特定条件或事件的系统。在嵌入式裸机开发中,可以将整个系统或某个复杂功能模块设计为一个FSM。系统包括状态定义、状态转移表(或函数)、事件处理函数以及主循环模块。

示例(以UART通信协议为例):

  enum UART_State {UART_IDLE,UART_RECEIVING,UART_SENDING,// ...};void uart_fsm(enum UART_Event event) {static enum UART_State state = UART_IDLE;switch (state) {case UART_IDLE:if (event == UART_RX_READY) {state = UART_RECEIVING;start_uart_reception();} else if (event == UART_TX_REQUEST) {state = UART_SENDING;start_uart_transmission();}break;case UART_RECEIVING:if (event == UART_RX_DONE) {process_received_data();state = UART_IDLE;} else if (event == UART_RX_ERROR) {handle_rx_error();state = UART_IDLE;}break;case UART_SENDING:if (event == UART_TX_DONE) {state = UART_IDLE;} else if (event == UART_TX_ERROR) {handle_tx_error();state = UART_IDLE;}break;// ...}}int main(void) {// 初始化模块:配置硬件、初始化变量等init_hardware();init_variables();while (1) {// 主循环模块:检查事件并调用FSM处理check_uart_events();uart_fsm(current_uart_event());}}

优缺点:

优点:清晰地描绘系统行为和状态转换,易于理解和调试;适用于状态复杂、事件驱动的系统。
缺点:随着状态和事件增多,FSM可能会变得庞大且难以管理;需要精心设计状态转移规则以避免无效状态和死循环。

小结

嵌入式软件裸机开发常用的软件架构包括循环查询、中断驱动、前后台和有限状态机等。选择何种架构应根据系统的实际需求(如实时性、任务复杂度、资源限制等)进行权衡。在实际项目中,这些架构可能单独使用,也可能结合使用以构建更复杂、高效的嵌入式系统。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/806600.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Lesson1--数据结构前言

1. 什么是数据结构? 2. 什么是算法? 3. 数据结构和算法的重要性 4. 如何学好数据结构和算法 5. 数据结构和算法书籍及资料推荐 1. 什么是数据结构? 数据结构(Data Structure) 是计算机存储、组织数据的方式,指相互之间存在一…

oracle 删除用户名

在Oracle数据库中,删除用户的操作通常需要DBA权限。以下是删除Oracle用户的基本SQL命令: DROP USER username CASCADE;请将username替换为你想要删除的用户名。 CASCADE关键字表示同时删除用户拥有的所有对象(如表、视图、序列等&#xff0…

机器学习和深度学习-- 李宏毅(笔记与个人理解)Day8

Day 8 classification :Probabilistic Generative Model 今天上了一整天的课, 本来实在是更新不动了,但是看到《剑来》更新了,想一想这本书里面一直强调的成功的feature – 心性,嗯心性坚毅就好!主人公陈平…

Unity 遮罩

编辑器版本 2017.2.3f1 学习Unity的三张遮罩方式 1. Mask 遮罩方式 首先,在界面上创建2个Image,一个命名Img_Mask,大小设置 400* 400, 一个命名Img_Show,大小设置500*500。 然后,给 Img_Mask添加Mask,选择Img_Mask,点击Add Com…

docker 创建容器过程

结合下图,本文讨论docker 创建容器过程: START└── [用户通过Docker Client发出指令]└── (1) docker run 或 docker create 命令├── (2) Docker Client与Docker Daemon建立通信连接└── (3) Docker Daemon接收到创建容器请求├── (4) 检查…

vue3里前端生成二维码和解析二维码(不需要后端参与)

1.生成二维码 1&#xff09;安装qrcode npm install qrcode 2&#xff09;生成二维码代码 <template><el-input v-model"formData.designation"></el-input><el-input v-model"formData.people"></el-input><el-button …

Python --- Python + Vs code的安装与使用(windows平台)

Python Vs code的安装与使用 今天是我第一次开始尝试用Python&#xff0c;然后我想借此机会记录一下整个安装过程和上手过程。之前一直都是用的matlab&#xff0c;这个东西不仅大而且收费&#xff0c;但不可否认的是。matlab的很多东西都做的比较好&#xff0c;但我一直用的都…

【Linux的进程篇章 - 进程终止和进程等待的理解】

Linux学习笔记---008 Linux之fork函数、进程终止和等待的理解1、fork函数1.1、什么是fork?1.2、fork的功能介绍1.3、fork函数返回值的理解1.4、fork函数的总结 2、进程的终止2.1、终止是在做什么&#xff1f;2.2、进程终止的3种情况 3、进程的终止3.1、进程终止的三种情况3.2、…

1.8.4 卷积神经网络近年来在结构设计上的主要发展和变迁——Inception-v2 和Inception-v3

1.8.4 卷积神经网络近年来在结构设计上的主要发展和变迁——Inception-v2 和Inception-v3 前情回顾&#xff1a; 1.8.1 卷积神经网络近年来在结构设计上的主要发展和变迁——AlexNet 1.8.2 卷积神经网络近年来在结构设计上的主要发展和变迁——VGGNet 1.8.3 卷积神经网络近年来…

阿里Canal使用

Canal 是阿里巴巴开源的一款基于 MySQL 数据库增量日志解析&#xff0c;提供实时的数据订阅和消费服务的工具。它可以用来读取 MySQL 的 binlog 日志并转换成 JSON 格式的事件消息&#xff0c;然后将这些消息发布到下游的消息中间件&#xff0c;比如 RabbitMQ&#xff0c;以实现…

输入输出系统的发展历程

发展阶段&#xff1a;1.早期阶段&#xff1a;i/o设备种类较少&#xff0c;i/o设备与主存交换信息都必须通过CPU&#xff0c;当时的i/o设备具有以下特点&#xff0c;每个i/o设备都必须配有一套独立的逻辑电路与CPU相连&#xff0c;线路十分庞杂散乱。输入输出过程是穿插在CPU执行…

MySQL innoDB存储引擎多事务场景下的事务执行情况

一、背景 在日常开发中&#xff0c;对不同事务之间的隔离情况等理解如果不够清晰&#xff0c;很容易导致代码的效果和预期不符。因而在这对一些存在疑问的场景进行模拟。 下面的例子全部基于innoDB存储引擎。 二、场景&#xff1a; 2.1、两个事务修改同一行记录 正常来说&…

Java 对象的初始化顺序

在 Java 中&#xff0c;对象的初始化顺序都是遵循一定的规则的。这涉及到类的构造函数调用、字段初始化以及继承关系中的初始化顺序。 当涉及到继承时&#xff0c;初始化顺序如下&#xff1a; 父类静态变量和静态初始化块&#xff1a;按照声明的顺序执行。子类静态变量和静态…

自动化测试框架-senlenium(2)

目录 1.前言 2.鼠标点击 2.1click点击对象 2.2senk_keys在对象上模拟键盘输入 2.3清除对象输入的文本内容 2.4submit提交 2.5 text用于获取文本信息 ​编辑3.获取信息 3.1获取title 3.2获取url 1.前言 前面我们讲了如何定位元素,那么我们把元素定位到了以后,又如何…

Python的MATLAB使用

Python和MATLAB是两种不同的编程语言&#xff0c;它们各自拥有不同的生态系统和库。然而&#xff0c;你可以在Python中使用一些方法来实现与MATLAB类似的功能。以下是一些方法和库&#xff0c;可以帮助你在Python中实现MATLAB风格的编程&#xff1a; 1. NumPy: NumPy是Python中…

图论知识汇总

算法可以发掘本质&#xff0c;如&#xff1a; 一&#xff0c;若干师傅和徒弟互有好感&#xff0c;有好感的师徒可以结对学习。师傅和徒弟都只能参加一个对子。如何让对子最多。 二&#xff0c;有无限多1X2和2X1的骨牌&#xff0c;某个棋盘若干格子坏了&#xff0c;如何在没有坏…

【力扣】104. 二叉树的最大深度、111. 二叉树的最小深度

104. 二叉树的最大深度 题目描述 给定一个二叉树 root &#xff0c;返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;3 示例 2&#xff1a; 输…

ENSP防火墙配置策略路由及ip-link探测

拓扑 配置目标 1.A区域走ISP1&#xff0c;B区域走ISP2 2. isp线路故障时及时切换到另一条线路 配置接口及安全区域 配置安全策略 配置nat 配置默认路由 配置ip-link 配置策略路由 cl-1 cl-2 验证配置成功 策略路由 A走ISP1 B走ISP2 验证线路故障 isp1 in g0/0/0 shoutdow…

Qt——示波器/图表 QCustomPlot

一、介绍 QCustomPlot是一个用于绘图和数据可视化的Qt C小部件。它没有进一步的依赖关系&#xff0c;提供友好的文档帮助。这个绘图库专注于制作好看的&#xff0c;出版质量的2D绘图&#xff0c;图形和图表&#xff0c;以及为实时可视化应用程序提供高性能。QCustomPlot可以导出…

HWOD:走方格的方案数

一、自己的解题思路 1、(0,m)和(n,0) (0,m)表示处在棋盘的左边线&#xff0c;此刻能回到原点的路线只有一个&#xff0c;就是一路向上 (n,0)表示处在棋盘的上边线&#xff0c;此刻能回到原点的路线只有一个&#xff0c;就是一路向左 2、(1,1) (1,1)表示只有一个方格&#…