基于Linux的光栅检测系统的软件设计与实现

2014-04-29 10:00张立立张鹏飞沙毅方晶晶
电子世界 2014年21期

张立立 张鹏飞 沙毅 方晶晶

【摘要】本文设计的光栅检测系统主要应用在高精度喷绘机的运动控制单元。本文以Linux操作系统为开发平台,分别从自动配置和初始化子程序、服务于I/O请求的子程序、中断程序三个部分详细说明了光栅检测系统的软件设计流程。本系统通过实际运行与测试,达到设计要求。

【关键词】光栅检测;高精度喷绘机;Linux操作系统;软件程序

近几年来,大幅面喷绘市场发生了巨大变化,大幅面产品的应用越来越广泛,已逐步渗透到包括广告、装饰、摄影等许多行业。随着大幅面打印技术的不断成熟,喷绘机[1]在全球范围得到迅速普及,特别是在我国的广告制作领域更是得到革命性的应用。

喷绘机的性能指标[2]主要包括:打印速度和打印精度。喷绘机的打印速度是以单位时间的出画面积来衡量,打印精度(分辨率)用DPI(点每英寸)来衡量,单位长度内的点数越多,DPI越大,画面就越清晰。为了提高打印精度,减少2个点之间距离,必须提高喷头的点火频率。为了提高喷绘机的打印速度必须提高喷头的移动速度。随着喷绘机制造行业的迅猛发展,原有产品不论在打印精度上还是在打印速度上已经不具有市场领先优势,甚至有一些方面已经处于劣势。这样必须及时推出高打印精度,高打印速度的喷绘设备,才能使公司在市场竞争中立于不败之地。本文设计的光栅系统主要用于小车打画过程中的精确定位,使画面的点均匀分布。光栅尺的精度为180DPI,通过正交解码最高可达到720DPI。

1.Linux设备驱动编程

Linux的核心设备驱动是一组运行在特权等级上的内存驻留底层硬件处理共享库,正是它们负责管理各个设备[3]。在Linux操作系统[4]中,需要内核建立应用程序和设备之间的抽象接口,而不是由应用程序直接操作硬件。为此,操作系统一般提供设备驱动程序,专门完成对特定硬件的控制。设备驱动程序实际是处理或操作硬件控制器的软件,从本质上讲,它们是内核中具有高特权级的、驻留内存的、可共享的底层处理硬件例程[5]。

在Linux系统中,一个基本的特点是它抽象了设备处理,所有硬件设备的操作和通常的文件一样,利用标准的系统调用可在设备上进行打开、关闭、读取或写入操作。系统中的每个设备由设备特殊文件代表,每个由相同设备驱动程序控制的设备具有相同的主设备号,而从设备号则用来区分同类设备中不同的设备。设备特殊文件的VFS索引节点中包含设备号的信息。如果通过系统调用来访问设备,则内核通过该VFS节点中的设备号信息调用适当的设备驱动程序。

Linux支持字符、块及网络设备三种硬件设备[6]。字符设备指那些无需缓冲直接读写的设备,像系统中的串口设备。块设备则仅能以块为单位进行读写。Linux核心中存在许多不同的设备驱动,这些驱动具有以下的共同特点[7]:

(1)核心代码:设备驱动是核心的一部分,如同核心中其他代码一样,出错将导致系统的严重损害,甚至使系统崩溃,导致文件系统的破坏和数据丢失。

(2)核心接口:设备驱动必须为Linux核心或者其从属子系统提供一个标准接口。

(3)核心机制与服务:设备驱动可以使用标准的核心服务,如中断发送和等待队列等。

(4)动态可加载:多数Linux设备驱动可以在核心模块发出加载请求时加载,在不再使用时卸载,这样核心能有效的利用系统资源。

(5)可配置:Linux设备驱动可以连接到核心中,可以配置决定那些设备驱动被连入核心。

(6)动态性:当系统启动和设备驱动初始化时,将查找它所控制的硬件设备,如果某个设备的驱动为一个空闲的过程并不会有什么问题。此时,设备驱动仅仅是一个冗余的程序,它除了占用少量系统内存外,不会对系统造成什么危害。

2.光栅检测系统的软件设计

Linux核心与设备驱动之间有一个标准方式进行互操作的接口。每一类设备驱动都提供通用的接口,这种通用接口使得核心可以用相同的方式来对待不同的设备及设备驱动。嵌入式Jupiter系统[8]通过外部中断5对光栅检测系统产生的信号进行响应,当中断信号产生时,相应的中断服务程序,即驱动程序执行设定的任务。外中断五中断服务程序流程图如图1所示。

图1 外中断五中断服务程序流程图

对用户程序来说,Linux系统的设备驱动程序隐藏了设备的具体细节,对各种不同设备提供一致的接口,一般来说是把设备映射为一个特殊的设备文件,用户程序可以像对其它文件一样对此设备文件进行操作。Linux对硬件设备支持两个标准接口:块设备文件和字符设备文件,分别称为块设备接口和字符文件接口。每一个设备驱动程序由如下三个部分组成:

2.1 自动配置和初始化子程序init

负责检测所要驱动的硬件设备是否存在和是否能正常工作,同时自动配置和初始化。这一部分程序会在系统启动的过程中自动执行。在内核启动的最后阶段运行这一部分程序,首先通过系统调用register_chrdev向系统申请一个主设备号,如果这个主设备号已经被别的设备占用,将会返回一个错误的信息;然后通过系统调用request_irq请求使用这个设备,如果这个设备没有注册成功,或者使用的条件不足,也会返回一个错误信息。如果这两步都没有问题的话,驱动程序就加载到了内核,在用户程序空间就可以使用这个设备。

2.2 服务于I/O请求的子程序

服务于I/O请求的子程序,又称为驱动程序的上半部分。调用这部分是由于系统调用的结果。这部分程序在执行的时候,系统仍认为是和进行调用的进程属于同一个进程,只是由用户态变成了核心态,但是具有进行此系统调用的用户程序的运行环境。因此,可以在子程序中调用于进程相关的系统库函数。

这一部分程序实际的作用就是用户程序空间和内核空间进行通信,由用户程序空间向内核空间传达各种参数,或者从内核空间获取设备的各种信息。

在系统内部,I/O设备的存取操作通过一组固定的入口点进行,这组入口点是由每个设备的驱动程序提供的。嵌入式操作系统中的字符型设备提供一下入口点:

open(struct inode *inode, struct file *file):

打开设备准备I/O操作,系统通过设备名称,函数的第一个参数来区分每个驱动程序的入口点操作函数;第二个参数说明这个函数的文件结构体,主要说明设备的使用类型。对字符特别设备文件进行打开操作,都会调用设备的open入口点函数。Open子程序必须对将要进行的I/O操作做好必要的准备工作。如果设备是独占的,那么同一时间只能有一个程序访问此设备,则open子程序必须设置一些标志,以表示设备处于忙状态。

在嵌入式操作系统中,定时器一、定时器二和外中断五主要用open函数设置驱动程序的打开状态,防止设备在打开之前就已经开始使用的情况,同时还将设备驱动程序的一些计数变量初始化。

release(struct inode*inode,struct file*file):

释放一个设备。当使用设备终结后,调用release子程序。在程序的试验开发阶段有用,因为嵌入式产品的控制程序主要是一个不断循环的过程,不存在设备的关闭和资源的释放。

read (struct inode*inode,struct file *filp,char *buf,int count):

从设备上读数据。对于有缓冲的I/O操作,一般是从缓冲区里读数据。对字符设备文件进行读操作将调用read子程序。Count指定了读取的字节数,读取的数据置入以buffer为首地址的内存空间。在定时器一中,read函数主要用来将定时器发生的次数清零,并且将主程序放入等待队列。

write(struct inode*inode,struct file *filp,char*buf,int count):

往设备上写数据。对于有缓冲区的I/O操作,一般是把数据写入缓冲区里。对字符设备特别设备文件进行写操作将调用write子程序,写入的数据放在Buf为起始地址的内存空间里,字节数为count代表的值。

2.3 中断服务子程序

中断服务子程序,又称为驱动程序的下半部分:

isr(int irq,void *dev_id,struct pt_regs *regs):

其中irq代表设备的硬件中断号,dev_id代表设备名称,pt_regs代表设备使用的寄存器的值。这是一个回调函数,中断发生时,系统调用这个函数,传入的参数包括硬件中断号、设备号、寄存器值。

在Linux系统中,并不直接从中断向量表中调用设备驱动程序的中断服务子程序,而是由Linux系统来接收硬件中断,再由系统调用中断服务子程序。中断可以产生在任何一个进程运行的时候。因此,在中断服务程序被调用的时候,不能依赖于任何进程的状态,也就不能调用与进程运行环境有关的函数。因为设备驱动程序一般支持同一类型的若干设备,所以一般在系统调用中断服务子程序的时候,都带有一个或者多个参数,以唯一标识请求服务的设备。

Jupiter提供了6个外中断源,中断反应时间在10-25微秒。每识别到一个光栅信号触发一次中断,在中断程序中首先用计数器记录中断产生的次数,如果次数达到给定的起始位置数,则开始往喷头送256次数,执行点火操作。

上面所述为驱动程序的内容部分,驱动程序做完以后,还要往系统里添加,把程序放在?Clinux内核的/drivers/char文件目录下,并且在/drivers/char/ mem.c添加驱动程序的init(),以便系统启动的时候执行该子程序测试并且初始化设备;然后在/drivers/char/Makefile文件中添加编译信息,在编译系统内核的时候,会自动编译所加的驱动程序。最后在系统启动末尾执行的批处理文件里加上设备的mknod命令。这样,在系统启动以后,在/dev目录下就可以观察到你所注册的设备,设备就可以在用户程序里进行调用了。

3.控制系统软件调试

嵌入式的运行环境是?Clinux,应用程序是在这个环境下运行的。在设计软件的时候,应该考虑到一切意外的情况下,应用程序都应该有自救的功能。例如,在串口通信的实现上,和PC机约定好为16个字节,利用read函数每次读取一个字节,循环16次度取完所有字节。但是如果操作系统的驱动程序丢失传送的字节后,应用程序就会死掉。所以采用对read()函数的属性进行设置,在2秒钟的时间内,如果还没有字节输入,会自动退出。然后向PC机发出出错信息,重发一次。这样就克服了上述的缺点。

4.结束语

本文在Linux的基础上设计了光栅检测控制的软件系统。配合喷绘机硬件设备,提高了喷绘机的打印精度。但随着喷头技术的发展,以及客户的不断要求,在一些方面还需要加强。提高嵌入式核心的主频,以增加数据的绝对处理速度;采用传输速率更高的方式如LVDS进行数据传输;增大系统板的内存容量,减小打印过程中的等待时间,这样就可以解除现有喷绘机打印速度不能显著提高的瓶颈。

参考文献

[1]刘晋,靳祥陆,张秋风,刘锋,顾彬彬.大幅面高速彩色喷绘机主控制系统研究与设计[J].计算机测量与控制,2011,19(9):

2140-2142.

[2]Kumar S,Bhat V,Vinoy K J,Santhanam V. Using an Office Inkjet Printer to Define the Formation of Copper Films on Paper[J].IEEE Transactions on Nanotechnology,2014,13(1):160-164.

[3]邹思轶主编.嵌入式Linux设计与应用[M].北京:清华大学出版社,2002:171-186.

[4]Lan Yuqing,Xu Hao,Liu Xiaohui.The Research of Performance Test Method for Linux Process Scheduling[C].2012 International Symposium on Information Science and Engineering (ISISE),2012,216-219.

[5]李善平,陈文智编著.边干边学Linux内核指导[M].杭州:浙江大学出版社,2002:337-347.

[6]Wong,William.Tiny Compact Flash-based sys runs ?Clinux[J].Electronics Design,2004,52(21):40-42.

[7]Gary Nutt. Kernel Projects for Linux[M].北京:机械工业出版社,2002.

[8]高世伟,刘亚利,陈秀萍.基于uCLinux和Jupiter的嵌入式通讯设备的设计[J].计算机工程与应用,2005(29):110-112.

基金项目:国家自然科学基金资助项目(项目编号:11273001)。

作者简介:张立立(1984—),女,辽宁沈阳人,硕士,实验师,主要研究方向:无线传感器网络等。