APP下载

基于QNX操作系统的多主桥PCIE总线驱动开发

2021-10-28王吉平

汽车实用技术 2021年19期
关键词:主桥寄存器驱动程序

王吉平

(中车青岛四方车辆研究所有限公司技术中心,山东 青岛 266031)

前言

QNX软件系统公司建立于1980年,是实时嵌入式操作系统主要提供商之一。QNX产品作为高可靠性的微内核系统,经过了近30年的发展,已经遍及全球100多个国家和地区,成功应用在各种嵌入式系统中。PCIE(PCI-Express)总线是取代PCI总线的第三代I/O技术,作为处理器系统的局部总线,目的是连接高速外部设备,采用高速差分总线,端对端的连接方式,因此PCIE总线与PCI总线的拓扑结构有所不同。

1 QNX操作系统驱动程序架构

在基于QNX构建的系统中,为了使裁剪的系统占用尽可能小的存储空间,同时还具有相当的灵活性,能够同时处理系统中的各种硬件设备,因此QNX允许用户编写用户进程作为资源管理器,管理各种设备[1]。图1为QNX内核和用户进程关系。

图1 QNX内核和用户进程关系

QNX内核通过消息总线可以实现进程管理、Flash驱动、串口驱动、PCI驱动、网络驱动和应用程序[1]。

QNX允许设备驱动程序单独编译为一个可执行程序,并在自己的进程空间中单独运行,这样体系结构不会因为驱动程序故障导致系统崩溃,保证系统的安全性,同时也给驱动程序的设计和调试带来方便[2]。

QNX驱动程序的实现的流程为[3]:

(1)初始化系统:启动系统,为系统中各设备分配资源,设置系统需要的接口。

(2)获取硬件接口参数:获取系统为硬件分配的资源,包含终端号、内存映射地址、I/O端口地址。

(3)设置硬件寄存器:根据硬件手册设置寄存器值,从而控制硬件行为。

(4)实现接口函数:驱动程序介于硬件和上层应用之间,同时提供硬件和应用程序接口,从而在两者之间建立联系。

(5)启动消息循环:接收应用进程的消息,解析消息,然后根据消息调用相应的处理功能。

2 PCIE总线系统

PCIE总线采用串行连接方式,并使用数据包(Packet)进行数据传输,数据报文在接收和发送过程中,需要通过多个层次,包括事务层、数据链路层和物理层。PCIE总线的层次结构如图2所示。

图2 PCIE总线层次结构

PCIE中,数据报文首先在设备的核心层(Device Core)中产生,然后经过该设备的事务层(Transaction Layer)、数据链路层(Data Link Layer)和物理层(Physical Layer),最终发送出去。在接收端的数据也需要经过物理层、数据链路层和事务层,最终到达核心层。

在PCIE的数据链路层使用Switch扩展PCIE链路后,PCIE链路能够连接多个设备,从而扩展整个PCIE系统。

PCIE总线规定访问PCIE设备配置空间的总线事务,即配置读写总线事务,使用ID号进行寻址,PCI设备的ID号是由总线号(Bus Number)、设备号(Device Number)和功能号(Function Number)组成[4]。总线号是在主桥遍历PCIE总线时确定,是由驱动程序及PCIE中总线中中Switch桥的个数决定的,主桥相连的总线编号为0。设备号由PCI设备的IDSEL信号与PCI总线地址线的连接关系确定,功能号与PCI设备的具体设计相关。

3 CPU平台

本文中使用的CPU平台为自研的基于Freescal PowerPC P1022处理器的板卡,板载一片FPGA作为协处理器,两者之间通过PCIE总线进行通信,板载PCIE设备拓扑如图3所示:

图3 板载PCIE拓扑结构

CPU平台通过CPCI连接器连接PCI总线背板,从而扩展CPU的外设,PCI外设和CPU之间的通信过程为:背板PCI总线->PCI8250桥->PLX8112桥-> HOST 1->CPU。

FPGA协处理器通过PCIE总线与 HOST 3连接。

4 QNX的多主桥PCIE总线驱动实现

4.1 创建底层硬件接口

在POWERPC P1022处理器的HOST主桥中,与PCIE设备相关的寄存器为CONFIG_ADDR和CONFIG_DATA。驱动程序使用CONFIG_ADDR和CONFIG_DATA寄存器访问PCI设备的配置空间,P1022处理器中PCIE总线配置寄存器地址偏移和属性如表1所示:

表1 寄存器地址偏移和属性表

驱动程序定义硬件接口结构体pdrvr_entry_t p2020_ entry,结构体内容如图4所示:

图4 驱动程序硬件接口结构体

p2020_attach函数获取系统分配给PCI总线的资源;p2020_detach函数作用释放系统分配给PCI总线的资源;p2020_cnfg_bridge函数设置PCI主桥的地址;p2020_read_ cnfg函数通过写CONFIG_ADDR寄存器,然后再读寄存器CONFIG_DATA获取PCI设备配置空间的值;p2020_write_ cnfg函数通过写CONFIG_ADDR寄存器,然后再写寄存器CONFIG_DATA修改PCI设备配置空间的值;p2020_map_ addr函数将PCI域空间地址转换为存储器域空间地址;p2020_bus_info函数设置PCI主桥以及映射的内存和I/O资源信息。

4.2 初始化PCI设备树

创建PCI设备树需要对整个PCI系统进行遍历,采用DFS(深度优先搜索:Depth-First Search)算法进行遍历,遍历过程的程序流程图如图5所示:

图5 遍历过程流程图

在遍历设备的过程中需要为树中设备分配内存资源和I/O资源,为PCI桥分配的内存资源和I/O资源是桥下挂载的设备的总和。将遍历搜索到的设备存放在设备链表中,定义设备链表的头指针和尾指针Device* DeviceHead *Device- Tail,结构体Device定义如图6所示:

图6 Device结构体

结构体中记录了指向下一个设备的指针,设备所在总线号、设备的功能号、设备厂商ID、设备ID、设备类型、设备分配的内存基地址、I/O基地址以及指向设备所在总线信息结构体的指针等设备重要信息。

4.3 创建上层应用进程接口

上层应用进程通过消息调用本驱动程序的接口函数完成对PCI总线访问,因此需要在驱动程序设置的上层应用进程接口含义如表2所示:

表2 应用接口函数

上层应用进程通过向本驱动程序发送相应的消息来调用接口函数去访问PCI总线。

4.4 创建消息通道

驱动程序需要建立消息通道,以使上层应用进程能够向驱动程序发送消息[2]。首先通过dispatch_create()函数创建并返回一个dispatch数据结构,在这个数据结构中包含通道的ID。初始化消息属性结构体resmgr_attr_t、resmgr_attr,使用函数iofunc_attr_init()函数初始化使用设备属性,使用iofunc_ func_init()函数初始化处理消息的功能,使用resmgr_attach()函数进行连接,建立真正的消息通道,使设备和文件能够相连,最后使用函数dispatch_block()接收消息,dispatch_handler()函数解析消息,根据接收到的消息调用相应的处理功能。

4.5 系统创建PCIE设备树

在P1022中启动QNX系统,运行编译生成的驱动pci- p2020-vv,得到的结果如图7所示,经过和设计的PCI树比较,本驱动能够准确生成设备树,满足驱动程序要求。

图7 编译结果

5 小结

在QNX系统下开发设计PCIE总线驱动程序,能够扩展P1022处理器外设。PCIE驱动程序具有良好的硬件和应用程序接口,应用程序通过本驱动方便访问底层PCI/PCIE设备,便于对整个系统进行扩展,本驱动程序已经用于轨道交通的列车牵引系统中,效果良好。

猜你喜欢

主桥寄存器驱动程序
浔江特大主桥桥型及结构优选分析
避免Windows系统更新反复安装显示驱动
阻止Windows Update更新驱动程序
第一桥
飞思卡尔单片机脉宽调制模块用法研究
移位寄存器及算术运算应用
数字电路环境下汽车控制电路信号设计
怀远县涡河二桥主桥加固工程结构安全验算
妙用鼠标驱动
驱动程序更新与推荐