用面向对象的思想开发CODESYS运行时之二

发布时间 2023-09-09 08:20:41作者: MichaelChen-99

通信接口抽象层设计

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数据结构中相应的函数指针去实现。