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

以串口接口为例介绍关于BSP底层架构开发的迭代过程

以串口接口为例介绍关于BSP底层架构开发的迭代过程

文章目录

  • 以串口接口为例介绍关于BSP底层架构开发的迭代过程
    • 架构概述
    • 初代BSP
    • 二代BSP:
    • 三代BSP:
    • 四代BSP:

架构概述

单片机开发有四个阶段:

阶段一:单一单片机的功能实现阶段

此阶段你开始熟悉STM32F1系列的单片机,并利用其完成相应的功能,比如点了个灯,通过串口发了个”STM32F103 Hello World“,你完成了第一个工程,将其命名为STM32F103_Hello.

此阶段不考虑单片机的移植性,只管实现功能,你可以在一个main函数写上几千行的代码,当你觉得一个main函数的代码太长不好维护时,即开始进入阶段二:

阶段二:单一单片机的模块化实现阶段

此阶段你已经会使用STM32F1系列单片机的各种不同外设,并打算将外设代码进行模块化。

此阶段不考虑单片机的移植性,但需要考虑代码的复用性,你将main函数的几千行代码拆分成一个个的模块,模块间的调用完全随性而为,低内聚,高耦合的代码随处可见,改动一个模块会影响太多其他模块,当你觉得需要对模块进行解耦,以实现标准化模块间的复用时,你就开始进入阶段三:

阶段三:同一厂商不同系列单片机的应用层模块复用实现阶段

此阶段你实现了代码模块化,会通过接口间的数据实现松散耦合调用

此阶段你可以通过调用以前写好的应用层模块,来满足更换同一厂商的不同单片机时,只需改动少量代码的需求,然而对于大量硬件传感器等外设,不可能做到模块复用,因为传感器的模块太过依赖于底层接口的实现,你要初始化它的引脚,就得调用它的时钟使能接口方法,调用它的gpio库初始化方法,要点个灯,就得调用它的gpio拉高拉低方法,而这些接口在同一厂商的不通系列单片机中,居然都会不一致。于是你不能忍,决定自己开发一个接口更加标准化的库。

阶段四:不用厂商不同系列单片机的分层架构实现阶段

此阶段你完成了BSP-SYSTEM-HARDWARE-APP四层架构,各个层次分工明确。BSP负责外设驱动初始化,配置,调用引脚电平拉高拉低等,SYSTEM负责系统精确延时,及时间片的轮询处理,HARDWARE负责调用BSP的统一接口,实现各个传感器或硬件的初始化及数据收发,APP包含各种通信协议处理及控制逻辑处理,不同单片机通过加入不同的BSP,而SYSTEM-HARDWARE-APP都可以做到不变。

类似的,我们的BSP底层架构开发也经历了若干版本。

初代BSP

最初的版本只限于单个单片机使用,底层和应用层完全没有隔离,经常可见在main函数里操作GPIO库函数的情况,这种架构模式的好处是开发简单,不用考虑复杂的移植性,因此耦合度过高,同厂商不同内核的单片机移植,都会改动大量代码。

初版的串口驱动接口是这个样的:

void USART_driverInit(USART_TypeDef* USARTx, uint32_t baudRate, uint8_t preemptionPriority, uint8_t subPriority);void USART_sendByte(USART_TypeDef* USARTx, uint8_t byte);
void USART_sendMsg(USART_TypeDef* USARTx, uint8_t *sendBuf, uint32_t len);void USART1_dmaTxIsr(void);
void USART2_dmaTxIsr(void);
void USART3_dmaTxIsr(void);
void UART4_dmaTxIsr(void);void USART1_recvIsr(void);
void USART2_recvIsr(void);
void USART3_recvIsr(void);
void UART4_RecvIsr(void);

假设某个应用层要引用它,就必须得包含USART_TypeDef*这个定义的文件,如果不同的厂商串口结构定义不是这个怎么办。

在迭代中我们想到用USART_t给USART_TypeDef*取别名

typedef USART_TypeDef* USART_t;

随着gpio口和dma操作的增加,这种取别名的方式,也不能解决问题,有些结构体内部的成员名都不相同。

于是,我们对BSP架构进行了升级,使其可以兼容更多单片机甚至国产化的单片机。

二代BSP:

方法是建立BSP-SYSTEM-HARDWARE-APP四层架构。

其中不同系列的单片机使用不同BSP框架,保留相同命令的接口,SYSTEM-HARDWARE-APP如果需要调用这个接口,只需要引用XXX系列单片机目录下的BSP头文件。

这个版本的串口驱动接口是这个样的:

typedef USART_TypeDef* USART_Type_t;
typedef struct USART_Struct* USART_t;
typedef struct USART_Struct
{USART_Type_t usart;uint32_t baudRate;  uint8_t priority;uint8_t subPriority;uint16_t parity;uint16_t stopBits;uint16_t wordLength;uint32_t RS485Delay;USART_Config_t config; USART_Transport_t *send;USART_Transport_t *receive;uint32_t timeout;uint32_t linkCount;bool isRS485Connected;void (*USART_TypeInit)(USART_t USART);void (*USART_SendByte)(USART_t USART, uint8_t byte);void (

相关文章:

以串口接口为例介绍关于BSP底层架构开发的迭代过程

以串口接口为例介绍关于BSP底层架构开发的迭代过程 文章目录 以串口接口为例介绍关于BSP底层架构开发的迭代过程架构概述初代BSP二代BSP:三代BSP:四代BSP:架构概述 单片机开发有四个阶段: 阶段一:单一单片机的功能实现阶段 此阶段你开始熟悉STM32F1系列的单片机,并利用…...

Label-Studio ML利用yolov8模型实现自动标注

引言 Label Studio ML 后端是一个 SDK,用于包装您的机器学习代码并将其转换为 Web 服务器。Web 服务器可以连接到正在运行的 Label Studio 实例,以自动执行标记任务。我们提供了一个示例模型库,您可以在自己的工作流程中使用这些模型&#x…...

【PostgreSQL】实战篇——用户管理、角色和权限控制的高级用法及技巧

数据库中用户管理、角色和权限控制不仅仅是基础的安全措施,更是实现复杂应用需求和优化数据库性能的重要手段。 通过深入理解这些概念,数据库管理员可以更有效地管理用户访问、确保数据安全,并优化系统性能。以下是对这些概念的详细介绍以及…...

Leetcode: 0011-0020题速览

Leetcode: 0011-0020题速览 本文材料来自于LeetCode solutions in any programming language | 多种编程语言实现 LeetCode、《剑指 Offer(第 2 版)》、《程序员面试金典(第 6 版)》题解 遵从开源协议为知识共享 版权归属-相同方式…...

Hive数仓操作(七)

一、 Hive动态分区表 1. 动态分区与静态分区的区别 分区定义: 静态分区:在插入数据时,需要手动指定分区字段的值。动态分区:分区字段的值是根据数据中的某个字段自动生成的,用户只需指定分区字段的类型。 数据加载方…...

Redis进阶篇 - 缓存穿透、缓存击穿、缓存雪崩问题及其解决方案

文章目录 1 文章概述2 缓存穿透2.1 什么是缓存穿透?2.2 缓存穿透的解决方法2.2.1 做好参数校验2.2.2 缓存无效Key2.2.3 使用布隆过滤器2.2.4 接口限流 3 缓存击穿3.1 什么是缓存击穿?3.2 缓存击穿的解决方法3.2.1 调整热点数据过期时间3.2.2 热点数据预热…...

一天认识一个硬件之电源

无论是台式机还是笔记本,都离不开电源,台式机和笔记本电脑的电源都承担着将交流电转换为直流电,并为电脑内部各个部件提供稳定电力供应的重要任务。今天就来分享一下台式机和笔记本的电源区别 设计和功率 台式机电源:设计为内置…...

关于BSV区块链覆盖网络的常见问题解答(上篇)

​​发表时间:2024年9月20日 在BSV区块链上的覆盖网络服务为寻求可扩展、安全、高效交易处理解决方案的开发者和企业家开辟了新的视野。 作为开创性的曼达拉升级的一部分,覆盖网络服务提供了一个强大的框架,用于管理特定类型的交易和数据访问…...

VUE 开发——Node.js学习(一)

一、认识Node.js Node.js是一个跨平台JavaScript运行环境,使开发者可以搭建服务器端的JavaScript应用程序 使用Node.js编写服务器端程序——编写数据接口、前端工程化; Node.js环境没有BOM和DOM; Node.js安装:下载node-v16.19…...

角膜移植难题现,传统方式缺陷显,创新水凝胶破局

大家好!今天来了解一篇天然聚合物衍生光固化生物粘附水凝胶研究——《Natural polymer-derived photocurable bioadhesive hydrogels for sutureless keratoplasty》发表于《Bioactive Materials》。本文介绍了一种用于无缝合角膜移植术的天然聚合物衍生光固化生物粘…...

探索Spring Boot:实现“衣依”服装电商平台

1系统概述 1.1 研究背景 如今互联网高速发展,网络遍布全球,通过互联网发布的消息能快而方便的传播到世界每个角落,并且互联网上能传播的信息也很广,比如文字、图片、声音、视频等。从而,这种种好处使得互联网成了信息传…...

使用 cron 来设置定时任务

使用 cron 来设置定时任务,以便定期运行这个脚本。 在 Linux 系统中设置定时任务的步骤: 1. 编辑 cron 任务 打开终端并输入以下命令以编辑 crontab 文件: crontab -e2. 设置每天 8 点运行脚本 在 crontab 文件的最后,添加以下…...

C# Blazor Server 调用海康H5Player播放摄像头画面

目标 调用海康综合安防平台api,通过摄像头的cameraIndexCode调用【获取监控点预览取流URLv2】api,得到websocket 的url,然后在blazor server中使用htplayer.js播放摄像头实时画面。 步骤 根据摄像头名字,调用【查询监控点列表v2…...

CSS实现服务卡片

CSS实现服务卡片 效果展示 CSS 知识点 回顾整体CSS知识点灵活运用CSS知识点 页面整体布局 <div class"container"><div class"card"><div class"box"><div class"icon"><ion-icon name"color-pal…...

问:如何判断系统环境是大端/小端存储?

大端存储&#xff08;Big Endian&#xff09;和小端存储&#xff08;Little Endian&#xff09;是两种不同的字节序&#xff08;即字节顺序&#xff09;规则&#xff0c;用于在计算机中存储和表示多字节数据类型&#xff08;例如整数&#xff09;。 概念解释 大端存储&#x…...

使用NumPy进行线性代数的快速指南

介绍 NumPy 是 Python 中用于数值计算的基础包。它提供了处理数组和矩阵的高效操作&#xff0c;这对于数据分析和科学计算至关重要。在本指南中&#xff0c;我们将探讨 NumPy 中可用的一些基本线性代数操作&#xff0c;展示如何通过运算符重载和内置函数执行这些操作。 元素级…...

uni-app之旅-day02-分类页面

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言创建cate分支4.1 渲染分类页面的基本结构4.2 获取分类数据4.3 动态渲染左侧的一级分类列表4.4 动态渲染右侧的二级分类列表4.5 动态渲染右侧的三级分类列表4.6 …...

鸿蒙harmonyos next flutter通信之BasicMessageChannel获取app版本号

本文将通过BasicMessageChannel获取app版本号&#xff0c;以此来演练BasicMessageChannel用法。 建立channel flutter代码&#xff1a; //建立通道 BasicMessageChannel basicMessageChannel BasicMessageChannel("com.xmg.basicMessageChannel",StringCodec());…...

【文件增量备份系统】MySQL百万量级数据量分页查询性能优化

&#x1f3af; 导读&#xff1a;本文针对大数据量下的分页查询性能问题进行了深入探讨与优化&#xff0c;最初查询耗时长达12秒&#xff0c;通过避免全表计数及利用缓存保存总数的方式显著提升了浅分页查询速度。面对深分页时依然存在的延迟&#xff0c;采用先查询倒数第N条记录…...

音视频入门基础:FLV专题(12)——FFmpeg源码中,解析DOUBLE类型的ScriptDataValue的实现

一、引言 从《音视频入门基础&#xff1a;FLV专题&#xff08;9&#xff09;——Script Tag简介》中可以知道&#xff0c;根据《video_file_format_spec_v10_1.pdf》第80到81页&#xff0c;SCRIPTDATAVALUE类型由一个8位&#xff08;1字节&#xff09;的Type和一个ScriptDataV…...

Wan2.1视频生成创意玩法:把你的想法变成动态视觉故事

Wan2.1视频生成创意玩法&#xff1a;把你的想法变成动态视觉故事 1. 从文字到视频的魔法 你有没有过这样的经历&#xff1f;脑海中浮现出一个绝妙的创意场景&#xff0c;却苦于没有专业的视频制作技能将它呈现出来。或许是一个科幻故事的开场&#xff0c;一个产品演示的构想&…...

简单三步:部署Qwen3-ForcedAligner,实现音频转字幕的自动化流程

简单三步&#xff1a;部署Qwen3-ForcedAligner&#xff0c;实现音频转字幕的自动化流程 1. 工具核心价值与工作原理 1.1 为什么需要本地字幕生成工具 在视频创作和会议记录场景中&#xff0c;手动添加字幕既耗时又费力。传统在线字幕服务存在隐私泄露风险&#xff0c;且通常…...

BusyBox根文件系统制作避坑指南:如何让QEMU模拟的ARM板成功挂载你的第一个Linux系统

BusyBox根文件系统制作避坑指南&#xff1a;如何让QEMU模拟的ARM板成功挂载你的第一个Linux系统 当你在QEMU上启动一个精心编译的ARM Linux内核时&#xff0c;最令人沮丧的莫过于看到内核在挂载根文件系统时崩溃。作为嵌入式Linux开发的关键环节&#xff0c;根文件系统的构建往…...

毕业设计用什么ai?实测8款AI论文生成工具测评,查重率仅6%超可靠!

每到毕业季&#xff0c;论文写作就成了无数学生的头号难题。从开题报告到文献综述&#xff0c;再到数万字的正文&#xff0c;每个环节都充满挑战。别担心&#xff01;AI论文写作工具的出现&#xff0c;让高效完成高质量论文成为可能。本文实测了8款主流AI论文生成工具&#xff…...

百考通:AI精准赋能实践报告,让实习总结高效又专业

对于每一位在校学生和职场新人而言&#xff0c;实践报告都是记录成长、沉淀经验的关键载体&#xff0c;却也常常成为令人头疼的难题&#xff1a;要么不知如何梳理工作脉络&#xff0c;要么难以精准提炼收获与反思&#xff0c;要么在格式规范和字数要求上反复纠结。百考通&#…...

OpenClaw开发环境配置:千问3.5-9B辅助的IDE插件管理

OpenClaw开发环境配置&#xff1a;千问3.5-9B辅助的IDE插件管理 1. 为什么需要AI辅助的IDE管理 作为一个长期在多个项目间切换的全栈开发者&#xff0c;我深受开发环境配置问题的困扰。每次换新电脑或者重装系统&#xff0c;光是配置VSCode插件和项目依赖就要耗费大半天时间。…...

嵌入式系统接口技术详解与应用实践

1. 嵌入式系统接口技术概述在嵌入式系统开发中&#xff0c;接口技术是连接处理器与外部设备的关键桥梁。作为一名嵌入式开发工程师&#xff0c;我经常需要根据项目需求选择合适的接口方案。本文将基于多年实战经验&#xff0c;深入解析各类嵌入式接口的工作原理、应用场景和选型…...

Linux驱动开发中的Devres资源管理机制解析

1. Linux驱动开发中的资源管理痛点 在Linux驱动开发中&#xff0c;资源管理一直是个令人头疼的问题。想象一下这样的场景&#xff1a;你正在编写一个摄像头驱动&#xff0c;需要依次申请内存、时钟、DMA通道、中断等多种资源。如果其中任何一步失败&#xff0c;都必须小心翼翼地…...

Word多级列表编号消失?别慌!用这个宏代码一劳永逸(附详细操作截图)

Word多级列表编号消失&#xff1f;三步根治方案与宏代码实战 写论文时目录编号突然消失&#xff1f;项目报告的多级列表格式莫名混乱&#xff1f;这种"幽灵问题"几乎困扰过每个深度使用Word的用户。传统方法往往只能临时修复&#xff0c;下次打开文档时问题依旧——直…...

别再只用Chat了!深度挖掘Cursor的‘规则’与‘上下文’功能,打造你的专属AI编程助手

解锁Cursor的隐藏力量&#xff1a;从代码助手到项目级智能架构师 在AI编程工具爆发的时代&#xff0c;大多数开发者仅仅停留在基础对话和代码补全的层面。但Cursor的真正价值远不止于此——它能够成为你项目架构的智能协作者、团队规范的自动化执行者&#xff0c;以及复杂工程问…...