《基于ARM的多終端自助打印系統(tǒng)》是以前和控制工程學(xué)院的建斌同學(xué)和儀器與電子學(xué)院的培松同學(xué)一起做的一個(gè)創(chuàng)新項(xiàng)目。
最終產(chǎn)品可以完成微信客戶端掃碼打印锐极。感覺構(gòu)思不錯(cuò)料饥,現(xiàn)把開發(fā)過程記錄一下收捣。
我們平時(shí)打印的一般流程是這樣:
趕去打印店缀辩。在電腦上打開文檔。然后打印弱睦。
這樣存在一些缺點(diǎn)百姓。
1. U盤很容易丟。
2. 浪費(fèi)PC機(jī)資源每篷。
打印店里面瓣戚。每個(gè)人需要打印的話。都要占用一個(gè)臺(tái)式機(jī)焦读。而打印機(jī)只有一臺(tái)子库。
用臺(tái)式機(jī)作為打印的終端未免太過奢侈〈;危可以說(shuō)除了打印程序所占用的那點(diǎn)內(nèi)存和CPU之外仑嗅。其他資源都浪費(fèi)了。
3. 邊角零錢。
打印花的經(jīng)常是1角2角的這種邊角零錢仓技。這種錢放在錢包里會(huì)感覺很不方便鸵贬。于是考慮電子的支付方式。
這個(gè)系統(tǒng)的打印流程是這樣的脖捻。
1. 用戶上傳文檔到自己的賬戶阔逼。
2. 選擇支付文檔。
3. 掃二維碼打印地沮。
上面的缺點(diǎn)取反就是這個(gè)系統(tǒng)的優(yōu)點(diǎn)了嗜浮。
具體架構(gòu)是這樣的:
ARM板通過USB線和打印機(jī)連接。
這里采用的ARM板是TQ2440摩疑。打印機(jī)是惠普的一款激光打印機(jī)HP_LaserJet_1020危融。
完成后的系統(tǒng)可以每個(gè)ARM板連接一臺(tái)打印機(jī)。
ARM板還有一個(gè)功能就是動(dòng)態(tài)顯示二維碼雷袋。
客戶端和服務(wù)器網(wǎng)絡(luò)連接吉殃。
這保證了文檔可以從終端傳到服務(wù)器上。
服務(wù)器的主要功能是實(shí)現(xiàn)賬戶管理楷怒。還有激活在ARM板上運(yùn)行的打印后臺(tái)進(jìn)程蛋勺。
大概整理一下這個(gè)數(shù)據(jù)流。
首先手機(jī)關(guān)注微信公眾號(hào)率寡∑嚷可以登錄自己的個(gè)人賬戶。
可以上傳文檔到個(gè)人賬戶冶共。
通過支付來(lái)獲得打印權(quán)限。
掃描平臺(tái)隨機(jī)產(chǎn)生的二維碼每界。就可以發(fā)送請(qǐng)求到服務(wù)器捅僵。
服務(wù)器處理請(qǐng)求。這包括檢查權(quán)限等眨层。(看你有沒有付款等)庙楚。
服務(wù)器激活各ARM板上的后臺(tái)進(jìn)程。(這里的后臺(tái)進(jìn)程是Linux下的cupsd趴樱。打印管理程序馒闷。)
cupsd調(diào)用特定于ARCH的驅(qū)動(dòng)(這里的ARCH是指不同的打印機(jī)架構(gòu)。)
發(fā)送字符流到USB叁征。
cupsd控制打印隊(duì)列纳账。
當(dāng)然。如果覺得我說(shuō)的不夠形象捺疼∈璩妫可以下載演示的視頻。
part1:
part2:
ARM板上運(yùn)行Linux。Linux下的打印機(jī)分為幾大類卧秘。PostScript打印機(jī)和其他的呢袱。。PS語(yǔ)言是PostScript打印機(jī)和計(jì)算機(jī)交流的方式翅敌。應(yīng)用層程序?qū)⑸傻腜ostScript文檔直接發(fā)送給打印機(jī)羞福。
如果打印機(jī)是PostScript的。就能打了蚯涮。有些打印機(jī)不能打坯临。
按照一貫的計(jì)算機(jī)思想×抵纾可以在中間加一層看靠。就是GhostScript、他將PostScript轉(zhuǎn)換成比較低級(jí)的打印機(jī)能識(shí)別的格式液肌。
driver程序(驅(qū)動(dòng))將轉(zhuǎn)化好的打印文件挟炬。按照各種打印機(jī)的不同格式發(fā)送給打印機(jī)。是應(yīng)用層程序與底層打印機(jī)硬件交互的媒介嗦哆。
不同打印機(jī)映射到的驅(qū)動(dòng)程序是不同的谤祖。
我們使用的是HP_LaserJet_1020。CUPS版本是1.4.8老速、不附帶特定的PPD文件粥喜。
PostScript Printer Description file是描述打印功能的文件,包含頁(yè)面橘券。字體额湘。的一些描述數(shù)據(jù)結(jié)構(gòu)。旁舰,簡(jiǎn)稱PPD文件锋华。與driver相對(duì)應(yīng)。
必須找到特定打印機(jī)的PPD文件箭窜。并安裝到打印管程上毯焕。
一旦牽涉到多進(jìn)程。各種stuff都變得不那么簡(jiǎn)單磺樱。為了讓打印作業(yè)之間不沖突纳猫。就需要打印管程。
在UNIX-like系統(tǒng)上竹捉。用的最多的就是CUPS了芜辕。她接收要打印的文件。判斷是否需要將其轉(zhuǎn)換成Postscript活孩。一般是通過文件類型來(lái)判斷的物遇。
判斷GhostScript應(yīng)使用什么樣的driver處理此PostScript文件乖仇。一般通過PPD文件中相應(yīng)的字段。把Ghostscript處理的結(jié)果輸出到打印設(shè)備上询兴。
CUPS和Ghostscript之間乃沙。還有一個(gè)層面。就是打印過濾程序foomatic-rip诗舰。是一個(gè)用Perl編寫的腳本程序警儒。
CUPS通過它來(lái)調(diào)用Ghostscript程序披坏。從而把PostScript作業(yè)轉(zhuǎn)化成PPD文件描述的打印機(jī)自身能識(shí)別的格式追逮。
在網(wǎng)上找了很長(zhǎng)時(shí)間。才先一篇介紹CUPS原理的绿语。
關(guān)于CUPS的詳細(xì)原理:http://www.linuxidc.com/Linux/2010-12/30698.htm
好了關(guān)于這個(gè)軟硬架構(gòu)介紹到此為止属百。下面開始搭建環(huán)境记劝。
嵌入式宿主機(jī)OS是RHEL6.3。
交叉編譯器是arm-linux-gcc-4.3.2族扰。
宿主機(jī)網(wǎng)絡(luò)設(shè)置厌丑。IP配置為192.168.0.107。
修改網(wǎng)卡配置文件渔呵。
[root@bogon ~]# vi /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE="eth0"
BOOTPROTO=dhcp
NM_CONTROLLED="yes"
ONBOOT="no"
TYPE="Ethernet"
UUID="bb46e64b-53d1-4229-8a36-8b53297b3601"
DEFROUTE=yes
IPV4_FAILURE_FATAL=yes
IPV6INIT=no
NAME="System eth0"
HWADDR=00:23:5A:DD:1E:57
PEERDNS=yes
PEERROUTES=yes
LAST_CONNECT=1442248415
將ONBOOT字段改成"yes"怒竿。
關(guān)閉NetworkManger。
[root@bogon ~]# service NetworkManager stop
重啟網(wǎng)絡(luò)服務(wù)扩氢。
[root@bogon ~]# /etc/init.d/network restart
關(guān)閉防火墻耕驰。
[root@bogon ~]# /etc/init.d/iptables stop
關(guān)閉SELinux。
[root@bogon ~]# setenforce 0
在宿主機(jī)上啟動(dòng)tftp服務(wù)录豺。
安裝tftp服務(wù)器:
[root@bogon Packages]# rpm -ivh tftp-server-0.49-7.el6.i686.rpm
[root@bogon Packages]# rpm -ivh tftp-0.49-7.el6.i686.rpm
修改配置文件:
# default: off
# description: The tftp server serves files using the trivial file transfer \
#? ? ? protocol.? The tftp protocol is often used to boot diskless \
#? ? ? workstations, download configuration files to network-aware printers, \
#? ? ? and to start the installation process for some operating systems.
service tftp
{
socket_type? ? ? ? ? ? = dgram
protocol? ? ? ? ? ? ? ? = udp
wait? ? ? ? ? ? ? ? ? ? = yes
user? ? ? ? ? ? ? ? ? ? = root
server? ? ? ? ? ? ? ? ? = /usr/sbin/in.tftpd
server_args? ? ? ? ? ? = -s /
disable? ? ? ? ? ? ? ? = yes
per_source? ? ? ? ? ? ? = 11
cps? ? ? ? ? ? ? ? ? ? = 100 2
flags? ? ? ? ? ? ? ? ? = IPv4
}
將server_args改成-s /tftpboot朦肘,將disable字段改成no。
創(chuàng)建/tftpboot:
[root@bogon Packages]#mkdir /tftpboot
[root@bogon Packages]#chmod -R 777 /tftpboot
重啟xinetd:
[root@bogon Packages]#/etc/init.d/xinetd restart
在宿主機(jī)上啟動(dòng)NFS服務(wù)巩检。
[root@bogon ~]# vi /etc/exports
添加一項(xiàng)厚骗。
#/rootfs 192.168.0.*(rw,sync,no_root_squash)
重啟NFS服務(wù)。
/etc/init.d/nfs restart
安裝引導(dǎo)程序到NorFlash兢哭。
要下載程序到NandFlash。首先要安裝開發(fā)板的啟動(dòng)引導(dǎo)程序到NorFlash夫嗓。
連接JLink迟螺。這個(gè)不用介紹了吧。
然后打開J-Flash軟件舍咖。如圖所示矩父。
然后就是操作JLink軟件。下面是指令流排霉。不展開說(shuō)明了窍株。
file->open project->2440.jflash
target->connect
file->open->u-boot
target->earse chip
target->program
現(xiàn)在啟動(dòng)引導(dǎo)程序已經(jīng)安裝好了。
在宿主機(jī)上安裝交叉工具鏈。
交叉工具鏈采用的是arm-linux-gcc-4.3.2球订。
在開源社區(qū)下載arm-linux-gcc-4.3.2.tgz后裸。
將交叉工具鏈解壓到相應(yīng)目錄。
[root@bogon Cross_Compiler]# tar xvzf arm-linux-gcc-4.3.2.tgz -C /usr/local/Cross_Compiler/arm/4.3.2
修改~/.bashrc冒滩。
[root@bogon Cross_Compiler]# vi ~/.bashrc
# .bashrc
# User specific aliases and functions
alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'
# Source global definitions
if [ -f /etc/bashrc ]; then
. /etc/bashrc
fi
export PATH=$PATH:/opt/arm-linux-gdb/bin
export PATH=$PATH:/opt/4.3.2/bin
#export PATH=$PATH:/opt/4.4.3/bin
vi ~/.bashrc{
export PATH=$PATH:/opt/4.3.2
}
擴(kuò)展PATH字段微驶。將交叉工具鏈中的bin目錄也作為命令的搜索路徑。
export PATH=$PATH:/usr/local/Cross_Compiler/arm/4.3.2/bin
使修改生效开睡。
source ~/.bashrc
重新登錄一下就可以使用arm-linux-gcc等交叉編譯命令了因苹。
嵌入式環(huán)境搭建:
設(shè)置網(wǎng)絡(luò)環(huán)境。
Windows的IP是192.168.0.101篇恒,宿主機(jī)的IP是192.168.0.107扶檐,開發(fā)板的IP是192.168.0.110
燒寫UBoot映像。
編譯UBoot胁艰。
使用開發(fā)板提供的UBoot款筑。
配置UBoot。
[root@bogon uboot_tq2440]# make TQ2440_config
Configuring for TQ2440 board...
[root@bogon uboot_tq2440]#
編譯UBoot蝗茁。
[root@bogon uboot_tq2440]# make ARCH=arm CROSS_COMPILE=arm-linux-
用USB線連接PC醋虏。
安裝dnw驅(qū)動(dòng)。
[root@bogon dnw1]# insmod dnw_usb.ko
[root@bogon dnw1]#
Message from syslogd@bogon at Jan 16 09:19:02 ...
kernel:GuoQian USB driver for DNW!
[root@bogon dnw1]#
使用dnw工具將編譯生成的u-boot.bin下載到開發(fā)板哮翘。
[root@bogon dnw1]# ./dnw ../u-boot.bin 0x30008000
這之后從NandFlash啟動(dòng)就可以看到UBoot的啟動(dòng)界面颈嚼。可以選擇燒寫內(nèi)核映像了饭寺。
燒寫內(nèi)核映像阻课。
使用開發(fā)板提供的內(nèi)核。
配置內(nèi)核艰匙。只選擇要用到的組件限煞。
[root@bogon linux-tq2440]# make menuconfig ARCH=arm
選項(xiàng)很多。查找資料才能完成员凝。這里不展開署驻。
有一項(xiàng)需要說(shuō)明的。我們要使用USB來(lái)驅(qū)動(dòng)打印機(jī)健霹。所以當(dāng)然應(yīng)該把打印機(jī)支持選上旺上。如圖所示。
需要
編譯內(nèi)核糖埋。
[root@bogon linux-tq2440]# make uImage ARCH=arm CROSS_COMPILE=arm-linux-
經(jīng)過幾十分鐘的編譯之后宣吱。得到內(nèi)核映像。提示如下瞳别。
征候。杭攻。。疤坝。
SYSMAP? System.map
SYSMAP? .tmp_System.map
OBJCOPY arch/arm/boot/Image
Kernel: arch/arm/boot/Image is ready
GZIP? ? arch/arm/boot/compressed/piggy.gz
AS? ? ? arch/arm/boot/compressed/piggy.o
LD? ? ? arch/arm/boot/compressed/vmlinux
OBJCOPY arch/arm/boot/zImage
Kernel: arch/arm/boot/zImage is ready
UIMAGE? arch/arm/boot/uImage
Image Name:? Linux-2.6.30.4-EmbedSky
Created:? ? ? Sat Jan 16 09:35:43 2016
Image Type:? ARM Linux Kernel Image (uncompressed)
Data Size:? ? 2433840 Bytes = 2376.80 kB = 2.32 MB
Load Address: 30008000
Entry Point:? 30008000
Image arch/arm/boot/uImage is ready
[root@bogon linux-tq2440]#
燒寫內(nèi)核兆解。
下載內(nèi)核:
tftp 0x31000000 uImage
制作根文件系統(tǒng)。
創(chuàng)建根目錄rootfs
[root@bogon /]# mkdir rootfs
[root@bogon /]# cd rootfs
[root@bogon rootfs]# mkdir usr dev sys bin sbin etc mnt lib proc tmp var
[root@bogon rootfs]# mkdir usr/bin usr/sbin usr/lib lib/modules
創(chuàng)建必要的設(shè)備文件卒煞。
[root@bogon rootfs]# cd dev
[root@bogon dev]# mknod -m 666 console c 5 1
[root@bogon dev]# mknod -m 666 null c 1 3
創(chuàng)建配置文件痪宰。
寫入相應(yīng)字段需要查閱資料。這里不展開了畔裕。就是在etc目錄下創(chuàng)建一些文件衣撬。
[root@bogon etc]# ls
fstab? init.d? inittab? profile
[root@bogon etc]#
添加內(nèi)核模塊。
進(jìn)入內(nèi)核代碼扮饶。編譯模塊具练。
[root@bogon etc]# cd /home/win/Kernel/TQ2440/linux-tq2440
[root@bogon linux-tq2440]# make modules ARCH=arm CROSS_COMPILE=arm-linux-
安裝模塊。
make modules_install ARCH=arm INSTALL_MOD_PATH=/rootfs
編譯busybox甜无。支持一些常用的命令扛点。
在開源社區(qū)下載busybox-1.7.0。
進(jìn)入busybox 根目錄岂丘。
[root@bogon APP_Src]# ls
busybox-1.7.0? busybox-1.7.0.tar.bz2? diffutils-2.8.1? diffutils-2.8.1.tar.gz
配置busybox
[root@bogon busybox-1.7.0]# make menuconfig
scripts/kconfig/mconf Config.in
#
# using defaults found in .config
#
將Busybox配置成靜態(tài)編譯陵究。
切記取消使用/usr的選項(xiàng)。不然會(huì)將宿主機(jī)的文件覆蓋奥帘。配置選項(xiàng)以下面這種形式寫出铜邮。以后或許也會(huì)用到這種方式。
make menuconfig {
busybox setting -> build option -> static
compile -> arm-linux-
install option -> donnot use /usr
prefix = /rootfs
}
安裝busybox寨蹋。
make && make install
HP_LaserJet_1020驅(qū)動(dòng)的安裝松蒜。下面有移植筆記。
很榮幸在開源社區(qū)找到了一些開源的打印機(jī)驅(qū)動(dòng):
http://www.openprinting.org/download/
關(guān)于Samba需要不需要已旧。當(dāng)時(shí)移植的時(shí)候還真沒想過秸苗。不過Samba很常用。順便把Samba交叉編譯了一下运褪。其過程出乎意料的痛苦惊楼。各種錯(cuò)誤。
下面的交叉配置選項(xiàng)是經(jīng)過很長(zhǎng)時(shí)間才完成的秸讹。實(shí)在是懶得遍歷這個(gè)過程了胁后。下面是一些移植時(shí)候的記錄。
====================================================================================================================================================
Samba的移植:
下載Samba-3.0.37
1.Samba的交叉編譯
[root@bogon source]# pwd
/root/Desktop/Samba/samba-3.0.37/source
[root@bogon source]# ./configure CC=arm-linux-gcc LD=arm-linux-ld RANLIB=arm-linux-ranlib AR=arm-linux-ar --host=arm-linux? --target=arm-linux --build=i686-linux --prefix=/root/Desktop/Tmp/Samba/samba-test SMB_BUILD_CC_NEGATIVE_ENUM_VALUES=yes
SAMBA VERSION: 3.0.37
LIBREPLACE_LOCATION_CHECKS: START
checking build system type... i686-pc-linux-gnu
checking host system type... arm-unknown-linux-gnu
checking target system type... arm-unknown-linux-gnu
LIBREPLACE_LOCATION_CHECKS: END
LIBREPLACE_CC_CHECKS: START
checking for arm-linux-gcc... arm-linux-gcc
checking for C compiler default output file name... a.out
checking whether the C compiler works... yes
checking whether we are cross compiling... yes
checking for suffix of executables...
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether arm-linux-gcc accepts -g... ^C
嗦枢。。屯断。文虏。侣诺。
[root@bogon source]# make --prefix=/rootfs.....
=======================================================================================================
交叉編譯cups-1.4.8
[root@bogon cups-1.4.8]# ./configure --prefix=/rootfs/usr/local/cups CC=arm-linux-gcc CXX=arm-linux-g++ AR=arm-linux-ar LD=arm-linux-ld RANLIB=arm-linux-ranlib --host=arm-linux --target=arm-linux --build=i686-linux --disable-gnutls --disable-gssapi --disable-dbus
checking for gawk... gawk
checking for arm-linux-gcc... arm-linux-gcc
checking for C compiler default output file name... a.out
checking whether the C compiler works... yes
checking whether we are cross compiling... yes
checking for suffix of executables...
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether arm-linux-gcc accepts -g... yes
checking for arm-linux-gcc option to accept ISO C89... none needed
checking how to run the C preprocessor... arm-linux-gcc -E
checking whether we are using the GNU C++ compiler... yes
checking whether arm-linux-g++ accepts -g... yes
checking for arm-linux-ranlib... arm-linux-ranlib
checking for ar... /usr/bin/ar
checking for chmod... /bin/chmod
在開發(fā)板上啟動(dòng)cupsd需要
./usr/local/cups/sbin/cupsd
./usr/local/cups/lib/cups/filter
./usr/local/cups/etc/cups/cupsd.conf
LogLevel info -> LogLevel debug
You can see some debug information in ./usr/local/cups/var/log/cups/error_log
=====================================================================================
交叉編譯foo2zjs
wget -O foo2zjs.tar.gz http://foo2zjs.rkkda.com/foo2zjs.tar.gz
tar xvzf foo2zjs.tar.gz
cd foo2zjs
make
make install
make install-hotplug
make cups
./getweb 1020
./arm2hpdl sihp1020.img > sihp1020.dl
cp sihp1020.dl /usr/share/foo2zjs/firmware/
cp /usr/share/foo2zjs/firmware/sihp1020.dl > /dev/usb/lp0
./foo2zjs -p9 -r600x600 test.pbm > /dev/lp0
=================================================================================
lpadmin -p HP_LaserJet_1020 -E -v usb:/dev/lp0 -P ./usr/local/cups/share/cups/model/HP_LaserJet_1020.ppd
lpstat -t
lpoptions -d HP_LaserJet_1020
lpr -P HP_LaserJet_1020 /etc/passwd
cat /etc/passwd | lp -d HP_LaserJet_1020
================================================================================
Compile the foomatic-rip:
./configure CC=arm-linux-gcc CXX=arm-linux-g++ LD=arm-linux-ld RANLIB=arm-linux-ranlib AR=arm-linux-ar --host=arm-linux --target=arm-linux --build=i686-linux --prefix=/root/Desktop/Test/foomatic-rip-4.3.2-test
modify the "config.h"
在服務(wù)器上添加打印機(jī)。
選擇Devices and Printers下的add printer
選擇鼠標(biāo)所指的那一項(xiàng)氧秘。添加網(wǎng)絡(luò)打印機(jī)年鸳。再選擇我要的打印機(jī)不在列表內(nèi)。
然后出現(xiàn)通過網(wǎng)絡(luò)添加打印機(jī)的菜單丸相。CUPS的端口號(hào)是631搔确,所以然后寫入目標(biāo)打印機(jī)的地址。就是灭忠,
http://192.168.0.110:631/printers/HP_LaserJet_1020
如下所示膳算。
從服務(wù)器上可以看到打印機(jī)的網(wǎng)絡(luò)地址是多少。也是CUPS提供的一個(gè)界面弛作。
在服務(wù)器上也能訪問ARM板上的CUPS進(jìn)程涕蜂。然后服務(wù)器將打印任務(wù)發(fā)送到cups進(jìn)程。cups管理打印任務(wù)映琳。調(diào)用ARM板上移植好的驅(qū)動(dòng)机隙。通過USB驅(qū)動(dòng)打印機(jī)。
HP_LaserJet_1020驅(qū)動(dòng)的安裝萨西。
原來(lái)打算自己寫一波Printer設(shè)備驅(qū)動(dòng)有鹿,但是找了一個(gè)1020的代碼,代碼量超級(jí)大谎脯,其中核心部分移植起來(lái)耦合度也很大葱跋,所以就簡(jiǎn)單做了。
在開源社區(qū)找到了一些開源的打印機(jī)驅(qū)動(dòng):
http://www.openprinting.org/download/
行文至此穿肄,驅(qū)動(dòng)項(xiàng)目算結(jié)束咯年局。感謝建斌同學(xué)和培松同學(xué)的配合~。~
***
Linkerist
2017年12月1日于北京酒仙橋