工控网首页
>

应用设计

>

基于RTLinux的运动控制器MC400D的驱动程序设计

基于RTLinux的运动控制器MC400D的驱动程序设计

2004/4/8 16:41:00
[摘要] 本文介绍一种由国防科技大学设计的用于机电系统中的运动控制卡MC400D在嵌入式实时操作系统RTLinux下的设备驱动程序的设计思想和设计流程,通过该驱动程序的设计,使得在RTLinux下原来基于Windows下的控制程序通过简单的软件移植后,能够实时的实现对机电系统的各种控制,并使机电产品的嵌入式实现成为可能。 [关键词] RTLinux;运动控制器;驱动程序;嵌入式系统   在伺服机电控制系统中,除了要满足机电产品在性能上的高稳定性、高效率要求以外,还在系统的实时性、可靠性和多功能方面提出了更高的要求,尤其是军事领域的机电控制系统中,要求对事件的处理有极强的实时性。90年代以后,随着对实时性要求的提高,软件规模不断上升,实时内核逐渐发展为实时多任务操作系统(RTOS),并作为一种软件平台逐步成为目前国际嵌入式系统的主流[1]。在嵌入式应用中使用实时操作系统已成为当前嵌入式应用的一个热点、一种时尚。今天,RTOS已经在全球形成了一种产业[2]。其中一些著名的公司更是选中了象Linux、VxWorks、UC/OS-II操作系统作为开发多任务实时控制系统的工具。而在国内,虽然嵌入式应用开发很广,但该领域几乎还是空白。 本文正是基于机电产品的嵌入式应用这一研究课题而展开的。在大型复杂的机电一体化产品中应用嵌入式实时操作系统对于我们来说还是比较陌生的,尚处于摸索阶段。软件方面,在综合比较多种实时操作系统如VxWorks、uc/os-ii等的基础上,作者最终选定了免费的、源代码开放的、功能齐全的实时操作系统RTLinux作为嵌入式机电产品研究的软件平台;硬件方面,由于在机电一体化产品中都离不开运动控制器,所以本文从研究由国防科技大学机电工程与自动化教研室开发的PCI接口的伺服运动控制卡MC400D入手,进行机电产品的嵌入式改造。   MC400系列运动控制器已成功运用于有四轴伺服交直流电机的大型控制系统中,系统的应用软件是用Visual C++融和LabWindows/CVI进行开发和设计的,软件控制代码约有120M,系统的稳定性和实时性不是很好,系统的运行需由硬盘启动,由工控机直接进行控制。为了适应武器装备对嵌入式控制系统的特殊需要,而且为了减少硬件成本,提高系统运行的稳定性,避免重复开发费用和减少开发时间,将原有的系统进行改造,深入研究机电产品中运动控制卡的设备驱动程序,以便于直接访问卡上的原有资源,并通过设定相应的运动控制参数,实现对电机的各种控制,从而开发出嵌入式RTLinux武器伺服系统。 1 MC400系列运动控制卡及Windows下的控制程序分析 运动控制器,是以实现预定运动轨迹目标,对以电机驱动的执行机构等设备进行控制的装置。运动控制器以其特有的灵活性和优秀的运动轨迹控制能力使许多工业生产设备焕发出勃勃生机,可以说,只要有伺服电机应用的场合就离不开运动控制器。   MC400系列运动控制器是由国防科技大学机电工程与自动化教研室自主开发的,设计为PCI接口的四轴通用型运动控制器。该卡采用DSP和CPLD相结合的结构,TMS320系列DSP控制器能将实时处理能力和控制器外设功能集于一身,主要处理轨迹规划、伺服控制等功能,CPLD主要处理外围接口电路,具有使用简单,可扩充性强,多用途,可编程,通用性强的特点,可直接用于交流伺服电机或直流伺服电机的控制,最大可同时控制4个电机。   卡的控制程序主要包括系统设置函数(如采样时间set_smpl_time()等)、伺服控制参数设置函数(如设定PID控制的比例函数set_kp())、轴参数设置函数(如设定一轴set_1())、运动参数设置函数、极限参数设置函数、位置捕获以及中断处理和参数更新函数等。 2 RTLinux下的运动控制器的设备驱动程序   几乎每个系统操作最终都会映射到物理设备上。除了处理器、内存以及其他很有限的几个实体之外,所有设备控制操作都由与被控制设备相关的代码来完成。这段代码就叫做设备驱动程序(device driver),内核必须为系统中的每件外设嵌入相应的驱动程序,包括硬盘驱动器、键盘和磁带等。   通过Windows下的机电控制系统的分析,控制程序是针对系统的具体控制要求和功能而提出来的,与所采用的软件平台相关不大,而整个系统的驱动程序设计却是进行嵌入式系统改造的关键所在。 2.1 RTLinux下的设备驱动程序简介   设备驱动程序在RTLinux内核中是一个个独立的“黑盒子”,使某个特定的硬件响应一个定义良好的内部编程接口,同时完全隐藏了设备的工作细节。用户操作通过一组标准化的调用来完成,而这些调用是和特定的驱动程序无关的。将这些调用映射到作用于实际硬件的设备特定的操作上,则是设备驱动程序的任务。这个编程接口能够使得驱动程序独立于内核的其他部分而建立,在需要的时候,可在运行时“插入”内核。这种模块化的特点,使得RTLinux驱动程序的编写变得简单。   MC400系列运动控制器设计为PCI接口的,所以该驱动程序的设计属于块设备驱动程序设计。   每个PCI外设都有一个总线号、一个设备号和一个功能号来标识。这可以从/proc/bus/pci/devices目录或者/proc/pci文件来查看PCI设备清单以及设备的I/O和内存。以下是本机用vi pci命令得到的有关PCI接口的运动控制卡MC400D的资源信息: Bus 0, device 20, function 0: Bridge: PCI device 10b5:5201(PLX Technology,Inc.)(rev 2). IRQ 5. Non_prefechable 32 bit memory at 0xdfffff80[0xdfffffff]. I/O at 0xd800[0xd87f] Non_prefechable 32 bit memory at 0xdffe0000[0xdffeffff]. I/O at 0xd400[0xd4ff].   从以上显示可见,MC400D运动控制卡的总线号、设备号、功能号及中断号分别是:0,20,0和5,其厂商ID和设备ID分别是0x10b5和0x5201。   后面两行显示内存和I/O映射区间。一个PCI设备可实现多达6个I/O地址区域。每个区域可以是内存也可以是I/O区间。此处,PCI定义的I/O空间是32位地址空间,MC400D运动控制卡上设置了两段I/O区间,标记为内存区域,采用memory访问方式,不作I/O口使用,其符号名称分别是PCI_BASE_ADDRESS_0和 PCI_BASE_ADDRESS_1。 2.2 PCI的配置寄存器、初始化和访问   PCI设备拥有一个256字节的地址空间,前64字节是标准化的,后面的字节则是设备相关的。用三个或五个PCI寄存器可标识一个设备:Vendor ID( 厂商ID)、 device ID(设备ID)和class(类),每个PCI厂商会将正确的值赋予上述三个只读的寄存器,驱动程序可利用它们查询设备[3]。   以下两个函数用来查询具有特定签名的设备和激活指定的设备: #include #include struct pci_dev *pci_find_device(unsigned int vendor,undigned int device,const struct pci_dev *from) int pci_enable_device(struct pci_dev *dev) 其中,dev为设备结构体变量。   访问配置空间的函数有6个,分别用来完成向配置空间读、写一个、两个或四个字节,以下两个函数用来实现向配置空间读写一个字节。 int pci_read_config_byte(struct pci_dev *dev,int where,u8 *ptr) int pci_write_config_byte(struct pci_dev *dev,int where,u8 *ptr) 2.3 RTLinux访问内存空间   下面几个函数用来访问PCI的I/O资源: unsigned long pci_resource_start(struct pci_dev *dev ,int bar) unsigned long pci_resource_end(struct pci_dev *dev ,int bar) unsigned long pci_resource_flags(struct pci_dev *dev ,int bar)   这三个函数返回bar个PCI I/O区域之一的首地址、尾地址及与资源关联的标志,该标志在中定义,有 IORESOURCE_IO 和IORESOURCE_MEM。另外,RTLinux还提供访问内存区间的读写函数如Writew()和 Readw()函数等。 2.4 MC400D驱动程序设计   MC400D运动控制器的Vendor ID 和device ID分别在系统的底层软件设计中指定为0x10b5和0x5201,TMS320系列DSP内部有544字双口RAM(DARAM), 可用于数据的读写和缓存,且已设定访问卡资源的方式采用MEM方式,所以驱动程序的内容除了模块的初始化和删除函数以外,还应包括以下几个函数: (1) 运动控制卡的初始化函数ISInitSuccess(); (2) 获取卡上双口RAM MEM基地址GetDRAMBaseAddrMem(); (3) 获取PCI寄存器MEM基地址GetPCIRegBaseAddrMem(); (4) 读写MEM空间的内容MCReadMem()和MCWriteMem(); (5) 运动控制器开关中断设定MCOpenInterrupt()和MCCloseInterrupt()等等。
  MC400D运动控制器的初始化函数部分,是该驱动程序的一个非常重要的内容,图1是其详细的程序流程。假定在获取了四个基地址0号和2号的首址(两个整型变量P1和P2)后,将其映射到内存中的区域函数为 lp1=ioremap(p1,0x50) (lp1是一个指针变量,为重映射区间的首址,此处映射了以lp1为首址的80个字节单元的内存空间) 而后,可以用readl()函数获取重映射空间的资源信息,也可以用writel()函数向其中写入控制信息,如以下函数语句为获取以lp1为基址,偏移量为0x4c存储单元的资源 t=readl(lp1+0x4c) (t为一个整型变量 ) 由于RTLinux提供了相应的访问硬件设备的函数,故其他的几个函数都比较容易编写,如第二个函数是获取卡上双口MEM基地址可以写为 typedef ULONG GETDRAMBaseAddrMem() { return pci_resource_start(dev,2) }  由于驱动程序在实时线程中是以模块的形式进行动态编译和加载的,因此要注意在卸载模块的时候,应该释放卡在内存中所占用的资源,即使用函数iounmap()。 4 单轴电机在RTLinux下的测试   在将原Windows下的控制软件向RTLinux系统下移植后,可以编写一个简单的让单轴
投诉建议

提交

查看更多评论
其他资讯

查看更多

PLC一体机之EK温度修正使用技巧

S7-300CPU存储器介绍及存储卡使用

0.05级超高精度互感器

DC-DC转换器(电源模块)应用指南——外接滤波电容选配

施罗德最小流量阀的应用范围及优点