linux lpte_请问在Linux下如何对并口送指令?

我在Linux环境下用C/C++开发一个POS软件,现在要写一个程序对钱箱操作的,比如往并口发一个指令弹开钱箱,请问在Linux下如何对并口送指令?

|

*前言*

本文主要是讨论不同平台下对并行端口进行编程的方法。因条件所限,目前只局限于Intel386体系下的

PC微机结构。

第一章 *简介*

并口在步进电机控制、数据采集等方面有广泛应用。本文就是讨论不同平台下,对并行端口的访问。

到目前为止,在DOS、Windows 95/98、Windows NT/2000/XP和Linux下实现了并口访问程序。

PC机上一般都至少有一个25针的并口,我们可以很容易在机箱后面找到它。当中,第18~25针是

地线,第2~9针是数据输出线,剩下的是状态线和输入线。

第二章 *实现*

在PC机上,并行端口有相应的寄存器(Registers),这些寄存器会被映射到系统地址空间当中去。

根据当初IBM设计PC时的方法,PC上的并口基址在系统地址一般是0x378和0x278(如果有第二个并口的话)。

端口映射地址都存放在PC机的BIOS中。根据BIOS的设计,从低端40[0]H处开始,共有256(100H)Byte的空间,

用来存放PC机外部设备的地址。所以我们也可以通过工具debug来查看这些内容,在命令行下:

C:>debug

进入debug环境,用d指令查看0x40[0]处的内容:

-d 40:00

0040:0000   F8 03 F8 02 E8 03 E8 02  BC 03 78 03 78 02 C0 9F

0040:0010   22 C8 20 80 02 85 00 20  00 00 2E 00 2E 00 64 20

0040:0020   20 39 34 4B 30 52 3A 27  30 52 30 52 0D E0 00 00

......

上面以16-bit(2Byte)为单位存放设备地址。偏移量0x00~0x07的,是4个串口地址(对应着COM1~COM4)。

接下来的0x08~0x0F偏移量中,是4个并口地址(对应着LPT1~LPT4)。在Intel的X86体系上,内存的存放

是Little-Endian顺序,也即小字节反而放在前面。这样,我们可以从上面的内存内容看出,LPT1的地址

是0x3BC,LPT2地址是0x378。

2.1 DOS、Win95/98下并口的访问

在DOS、Win95/98下访问并口,相对而言较简单,只需要调用下面两个函数:

#include

int   _outp(unsigned short port,  int databyte);

int   _inp(unsigned short port);

其中_outp是输出,_inp是输入。比如我要对8个输出数据线都写高电平(即0xFF),则可以用:

/* 让8个输出数据线均为高电平1 */

_outp(0xFF,0x378);

要让第1、2、3数据线为高电平,则可用:

_outp(0x07,0x378);

其余类推。

2.2 Win NT/2000/XP下并口的访问

由于Windows NT/2000内核与Windows 98/95的不同,所以访问并口的方法也要作相应的调整。也

就是说,前面所讲的方法在NT内核下,已经不再实用啦!大家可以在NT下调用前面的_outp和_inp试试

看,会发现,在执行这两个函数时,程序出现“执行非法程序”的错误框,然后程序就结束了。这是因为

在Windows NT/2000下,从安全性出发,程序会被系统授予一定的特权(Privilege)和限制(Restriction)。

通常,这种特权级会分作两个:用户模式(User Mode)和核心模式(Kernel Mode)。用户模式下的运行的

程序等级是Ring 3。在核心模式下运行的程序等级是Ring 0。而在Ring 3下系统是不允许直接访问端口的。

所以前面所用调用库函数_outp等的方法在Windows NT/2000下是行不通的。

既然了解了上面的原因,我们就明白了:要在Windows NT/2000下实现对硬件端口的访问,就要通过

一定的途径获得Ring 0下的权限。这个工作可以通过Windows的DDK(Device Drive Kits)来实现。Windows

下的DDK也是一系列的API函数,只是这些函数是专门用于Windows下硬件驱动程序编写的。由于驱动程序可

以运行在Ring 0的权限下面,所以也就解决了用户程序不能进入Kernel模式下的矛盾。另一个要解决的问

题是驱动程序和用户程序之间要定义一个通信接口。这样,用户程序通过自己定义的驱动程序接口来实现

对并口的访问。我们运用的方法是先利用DDK编写一个可访问并口的驱动程序(一般是XXXX.sys模样的文件),

之后,由一个DLL文件指定外露接口。

幸运的是,已经有人在这方面为我们做好了相应的可访问并口的驱动程序,而且提供了源代码让我们

学习。大家可以在参考文献[1]上找到源代码和使用文档说明。文档写得很清楚、详细,这里我就不多说啦。

2.3 Linux下并口的访问

由于Linux的开放性和高度的用户自定义性,要让Linux支持并口,首先要让Linux的内核支持并口。

一般我们在从光盘安装Linux时,都会把并口支持功能放进内核当中。但如果是自己升级内核、编译内核时

就要注意了:不要把并口支持功能给去掉。不然,你会发现并口死活“不肯”产生信号。要让内核支持并口

(如果大家是从光盘安装Linux的话,则不要下面的步骤,因为系统会自动加载并口支持功能的),就要在

设置系统内核时选择上"Parallel port support"这个选项。这个选项可以在make config或make xconfig

或make gconfig或make menuconfig时找到。如果大家以上面几个命令不太了解,可以参考编译内核的文档。

这样,在编译内核时,我们就预定义了宏CONFIG_PARPORT,编译器就被通知到要把并口支持部分代码给编

进内核当中去。当然,我们也可以把并口支持功能编译成模块(Module)形式,这些模块的存放位置在

"/lib/module/内核版本号/kernel/drivers/parport"目录下,相应的文件是parport.o、parport_pc.o等。

在需要使用并口时,用命令insmod、rmmod来加载、去除并口支持功能。其中insmod是指"Insert Module",

rmmod是指"Remove Module"。

在确定Linux内核支持并口功能后,我们就可以进入下面的主题了。

访问Linux下并口的函数,和前面介绍的Windows95/98下的_outp是极其类似的:outb、inb函数,当中

的参数含义也和前面讲到的_outp、_inp一样。

但需要指出的是,Linux也采用了与Windows NT/2000相似的保护措施,禁止用户进程直接对硬件端口

访问(用户空间程序不允许访问内核空间中的内容)。为了简化并口访问,Linux又提供了一个Helper Function,

这就是ioperm。这个函数可以告诉内核:给出一定的控制权与用户进程,当用户程序结束后,再把控制权给收

回来。如果我们不事先调用ioperm的话,访问并口的程序也可以编译成功,但在运行时会出错,一般会在屏幕

上出现"Segment Failure"的出错提示。

使用到的两个函数原型如下:

#include

int ioperm(unsigned long  from, unsigned long  num, int turn_on);

void outb(unsigned char byte, unsigned port);

当中的ioperm是让从from开始,直到num个字节,这段范围内的I/O映射地址可以为普通用户程序访问。上

述行为是在当turn_on参数为"真"(非零)时允许的。当为"假"时,就禁止这种行为。这可以在程序完成,

不再要访问硬件端口时调用。

下面给出Linux下访问并口的示例代码:

... ...

ioperm(0x000,0x3FF,1); //把0x000~0x3FF之间空间开放给用户程序

//这段范围对访问并口而言,已经足够了。

outb(0xFF,0x378);      //向并口数据位写数据。这里是将8个数据位全置为1

...  ...

ioperm(0x000,0x3FF,0); //收回控制权,用户程序在这之后就不再可以

//访问内核空间内容了。

第三章 *总结*

目前为止,已经在如下平台实现了对并口的编程:

*Windows 98 SE

*Windows 2000 Professional

*Linux(RedHat 9.0 Kernel 2-4-20)

*Linux(Slackware 9.1 Kernle 2-4-22)

*参考文献*

[1] Accessing Parallel Port.   http://www.logix4u.net/index.htm

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值