一文初识瑞萨FSP固件库
第9章
初识瑞萨FSP固件库
9.1瑞萨FSP库简介
FSP全称为“Flexible Software Package”,中文译为“灵活配置软件包”。
FSP旨在以较低的内存占用量提供快速高效的驱动程序和协议栈。FSP集成了中间件协议栈、独立于RTOS的硬件抽象层(HAL)驱动程序,以及最基础的板级支持包(BSP)驱动程序。FSP还支持FreeRTOS实时操作系统(RTOS)。
如图所示为FSP的软件架构。
FSP由瑞萨公司维护和提供支持,开发人员可以从集成开发环境(e2s)或FSP的GitHub仓库查看或下载FSP的源代码,从而全面地了解FSP。(您可复制下方链接至浏览器,或扫描二维码进行查看)
FSP的GitHub仓库
https://github.com/renesas/fsp
提示
FSP是使用C99(C语言标准)编写的开源软件,提供完整的源代码,但仅限用于瑞萨的硬件。
9.2瑞萨FSP库架构分析
下面简单分析一下瑞萨FSP库架构。本小节内容当中的一些概念可能会让初学者觉得较难理解,对此,建议是大概浏览然后跳过即可,这不影响后面的章节阅读,现在只需要大概、初步地了解一遍,不求甚解,等到学习到了后期再回过头来看,或对FSP库架构会有新的体会。
9.2.1FSP库层次结构
如图所示,展示了FSP库的层次划分,我们可以很直观地看到进行层次划分之后的软件结构。
RA MCU
位于最底层的是RA系列微控制器硬件。不同系列的RA微控制器之间具有非常一致、高度兼容的外设硬件,这为软件开发人员提供了极大的便利。
BSP
往上一层是板级支持包(BSP)。BSP处于FSP软件的底层,是FSP的功能基础。BSP负责MCU复位后初始化系统使程序执行进入main函数,并为上层软件提供其他服务。
BSP函数名称以R_BSP_开头,BSP宏以BSP_开头,数据类型定义以_bsp开头,以便于与FSP的其他部分区分开来。
HAL
在BSP之上是硬件抽象层(Hardware Abstraction Layer(HAL)),它以较小的内存占用量为外设提供高效的设备驱动程序,实现易于使用的接口,使开发人员不必直接处理单片机的寄存器组,并使处于HAL层以上的软件更容易在整个RA产品家族中移植。它是模块(Modules)的集合,每个模块都是RA系列微控制器中可用的外设的驱动程序(比如SPI、I2C、ADC),其名称以r_开头。所有这些模块本质上均与RTOS无关。HAL层除了“模块”以外还有:“接口”、“实例”等关键概念。
HAL层的函数的名称以R_开头,格式一般为R_
操作系统和中间件
FSP库首选支持FreeRTOS,可以通过软件快速配置。FreeRTOS是非常流行的实时操作系统,支持多任务调度、任务通知、队列、互斥、信号量和软件计时器等功能,其系统开销非常小,占用的内存也很小,性能可靠,经常被用于内存资源十分有限且需要实时响应处理的操作环境。
中间件介于HAL硬件抽象层和用户应用层之间,为应用层提供服务。FSP的中间件支持包括:TCP/IP协议栈、USB协议栈、WiFi和蓝牙BLE协议栈、电容式触摸、FAT文件系统、图形库、加密等等。FSP中间件函数的名称命名格式一般为:RM_
应用层
该层为FSP层次划分的最顶层,包含了用户的应用代码。用户通过FSP底层提供的直观、简单和统一的API接口调用下面各层,从而访问FSP的所有功能,这样用户就能以非常简单和直接的方式编写易于理解、维护简单、移植方便的代码。
9.2.2FSP库工程结构
我们再来看由软件自动生成的FSP库工程的结构究竟是什么样子的。
列表1:FSP库工程结构
左右滑动查看完整内容
Project ├─ ra │ ├─ arm 包含 ARM CMSIS 代码 │ └─ fsp 包含 FSP 库本体 │ ├─ inc │ │ ├─ api FSP 接口 (FSP Interfaces)(接口包含 API 定义) │ │ └─ instances FSP 实例 (FSP Instances)(接口的实例) │ └─src │ ├─ bsp BSP 层 (Board Support Package) │ │ ├─ cmsis 包含寄存器定义文件和启动文件 │ │ └─ mcu 包含 BSP 代码 │ └─ r_FSP 模块 (FSP Modules)(接口由模块实现,模块通过接口提供通 用功能) ├─ ra_cfg 包含 FSP 库的配置(包括 BSP 和 HAL 层的配置) ├─ ra_gen 包含用户的 FSP 配置数据(包括 时钟、引脚、各个外设、中断向量等 配置数据) ├─ Debug/Release 包含编译后生成的中间文件和最终可执行文件等 └─src └─hal_entry.c包含了用户裸机应用程序的入口函数 hal_entry。 当没有使用 RTOS 的时候,hal_entry 函数由 C 语言main函数 调用, 所以其作用基本等同于main
上面的FSP库工程的结构其实非常的简单。只要我们把“Project”下的内容分为三部分:
第一部分为FSP库及其配置,包括ra、ra_cfg、ra_gen这3个文件夹,它们由软件生成。
第二部分为用户代码,包括src文件夹。
第三部分为编译输出文件,包括Debug或Release文件夹。
那么,我们便不需要深入地理解FSP库的架构也可以很好的上手FSP库进行开发,因为我们在配置FSP库的时候,是通过软件的图形界面(FSP配置器)来配置的。
警告
注意:任何由软件生成的文件用户都不应该去编辑!因为在每次进行FSP配置之后单击“生成项目内容(Generate Project Content)”图标按钮时,软件都会自动重新创建这些文件,因此任何的更改都将被覆盖。
对于想要深入理解FSP库的读者,可以尝试阅读其源码。同时,要想清晰地理解FSP库的架构,需要掌握以下几个相关的重要概念。
1.模块(Modules):模块可以是外设驱动程序、纯软件或介于这两者之间,并且是FSP的构建模块。模块通常是独立的单元,但它们可能依赖于其他模块。可以通过组合多个模块来构建应用程序,为用户提供所需功能。
2.模块实例(Module Instance):模块的单个、独立实例化(模块配置)。例如,USB端口可能需要使用r_dmac模块的两个实例与其他端口之间来回传输数据;又例如,当应用程序需要使用两个GPT定时器时,每一个这个定时器都是r_gpt模块的实例。
3.接口(Interfaces):接口包含API定义,具有相似功能的模块可以共用这些API定义。模块通过这些定义提供通用功能。通过这些API定义,使用相同接口的模块可以互换使用。可以将接口视为两个模块之间的合同,两个模块均同意使用合同中达成一致的信息进行协作。接口只是定义,并不会增加代码的大小。
4.实例(Instances):接口规定所提供的功能,而接口的实例则真正实现了这些功能。每个实例都与特定的接口关联,并使用接口中的枚举、数据结构和API原型。这样,应用程序便可以在需要时交换实例。
5.堆叠(Stacks):FSP架构所采用的设计方式是,模块可以堆叠起来协同工作,从而形成了一个FSP堆。将一个模块所能提供的功能与另一个模块所需要的功能相匹配,这就是堆叠过程。堆由顶层模块及其所有依赖项组成。
6.应用程序(Application):归用户所有并由用户维护的代码。
7.回调函数(Callback Functions):当有事件发生时(例如,USB接收到一些数据时),中断服务程序(ISR)将调用这些函数。中断回调函数是应用程序的组成部分,如果是在中断使用,应尽量简短,因为它们将在中断服务程序内运行,会阻碍其他中断执行。
关于接口与实例的概念:接口规定所提供的功能,而实例则真正实现了这些功能。每个实例都与特定的接口关联,并使用接口中的枚举、数据结构和API原型。这样,使用接口的应用程序便可以根据需要交换实例,从而在需要更改代码或所用外设时节省大量的时间。在RA产品家族MCU上,一些外设(例如IIC)将具有一对一的映射关系(只映射到IIC接口),而其他外设(例如SCI)将具有一对多的映射关系(实现三个接口:IIC、UART、SPI)。如下图所示展示了这种映射关系。