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

server/2024/10/20 18:53:44/

以串口接口为例介绍关于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 (

http://www.ppmy.cn/server/127388.html

相关文章

探索Python的工业通信之光:pymodbus的奇妙之旅

文章目录 探索Python的工业通信之光:pymodbus的奇妙之旅背景:为何选择pymodbus?pymodbus是什么?如何安装pymodbus?5个简单的库函数使用方法3个场景使用示例常见bug及解决方案总结 探索Python的工业通信之光&#xff1a…

Linux下Socket编程

1. Socket简介 Socket是什么? Socket是一种进程间通信的机制,通过它应用程序可以通过网络进行数据传输。Socket提供了一种跨平台的接口,使得同样的代码可以在不同的操作系统上运行。Socket类型 流式套接字(SOCK_STREAM&#xff0…

Linux中的 `vi` 与 `vim` 使用详解

文章目录 Linux中的 vi 与 vim 使用详解1. vi 编辑器1.1 什么是 vi1.2 vi 的基本用法1.2.1 启动 vi1.2.2 模式1.2.3 基本操作1.2.4 常用命令 1.3 vi 的特点 2. vim 编辑器2.1 什么是 vim2.2 vim 的基本用法2.2.1 启动 vim2.2.2 模式2.2.3 vim 的增强功能2.2.4 vim 的基本操作 2…

Oracle 配置恢复目录catalog

一.介绍 Oracle中使用RMAN备份的数据我们分为两类 RMAN知识库数据库的数据块 Oracle默认把 RMAN知识库 放在目标数据库的控制文件中,在以后进行恢复的时候 我们要先读知识库的信息然后才能恢复。 但这样就产生了一个问题,知识库放在了控制文件上&#xf…

国庆更新|芒果YOLOv8改进181:即插即用,最新注意力机制EMA:具有跨空间学习的高效多尺度注意力模块,ICCASSP论文

💡本篇内容:芒果YOLOv8改进135:最新注意力机制EMA:即插即用,具有跨空间学习的高效多尺度注意力模块,ICCASSP 论文 **EMA|具有跨空间学习的高效多尺度注意力模块 | 即插即用 该模块通常包括多个并行的注意力子模块,每个子模块关注于输入数据的不同尺度或分辨率。这些子模块…

2017~2018博文汇总目录

2018 设置IDEA支持JS ES6语法_idea 社区版 js语法-CSDN博客 Slf4j 不起作用的问题_slf4j不起作用-CSDN博客 GC垃圾回收器:CMS收集器和G1收集器优缺点_g1gc的缺点-CSDN博客 Java并发之AQS详解-CSDN博客 计数排序、桶排序、基数排序_if (array.length 0) return …

检查cuda和显卡的可用性

检查cuda和显卡的可用性 import torch device_gpu torch.device(cuda if torch.cuda.is_available() else cpu) print(device_gpu) print(torch.cuda.is_available())

通讯录动态+文件版本

通讯录 前言初始化通讯录增加联系人展示通讯录查找联系人删除联系人修改联系人排序加载文件到通讯录保存通讯录到文件销毁通讯录 源代码文末 前言 🎊个人主页:https://blog.csdn.net/2401_83251330?spm1000.2115.3001.5343 🎀 🎉欢迎大家点赞…