1.系统架构

系统划分为三层,即业务层(应用层),中间件层和驱动层.
应用层:专注于业务逻辑功能实现.
中间层:为应用层服务,为应用层提供相关服务接口,也具有少量的业务逻辑.
驱动层:提供硬件底层驱动程序.

架构框图
架构框图

分层思想优点:

(1).最大程度隐藏驱动代码,保护了代码的安全性。
(2).
接口统一,方便应用层开发。
(3).方便代码管理,同步开发。

2.接口标准化

标准接口分为三部分:驱动层接口、中间件统一接口、应用层接口
驱动接口:
由官方提供的统一接口,操作芯片相关寄存器实现某一功能接口(例如:STM32官方提供驱动接口有HAL库、LL库)。
中间件接口:中间件接口分为两类,对驱动层封装接口、供应用层调用接口。
应用层接口:本架构中,对应用层接口标准化并不严格,符合Linux内核编程规范与代码风格即可。

(1).驱动层接口(以STM32 LL库GPIO接口为例)

STM32 LL库是有意法半导体(STMicroelectronics)提供的一个官方标准可以,本库可用STM32CubeMX软件生成(使用STM32CubeMX软件记得及时更新官方最新版本,否则会出现各种奇奇怪怪的问题)。

 准备工作:

搭建STM32 GCC编译环境(详情见前面搭建环境的文章
使用STM32CubeMX软件生成STM32工程代码
修改Makefile文件,输出驱动层.a文件供中间层调用
驱动层接口:(LL_xxx_xxx)

ErrorStatus LL_GPIO_DeInit(GPIO_TypeDef *GPIOx);
ErrorStatus LL_GPIO_Init(GPIO_TypeDef *GPIOx, 
                            LL_GPIO_InitTypeDef *GPIO_InitStruct);
void LL_GPIO_StructInit(LL_GPIO_InitTypeDef *GPIO_InitStruct);

此类接口都是有官方提供,如需修改,先联系原厂工程师咨询。

(2).中间件接口

中间件接口分为两类:与驱动层对接、供应用层调用
与驱动层对接接口:(xxx_service.c)
此类函数接口以xxx_service的方式命名,实现对硬件接口的驱动功能,基本不包含逻辑类代码。

/// gpio初始化
int gpio_init_service(int argc);
/// gpio释放
int gpio_free_service(void);
/// 获取gpio的电平状态
int gpio_get_pin_service(int pin);
/// 设置gpio为高电平
int gpio_set_pin_service(int pin);
/// 设置gpio为低电平
int gpio_clear_pin_service(int pin);
/// 设置gpio为level电平
int gpio_set_pin_level_service(int pin, int level);
/// 设置gpio为输出引脚类型
int gpio_as_output_service(int pin, GPIO_PULL_SERVICE Pull_choice);
/// 设置gpio为输入引脚类型
int gpio_as_input_service(int pin, GPIO_PULL_SERVICE Pull_choice);
/// 设置gpio为模拟输入
int gpio_as_analog_input_service(int pin, GPIO_PULL_SERVICE Pull_choice);
/// 将gpio设置为pwm输出
int gpio_as_pwm_service(int pin);
/// 设置pwm gpio的输出频率
int gpio_set_pwm_freq_service(int pin, int freq, int duty_cycle);

应用层调用接口:(middle_xxx.c)
此类函数接口主要以mid_xxx_xxx的方式来命名,主要工作为申请内存、创建函数指针等工作。

/// gpio初始化
int mid_gpio_init(int argc);
/// gpio释放
int mid_gpio_free(void);
/// 获取gpio的电平状态
int mid_gpio_get_pin(int pin);
/// 设置gpio为高电平
int mid_gpio_set_pin(int pin);
/// 设置gpio为低电平
int mid_gpio_clear_pin(int pin);
/// 设置gpio为level电平
int mid_gpio_set_pin_level(int pin, int level);
/// 设置gpio为推挽输出引脚类型
int mid_gpio_as_output(int pin, GPIO_PULL_SERVICE Pull_choice);
/// 设置gpio为输入引脚类型
int mid_gpio_as_input(int pin, GPIO_PULL_SERVICE Pull_choice);
/// 设置gpio为模拟输入
int mid_gpio_as_analog_input(int pin, GPIO_PULL_SERVICE Pull_choice);
/// 将gpio设置为pwm输出
int mid_gpio_as_pwm(int pin);
/// 设置pwm gpio的输出频率
int mid_gpio_set_pwm_freq(int pin, int freq, int duty_cycle);

(3).应用层接口

应用层接口标准化并不严格,符合Linux内核编程规范与代码风格即可。
以main函数为例:

int main(int argc, char** argv)
{
	///调用middle层接口,现实相关应用逻辑
	mid_xxx();
	mid_xxx();
	....;
}

3、函数调用

应用层 ---> 调用 ---> 中间件(mid_xxx) ---> 调用 ---> 驱动对接接口(xxx_service) --->调用---> 驱动接口(LL_xxx_xxx)

4、分层架构目录

├── application
│   ├── bin
│   ├── burntools
│   ├── doc
│   ├── libs
│   └── src
│       ├── buildmake.pl
│       ├── datamng
│       ├── main.c
│       ├── Makefile
│       ├── massage
│       └── menu
├── driver_os
│   ├── fm33lc0xx
│   ├── stm32f0xx
│   └── stm32g0xx
│       ├── CMSIS
│       ├── Makefile
│       ├── stm32g0xx_hal_conf.h
│       └── STM32G0xx_LL_Driver
└── middle
    ├── buildMakefile.pl
    ├── lib
    ├── Makefile
    ├── middle_api
    │   ├── include
    │   └── source
    │          └── middle_gpio.c
    └── plateform
        ├── fm33lc0xx
        ├── stm32f030xx
        └── stm32g0xx
            ├── include
            ├── libs
            	   └── lib_stm32g0xx.a
            └── src
                   └── gpio_stm32g0xx.c

application:应用层逻辑函数
middle:中间件相关接口
driver_os:官方驱动接口

Logo

开源、云原生的融合云平台

更多推荐