基于嵌入式ARM Linux步进电机驱动程序的设计
扫描二维码
随时随地手机看文章
摘要:本平台基于Samsung公司的友善之譬QQ2440V3开发板,它采用Samsung S3C2440为微处理器,Samsung S3C2440的内核为ARM920T,且采用Linux2.6.13内核作为它的操作系统。设计了硬件系统,并实现驱动程序对步进电机的控制,在QQ2440V3开发板上的实验结果表明驱动运行正常、稳定。这是实现激光雕刻的核心,为以后实现传能激光雕刻夯实了基础。
关键词:ARM;Linux;步进电机;驱动
0 引言
随着激光雕刻机的不断发展和改进,嵌入式Linux的激光雕刻机比CNC(Computer numerical control)激光雕刻的优势不断显现,它大幅度提高了处理能力,方便了设计开发,节约了成本,是未来经济型激光雕刻机发展的趋势。而嵌入式ARM(Advanced RISC Machines)Linux步进电机驱动是实现激光雕刻的核心。
嵌入式开发过程中,经常需要为特定设备开发驱动程序。这些驱动程序的编写和编译与PC上的Linux驱动开发相比存在明显的差异,需要考虑的因素较多,实现过程较为复杂。本文以Samsung公司的友善之譬S3C2440开发板为例,探讨如何使用嵌入式Linux开发字符设备驱动程序来驱动步进电动机。
1 硬件系统设计方案
控制系统由处理器、步进电机驱动器、步进电机3部分组成,如图1所示。
处理器用友善之譬QQ2440V3开发板,内核为ARM920T。步进电机驱动器采用北京和利时电机技术有限公司(原四通电机)的SH-20403。驱动器共有四路输入信号:公共、脉冲信号输入、方向信号输入和脱机信号输入。驱动器的输入信号既可以采用共阳极也可以采用共阴极接线方式,使用共阳极模式时,应将输入信号的电源正极连接到公共端,将输入信号连接到对应的信号端子,信号低电平有效,此时对应的内部光耦导通,控制信号输入驱动器中;对应共阴极模式时,将输入信号的电源负极连接到公共端,信号高电平有效,我们采用的是共阳极接法。
控制步进电机驱动器的时序如图2所示。
[!--empirenews.page--]
2 步进电机驱动系统设计
Linux内核结构体系可分为:应用程序、库函数、操作系统(内核)、驱动程序。在Linux操作系统中,驱动程序是操作系统内核与硬件设备的直接接口,驱动程序屏蔽了硬件的细节,驱动程序是内核的一部分,它具有以下功能:
对设备初始化和释放:比如向内核注册这个程序,这样应用程序传入文件名时,内核才能找到相应的驱动程序。
对设备进行管理,包括实时参数设置以及提供对设备的操作接口。
读取应用程序传送给设备文件的数据并回送给应用程序请求的数据。
检测是处理设备出现的错误。
如图3所示,应用程序通过Linux系统的调用实现与内核通信。由于Linux中将设备当做文件处理,所以对设备进行操作的调用和对文件操作的操作类似,主要包括open()、read()、write()、ioctl()、close()等接口函数。应用程序发出系统调用命令后,会从用户态转到内核态,通过内核将openO等的系统调用转换成对物理设备的操作。在Linux中通过分层实现对物理设备的调用,这样使得内核的结构清晰,提高了模块化的独立性。
2.1 嵌入式Linux设备驱动程序的框架
Linux系统设备分成三种基本类型:字符设备、块设备、网络设备。每个模块通常实现其中某一种:字符模块、块模块或网络模块。
嵌入式设备驱动整体可分以下两部分:
(1)硬件设备接口层。这部分主要描述驱动程序与设备的交互。
(2)驱动与内核接口层,它实现驱动模块在Linux内核的注册加载与卸除工作。
对于驱动程序与内核接口层,Linux提供了标准的入口点函数init_functionO;在通过模块化的设计方法设计驱动程序时,使用insmod加载核心模块时会调用本函数,通知内核对驱动程序进行注册。模块的卸除工作与加载工作类似,通过rmmod卸载模块时,调用cleanup_funct-ion0取消驱动程序的注册。
2.2 GPIO的步进电机驱动开发
GPIO(General Purpose Input Output)的步进电机驱动可以归类为Linux设备驱动的字符设备驱动,以下是开发它的一些具体步骤。
2.2.1 开发步骤
(1)模块化驱动程序
写字符设备的驱动程序时,也要遵守模块化编程的一般规范。设备模块在用户空间的初始化和终止:
Init_mnodule()向内核注册模块提供数据结构、局部和全局变量。
Cleanup_module()取消所有init_module在内核中的注册。
(2)设备模块在内核空间的内存申请和释放
kmalloc()函数分配一段内存,这样就实现了Chrdevs向量表中指向设备驱动程序名称的指针。使用kfree释放内存。
(3)字符设备主设备号和次设备号的分配
主设备号标志设备对应的驱动程序,内核利用主设备号将设备与相应的驱动程序对应起来。主设备号的取值范围是O~255,如果不善加规划,则容易造成主设备号的冲突。
次设备号由驱动程序使用,内核的其他部分并不使用它,仅将它传递给驱动程序。
(4)设备模块在内核空间的注册与注销
字符设备的注册有两种方法,一种是常用注册方法,通过系统函数registel_chrdev()将设备加入到系统设备列表中;另一种是devfs技术,通过系统函数devfs-regisrer()实现设备的注册。注销与注册相反,分别调用unregister_chrdev()函数和devfs_unregister()函数。
(5)设备模块在内核空间提供系统调用的函数设备驱动程序在注册成功以后,用户可以通过访问设备特殊文件(一般情况在/dev目录下)实现系统调用。
GPIO驱动程序只需要一个file operations数据结构体就可以了。
2.2.2 驱动开发
要写实际的驱动,就必需了解相关的硬件资源。比如:用到的寄存器、物理地址、中断等。在这里,它用到如下硬件资源,如表2所示。
[!--empirenews.page--]
要用操作所用到的IO口,就要设置他们所用到的寄存器,我们需要调用一些现成的函数或者宏,比如:
/*每个port有16个引脚,而每个引脚由两位来配置,所以你看到32×N。 32表示一个port的配置寄存器,而N代表是第几个端口。而这里的offset表示的是第几个引脚。*/
S3C2440开发板中GPIO的许多引脚是和地址线、数据线、串口线等引脚复用的。所以我们必须对GPIO进行重新定义和配置。一般来说,写驱动可以在内核中找相近的驱动程序,以它为模板进行开发,有时也要从零开始,这次作者在内核Linux-2.6.13-qq2440\kernel2.6.13\drivers\char中的qq2440 led.c进行修改。
最后定义了file_operations和各种API函数,配置了init和exit函数以及module_exit和module_init。
驱动开发完后,要进行测试。把编写好的驱动程序在PC机上进行交叉编译。然后用命令#insmod stepper.ko加载模块到内核中,通过命令#rmmod stepper.ko可以卸载模块。用mknod/dev/stepper 1000 0建立与驱动程序相应的设备节点。编写相应的应用程序。在应用程序中打开步进电机的设备文件,通过调用ioctl(fd,1&dir,O),运行应用程序,查看步进电机的转向。
3 结论
本文在S3C2440开发板下实现了步进电机的控制。给出了简单的驱动程序,实验结果表明驱动运行正常、稳定。但对于实现传能激光雕刻的图形及灰度雕刻,还有待于进一步的完善。