Chinaunix

标题: 嵌入式Linux打印功能的实现 [打印本页]

作者: pilgrim_kevin    时间: 2008-08-08 16:19
标题: 嵌入式Linux打印功能的实现
  我打算实现一个嵌入式arm linux系统中的打印接口,请教一下思路。因为之前没有做过,所以概念比较模糊。具体来说,我的应用程序是一个基于Minigui的程序,系统是arm926核的CPU+ 2 FPGA的硬件架构,常用的外设接口都有,包括RS232,USB Host/Device,VGA,Ethernet等。打印机准备选用HP的,使用USB接口。

  现在我想实现的是一个简单的打印功能,比如软件中生成一个报告,按打印键打印出来。具体实现的思路是什么?我大概知道"应用程序->Ghostscript->打印任务管理模块->打印驱动"这样一个流程,但是具体的实现方式比较模糊。有相关经验的朋友,指教一下。谢谢。

------------------------------------------------------------------------------------------------------------------------------------

经过一段时间的研究,现已基本实现在arm linux里打印的功能。

首先交叉编译CUPS,这个就不细说了,configure一下即可。

先后用过两个打印机,第一个打印机HP P1008由于不支持标准的PCL,而只支持特殊的XQX Stream Protocol,最终无法搞定在板子上的文档数据转换而放弃。原因主要是:cups使用foomatic-rip做智能文档过滤器,这是一个perl程序,需要一个perl运行环境;需要调用第三方驱动foo2xqx和gs去进行数据转换,太复杂,通用性也不够(假如换打印机或支持更多打印机)。后来更换了一个支持PCL的HP打印机。

最终的实现抛开了cupsd和ghostscript,因为我的需求比较简单:打印jpeg图片。

我最终只使用了cups的两个过滤器程序imagetoraster, rastertohp,后端backend程序usb,还有打印机的PPD文件,一共只有几百K的大小。自己写脚本和程序实现打印,基本的流程如下:

imagetoraster | rastertohp | cat > /dev/usb/lp0

因为/dev/usb/lp0是独占打开的,所以这样打印会导致无法并发提交打印任务,所以自己写了个to_printer程序代替cat,其中使用简单的文件锁来产生当前有进程在打印时另外的打印进程等待的效果。

如果要支持多种复杂文档格式的打印,估计gs还是必不可少的,因为cups的过滤器也会调用gs,比如imagetops。

------------------------------------------------------------------------------------------------------------------------------------

目前针对支持HP PCL打印语言的打印机可以使用上贴的方法进行打印。如果是使用Epson的打印机,如果支持ESC/P,应该使用rastertoepson也可以实现。

上述的实现主要针对打印图片。实际上打印其他任何文档的思路应该是一样的,选择一个过滤器路径,用管道组合,比如pdftops | pstoraster | rastertohp > printer 。只是涉及到要转换到ps的状况,要调用gs。

另外,我自己实现打印过程的原因是CUPS没有彻底搞定(我这里主要是backend/usb的问题)。如果彻底搞定CUPS(配合ghostscript),那么会是一个比较理想的嵌入式Linux打印管理系统的方案。

[ 本帖最后由 pilgrim_kevin 于 2008-9-27 09:04 编辑 ]
作者: pilgrim_kevin    时间: 2008-08-11 11:38
没有人了解吗?。。。。。。
作者: vitoUNIX    时间: 2008-08-11 11:56
有心无力 有请帮顶!!!
作者: rodgerluo    时间: 2008-08-11 12:27
标题: 回复 #1 pilgrim_kevin 的帖子
把你的数据写入打印机不就可以了吗?当然要了解打印机的数据格式啦!
作者: rodgerluo    时间: 2008-08-11 12:30
标题: 回复 #1 pilgrim_kevin 的帖子
与LCD一样,你把你的输出改为打印机。
作者: T-bagwell    时间: 2008-08-11 12:31
同楼上的回答一样
写到打印机里就可以了
作者: pilgrim_kevin    时间: 2008-08-13 13:56
http://www.mcu361.com/Worki.asp?Id=72

我想要实现的应该是类似于这个的。
作者: pilgrim_kevin    时间: 2008-08-14 10:52
现在完成了netpbm、cups的交叉编译,在ghostscript的交叉编译上出现了一些困难。
作者: pilgrim_kevin    时间: 2008-08-27 16:35
楼上有几位说直接向打印机输出,目前为止是不可以的。过去老的文本打印机可以直接通过cat file > /dev/lp0 这种方式进行打印,但是如果要打印图像呢?打印复杂文档格式呢? 使用cat textfile > /dev/usb/lp0这种方式无法在我的打印机上打印文本。

也有一个思路就是将需要打印的文档转换成打印机可直接识别的数据,这种方式需要研究打印机指令语言比如HP用的PCL,太复杂了,而且有一个最大的问题是需要更换或者支持更多打印机的时候很麻烦,通用性太差。

目前我使用的打印机是USB接口的HP LaserJet P1008。在PC上可以简单地通过CUPS进行配置,打印正常,可打印pdf, image, text。我已经把CUPS/Ghostscript已经移植到ARM上,USB打印机也可正常初始化(P1008需要在加电后从上位机加载一个firmware到打印机ram里来初始化,便宜货,把存放固件的rom都省了)。现在的问题是移植的整套东西太庞大了,CUPS使用foomatic-rip进行文档过滤智能分析,但是foomatic-rip是一个perl脚本程序,我试图移植一个perl5.8.8进来,最终卡在perl的库环境的交叉编译上。而且即使可以,这些乱七八糟的东西也太庞大了。现在的思路是不使用foomatic-rip,自己配置文档过滤器,目前我只需要打印text和image文档,cups里也有texttops, imagetops, imagetoraster, rastertohp这些过滤器。正在研究中,网上能参考的资料简直太少了,希望搞过的兄弟能多指教一下。
作者: pilgrim_kevin    时间: 2008-08-28 21:07
看来这个问题so hard:-(
作者: T-bagwell    时间: 2008-08-29 09:47
是很困难啊

对了
不能像在LCD上输出一样的实现在打印机上?
比如颜色的值

黑白打印机用0xff000000这样的黑色的或者0x00000000这样的通过alpha值来做判断打印不打印?
彩色打印机就用他的颜色值来做打印,不可以吗?
有点不理解,主要是没做过,所以就按照自己在这方面的通用性来做的理解,呵呵
做好了一定要发篇原创给大伙学习学习啊
作者: pilgrim_kevin    时间: 2008-08-29 12:43
原帖由 T-bagwell 于 2008-8-29 09:47 发表
是很困难啊

对了
不能像在LCD上输出一样的实现在打印机上?
比如颜色的值

黑白打印机用0xff000000这样的黑色的或者0x00000000这样的通过alpha值来做判断打印不打印?
彩色打印机就用他的颜色值来做打印 ...


在过去的老式的文本打印机上,可以通过 cat xxx > /dev/lp0的方式进行打印,但是现代的打印机都是在特定的打印机语言驱动下工作的。打印机语言指的是控制打印机工作的命令,它告诉打印机如何组织被打印的文档,打印机按照这些命令来处理计算机传来的打印数据,并最终准确的打印出文字与图像。打印语言就是一个命令集,这些命令不是被单独地传送,而是由打印机驱动程序把它们嵌在打印数据中传给打印机,并由打印机的打印控制器再分开解释。打印机语言大体上可分为两类:一种是页面描述语言(PDL),另一种是嵌入式语言(Escape码语言)。它们的代表分别是Adobe公司的Postscript语言和Hp公司的PCL语言,它们是已经成为业界标准的两种打印机语言。而现在普遍应用的是PCL6和postscript level 2的版本。

除了这两种打印机语言之外许多厂商都使用自己的打印机控制语言,如爱普生(Epson)的Esc/Page,佳能的Capsyl,施乐的Xes、Jdl,Ibm的Ipds,Dec的Ansi/Sixel等,它们都各具特点。

所以从概念上来说,向打印机发送真正打印机可接受的打印数据,跟向LCD的framebuffer输出图像数据相差甚远。也跟老式文本打印机可以直接接收文本数据进行打印相差甚远。

[ 本帖最后由 pilgrim_kevin 于 2008-8-29 12:48 编辑 ]
作者: pilgrim_kevin    时间: 2008-08-29 12:54
现在的打印机本身就是一个嵌入式系统,用ARM的CPU,P1008有8M ram。它接收到打印数据后要进行若干处理与运算来控制打印机工作,跟过去的老式打印机不可同日而语。
作者: T-bagwell    时间: 2008-08-29 14:06
经典,斑竹不给他的回帖加精就太浪费啦
作者: pilgrim_kevin    时间: 2008-08-29 17:31
回头我做完了一定写个帖子。我在网上找资料,太TMD痛苦了,基本上啥也找不到
作者: ivorhuang    时间: 2008-09-06 09:31
楼主是准备 通过网络进行打印吗?
只要有CUPs,网络功能正常。就可以通过IPP协议进行网络打印了。
作者: pilgrim_kevin    时间: 2008-09-06 13:20
原帖由 ivorhuang 于 2008-9-6 09:31 发表
楼主是准备 通过网络进行打印吗?
只要有CUPs,网络功能正常。就可以通过IPP协议进行网络打印了。


你好像没有仔细看我的帖子
作者: eveson    时间: 2008-09-08 15:46
这个帖子这么多人加分,我也要加阿
作者: pilgrim_kevin    时间: 2008-09-24 17:36
经过一段时间的研究,现已基本实现在arm linux里打印的功能。

首先交叉编译CUPS,这个就不细说了,configure一下即可。

先后用过两个打印机,第一个打印机HP P1008由于不支持标准的PCL,而只支持特殊的XQX Stream Protocol,最终无法搞定在板子上的文档数据转换而放弃。原因主要是:cups使用foomatic-rip做智能文档过滤器,这是一个perl程序,需要一个perl运行环境;需要调用第三方驱动foo2xqx和gs去进行数据转换,太复杂,通用性也不够(假如换打印机或支持更多打印机)。后来更换了一个支持PCL的HP打印机。

最终的实现抛开了cupsd和ghostscript,因为我的需求比较简单:打印jpeg图片。

我最终只使用了cups的两个过滤器程序imagetoraster, rastertohp,后端backend程序usb,还有打印机的PPD文件,一共只有几百K的大小。自己写脚本和程序实现打印,基本的流程如下:

imagetoraster | rastertohp | cat > /dev/usb/lp0

因为/dev/usb/lp0是独占打开的,所以这样打印会导致无法并发提交打印任务,所以自己写了个to_printer程序代替cat,其中使用简单的文件锁来产生当前有进程在打印时另外的打印进程等待的效果。

如果要支持多种复杂文档格式的打印,估计gs还是必不可少的,因为cups的过滤器也会调用gs,比如imagetops。

[ 本帖最后由 pilgrim_kevin 于 2008-9-25 11:02 编辑 ]
作者: pilgrim_kevin    时间: 2008-09-27 09:03
目前针对支持HP PCL打印语言的打印机可以使用上贴的方法进行打印。如果是使用Epson的打印机,如果支持ESC/P,应该使用rastertoepson也可以实现。

上述的实现主要针对打印图片。实际上打印其他任何文档的思路应该是一样的,选择一个过滤器路径,用管道组合,比如pdftops | pstoraster | rastertohp > printer 。只是涉及到要转换到ps的状况,要调用gs。

另外,我自己实现打印过程的原因是CUPS没有彻底搞定(我这里主要是backend/usb的问题)。如果彻底搞定CUPS(配合ghostscript),那么会是一个比较理想的嵌入式Linux打印管理系统的方案。
作者: yfc02341    时间: 2008-10-17 14:51
标题: replay
兄弟,我现在也在搞潜入式打印。
方案是HPIJS + GOSTSCRIPT(GS)
上面两个东西已经交叉编译好了,ARM上需要打印的图片也已经转化成。PS格式
现在问题是打不开/dev/lp0
cat "..." > /dev/lp0 显示打不开设备
哪个高手能帮帮我。。。。
linux内核打开/dev/lp0需要配置特别燃东西吗?
作者: pilgrim_kevin    时间: 2008-10-17 15:47
你的打印机是USB还是并口设备?内核里面需要打开对应的支持,比如有usb printer的选项。

另外,还要建立对应的设备节点,比如usb printer设备节点可用mknod /dev/usblp0 c 180 0建立。
作者: myforever    时间: 2008-10-21 13:47
直接往设备里面写数据就是了
作者: pilgrim_kevin    时间: 2008-10-21 18:10
原帖由 myforever 于 2008-10-21 13:47 发表
直接往设备里面写数据就是了


老兄高见。不过问题不是怎么向设备里写数据,而是怎么生成设备需要的数据。
作者: weijianhua    时间: 2008-10-24 11:36
我正在做这方面的,arm9+linux2.4下已经可以工作了
作者: 天傲    时间: 2008-11-13 13:02
我用的是 HP laserjet P1008,是基于主机的,不支持PCL。
我通过移植gs, foo2xqx,成功打印了。
中文打印我使用了cnprint.

[ 本帖最后由 天傲 于 2009-5-20 10:45 编辑 ]
作者: pilgrim_kevin    时间: 2008-11-16 23:16
不错不错。
作者: nihao111111    时间: 2008-12-05 11:37
这么好,能看到这样的讨论。
能否说一下,文件怎么使用imagetoraster, rastertohp,
我还不知道怎么使用这两个程序,谢谢!
作者: foochow    时间: 2008-12-08 11:15
LZ介绍下imagetoraster, rastertohp的用法?
作者: locom    时间: 2008-12-08 19:23
标题: 回复 #29 foochow 的帖子
跟在后面学习
作者: pilgrim_kevin    时间: 2008-12-09 22:13
imagetoraster, rastertohp这两个命令参数格式类似,我原来什么都查不到,就是自己看这两个命名的help自己试出来的。现在记不清,明天去办公室电脑看看再告诉你们。

另外,有一些诸如pdftops,imagetops等filter命令还会调用其它的工具,比如gs命令(ghostscript),所以涉及到的东西还是蛮多的。
作者: pilgrim_kevin    时间: 2008-12-10 10:47
#!/bin/sh



export PPD=/etc/cups/ppd/P2015.ppd

/usr/lib/cups/filter/imagetoraster xx "" "" 1 "" "x.jpg" | /usr/lib/cups/filter/rastertohp xx "" "" 1 "" | cat > /dev/usb/lp0

#上面的xx可以是随便一个数字
作者: nihao111111    时间: 2008-12-16 11:57
能否说说怎么改的configure,我交叉编译出现问题(为PPC),错误是:

/tmp/ccYpPSxl.s: Assembler messages:
/tmp/ccYpPSxl.s:55: Error: Unrecognized opcode: `rorw'
作者: pilgrim_kevin    时间: 2008-12-18 19:30
楼上的不好意思,PPC的交叉编译没接触过。
作者: nihao111111    时间: 2008-12-19 08:39
谢谢!楼主能说说你在arm交叉编译下是怎么configure的,应该差不多的吧?
作者: pilgrim_kevin    时间: 2008-12-19 23:14
嗯,在arm下就是参考configure --help去进行配置,先尽量减少依赖模块。其中编译遇到错误,则自己先看看能不能修改代码解决。
作者: gobbin    时间: 2008-12-20 20:05
printk???
作者: 37356100    时间: 2009-01-09 11:25
pilgrim_kevin,我现在在交叉编译ghostscript,参考make.htm手册,但是在执行 make obj/arch.h时通不过,请问为什么?
作者: printerhard    时间: 2009-05-27 07:48
楼主还有没有在??我现在烦恼的就是一件事,无论我装好UBUNTU还是DEBIAN,我使用的HP 1008装上驱动后就是无法驱动打印机工作,

我也大概的清楚了一些流程,就是说从ZJS里包含的XQX要灌入固件到打印机,可是具体怎么实现,我是真的不知道,还请指教,我的邮箱是mzwhben@yahoo.cn
作者: pilgrim_kevin    时间: 2010-01-21 11:15
HP P1008在PC上的驱动应该不复杂,CUPS里配置好就可以,我这里用得很正常。我用fedora 8。
作者: cltnet    时间: 2010-04-24 16:24
你好,想请问你关于CUPS移植的问题。

我把cups arm-linux-uclibc-gcc交叉编译完后,
把cupsd lpr cupsenable拷贝到我的板子上面。
/etc/cups下面的文件如下
cupsd.conf  mime.convs  ppd/         mime.types
然后我编译cupsd.conf和printers.conf文件
printers.conf文件内容如下
  1. <DefaultPrinter printer>
  2. DeviceURI usb:/dev/usb/lp0
  3. Location
  4. Info
  5. State Idle
  6. Accepting Yes
  7. JobSheets none none
  8. QuotaPeriod 0
  9. PageLimit 0
  10. KLimit 0
  11. </Printer>
复制代码
这时我执行cupsd把cups服务起来
但是我执行lpr -p printer test.txt没有任何反应。
但是我 echo "1111" > /dev/usb/lp0是可以打印的。

这时我就不懂了,看/var/log/cups/error下面的日志信息也没有什么有用的发现。
还请问一下是不是我上面有啥操作遗漏的地方,或是错误的地方呢?

另请问一下那个PPD文件是否我下载放到/etc/cups/ppd/目录下面就可以了。
我这个PPD文件是直接在我的FC4上面拷贝下来的,我的是EPSON230 网上没有找到PPD。麻烦你了。谢谢
作者: newnewman80    时间: 2012-12-07 13:34
有没有详细的结论贴呢?   我现在CUPS都移植好了   使用ld -d printer 1.txt  无法打印   ,打印机没反应。   使用cat 1.txt > /dev/usb/lp0  打印机显示正在打印,不过也没有反应,   找到说 文本最后加入 ^L  符号 也没有用。  使用打印命令以后,显示几经加入打印队列。
环境: mini2440  + linux 2.6.33.3  + cups 1.4.8   
大概按照网上帖子安装: http://www.cena.com.cn/a/2008-03-17/12057241715769.shtml

1122516.jpg (8.47 KB, 下载次数: 32)

1122516.jpg





欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2