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

嵌入式软件架构设计:硬件抽象层实践

嵌入式软件架构设计建立硬件抽象层的工程实践1. 嵌入式软件架构概述1.1 架构设计的必要性在嵌入式系统开发中软件架构设计直接影响产品的可维护性、可扩展性和可移植性。良好的架构设计能够减少不必要的返工建立宏观层面的开发规划增强代码复用性降低开发成本便于团队技术培训与知识积累1.2 架构设计的六个关键步骤隔离硬件相关代码建立抽象层建立统一的软件基础设施识别和处理产品数据功能分层与分解组件及其接口设计测试、调试与跨平台开发支持2. 耦合架构的问题分析2.1 典型耦合架构示例以下是一个典型的硬件耦合代码示例展示了Modbus协议实现直接调用MCU硬件寄存器void modbus_rtu_write_reply(uint8_t add, uint8_t func_code, uint16_t reg, uint16_t data) { rs485.buff_tx[0] add; rs485.buff_tx[1] func_code; rs485.buff_tx[2] (uint8_t)(reg 8); rs485.buff_tx[3] (uint8_t)(reg); rs485.buff_tx[4] (uint8_t)(data 8); rs485.buff_tx[5] (uint8_t)(data); uint16_t crc16 mb_crc16(rs485.buff_tx, 6); rs485.buff_tx[6] (uint8_t)(crc16); rs485.buff_tx[7] (uint8_t)(crc16 8); rs485.tx_total 8; rs485.tx_num 0; /* 直接操作硬件寄存器 */ LL_USART_ClearFlag_TC(USART1); LL_USART_EnableIT_TC(USART1); USART1-DR rs485.buff_tx[rs485.tx_num]; }2.2 耦合架构的主要问题移植困难硬件变更需要修改大量直接操作硬件的代码测试复杂无法脱离目标硬件进行单元测试扩展性差全局变量滥用导致系统复杂度指数增长违反SOLID原则特别是违反依赖倒置原则(DIP)3. 抽象层设计原理3.1 抽象层的基本概念硬件抽象层(HAL)是在应用程序和硬件之间建立的中间层它提供统一的硬件操作接口隐藏底层硬件差异。常见的抽象层类型包括硬件抽象层(HAL)设备抽象层(DAL)操作系统抽象层(OSAL)文件系统抽象层Flash抽象层3.2 依赖倒置原则的实现抽象层的核心是遵循依赖倒置原则高层模块(应用逻辑)不应依赖低层模块(硬件驱动)两者都应依赖于抽象接口抽象不应依赖细节细节应依赖抽象4. 隔离架构的实现4.1 改进后的代码结构通过引入抽象层上述Modbus实现可改进为/* 应用层代码 */ void modbus_rtu_write_reply(uint8_t add, uint8_t func_code, uint16_t reg, uint16_t data) { rs485.buff_tx[0] add; rs485.buff_tx[1] func_code; rs485.buff_tx[2] (uint8_t)(reg 8); rs485.buff_tx[3] (uint8_t)(reg); rs485.buff_tx[4] (uint8_t)(data 8); rs485.buff_tx[5] (uint8_t)(data); uint16_t crc16 mb_crc16(rs485.buff_tx, 6); rs485.buff_tx[6] (uint8_t)(crc16); rs485.buff_tx[7] (uint8_t)(crc16 8); rs485.tx_total 8; /* 通过抽象层接口发送数据 */ hal_uart_send(HAL_UART_ID_1, rs485.buff_tx, rs485.tx_total); } /* 硬件抽象层实现 */ void hal_uart_send(uint8_t uart_id, void *buffer, uint32_t size) { /* 具体的硬件操作 */ MCU_NEW_USART_ClearFlag_TC(NEW_USART1); MCU_NEW_USART_EnableIT_TC(NEW_USART1); NEW_USART1-DR rs485.buff_tx[rs485.tx_num]; }4.2 抽象层的工程优势硬件可移植性更换硬件平台只需修改抽象层实现并行开发应用开发可在硬件就绪前开始测试便利可通过Mock对象进行单元测试早期验证支持在仿真环境验证核心算法5. 抽象层设计实践要点5.1 抽象程度控制过度的抽象会增加系统复杂度不足的抽象无法有效隔离硬件变化应根据产品生命周期和硬件变更预期确定抽象程度5.2 接口设计原则硬件无关性接口定义不应包含硬件特定概念功能完整性覆盖硬件所有关键功能性能可预期接口应有明确的性能特征错误处理统一的错误码和异常处理机制5.3 典型抽象层接口示例/* UART抽象层接口 */ typedef enum { HAL_UART_ID_1, HAL_UART_ID_2, // ... } hal_uart_id_t; typedef void (*hal_uart_rx_callback_t)(uint8_t data); int hal_uart_init(hal_uart_id_t id, uint32_t baudrate); int hal_uart_send(hal_uart_id_t id, const void *data, uint32_t size); int hal_uart_receive(hal_uart_id_t id, void *buffer, uint32_t size); int hal_uart_set_rx_callback(hal_uart_id_t id, hal_uart_rx_callback_t callback);6. 抽象层的测试支持6.1 Mock对象实现/* 测试环境的Mock UART实现 */ static uint8_t mock_uart_buffer[256]; static uint32_t mock_uart_index 0; int hal_uart_send(hal_uart_id_t id, const void *data, uint32_t size) { if(id ! HAL_UART_ID_1) return -1; memcpy(mock_uart_buffer[mock_uart_index], data, size); mock_uart_index size; return 0; } /* 单元测试用例 */ void test_modbus_rtu_write(void) { uint8_t test_data[] {0x01, 0x03, 0x00, 0x01, 0x00, 0x01}; modbus_rtu_write_reply(0x01, 0x03, 0x0001, 0x0001); /* 验证Mock UART接收到的数据 */ TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_data, mock_uart_buffer, sizeof(expected_data)); }6.2 持续集成支持抽象层使嵌入式软件能够纳入CI/CD流程可在构建服务器上运行自动化测试支持静态代码分析、单元测试和集成测试7. 工程实践建议逐步重构对已有项目可逐步提取抽象层接口稳定抽象层接口应保持向后兼容文档完善每个抽象接口应有详细的使用说明性能考量抽象层不应成为系统性能瓶颈团队共识确保所有开发人员遵循抽象层规范

相关文章:

嵌入式软件架构设计:硬件抽象层实践

嵌入式软件架构设计:建立硬件抽象层的工程实践 1. 嵌入式软件架构概述 1.1 架构设计的必要性 在嵌入式系统开发中,软件架构设计直接影响产品的可维护性、可扩展性和可移植性。良好的架构设计能够: 减少不必要的返工 建立宏观层面的开发规…...

FPGA调试避坑指南:Vivado ILA采样深度和探针位宽怎么设?资源占用与调试效果的平衡术

FPGA调试实战:ILA采样深度与探针位宽的黄金平衡法则 当你在Artix-7芯片上调试一个包含32位计数器和多状态机的设计时,突然发现ILA吃掉了一半的Block RAM资源,而采样深度却只够捕获5个时钟周期的数据——这种场景是否似曾相识?本文…...

轨迹规划实战:用多项式插值+粒子群玩转机械臂运动优化

轨迹规划 路径规划 matlab 353多项式插值 基于改进粒子群算法 时间最优 针对六自由度 四自由度都可以,轨迹规划,多项式插值,更改轨迹点位置就可以搞机器人轨迹规划最头疼的就是既要轨迹丝滑又要时间最短。今天咱们用Matlab整点狠活—…...

开源条码字体技术:如何通过字体文件彻底改变条码生成方式

开源条码字体技术:如何通过字体文件彻底改变条码生成方式 【免费下载链接】librebarcode Libre Barcode: barcode fonts for various barcode standards. 项目地址: https://gitcode.com/gh_mirrors/li/librebarcode 条码生成技术长期以来依赖专业软件和专用…...

气候降尺度全流程实战:从 CMIP6 数据到极端气候预估,科研人一站式通关

做水文气象、气候学、地理遥感、生态环境等领域的科研人&#xff0c;是不是都逃不过这些噩梦&#xff1a;尺度鸿沟难跨越&#xff1a;GCM 粗网格&#xff08;>100km&#xff09;和流域 / 城市精细尺度&#xff08;<10km&#xff09;不匹配&#xff0c;动力降尺度成本太高…...

STM32F103 LoRa物理层驱动库详解与工程实践

1. 项目概述LoRa_STM32 是一个面向 STM32F103CB 微控制器平台的 LoRa 通信库&#xff0c;本质是 sandeepmistry/arduino-LoRa 库在 STM32 平台上的适配分支。它并非独立开发的全新协议栈&#xff0c;而是通过 Arduino Core for STM32&#xff08;rogerclarkmelbourne/Arduino_S…...

3步搞定Google Drive受保护PDF:高效下载完整指南

3步搞定Google Drive受保护PDF&#xff1a;高效下载完整指南 【免费下载链接】Google-Drive-PDF-Downloader 项目地址: https://gitcode.com/gh_mirrors/go/Google-Drive-PDF-Downloader 你是否曾遇到过这样的情况&#xff1f;在Google Drive中找到一个急需的技术文档或…...

高效解决多设备滚动冲突难题的Scroll Reverser工具

高效解决多设备滚动冲突难题的Scroll Reverser工具 【免费下载链接】Scroll-Reverser Per-device scrolling prefs on macOS. 项目地址: https://gitcode.com/gh_mirrors/sc/Scroll-Reverser Scroll Reverser是一款专为macOS用户设计的开源效率工具&#xff0c;它能够为…...

告别杂乱农场:星露谷物语规划神器助你打造高效田园

告别杂乱农场&#xff1a;星露谷物语规划神器助你打造高效田园 【免费下载链接】stardewplanner Stardew Valley farm planner 项目地址: https://gitcode.com/gh_mirrors/st/stardewplanner 你是否曾在星露谷物语中面对一片荒地感到无从下手&#xff1f;种植区域混乱、…...

HunyuanVideo-Foley实战案例:为纪录片自动匹配环境音效的完整工作流

HunyuanVideo-Foley实战案例&#xff1a;为纪录片自动匹配环境音效的完整工作流 1. 项目背景与需求 在纪录片制作过程中&#xff0c;环境音效的采集和匹配往往需要耗费大量时间和人力成本。传统方式需要音效师实地录制或从音效库中手动挑选&#xff0c;整个过程耗时且难以保证…...

OpenClaw怎么集成?OpenClaw移动云小白6分钟搭建及使用指南【最新!】

OpenClaw怎么集成&#xff1f;OpenClaw移动云小白6分钟搭建及使用指南【最新&#xff01;】。OpenClaw怎么部署&#xff1f;本文面向零基础用户&#xff0c;完整说明在轻量服务器与本地Windows11、macOS、Linux系统中部署OpenClaw&#xff08;Clawdbot&#xff09;的流程&#…...

从人工到智能:SubtitleOCR如何实现硬字幕提取的效率革命

从人工到智能&#xff1a;SubtitleOCR如何实现硬字幕提取的效率革命 【免费下载链接】SubtitleOCR 快如闪电的硬字幕提取工具。仅需苹果M1芯片或英伟达3060显卡即可达到10倍速提取。A very fast tool for video hardcode subtitle extraction 项目地址: https://gitcode.com/…...

OpenClaw核心揭秘:Agentic Loop如何驱动AI持续思考与行动?

上一篇讲了 Gateway——它像餐厅前台&#xff0c;负责接收订单、分发任务。 但订单到了厨房&#xff0c;厨师是怎么做菜的&#xff1f; 这就是 Agentic Loop&#xff08;推理循环&#xff09;的事了。 它是 OpenClaw 的"大脑"&#xff0c;决定 Agent 如何思考、如何行…...

东佑达步进电缸控制器TC100的labview控制vi,可以通过RS485控制电缸运动

东佑达步进电缸控制器TC100的labview控制vi&#xff0c;可以通过RS485控制电缸运动搞TC100步进电缸纯粹是工位剩下一台&#xff0c;手边摸鱼攒的带隔离USB转485&#xff08;怕烧这玩意儿的输入输出&#xff0c;几十块钱的CP2102光耦隔离那种&#xff0c;学生党/小作坊首选&…...

Linux initramfs深度解析: 从内核启动到根文件系统的桥梁(3)

接前一篇文章&#xff1a;Linux initramfs深度解析: 从内核启动到根文件系统的桥梁&#xff08;2&#xff09; 设计思想与架构 1. 为什么需要initramfs 在initramfs出现之前&#xff0c;系统启动有一个根本性的问题&#xff1a;内核需要访问根文件系统来加载驱动程序&#xf…...

深入解析NAND Flash基础操作与系统集成——从阵列结构到多Die协同

1. NAND Flash基础结构与工作原理 NAND Flash存储器是现代存储系统的核心组件&#xff0c;从U盘到企业级SSD都依赖这项技术。要理解它的强大之处&#xff0c;得先从它的物理结构说起——想象一个巨大的立体停车场&#xff0c;每个停车位就是一个存储单元&#xff0c;而控制电路…...

颠覆PDF转换体验:Marker无缝实现25页/秒全场景文档格式精准迁移

颠覆PDF转换体验&#xff1a;Marker无缝实现25页/秒全场景文档格式精准迁移 【免费下载链接】marker 一个高效、准确的工具&#xff0c;能够将 PDF 和图像快速转换为 Markdown、JSON 和 HTML 格式&#xff0c;支持多语言和复杂布局处理&#xff0c;可选集成 LLM 提升精度&#…...

GitHub Desktop中文汉化终极指南:三分钟解锁全中文Git操作体验

GitHub Desktop中文汉化终极指南&#xff1a;三分钟解锁全中文Git操作体验 【免费下载链接】GitHubDesktop2Chinese GithubDesktop语言本地化(汉化)工具 项目地址: https://gitcode.com/gh_mirrors/gi/GitHubDesktop2Chinese 还在为GitHub Desktop的英文界面而烦恼吗&am…...

宁波小程序公司提供专业的小程序开发服务

在宁波小程序公司的服务中&#xff0c;我们致力于为客户提供清晰的内容结构和流畅的表达。我们通过深入的需求分析&#xff0c;确保每个项目都能符合客户特定的期望和市场需求。设计阶段注重市场调研&#xff0c;力求在视觉和功能上都能满足用户的使用习惯和偏好。开发过程中&a…...

Play Integrity Fix:高效解决Android设备认证问题的实战指南

Play Integrity Fix&#xff1a;高效解决Android设备认证问题的实战指南 【免费下载链接】PlayIntegrityFix Fix Play Integrity (and SafetyNet) verdicts. 项目地址: https://gitcode.com/GitHub_Trending/pl/PlayIntegrityFix 问题引入&#xff1a;Android设备认证的…...

突破VMware限制:在非苹果硬件上构建macOS开发环境完全指南

突破VMware限制&#xff1a;在非苹果硬件上构建macOS开发环境完全指南 【免费下载链接】unlocker 项目地址: https://gitcode.com/gh_mirrors/unloc/unlocker 实现跨平台macOS体验&#xff1a;VMware Unlocker核心价值解析 当开发者需要在Windows或Linux工作站上构建m…...

微信无法登录时的恢复操作

本文记录 OpenClaw 中 openclaw-weixin 插件在登录态丢失、微信链接不可用、扫码登录失败时的恢复流程。2026-03-23 版本 OpenClaw 更新后曾出现微信插件失效,但在 2026-03-24 版本中已恢复。本文目标是先判断问题类型,再选择最小影响的修复方式,避免不必要的全量重装。 一、…...

老牌CMS的隐痛:从DedeCMS漏洞看开源系统会员模块的安全设计误区

DedeCMS会员模块漏洞剖析&#xff1a;开源系统安全设计的深层反思 当一款拥有百万级安装量的老牌CMS系统曝出前台任意密码修改漏洞时&#xff0c;我们看到的不仅是一个具体的技术缺陷&#xff0c;更是开源项目在安全架构设计上的系统性隐忧。2018年那场影响广泛的DedeCMS漏洞事…...

【RISC-V 指令集】RISC-V 向量V扩展指令集介绍(五)- 动态配置与性能优化实战(vsetvli/vsetivli/vsetvl)

1. 动态向量配置指令的核心作用 RISC-V向量扩展指令集中最精妙的设计之一&#xff0c;就是允许程序运行时动态调整向量处理参数的机制。想象你正在用不同尺寸的螺丝刀组装家具——当遇到大螺丝就换大号刀头&#xff0c;碰到小螺丝立即切换精密刀头&#xff0c;这就是vsetvli/vs…...

MicroOS:Arduino轻量级任务调度内核详解

1. MicroOS&#xff1a;面向Arduino的轻量级任务管理内核概述MicroOS是一个专为Arduino平台设计的极简型实时任务管理器&#xff0c;其核心定位并非替代FreeRTOS或Zephyr等完整RTOS&#xff0c;而是填补Arduino原生loop()单线程模型在多任务调度、精确定时与事件解耦方面的空白…...

利用快马平台十分钟搭建树莓派环境监测系统原型

今天想和大家分享一个快速搭建树莓派环境监测系统的小实验。作为一个硬件爱好者&#xff0c;我经常用树莓派做各种物联网原型开发&#xff0c;但每次从零开始配置环境、写基础代码都很耗时。最近发现InsCode(快马)平台能帮我省去很多重复工作&#xff0c;特别适合快速验证想法。…...

用MediaPipe和Python做个隔空切水果游戏:从手势骨架提取到简单游戏逻辑实现

用MediaPipe和Python打造体感切水果游戏&#xff1a;从手势识别到游戏逻辑全解析 还记得小时候在街机厅玩《水果忍者》的畅快感吗&#xff1f;现在&#xff0c;我们完全可以用Python和MediaPipe技术&#xff0c;在电脑前通过手势隔空切水果&#xff01;本文将带你从零开始&…...

STM32串口通信原理与实现详解

串口通信技术深度解析&#xff1a;从原理到STM32实现1. 串口通信基础概念1.1 数据传送方向分类串行通信根据数据传输方向可分为三种基本模式&#xff1a;单工模式&#xff1a;数据仅支持单向传输&#xff0c;如传统的广播系统。发送端和接收端角色固定&#xff0c;硬件上只需单…...

Android开机向导定制实战:从源码分析到禁用状态栏的隐藏技巧

Android开机向导深度定制&#xff1a;从源码解析到状态栏控制实战 第一次接触Android开机向导定制时&#xff0c;我被这个看似简单却隐藏复杂逻辑的系统组件深深吸引。作为设备初始化的第一道门户&#xff0c;开机向导不仅承载着用户体验的第一印象&#xff0c;更是厂商品牌展示…...

AceCommon:Arduino嵌入式零堆分配轻量C++工具库

1. AceCommon 库概述&#xff1a;面向嵌入式 Arduino 的轻量级底层工具集AceCommon 是一个专为资源受限的微控制器平台&#xff08;尤其是 Arduino 生态&#xff09;设计的零依赖、低开销 C 工具库。其核心设计哲学是“小而精、无侵入、可复用”。与常见的功能臃肿、依赖繁杂的…...