本文主要以惠普P1008型号的打印机为示例,来进行方案细节阐述。html
目前,打印机驱动大多数是在windows与linux发行版上提供了支持。直接移植到嵌入式上不太现实,故而了解打印机的原理的前提下,移植必要的驱动到ARM平台。linux
因客户只打印PDF,本文采用ghostscript+foo2xqx(惠普驱动),这种最简单的方案进行具体说明。git
各类类型的文档经由一个(或一些)转换程序转换成用户正在使用的打印机能够认识的格式,即用各类类型的打印机语言描述的流,系统将这个流直接发送到打印机端口,由打印机对其进行解释并造成硬拷贝。github
▼目前大多数Linux系统如下面的流程,来实现文档到打印机语言的转换。web
普通文本文件和各类类型的图形由适当的转换程序转换成PostScript文件,有些应用程序将其输出直接写成PostScript文件,这些PostScript文件经由一个做为打印机过滤器的应用程序Ghostscript转换成打印机语言。windows
所以,若是系统的打印系统已经配置成使用Ghostsript做为打印过滤器,应用程序要实现的就是输出合乎程序要求和语法的PostScript文件。网络
飞凌公司研发出来的i.MX6UL系列FETMX6UL-C核心板能够能实现USB与网络打印的方法,小巧且应用普遍。架构
FETMX6UL-C核心板是一款基于 NXP(原Freescale)i.MX6Ul traLite Cortex-A7架构 处理器设计的核心板,主频528MHz,核心板采用两组优质进口80P板对板链接器设计,独特的电源管理架构相比ARM9系列的核心板功耗更低。严酷的温度等级测试确保核心板在-40℃~85℃环境中稳定运行。最大支持8路UART、2路以太网、2路CAN等工业级总线接口;核心板标配256RAM/256MB NAND Flash、512RAM/4GB eMMC两种配置。app
实现流程说明:ide
❶ 在打印过程当中,一般是应用程序产生输出并以管道的方式传送给lpr或者直接应用lpr打印一个文件。
❷ lpr与打印机后台服务程序经过网络进行链接并进行通讯,传送相应的打印数据和打印选项。
❸ 打印机后台服务程序将在相应的spooler目录存储打印信息,在输出设备能够利用的状况下将打印任务送给打印设备。
修改drivers/usb/Kconfig中将#source "drivers/usb/class/Kconfig"前的#去掉
➢ 静态配置如图所示
make menuconfig➞Device Drivers➞USB Support➞USB Printer support
<图1 内核配置支持USB打印>
➢ 动态加载
若是不想改变当前iMX6UL开发板的内核,能够将usb打印编译成模块,而后动态加载进去。编译后的模块为usblp.ko。而后下载到开发板上执行以下命令加载进去:
insmod usblp.ko
将打印机与iMX6UL开发板经过USB链接,而后打开打印机的电源就会在开发板上出现/dev/usb/lp0设备文件。
2交叉编译Ghostscript
1.下载源码
官网地址: https://github.com/ArtifexSoftware/ghostpdl-downloads/releases
下载ghostscript版本
*注明:网上不少交叉编译方法,此处再也不展开
3交叉编译foo2xqx具体细节以下
#1. 下载foo2zjs源码
wget http://foo2zjs.rkkda.com/foo2zjs.tar.gz &&
2.解压源码
tar zxvf foo2zjs.tar.gz &&
3.分别拷贝为PC版本和ARM版本
cp foo2zjs foo2zjs-arm -r &&
mv foo2zjs foo2zjs-x86 &&
4.编译PC版本
cd foo2zjs-x86 &&
make &&
cd ../ &&
5.编译ARM版本
cd foo2zjs-arm &&
source ~/poky/toolchain/environment-setup-cortexa7hf-neon-poky-linux-gnueabi
修改Makefile 文件,注释掉
@if ! type $(CC) >/dev/null 2>&1; then \
...
fi
@if [ "ls $(MACOSX_stdio) 2> /dev/null
" != "" ]; then \
....
fi
@if ! type gs >/dev/null 2>&1; then \
...
fi
@if ! type dc >/dev/null 2>&1; then \
...
fi
@if ! dc -V >/dev/null 2>&1; then \
...
fi
#ifeq ($(UNAME),Darwin)
@if ! type gsed >/dev/null 2>&1; then \
...
fi
#endif
编译
make -j32&&
6.使用编译出来的getweb程序, 获得对应打印机的固件程序: sihp1006.img
./getweb P1008 &&
7.用x86 gcc编译的arm2hpdl工具将sihp1006.img转化为sihp1006.dl
cd ../foo2zjs-x86 &&
./arm2hpdl ../foo2zjs-arm/sihp1006.img > ../foo2zjs-arm/sihp1006.dl &&
cd ../ &&
8.将生成的sihp1006.dl和foo2zjs拷贝至目标板的文件系统中
cp foo2zjs-arm/sihp1006.dl /usr/share/cups/sihp1006.dl &&
cp foo2zjs-arm/foo2zjs /usr/share/cups/foo2zjs &
4交叉编译cups
下载cups 源码,地址https://github.com/apple/cups/releases中的cups-2.3b7-source.tar.gz
按照cups补丁文件,修改源码(根据buildroot中补丁文件进行修改)。
0001-Remove-man-from-BUILDDIRS-in-configure.patch
0002-Do-not-use-genstrings.patch
0003-Sanitize-the-installation-process.patch
0004-Remove-PIE-flags-from-the-build.patch
0005-Fix-static-linking-with-GnuTLS.patch
./configure -host=arm-linux
make -j16
make install DSTROOT=/usb-printers/cups-2.3b7/install
安装完成以后可看到etc include lib usr var文件夹。移植到嵌入式板卡中。
5打印pdf
具体细节以下
#1.加载打印机固件
cat /usr/share/cups/sihp1006.dl > /dev/usb/lp0
此时打印机有响声
#2.经过gs将pdf转换为test.pbm
./bin/gs -q -dBATCH -dSAFER -dQUIET -dNOPAUSE -sPAPERSIZE=a4 -r600x600 -sDEVICE=pbmraw -sOutputFile=test.pbm /tiger.pdf
#3.打印测试
./foo2xqx -p9 -r600x600 /test.pbm > /dev/usb/lp0
#4.将打印机设置为共享
使用cups
配置文件为:/etc/cups/cupsd.conf修改配置文件中
LogLevel warn 修改成LogLevel debug
在
Restrict access to the server...
<Location />
Order allow,deny
</Location>
的第3行以后添加Allow 192.168.1.0/24,同时在<Location /admin> <Location /admin/conf>中也添加上Allow 192.168.1.0/24(具体根据打印机的使用环境进行IP配置)。
开启cups服务:/etc/init.d/cups start
修改/etc/cups/cups-file.conf 将Systemgroup 中lpadmin 去掉。或者将当前用户加入lpadmin。
将打印机设置为共享打印机:
$lpstat -t查看当前打印机的状态
$lpoptions -d printer 将打印机设置为默认打印机
$lpdamin -d printer –o printer-is-shared=true 将打印机设置为共享。假设此打印机的IP地址为192.168.1.108
#5. 局域网打印
局域网其余板卡,也移植cups,经过局域网进行打印
$lp test.pdf -h 192.168.1.108:631便可经过网络进行打印。
参考资料:
[1]. Linux打印系统CUPS原理分析
[2]. cups-wiki简介
[3]. foo2zjs 简介
[4]. cups命令行打印和选项配置