嵌入式驱动接口在C语言里的实现
为什么要实现接口
接口,可以是硬件与硬件之间连接的桥梁,可以是软件与软件之间沟通的窗户,也可以是硬件与软件之间通信的枢纽。其中硬件与硬件之间的桥梁,比如I2C、UART、CANFD、等等,软件与软件之间沟通的窗户,比如操作系统提供的各种API、等等。我实现的这套“接口”,连接了硬件与软件,它可以实现软硬件的完全解耦合,引入了平台无关性,提供了尽可能简化的逻辑,这有点类似于开汽车,一个人一旦学会了开汽车,那开什么牌子的汽车都基本是一个道理,实现了一套驱动,一套接口,对于不同系统、硬件平台的支持,这无疑会大大提高代码的易用性、复用性,大大减少重复的造轮子。
我所实现的接口
- 首先,需要一个结构体来存放系统接口,不妨叫system_interface_t,它用来存放系统的函数实现,是我们将驱动对接到不同平台的关键
1 | typedef struct { |
推荐将上述代码放在一个.h文件里,这样不同的驱动只需要这一套接口即可
- 接下来,需要一个结构体来存放system_interface_t(这样做的目的是实现不同驱动可以复用同一套接口),以及驱动内部实现的各种函数,比如对于aht20温度计而言,则除了对接系统的system_interface_t结构体,还应存放用于读取温度的函数
1 | typedef struct { |
- 然后可以构建一个whoami函数,用于对底层驱动的对接写入,以及对设备调用函数的暴露
1 | generic_err_t generic_sensor_aht20_whoami(generic_sensor_aht20_driver_interface_t *pfdev, |
注意这里要先给generic_sensor_aht20_driver_interface_t下的system_interface_t申请一块内存,否则直接调用pfdev->pfsystem_interface会指向非法内存,造成段错误
关于调用
可以在初始化的时候进行驱动程序的注册,不要忘记申请内存
1 | generic_sensor_aht20_driver_interface_t *aht20_device = malloc(sizeof(generic_sensor_aht20_driver_interface_t)); |
然后调用whoami函数,对接系统底层到驱动层
1 | generic_sensor_aht20_whoami(aht20_device, |
接着,便可以通过下面这种方式调用驱动暴露出来的API
1 | aht20_device->pfinit(aht20_device); // 如pfinit(void *pfdev) |
删除设备
我们前面通过malloc为设备的系统驱动以及设备暴露的接口分配了内存,下面通过释放这两块内存来删除设备
1 | generic_err_t generic_sensor_aht20_del(generic_sensor_aht20_driver_interface_t *pfdev) { |
驱动编写
驱动编写中,注意每个驱动内部的API都需要一个void *类型的指针,用来调用generic_sensor_aht20_driver_interface_t的驱动接口
All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.
Comment