1. 程式人生 > >Android遇上印表機

Android遇上印表機

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow

也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!

               

       印表機其實和Android沒有什麼大的關係,和linux核心關聯才是比較強的。最近除錯印表機,有那麼一點心得,一點一點記錄下來。

       

最終的結果是要在Android實現驅動印表機,但是一般除錯一個新的驅動的流程是這樣的:1.先在linux PC上進行測試。2.在標準嵌入式linux上進行除錯。3.改裝到Android中去

       為什麼這麼安排,是有說道的。因為資源是遞減的,可以在第一階段確定裝置有無問題,以及該裝置在linux工作流程;在第二階段是因為標準的嵌入式linux還是遵循GNU規定的,包括大部分,這個階段驗證該裝置能否在ARM架構的上順利編譯通過;第三階段就是實用階段了,因為最終要在這個不是怎麼遵守GNU規定的Android系統上執行的。


第一階段


       我測試了3臺印表機:1.Canon iP2780 2.Canon MX428 3.HP Deskjet 1000。由於的我作業系統就是Linux,在Linux PC上很快就逐個搞定。第1臺用的是這裡的驅動(包括deb包和部分開源原始碼)加上這個iP2700 series IJ Printer Driver Ver. 3.30 for Linux (操作說明)》,機器就可以正常使用了;第2臺和第一臺驅動模式都是一樣的只不過在這裡;第3臺用的是這裡的一級一級選擇最終下載檔案是:hplip-3.14.1.run,直接執行會把所缺失的東西全部安裝,可以成功使用。

       如果我僅僅是一個使用者,那麼到現在可以就結束了。但是我是一個開發者,我最終的目標是移植到Android中,所以我的目的地不在這裡,我要繼續深度挖掘。要挖掘的點很多,這裡說一個最迫切的就是如何用命令列印一個檔案?這個問題似乎很奇怪,但是我也不知道如何做。不過最終找到了就是:lp或者lpr加檔名,就可以打印出一個檔案了。例如:

lp ~/hello.pdf

       找這麼一個命令我就花費了幾個小時的時間,這裡我就有一種很強的預感,前邊的路很還很遙遠。(整理文章的順序和實驗的步驟會稍有不同,其實這個命令在iP2700 series IJ Printer Driver Ver. 3.30 for Linux (操作說明)》是有的,但是這個“操作說明”是後來才看到的)。

       現在看來我不應該草率進行去進行第二個階段,應該好好的研究一下Linux的列印系統。總結文章就按照最好的流程來吧。先說我是怎麼了解了linux的列印系統的。

       意外發現的這個本書《Linux系統管理技術手冊》,真是對我瞭解Linux的列印系統幫助是最大的,涵蓋的知識面也是最全的,以後的階段中用到的自認為是新的東西,其實這本書上都詳細講解了。講解列印不是講解如何列印就好了,而是詳細的講解了印表機的原理,要經過哪些步驟,印表機語言等等,如果是國人寫的書一般會說“此內容不在本書要討論的範圍內”一句概括。那一章我反覆看了一週時間才算有些眉目。

       一切終歸一張圖:


       其實到目前為止我應該好好規劃一下我要設計的東西,實現中我急功近利了,並沒有做完全的規劃就進行了第二階段。

小規劃:

       印表機選擇:推薦選擇HP的,鐳射的噴墨的都可以,HP是全力支援Linux的。

       列印系統的選擇:

              大的架構是CUPS,主要的模組有:

                     後臺:

                     過濾器:

                     PPD:

其實在圖中隨便從上到下連一條線,就可以組合成一套列印系統。下面進入第二階段吧。


       在測試過程中還意外發現CUPS一個bug,或者是我還沒有已經有解決方案我還沒有發現而已。那就是CUPS缺少錯誤處理, 一臺印表機,如果出現墨盒用完,墨盒實效等等問題的時候,CUPS是沒有告知使用者的。比如我的HP Deskjet 1000,在使用CUPS列印時出現了這個情況:印表機無響應,用lpstat -t檢視到的狀態是“Rendering completed”。這就找不到問題所在了,不過同樣的情況下在Windows下找到了答案:





第二階段


       除錯Canon的印表機的時候我選擇了這樣的架構:CUPS+cnijfilter-source-3.30-1.tar.gz.

1.配置Linux核心(作用:生成裝置節點


make menuconfig 選上USB印表機選項:        Device Drivers  --->
                      [*] USB support  --->                                     <*>   USB Printer support      (配置成功後,插入印表機後設備節點會出現在/dev/usb/目錄下一般名字"lp0")   

2.交叉編譯CUPS 1.3.9

#!/bin/sh# 1.下載原始碼wget http://www.cups.org/software/1.3.9/cups-1.3.9-source.tar.gz &&# 2.解壓並開啟tar xvzf cups-1.3.9-source.tar.gz && cd cups-1.3.9 &&# 3.配置./configure --host=arm-linux --target=arm-linux --build=i686-linux CC=arm-linux-gcc CXX=arm-linux-g++ LD=arm-linux-ld RANLIB=arm-linux-ranlib AR=arm-linux-ar  --disable-gnutls --disable-gssapi --disable-dbus --prefix=/ &&# 4.修改Makefile使其不編譯mansed -i '22s/locale man monitor/locale monitor/' ./Makefile  &&# 5.編譯並安裝make && make install DSTROOT=/work/rootfs/rootfs_qtopia_qt4 &&echo "cups build install ok!"


3.交叉編譯ghostscript 8.15

#!/bin/shDESTDIR=/work/rootfs/rootfs_qtopia_qt4# 1.下載原始碼wget http://iweb.dl.sourceforge.net/project/ghostscript/GPL%20Ghostscript/8.15/ghostscript-8.15.tar.gz &&# 2.解壓原始碼tar xvzf ghostscript-8.15.tar.gz  &&# 3.分別拷貝為PC版本和ARM版本cp ghostscript-8.15 ghostscript-8.15-arm -r && mv ghostscript-8.15 ghostscript-8.15-pc  &&# 4.編譯PC版本# -DHAVE_SYS_TIME_H是解決warning: implicit declaration of function 'gettimeofday'cd ghostscript-8.15-pc && ./configure && make XCFLAGS=-DHAVE_SYS_TIME_H=1 && cd ../ &&# 5.配置arm版本cd ghostscript-8.15-arm && ./configure --host=arm-linux &&# 6.修改Makefile中STDLIBS=-lm 為STDLIBS=-lm -staticsed -i '257s/STDLIBS=-lm/STDLIBS=-lm -static/' ./Makefile &&# 7.拷貝PC版本工具mkdir obj && cp ../ghostscript-8.15-pc/obj/genarch ../ghostscript-8.15-pc/obj/genconf ../ghostscript-8.15-pc/obj/echogs  ./obj/  &&# 8.編譯make XCFLAGS=-DHAVE_SYS_TIME_H=1 &&# 9.安裝(這個版本不支援make install的DESTDIR指定根目錄所以要手動拷貝,以後要調整目錄)mkdir -p          ${DESTDIR}/usr/local/share/ghostscript/8.15/  &&cp    -r lib      ${DESTDIR}/usr/local/share/ghostscript/8.15/  &&cp    -r Resource ${DESTDIR}/usr/local/share/ghostscript/8.15/  &&cp       bin/gs   ${DESTDIR}/bin/


4.交叉編譯gutenprint 5.2.9

#!/bin/sh# 1.下載原始碼 專案地址:http://sourceforge.net/projects/gimp-print/files/gutenprint-5.2/5.2.9/wget http://softlayer-ams.dl.sourceforge.net/project/gimp-print/gutenprint-5.2/5.2.9/gutenprint-5.2.9.tar.bz2 &&# 2.解壓tar xvjf gutenprint-5.2.9.tar.bz2  &&# 3.分別拷貝為PC版本和ARM版本 cp -r gutenprint-5.2.9 gutenprint-5.2.9-arm && mv gutenprint-5.2.9 gutenprint-5.2.9-pc &&# 4.編譯PC版本cd gutenprint-5.2.9-pc && ./configure && make && cd ../ &&# 5.配置arm版本  cd gutenprint-5.2.9-arm && ./configure --host=arm-linux --target=arm-linux --build=i686-linux CC=arm-linux-gcc CXX=arm-linux-g++ LD=arm-linux-ld RANLIB=arm-linux-ranlib AR=arm-linux-ar --with-gimp2=no --without-gimp2 --enable-cups-ppds  --enable-cups-level3-ppds --without-ghostscript --without-foomatic --disable-libgutenprintui2 &&# 6.拷貝PC版本工具  make || cp ../gutenprint-5.2.9-pc/src/xml/.libs/extract-strings ./src/xml/.libs/ &&# 7.編譯並安裝make && make install DSTROOT=/work/rootfs/rootfs_qtopia_qt4 &&echo "gutenprint build install ok!"

5.交叉編譯hpijs-2.1.4

#!/bin/sh# 1.下載原始碼 專案地址:http://sourceforge.net/projects/hpinkjet/files/wget http://superb-dca2.dl.sourceforge.net/project/hpinkjet/hpijs/2.1.4/hpijs-2.1.4.tar.gz# 2.解壓原始碼tar xvzf hpijs-2.1.4.tar.gz && cd hpijs-2.1.4# 3.配置./configure --host=arm-linux --target=arm-linux --build=i686-linux CC=arm-linux-gcc CXX=arm-linux-g++ LD=arm-linux-ld RANLIB=arm-linux-ranlib AR=arm-linux-ar# 4.修正語法錯誤 dj3320.cpp第403行和registry.cpp第249行 開頭的char改為const charsed -i '249s/\tchar\t/\tconst char\t/' registry.cppsed -i '403s/  char/  const char/' dj3320.cpp# 5.編譯並安裝make && make install DESTDIR=/work/rootfs/rootfs_qtopia_qt4


6.啟動各個模組

以上是我編譯的原始碼所有記錄,它們每個都是可以單獨執行驗證的。

啟動cups:$ /etc/init.d/cups start

CUPS可以將/etc/cups/cupsd.conf的日誌級別LogLevel設定為debug,這樣如果啟動失敗會將原因列印到/var/log/cups/error_log中。我沒有遇到什麼大的bug,遇到的都是缺少目錄問題。


7.最簡的列印系統ghostscript+hpijs


           這個方案主要是參考了《基於嵌入式Linux的列印控制系統的設計》,這個是比較適合嵌入式印表機的,不佔資源,不需要一些相比比較雞肋的功能。儲存了一份到資源中,下載(注:最好是自己原始碼編譯,不保證對所有cpu可用,必須是ARM架構且在ARMv7以上)直接可以用。可以直接安裝主到Android中或者普通的嵌入式Linux中。


8.無系統的印表機實現


            這個是更簡的,就是沒有作業系統的控制器來操作印表機,是我在除錯這個HP Deskjet 1000意外發現一個牛人實現的《USB HOST+HP DeskJet 1000印表機》。當然我是真實的實驗了他提供的BIN檔案,他用是TQ2440,我在MINI2440上直接測試也是沒有問題的,打印出來的內容是“HP802黑色墨盒加墨方法”,這兩款開發板都是採用的S3C2440這個ARM的CPU。雖然沒有提供原始碼,不過也算是提供了一種可能,如果以後有這方面的需求可以順這條路研究下去。



第三階段 移植到Android中

預留

1. 最簡列印移植到Android中

       首先強扭過去,庫不用擔心,都是才用的靜態連結編譯的。關鍵是“檔案系統層次結構標準”Android沒有遵守,經過實驗強制建立了兩個目錄,才能正常使用/usr和/tmp目錄。
       需要優化的幾點:1.關於/tmp目錄的調整 2.關於/usr目錄的調整 3.裝置節點的動態建立,。。。。
               1.關於/tmp目錄的調整 在stackoverflow上討論出一個解決方案是用/data/local/tmp來代替;
               2.關於/usr目錄的調整 重新編譯ghostscript調整的/system/usr/..目錄;

               3.裝置節點 還沒有除錯;

    4.列印中英文字型檔的問題;

Fix /tmp目錄問題:

       為了按照功能區別開來,最終選用/data/misc/printer/tmp/目錄作為/tmp目錄。將gs程式碼gp_unifs.c中tmp/目錄更換。

       $ sed -i '74s/"\/tmp\/"/"\/data\/misc\/printer\/tmp\/"/' ./src/gp_unifs.c

Fix /usr目錄問題:

  一般是usr是在根目錄下的,Android中是在/system/上的,ghostscript編譯時要進行調整,調整的結果是在配置時新增:--prefix=/system/那麼ghostscript就會把資原始檔調整到/system/usr/share/....目錄下,這樣剛好可以解決問題。

Fix裝置節點問題:

  根據《Android與標準Linux對比》經驗和實驗得出:Android中用ueventd+VOLD來完成了普通Linux中udev的工作,前者負責建立裝置節點,後者用於處理。插入印表機後,會自動建立裝置節點/dev/usb/lp0。、
ueventd預設創建出來的是隻有root使用者才能夠訪問的許可權,Android中改變許可權的方法是在uevent.${BOARD}.rc中新增如下:

#For USB printer/dev/usb/lp0  0666 system system

再次檢視裝置節點許可權,正常。


Fix字型問題:

  一直測試列印的都圖片,列印中英文的時候會報錯,根據具體報錯原因打到解決方法。

#!/bin/sh# 說明:本指令碼下載並打包GS所需字型檔# 版本:2013-01-17# 將打包好的字型檔放到# Android: /system/usr/share/ghostscript/8.15/Resource/ 中解壓# Linux  : /usr/local/share/ghostscript/8.15/Resource/  中解壓# * 解決了常用中英文列印所需的字型檔DESTDIR=${PWD}/system# 1.下載gs-fonts原始碼 專案地址:http://sourceforge.net/projects/gs-fonts/wget http://superb-dca2.dl.sourceforge.net/project/gs-fonts/gs-fonts/8.11%20%28base%2035%2C%20GPL%29/ghostscript-fonts-std-8.11.tar.gz &&# 2.解壓gs-fonts原始碼tar xvzf ghostscript-fonts-std-8.11.tar.gz  &&# 3.下載gs-9.04,獲取其中的字型檔 專案地址:http://sourceforge.net/projects/ghostscript/files/GPL%20Ghostscript/9.04/wget http://softlayer-ams.dl.sourceforge.net/project/ghostscript/GPL%20Ghostscript/9.04/ghostscript-9.04.tar.bz2 &&# 4.解壓gs-9.04原始碼tar xvjf ghostscript-9.04.tar.bz2 &&# 5.建立字型檔目錄 Fonttest -d ./Font && rm -rf ./Font ; mkdir ./Font &&# 6.拷貝字型檔到Font目錄中#   拷貝gs-fontscp -rf fonts/* ./Font  &&#   拷貝gs-9.04的字型檔 cp -rf ghostscript-9.04/Resource/Font/*  ./Font &&# 7.打包字型檔tar cvzf Font.tar.gz Font &&echo "Fonts ok!"
  字型的問題解決了,Android中也有自己的字型位於/system/fonts中,其中ttf格式居多,而這裡用的大多都是pfb格式的。



           

給我老師的人工智慧教程打call!http://blog.csdn.net/jiangjunshow

這裡寫圖片描述