通信接口抽象层设计
CODESYS开发包中IoDrv的基本框架是通过调用实际的Linux驱动程序来实现操作硬件的,在针对不同的控制器外设,以及与控制器模块连接的不同硬件模块,需要做大量的工作来编写驱动和适配,花费大量的时间去调试和维护这些接口。
如果能采用分层架构设计,专门设计一层通信接口层,就可以做到IoDrv和嵌入式操作系统的驱动程序分离,不同功能分开管理,就可以降低开发难度,减少维护成本。
面向对象的角度看通信接口
虽然不同的通信接口实现不同,调用的嵌入式驱动不同,但最大的作用无非就是发送和接口,可以将基本相同部分抽象出来。
从面向对象的角度看,通信接口层是一个抽象类(abstract),接口抽象层用于将不同接口的数据提取出来,包括初始化,关闭,发送接收,处理,不同的帧头,不同硬件接口的可变参数是接口的文件操作符,发送接收的帧头打包和处理。
通信接口层的数据结构
通信接口数据结构为netif,将使用一个接口链表统一管理所有接口。
netif_list
|
\|/ netif netif netif
+-----------+ +-----------+ +-----------+
| next | ---> | next | ---> | next | ---> NULL
+-----------+ +-----------+ +-----------+
| init_fn | | init_fn | | init_fn |
+-----------+ +-----------+ +-----------+
| close_fn | | close_fn | | close_fn |
+-----------+ +-----------+ +-----------+
| send_fn | | send_fn | | send_fn |
+-----------+ +-----------+ +-----------+
| recv_fn | | recv_fn | | recv_fn |
+-----------+ +-----------+ +-----------+
具体说明如下:
变量 | 描述 |
---|---|
next | 链表指针 |
init_fn | 初始化函数指针 |
close_fn | 关闭函数指针 |
send_fn | 发送函数指针 |
recv_fn | 接收函数指针 |
update_fn | 交互通信函数指针 |
有时,控制器模块和连接的其他模块的内部通信采用采用交互式通信,即CPU发送命令或者数据后会马上等待回复,在回复中得到应答或者数据。因此还需要添加一个交互通信函数指针。
通信接口层的外部接口函数
用C语言来实现面向对象的编程方式,不仅需要定义相应的数据结构,还需要提供一些函数声明和实现,给其他源文件调用。
接口函数 | 描述 |
---|---|
create_if | 创建一个通信接口,并加入通信接口链表中 |
delete_if | 从通信接口链表中删除一个通信接口 |
find_if | 从通信接口链表中查找一个通信接口 |
小结
netif是对不同通信接口共同部分进行抽象而得到的接口层,外设或者扩展模块所使用的实际通信驱动程序需要在netif抽象层基础上进行扩展,也就是面向对象中的继承,通过定义netif数据结构中相应的函数指针去实现。