(Microsoft Word - EELiod_Linux\271\352\305\347\244\342\245U_part2.doc)

Size: px
Start display at page:

Download "(Microsoft Word - EELiod_Linux\271\352\305\347\244\342\245U_part2.doc)"

Transcription

1 第二部份 EELiod Linux 實驗指導手冊

2 實驗一 Linux 常用工具實驗 實驗目的實驗目的 1 瞭解 minicom 設定串列埠通訊參數的過程, 掌握利用 minicom 進行傳輸檔案方法 2 瞭解網路共享系統 nfs 的設定, 掌握利用 nfs 進行檔案的傳輸和遠端執行目標板程式 3 掌握 ftp 的使用方法 實驗原理實驗原理 一 minicom 的使用 1 串列埠通訊參數的設定 首先執行 minicom, 由於 minicom 是通過串列埠來工作的, 所以要通過 minicom 程式來對串列埠通訊 參數進行設定 啟動 minicom 的設定視窗 : 在 linux 的終端中輸入 minicom s, 然後, 按下 Enter 鍵 [root@localhost root]# minicom s -s 選項顯示設定資訊 下面顯示的就是設定的功能表 有關串列埠通訊選項的含義 : "Filenames and paths": 選擇需要傳輸的檔案和路徑 "File transfer protocols": 選擇傳輸檔案的通訊協定 "Serial port setup": 設定串列埠通訊參數 "Save setup as dfl": 將設定好的各項參數儲存為 dfl "Save setup as": 將設定好的各項參數儲存為自定義的檔案名稱 "Exit": 退出返回到 minicom 設定好後的終端機 "Exit from Minicom": 從 minicom 命令中退出返回 Linux 終端將游標移到 "Serial port setup", 按 Enter 鍵會彈出串列埠通訊參數的設定功能表

3 (1) 串列埠通訊介面的選擇 :(A - Serial Device) 接 "A" 鍵把游標移動到 Serial Device 如果串列埠線連在 PC 的串列埠 1 上, 則把 Serial device 設定為 /dev/ttys0 如果連在串列埠 2 上, 則把 Serial device 設定為 /dev/ttys1, 然後按下 Enter 鍵 (2) 串列埠參數的設定 (E - Bps/Par/Bits) 按 "E" 鍵來設定通訊串列傳輸速率 資料位元 奇偶校驗位元和停止位元 可以通過按下不同的按鍵來設定通訊參數 例如 XSBase270 平台需要把串列傳輸速率設為 , 資料位元設為 8, 奇偶校驗位設為無, 停止位設為 1 可以分別通過按"I" "V" "L" "W" 鍵設定串列傳輸速率 資料位元 奇偶校驗位元和停止位元 設定完後按 "Esc" 返回 (3) 資料流程的控制選擇 (F - Hardware Flow Control G - Software Flow Control) 按 "F" 鍵可以完成硬體流量控制切換, 即完成 "Yes" 與 "No" 之間的切換 按 "G" 鍵完成軟體流量控制切 換, 即完成 "Yes" 與 "No" 之間的切換 下圖顯示的是串列埠設定好的後完整資訊

4 (4) 設定參數的儲存與退出 設定完成後, 按下 Esc 鍵, 將會出現下圖的設定功能表 選擇 Save setup as dfl 按 ENTER 鍵來 儲存, 當設定儲存後, 按下 Esc 鍵完成設定 當 minicom 視窗出現後, 重起 XSBase270 將會看到啟動資訊 如果沒有出現啟動資訊, 請檢查 mincom 的設定和線纜連接是否有錯

5 2 利用串列埠通訊檔傳輸在與目標板連接後, 可以通過串列埠下傳一些檔案到目標板, 操作步驟如下 : (1) 在與目標正確連接後, 進入 [root@51board~], 按下 CTRL+A 鍵後, 再按 Z 鍵, 系統顯示 minicom 的命令選項功能表 ; 其中 Send files 和 Receive files 兩項負責檔案資料的傳輸, 所用命令使用熱鍵進行啟動 如上傳檔案只需按 S 鍵 (2) 當向目標板上傳檔案時, 按 S 鍵, 系統顯示串列埠通訊協定選項, 利用方向鍵選中 zmodem 傳輸協定, 按 Enter 鍵, 進入檔案選擇功能表

6 (3) 檔案傳輸檔案選擇功能表彈出後, 利用空白鍵選中需要上傳的檔案, 一次可以選擇多個檔案, 選好需要傳輸的檔案後按 Enter 鍵, 便可以進行檔資料傳輸 當資料傳輸完畢, 系統會彈出傳輸完畢提示功能表 ( 如下圖所示 ) 二 網路共享系統 nfs 的設定網路共享系統 nfs 可以將 PC 上的一部分檔案系統作為目標板的資源, 這樣可以彌補目標板儲存空間的不足 在使用網路檔案之時, 應對網路檔案設定進行一定的設定 1 主機(host) 的設定 : 在主機 /mnt 目錄下建立 nfs 目錄, 並利用文書編輯器編輯修改 /etc/exports 檔, 增加如下內容 : /mnt/nfs *(rw,no_root_squash,no_all_squash) 將主機的 /mnt/nfs 目錄設定為能夠通過網路共享系統存取可讀寫的目標,

7 2 重新啟動 nfs /etc/rc.d/init.d/nfs stop /etc/rc.d/init.d/nfs start 3 目標板設定 ( 假設主機的 IP 位址為 ) [root@51board~]$ portmap 請先確定開發板在 /mnt 路徑底下有 nfs 資料夾, 若沒有就自行新增 EELiod Linux 實驗指導手冊 [root@51board~]$ mount t nfs o tcp o nolock :/mnt/nfs /mnt/nfs 上述設定實現將主機上的 /mnt/nfs 目錄掛載到目標板的 /mnt 目錄下, 並作為目標板檔案系統的一部分 這 時, 可以將需要傳輸的檔案或需要執行的程式儲存在主機的 /mnt/nfs 目錄下, 然後在目標板對主機 /mnt/nfs 上的檔案進行執行或複製等相對應的處理 三 ftp 檔案傳輸檔案傳輸協定 ftp(file Transimit Protocol) 利用乙太網實現檔案的傳輸 ftp 相對於串列埠傳輸檔案來 說, 傳輸速度快, 所以上傳比較大的檔案一般採用 ftp 來實現, 需要上傳的檔案應儲存到主機的 /var/ftp/pub 目錄下 下面介紹 ftp 檔案傳輸過程 ( 假設主機的 IP 位址為 ) (ftp 的其他用法可以在 linux 終端機提示符輸入 man ftp 查看 ) 1 在目標板的終端輸入 ftp 命令 [root@51board~]$ ftp 輸入使用者名稱和密碼 : 使用者採用匿名登陸網路 (anonymous), 無需輸入密碼 如果使用者需要採 用其他的使用者名登陸, 必須修改 ( 腳本 ) 3 當使用者名稱和密碼都正確後, 在終端顯示登陸成功資訊和 ftp 提示符, 如圖所示 4 檔案傳輸 :ftp 提示符號下利用 cd 命令轉到主機的 pub 目錄下, 利用 get 命令上傳需要傳輸的檔案 假 設需要上傳的檔名為 facedect( 確保檔案儲存在主機的 /var/ftp/pub 目錄下 ) ftp>bi ( 進入二進位傳輸模式必要 ) ftp>get facedect 檔案傳輸完畢後,ftp 輸出成功資訊和被傳輸檔案的位元組數 ( 如圖所示 )

8 實驗儀器實驗儀器 1 裝有 Linux 作業系統的 PC 一台 ; 2 XSBase270 或 XSBase255 ARM 實驗開發平台一套 實驗內容實驗內容 一 minicom 的使用實驗內容 1 將目標板與 PC 相連, 利用 minicom s 正確設定串列埠的參數, 啟動目標板, 記錄 PC 顯示的內容 2 關閉目標板, 利用 minicom s 重新設定串列埠參數, 啟動目標板, 記錄 PC 顯示的現象 3 利用串列埠通訊向目標板下載一個 hello 的應用程式, 同時執行該應用程式 記錄檔案下載在目標板目錄和下載檔的基本步驟 二 網路共享系統 nfs 的設定設定及應用實驗內容 1 通過網路共享系統的設定將主機的其他目錄( 如 /root/mkdir 目錄 ), 並掛載到目標板上, 記錄設定的步驟 2 將主機 example 目錄下的 ARM 程式 hello 複製到主機的網路共享系統目錄上, 在目標板的掛載目錄執行該程式, 記錄執行結果並寫出你的結論 3 將目標板其他目錄上的檔案複製到網路共享系統掛載的目錄上, 然後到主機上查看檔案是否完成傳輸 4 將主機上其他目錄上的檔案複製到網路共享系統掛載的目錄上, 然後到目標板掛載網路共享系統的目錄中將該檔案複製到目標板其他目錄上, 重新啟動目標板系統查看檔案是否複製成功 最後寫出你的結論 三 ftp 實驗內容 1 將 example 目錄下的檔案 cxcore.lib 檔通過 ftp 直接傳輸到目標板的 /usr/lib 目錄下, 記錄通過 ftp 傳輸檔案的基本步驟, 並與通過串列埠傳輸檔案進行比較, 寫下你的結論 2 將目標板中/usr/lib 目錄下的一個檔傳輸到主機上, 記錄傳輸的基本步驟和檔傳輸所在的目錄

9 思考題思考題 1 一目標平台通過串列埠與 PC 連接後, 使用者啟動目標平台時發現串列埠終端出現亂碼, 請分析串列埠終端機產生亂碼的原因 2 某同學想利用 ftp 進行檔案傳輸, 他已經設定主機平台的 IP 位址為 , 可在串列埠終端輸入 ftp 時, 出現 ftp:connect:connection refused 錯誤, 請分析產生錯誤的原因 3 參考 ftp 檔案, 分析在 ftp 方式下如何使用 linux 下如 mkdir 等常用命令

10 實驗二 Makefile 實驗 實驗目的實驗目的 1 瞭解 Makefile 的基本概念和基本結構 2 初步掌握編寫簡單 Makefile 的方法 3 瞭解遞迴 Make 的編譯過程 4 初步掌握利用 GNU Make 編譯應用程式的方法 實驗原理實驗原理 在 Linux 或 Unix 環境下, 對於只含有幾個程式碼檔案案的小程式 ( 如 hello.c) 的編譯, 可以手動輸入 gcc 命令對程式碼檔案逐個進行編譯 ; 然而在大型的專案開發中, 可能涉及幾十到幾百個原始檔案, 採用 手動輸入的方式進行編譯, 則非常不方便, 而且一旦修改了程式碼, 尤其標頭檔發生了的修改, 採用手動 方式進行編譯和維護的工作量相當大, 而且容易出錯 所以在 Linux 或 Unix 環境下, 人們通常利用 GNU make 工具來自動完成應用程式的維護和編譯工作 實際上,GNU make 工具通過一個稱為 Makefile 的檔案 來完成對應用程式的自動維護和編譯工作 Makefile 是按照某種腳本語法編寫的文字檔案, 而 GNU make 能夠對 Makefile 中指令進行解釋並執行編譯操作 Makefile 檔案定義了一系列的規則來指定哪些檔案需要 先編譯, 哪些檔案需要後編譯, 哪些檔案需要重新編譯, 甚至於進行更複雜的功能操作 GNU make 工作 時的執行步驟如下 : 1 讀入所有的 Makefile 2 讀入被 include 的其他 Makefile 3 初始化檔案中的變數 4 推導隱含規則, 並分析所有規則 5 為所有的目標檔案建立依賴關係鏈 6 根據依賴關係, 決定哪些目標要重新產生 7 執行產生命令 1-5 步為第一個階段,6-7 為第二個階段 第一個階段中, 如果定義的變數被使用了, 那麼,make 會把其 展開在使用的位置 但 make 並不會完全馬上展開,make 使用的是拖延戰術, 如果變數出現在依賴關係的 規則中, 那麼僅當這條依賴被決定要使用了, 變數才會在其內部展開 下面對 makefile 的相關問題進行簡 單介紹 : 1 Makefile 的基本結構 Makefile 的一般結構 : target :dependency command 結構中各部分的含義 : (1) target( 目標 ): 一個目標檔, 可以是 Object 檔, 也可以是執行檔 還可以是一個標籤 (Label) (2) dependency( 依賴 ): 要產生目標檔 (target) 所依賴哪些檔 (3) command( 命令 ): 建立專案時需要執行的 shell 命令 ( 注 : 命令 (command) 部分的每行的縮進必 須要使用 Tab 鍵而不能使用多個空格 ) Makefile 實際上是一個檔案的依賴關係, 也就是說, target 這一個或多個的目標檔依賴於 dependency 中的檔, 其產生規則定義在命令 command 中 如果依賴檔 (dependency) 中有一個以上的檔比目標 (target)

11 檔要新的話,shell 命令 (command) 所定義的命令就會被執行 這就是 Makefile 的規則 也就是 Makefile 中最核心的內容 例如, 假設有一個 C 原始檔案 test.c, 該原始檔案包含有自定義的標頭檔 test.h, 則目標檔 test.o 明確依賴於兩個原始檔案 :test.c 和 test.h 如果只希望利用 gcc 命令來產生 test.o 目標檔, 這時, 就可以利用如下的 makefile 來定義 test.o 的建立規則 : #This makefile just is a example. test.o: test.c test.h gcc c test.c 從上面的例子注意到, 第一個字元為 # 的行表示注釋行 第一個非注釋行指定 test.o 為目標, 並且依賴於 test.c 和 test.h 檔案 隨後的行指定了如何從目標所依賴的檔建立目標 當 test.c 或 test.h 檔在編譯之後又被修改, 則 make 工具可自動重新編譯 test.o, 如果在前後兩次編譯之間,test.c 和 test.h 均沒有被修改, 而且 test.o 還存在的話, 就沒有必要重新編譯 這種依賴關係在多原始檔案的程式編譯中尤其重要 通過這種依賴關係的定義,make 工具可避免許多不必要的編譯工作 一個 makefile 檔案中可定義多個目標, 利用 make target 命令可指定要編譯的目標, 如果不指定目標, 則使用第一個目標 通常,makefile 中定義有 clean 目標, 可用來清除編譯過程中的中間檔 # This makefile just is a example. test.o: test.c test.h gcc -c test.c clean: rm -f *.o 執行 make clean 時, 執行 rm f *.o 命令, 刪除編譯過程中產生的所有中間檔 2 Makefile 的基本內容 Makefile 一般包括包含 : 顯式規則 隱含規則 變數定義 檔案指示和注釋等五個內容 (1) 顯式規則 : 顯式規則說明如何產生一個或多個的目標檔 這是由 Makefile 的書寫者明顯指出, 要產生的檔, 檔的依賴檔, 產生的命令 (2) 變數定義 在 Makefile 中可以定義一系列的變數, 變數一般都是字串, 當 Makefile 被執行時, 變數的值會被擴充到相對應的引用位置上 (3) 隱含規則 : 由於 GNU make 具有自動推導功能, 所以隱含規則可以比較粗糙地簡略地書寫 Makefile, 然後由 GNU make 的自動推導功能完成隱含規則的內容 (4) 檔指示 其包括了三個部分, 一個是在一個 Makefile 中引用另一個 Makefile, 就像 C 語言中的 include 一樣 ; 另一個是指根據某些情況指定 Makefile 中的有效部分, 就像 C 語言中的預編譯 #if 一樣 ; 還有就是定義一個多行的命令 (5) 注釋 Makefile 中只有行注釋, 和 UNIX 的 Shell 腳本一樣, 其注釋是用 # 字元, 如果你要在你的 Makefile 中使用 # 字元, 可以用反斜框進行轉義, 如 : \# 2.1 Makefile 中的變數 (1) Makefile 中定義的變數, 與 C/C++ 語言中的巨集一樣, 代表一個文本字串, 在 Makefile 被執行時候變數會自動地展開在所使用的地方 Makefile 中的變數可以使用在 目標, 依賴目標, 命令 或 Makefile 的其他部分中 (2) Makefile 中變數的命名字可以包含字元 數位, 下劃線 ( 可以是數位開頭 ), 但不應該含有 : # = 或是空字元 ( 空格 Enter 等 ) (3) Makefile 中變數是大小寫敏感的, foo Foo 和 FOO 是三個不同的變數名 傳統的 Makefile 的變數名是全大寫的命名方式 (4) 變數在聲明時需要給予初值, 而在使用時, 需要在變數名前加上 $ 符號

12 # makefile test for hello program #written by Emdoor CC=gcc CFLAGS= OBJS=hello.o all: hello hello: $(OBJS) $(CC) $(CFLAGS) $(OBJS) o hello hello.o: hello.c $(CC) $(CFLAGS) c hello.c o $(OBJS) clean: rm rf hello *.o 上面自定義變數 OBJS 表示 hello.o, 當 makefile 被執行時, 變數會在使用它的地方精確地展開, 就像 C/C++ 中的 Macro 一樣 上述 makfile 變數展開後的形式為 : # makefile test for hello program #written by Emdoor CC=gcc CFLAGS= OBJS=hello.o all: hello hello: hello.o gcc hello.o o hello hello.o: hello.c gcc c hello.c o hello.o clean: rm rf hello *.o GNU make 的主要預定義變數 GNU make 有許多預定義的變數, 這些變數具有特殊的含義, 可在規則中使用 以下給出了一些主要的預定義變數, 除這些變數外,GNU make 還將所有的環境變數作為自己的預定義變數 $@ 表示規則中的目標檔集 在模式規則中, 如果有多個目標, 那麼,"$@" 就是匹配於目標中模式定義的集合 $% 僅當目標是函數函式庫檔中, 表示規則中的目標成員名 例如, 如果一個目標是 "foo.a(bar.o)", 那麼,"$%" 就是 "bar.o","$@" 就是 "foo.a" 如果目標不是函數函式庫檔 (Unix 下是 [.a],windows 下是 [.lib]), 那麼, 其值為空 $< 依賴目標中的第一個目標名字 如果依賴目標是以模式 ( 即 "%") 定義的, 那麼 "$<" 將是符合模式的一系列的檔集 注意, 其是一個一個取出來的 $? 所有比目標新的依賴目標的集合 以空格分隔 $^ 所有的依賴目標的集合 以空格分隔 如果在依賴目標中有多個重複的, 那個這個變數會去除重複的依賴目標, 只保留一份 $+ 這個變數很像 "$^", 也是所有依賴目標的集合 只是它不去除重複的依賴目標 命令的變數 AR 函式庫打包程式 預設命令是 ar AS 組合語言編譯程序 預設命令是 as

13 CC C 語言編譯程序 預設命令是 cc CXX C++ 語言編譯程序 預設命令是 g++ CO 從 RCS 檔中擴充檔程式 預設命令是 co CPP C 程式的預處理器 ( 輸出是標準輸出設備 ) 預設命令是 $(CC) E FC Fortran 和 Ratfor 的編譯器和預處理程式 預設命令是 f77 GET 從 SCCS 檔中擴充檔的程式 預設命令是 get LEX Lex 方法分析器程式 ( 針對於 C 或 Ratfor) 預設命令是 lex PC Pascal 語言編譯程序 預設命令是 pc YACC Yacc 文法分析器 ( 針對於 C 程式 ) 預設命令是 yacc YACCR Yacc 文法分析器 ( 針對於 Ratfor 程式 ) 預設命令是 yacc r MAKEINFO 轉換 Texinfo 原始檔案 (.texi) 到 Info 檔程式 預設命令是 makeinfo TEX 從 TeX 原始檔案建立 TeX DVI 檔的程式 預設命令是 tex TEXI2DVI 從 Texinfo 原始檔案建立軍 TeX DVI 檔的程式 預設命令是 texi2dvi WEAVE 轉換 Web 到 TeX 的程式 預設命令是 weave CWEAVE 轉換 C Web 到 TeX 的程式 預設命令是 cweave TANGLE 轉換 Web 到 Pascal 語言的程式 預設命令是 tangle CTANGLE 轉換 C Web 到 C 預設命令是 ctangle RM 刪除檔命令 預設命令是 rm f 命令參數變數 : EELiod Linux 實驗指導手冊 下面的這些變數都是相關上面的命令的參數 如果沒有指明其預設值, 那麼其預設值都是空 ARFLAGS 函式庫打包程式 AR 命令的參數 預設值是 rv ASFLAGS 組合語言編譯器參數 ( 當明顯地調用.s 或.S 檔案時 ) CFLAGS CXXFLAGS COFLAGS C 語言編譯器參數 C++ 語言編譯器參數 RCS 命令參數 CPPFLAGS C 預處理器參數 ( C 和 Fortran 編譯器也會用到 ) FFLAGS GFLAGS LDFLAGS LFLAGS Fortran 語言編譯器參數 SCCS get 程式參數 鏈結器參數 ( 如 : ld ) Lex 文法分析器參數 PFLAGS Pascal 語言編譯器參數 RFLAGS YFLAGS Ratfor 程式的 Fortran 編譯器參數 Yacc 文法分析器參數 2.2 隱含規則 GNU make 包含有一些內置的或隱含的規則, 這些規則定義了如何從不同的依賴檔建立特定類型的目 標 GNU make 支援兩種類型的隱含規則 : (1) 附檔名規則 (Suffix Rule) 附檔名規則是定義隱含規則的方法 附檔名規則定義了將一個具有某個 附檔名的檔 ( 例如,.c 檔 ) 轉換為具有另外一種附檔名的檔 ( 例如,.o 檔 ) 的方法 每個附檔名規則以兩 個成對出現的附檔名定義, 例如, 將.c 檔轉換為.o 檔的附檔名規則可定義為 :.c.o: $(CC) $(CCFLAGS) $(CPPFLAGS) -c -o $@ $< (2) 模式規則 (pattern rules) 這種規則更加通用, 因為可以利用模式規則定義更加複雜的依賴性規則 模式規則看起來非常類似於正則規則, 但在目標名稱的前面多了一個 % 號, 同時可用來定義目標和依賴檔 之間的關係, 例如下面的模式規則定義了如何將任意一個 X.c 檔轉換為 X.o 檔案 : %.c:%.o $(CC) $(CCFLAGS) $(CPPFLAGS) -c -o $@ $<

14 2.3 檔案引用 EELiod Linux 實驗指導手冊 在 Makefile 使用 include 關鍵字可以把別的 Makefile 包含進來, 這很像 C 語言的 #include, 被包含的檔案會放在當前檔案的包含位置 例如 : 有這樣幾個 Makefile:a.mk b.mk c.mk, 還有一個檔叫 foo.make, 以及一個變數 $(bar), 其包 含了 e.mk 和 f.mk, 那麼, 下面的語句 : include foo.make *.mk $(bar) 等於 : include foo.make a.mk b.mk c.mk e.mk f.mk make 命令開始時, 會把找尋 include 所指出的其他 Makefile, 並把其內容安置在當前的位置 如果檔都沒有指定絕對路徑或是相對路徑的話,make 首先會在當前目錄下尋找, 如果當前目錄下沒有找 到, 那麼,make 還會在下面的幾個目錄下找 : (1) 如果 make 執行時, 有 -I 或 --include-dir 參數, 那麼 make 就會在這個參數所指定的目錄 下去尋找 (2) 如果目錄 <prefix>/include( 一般是 :/usr/local/bin 或 /usr/include) 存在的話,make 也會去找 如果有檔案沒有找到的話,make 會產生一條警告資訊, 但不會馬上出現致命錯誤 它會繼續載入其 他的檔案, 一旦完成 makefile 的讀取,make 會再重試這些沒有找到, 或是不能讀取的檔案, 如果還是 不行,make 才會出現一條錯誤資訊 2.4 Makefile 中的函數 在 Makefile 中可以使用函數來處理變數, 從而讓命令或規則更為的靈活和具有智慧, 函數調用, 很 像變數的使用, 也是以 $ 來標識的, 函數調用後, 函數的返回值可以當做變數來使用 例如 :'wildcard' 的函數, 可以展開成一列所有符合由其參數描述的檔案名 檔案間以空格間隔 語法 如下 : $(wildcard PATTERN...) 用 'wildcard' 函數找出目錄中所有的 ".c" 檔案 :SOURCES = $(wildcard *.c) 實際上,GNU make 還是許多如字串處理函數字串處理函數 檔案名操作函數等檔案名操作函數等其他函數 3 執行 make 3.1 Make 的執行 一般來說, 最簡單的就是直接在命令行下輸入 make 命令,GNU make 找尋預設的 Makefile 的規則是 在當前目錄下依次找三個檔案 GNUmakefile makefile 和 Makefile 其按順序找這三個檔案, 一 旦找到, 就開始讀取這個檔案並執行, 也可以給 make 命令指定一個特殊名字的 Makefile 要達到這個功 能, 要求使用 make 的 -f 或是 --file 參數, 例如 :make f Hello.makefile 3.2 嵌套執行 make 在一些大的工程中, 不同模組或是不同功能的原始檔案放在不同的目錄中, 可以在每個目錄中都書寫 一個該目錄的 Makefile, 這有利於 Makefile 變得更加地簡潔, 而不至於把所有的東西全部寫在一個 Makefile 中, 這個技術對於進行模組編譯和分段編譯有著非常大的好處 例如, 有一個子目錄叫 subdir, 這個目錄下有個 Makefile 檔指明了這個目錄下檔案的編譯規則 那麼 Top 層的 Makefile 可以書寫 : subsystem: cd subdir && $(MAKE) 如果要傳遞變數到下級 Makefile 中, 那麼可以使用 export <variable...> 來聲明 3.3 GNU make 命令選項 GNU make 命令還有一些其他選項, 下面給出了這些選項 命令行選項 含義 -C DIR 在讀取 makefile 之前改變到指定的目錄 DIR -f FILE 以指定的 FILE 檔作為 makefile

15 -h 顯示所有的 make 選項 -i 忽略所有的命令執行錯誤 -I DIR 當包含其他 makefile 檔時, 可利用該選項指定搜索目錄 -n 只列印要執行的命令, 但不執行這些命令 -p 顯示 make 變數資料庫和隱含規則 -s 在執行命令時不顯示命令 -w 在處理 makefile 之前和之後, 顯示工作目錄 -W FILE 假定檔 FILE 已經被修改 實驗儀器實驗儀器 1 裝有 Linux 作業系統的 PC 一台 ; 2 XSBase270 或 XSBase255 ARM 實驗開發平台一套 實驗內容實驗內容 一 使用命令行的方式手動編譯程序方法 1 利用文書編輯器建立 hello.c 檔案 //hello.c //written by Chhnet #include <stdio.h> int main() { } printf("welcome chhnet!\n"); return 1; 2 手動編譯 hello 應用程式 在 hello.c 的目錄的終端下輸入 : [root@local]$ gcc c hello.c [root@local]$gcc hello.o o hello 通過 ls 命令查看當前目錄下是否產生程式碼 hello.c 的 object 檔案 hello.o 和可執行檔 hello, 執行可執行檔 hello 查看一下執行結果 [root@local]$./hello 3 修改 hello.c 檔, 重新手動編譯應用程式 4 刪除 hello.o 和 hello 檔案 [root@local]$rm f hello.o [root@local]$rm f hello 二 利用 GNU make 自動編譯應用程式方法 1 利用文書編輯器建立一個 makefile 檔, 並將其儲存到與 hello.c 相同的目錄下

16 # makefile test for hello program #written by Chhnet CC=gcc CFLAGS= all: hello hello: hello.o $(CC) $(CFLAGS) hello.o o hello hello.o: hello.c clean: $(CC) $(CFLAGS) c hello.c o hello.o rm rf hello *.o 2 先後執行如下命令 [root@local]$make [root@local]$ls [root@local]$./hello 查看並記錄所產生的檔和執行的結果 3 執行 make clean 命令 : [root@local]$make clean 4 修改 hello.c 檔, 重複第 2 3 步操作, 查看並記錄所產生的檔和執行結果, 並與手動編譯進行比較, 寫 出你的結論 5 重新編輯 makefile 檔 ( 斜黑體表示修改部分 ) # makefile test for hello program #written by Chhnet CC=gcc CFLAGS= OBJS=hello.o all: hello hello: $(OBJS) $(CC) $(CFLAGS) $^ -o $@ hello.o: hello.c clean: $(CC) $(CFLAGS) c $< -o $@ rm rf hello *.o 6 重複第 2,3 步操作, 查看並記錄所產生的檔和執行的結果 比較這兩種操作, 寫出你的結論 同時指 出 $^ $@ $< 在上述 Makefile 中的含義 三 多個.c 檔的編譯 1 建立檔案 hello1.c hello2.c hello.h 和 makefile

17 //hello1.c //written by Chhnet #include <stdio.h> int main() { printf("welcome Chhnet!\n"); test2(); return 1; } //hello2.c //written by Chhnet #include "hello2.h" #include <stdio.h> void test2(void) { } printf("welcome Chhnet! hello2\n"); //hello2.h //written by Chhnet void test2(void); # makefile test for multi files program #written by Emdoor CC=gcc CFLAGS= OBJS=hello1.o hello2.o all: hello hello: $(OBJS) $(CC) $(CFLAGS) $^ -o $@ hello1.o: hello1.c $(CC) $(CFLAGS) c $< -o $@ hello2.o: hello2.c clean: $(CC) $(CFLAGS) c $< -o $@ rm rf hello *.o 2 先後執行如下命令 [root@local]$make [root@local]$ls [root@local]$./hello 查看並記錄所產生的檔和執行的結果, 寫出你的結論 3 修改 makefile 檔 ( 斜黑體表示修改部分 )

18 # makefile test for multi files program #written by Chhnet CC=gcc CFLAGS= CFILES=$(wildcard *.c) OBJS=$(CFILES:%c=%.o) all: hello hello: $(OBJS) $(CC) $(CFLAGS) o hello $(OBJS).c.o: $(CC) c $< clean: rm rf hello *.o 4 重複第 2 步操作, 查看並記錄所產生的檔和執行的結果, 寫出你的結論 並指出 wildcard.c.o 的含義和變數 CFILES 代表的內容 思考題思考題 1 根據提供的 Linux 作業系統程式中得 Makefile 結構, 分析在專案中多級目錄中存在著多個 makefile 時, 編譯的順序如何? 2 根據 Makefile 中變數定義規則, 如果實驗中的 hello.c 檔編譯到目標平台中執行, 應該怎樣修改 Makefile 中變數參數?

19 實驗三 BootLoader 實驗 實驗目的實驗目的 1 瞭解 BootLoader 的基本概念和框架結構 2 瞭解 BootLoader 引導作業系統的過程 3 掌握 bootloader 程式的編譯方法 4 掌握 BootLoader 程式的使用方法 實驗原理實驗原理 1 bootloader 的作用 PC 中的引導載入程式由 BIOS 和位於硬碟 MBR 中的 OS Boot Loader 一起組成 BIOS 在完成硬體檢測和資源分配後, 將硬碟 MBR 中的 Boot Loader 讀到系統的 RAM 中, 然後將控制權交給 OS Boot Loader Boot Loader 的主要執行任務就是將核心映像從硬碟上讀到 RAM 中, 然後跳轉到核心的入口點去執行, 也即開始啟動作業系統 嵌入式系統中, 通常並沒有像 BIOS 那樣的硬體程式, 因此整個系統的載入啟動任務完全由 bootloader 來完成 bootloader 的主要作用 : (1) 初始化硬體設備 (2) 建立記憶體空間的映射圖 (3) 完成核心的載入, 為核心設定啟動參數 2 bootloader 程式結構框架嵌入式系統中的 boot Loader 的實現完全依賴於 CPU 的體系結構, 因此大多數 Boot Loader 都分為第一階段和第二階段兩大部分, 依賴於 CPU 體系結構的程式, 比如設備初始化程式等, 通常都放在階段 1 中, 而且通常都用組合語言來實現, 以達到高效能的目的 而階段 2 則通常用 C 語言來實現, 這樣可以實現一些複雜的功能, 而且程式會具有更好的可讀性和可攜性 (1) Boot Loader 的階段 1 通常主要包括以下步驟 : 硬體設備初始化 ; 複製 Boot Loader 的程式到 RAM 空間中 ; 設定好堆疊 ; 跳轉到階段 2 的 C 入口點 (2) Boot Loader 的階段 2 通常主要包括以下步驟 : 初始化本階段要使用到的硬體設備 ; 系統記憶體映射 (memory map); 將 kernel 映射和根檔案系統映射從 Flash 讀到 RAM 空間中 ; 為核心設定啟動參數 ; 調用核心 3 bootloader 程式架構分析 3.1 Boot Loader 階段 1 分析 (1) 基本的硬體初始化 Boot Loader 一開始就執行基本硬體初始化操作, 其目的是為階段 2 的執行以及隨後的核心的執行準備

20 好一些基本的硬體環境 它通常包括以下步驟 : 初始化 GPIO 功能, 通過 GPIO 來驅動 LED, 其目的是表明系統的狀態是 OK 還是 Error 如果板子上沒有 LED, 那麼也可以通過初始化 UART 向串列埠列印 Boot Loader 的 Logo 字元資訊來完成這一點 ( 參考 fixgpio.s define_gpio: ldr r1, =GPIO_BASE /* 0x40E00000*/ ldr r0, =_GPSR0 /*0x */ str r0, [r1, #GPSR0] /*GPIO<13,12> is set as output */ ldr r0, =_GPCR0 /* 0x */ str r0, [r1, #GPCR0] /*GPIO<11> is clear to level zero*/ ldr r0, =_GAFR0L /* 0x */ str r0, [r1, #GAFR0L] /* GPIO(15) is set as alternate functions 2->nCS<1>*/ ldr r0, =_GAFR0U /* 0x (2<<0 )*/ str r0, [r1, #GAFR0U] /*GPIO<18,16> set as alternate functions 2 設定 CPU 的速度和 clock 頻率 ( 參考 start.s 部分程式 ) clock_enable :/* start.s*/ #if defined(config_pxa25x) ldr r0, =0x0001FFFF #elif defined(config_pxa27x) ldr r0, =0x01FFFFFF #endif ldr r1, =CKEN str r0, [r1] mov pc, lr 記憶體控制單元初始化 包括正確地設定系統動靜態記憶體控制器的各個暫存器等 setup_memory : /* change cpu speed function ldr r1, =CCCR ldr r0, =_CCCR str r0, set CCCR (2) 將 bootloader 程式載入到 RAM 空間

21 /* copy bootloader to dynamic memory area*/ /* start.s*/ ldr r0, =0x00 ldr r1, = boot_start file */ ldr r2, = boot_end file */ 1: ldmia r0!, {r3-r10} stmia r1!, {r3-r10} cmp r1, r2 blt 1b (3) 設定堆疊指標 sp 堆疊指標的設定是為了執行 C 語言程式作好準備 通常我們可以把 sp 的值安排在 RAM 空間的最頂端 ( 堆疊向下生長 ) 此外, 在設定堆疊指標 sp 之前, 也可以關閉 led 燈, 以提示準備跳轉到階 段 2 經過上述這些執行步驟後, 系統的實體記憶體佈局應該如圖 3-1 set stack point /* start.s*/ ldr sp, =stack_point-4 /*stack_point = boot_start + 0x ;*/ 圖 3-1 系統的實體記憶體佈局 (4) 跳轉到階段 2 的 C 入口點 在上述一切都就緒後, 就可以跳轉到 Boot Loader 的階段 2 去執行了 在 ARM 系統中, 可以通過修改 PC 暫存器為合適的位址來實現 ldr pc, =main start.s file*/ 3.2 Boot Loader 階段 2 分析階段 2 的程式通常用 C 語言來實現, 以便於實現更複雜的功能和取得更好的程式可讀性和可攜性 但

22 是與普通 C 語言應用程式不同的是, 在編譯和鏈結 Boot Loader 程式時, 不能使用 glibc 庫中的任何支援函數 可以直接把 main() 函數的起始位址作為整個階段 2 jump to c code ldr pc, =main (1) 初始化本階段要使用到的硬體設備 ; 本階段初始化的硬體設備通常包括 : 初始化至少一個串列埠, 以便和終端使用者進行 I/O 輸出資訊 ; 初始化計時器 初始化網路傳輸等 在初始化這些設備之前, 也可以重新把 LED 燈點亮, 以表明程式 bootloader 程式已經進入 main() 函數執行 設備初始化完成後, 可以輸出一些列印資訊, 程式名字字串 版本號等 ( 參考 main.c 檔案 ) (*(volatile unsigned short *)(0x0a000000)) = (1<<9) (1<<8) (1<<6) (1<<15); uart_init(); // 初始化串列埠 time_init(); // 初始化計時器 config_init(); // 記憶體映射配置初始化 // 資訊提示 printf("\033[h\033[j\n"); // clear screen. printf(" %s : bootloader for Xscale 270 board\n", PACKAGE); printf(" Copyright (C) Emdoor Co,. ltd.\n"); printf(" support : (2) 系統的記憶體映射 所謂記憶體映射就是指在整個 4GB 物理位址空間中有哪些位址範圍被分配用來定址系統的 RAM 單 元 雖然 CPU 通常預留出一大段足夠的位址空間給系統 RAM, 但是在搭建具體的嵌入式系統時卻不一定 會實現 CPU 預留的全部 RAM 位址空間 也就是說, 具體的嵌入式系統往往只把 CPU 預留的全部 RAM 位 址空間中的一部分映射到 RAM 單元上 開發板的 bootloader 程式利用 map bsetup parts[] 結構體對記憶體 的分配進行設定 ( 參考 partition.c), 從記憶體分佈可以看出,PXA27X 開發板 SRAM 和 SDRAM 起始位址 的儲存分佈情況 : bootloader: 0x _0x , 共占 256K,SDRAM 起始位址 :0xA1E00000 kernel: root: iflash_init(); PWMPCR0 = 0xff; //flash 記憶體初始化 PWMDCR0 = (0x4ff>>2); //let eth CS is ok (*(volatile unsigned long *)(0x c)) = _MSC1_ED; eth_init(); // 網路初始化 0x _0x , 共占 1.25M,SDRAM 起始位址 :0xA x _0x , 共占 30.5M,SDRAM 起始位址 :0xA

23 struct map bsetup parts[] = { }; { }, { }, { }, { }.name = "loader",.sramb = LOADER_SRAM_BASE, //0x srams = LOADER_MAX_SIZE, //0x >256K.dramb = LOADER_DRAM_BASE, //0xA1E00000.drams = 0,.maxs.name (3) 載入核心映射和根檔案系統映射 規劃記憶體佔用的佈局 EELiod Linux 實驗指導手冊 這裡包括兩個方面 :1 核心映射所佔用的記憶體範圍 ;2 根檔案系統所佔用的記憶體範圍 在規劃記憶體佔用的佈局時, 主要考慮基底位址和映射的大小兩個方面 對於核心映射, 一般將其複製到從 (MEM_START+0x8000) 這個基底位址開始的大約 1MB 大小的記憶 體範圍內 ( 嵌入式 Linux 的核心一般都不操過 1MB) 為什麼要把從 MEM_START 到 MEM_START+0x8000 這段 32KB 大小的記憶體空出來呢? 這是因為 Linux 核心要在這段記憶體中放置一些全局資料結構, 如 : 啟動參數和核心頁表等資訊 = LOADER_MAX_SIZE, = "kernel",.sramb = KERNEL_SRAM_BASE, //0x srams = KERNEL_MAX_SIZE, //0x >1.25M.dramb = KERNEL_DRAM_BASE, //0xA drams = 0,.maxs.name = KERNEL_MAX_SIZE, = "ramdisk",.sramb = RAMDISK_SRAM_BASE, //0x srams = RAMDISK_MAX_SIZE, //0x >3M.dramb = RAMDISK_DRAM_BASE, //0xA drams = 0,.maxs.name = RAMDISK_MAX_SIZE, = "root",.sramb = ROOTFS_SRAM_BASE, //0x srams = ROOTFS_MAX_SIZE, //0x01e80000->30.5M.dramb = ROOTFS_DRAM_BASE, //0xA drams = 0,.maxs = ROOTFS_MAX_SIZE, 而對於根檔案系統映射, 則一般將其複製到 MEM_START+0x 開始的地方 如果用 Ramdisk 作為根檔案系統映射, 則其解壓後的大小一般是 1MB (4) 設定核心的啟動參數 應該說, 在將核心映射和根檔案系統映射複製到 RAM 空間中後, 就可以準備啟動 Linux 核心了 但是在調用核心之前, 應該作一步準備工作, 即 : 設定 Linux 核心的啟動參數 Linux 2.4.x 以

24 後的核心都傾向以標記列表 (tagged list) 的形式來傳遞啟動參數 啟動參數標記列表以標記 ATAG_CORE 開始, 以標記 ATAG_NONE 結束 每個標記由 tag_header 結構和隨後的特定參數值資料結構來組成 ( 參考檔案 :linux.c) #define ATAG_NONE 0x struct tag_header { uint32 size; uint32 tag; }; struct tag { struct tag_header hdr; union { struct tag_core core; struct tag_mem32 mem; struct tag_videotext videotext; struct tag_ramdisk ramdisk; struct tag_initrd initrd; struct tag_serialnr serialnr; struct tag_revision revision; struct tag_videolfb videolfb; struct tag_cmdline cmdline; struct tag_acorn acorn; /* * DC21285 specific */ struct tag_memclk memclk; } u; }; 在嵌入式 Linux 系統中, 通常需要由 Boot Loader 設定的常見啟動參數有 :ATAG_CORE ATAG_MEM ATAG_CMDLINE ATAG_RAMDISK ATAG_INITRD 等 比如, 設定 ATAG_CORE 的程式如下 :

25 void create_tags(void){ tags = (struct tag *)BOOT_PARAMS; setup_tag_core(0, 0); setup_tag_initrd2(0xa , 0x ); setup_end_tag(); return; } static void setup_tag_core(uint32 rootdev, uint32 flags){ tags->hdr.tag = ATAG_CORE; tags->hdr.size = tag_size(tag_core); tags->u.core.flags = flags; // not use. tags->u.core.pagesize = 0; // set read/write. tags->u.core.rootdev = 0; tags = tag_next(tags); return; } 其中,BOOT_PARAMS 表示核心啟動參數在記憶體中的起始基底位址, 指標 tags 是一個 struct tag 類型的指標 巨集 tag_next() 將以指向當前標記的指標為參數, 計算出當前標記的下一個標記的起始位址 注意, 核心的根檔案系統所在的設備 ID 就是在這裡設定的 下面是設定 ATAG_INITRD 的示例程式, 它告訴核心在 RAM 中的什麼地方可以找到 initrd 映象 ( 壓縮格式 ) 以及它的大小 : static void setup_tag_initrd2(uint32 start, uint32 size){ tags->hdr.tag = ATAG_INITRD2; tags->hdr.size = tag_size(tag_initrd); tags->u.initrd.start = start; tags->u.initrd.size = size; tags = tag_next(tags); return; } 最後, 設定 ATAG_NONE 標記, 結束整個啟動參數列表 : static void setup_end_tag(void){ tags->hdr.tag = ATAG_NONE; tags->hdr.size = 0; return; } (5) 調用核心 Boot Loader 調用 Linux 核心的方法是直接跳轉到核心的第一條指令處, 也即直接跳轉到 MEM_START+0x8000 位址處 在跳轉時, 下列條件要滿足 : CPU 暫存器的設定 : R0=0; R1= 機器類型 ID; 關於機器類型號, 可以參見 linux/arch/arm/tools/mach-types; R2= 啟動參數標記列表在 RAM 中起始基底位址 ;

26 CPU 模式 : 必須禁止中斷 (IRQs 和 FIQs); CPU 必須 SVC 模式 ; Cache 和 MMU 的設定 : MMU 必須關閉 ; 指令 Cache 可以打開也可以關閉 ; 資料 Cache 必須關閉 ; 如果用 C 語言, 可以像下列示例程式這樣來調用核心 :( 粗體表示 ) EELiod Linux 實驗指導手冊 static bool do_boot(int argc, char **argv){ void (*kernel)(int zero, int arch); if (argc == 1) { struct map *mp; mp = find_map("kernel"); if (!mp){ printf(" can't found map for kernel.\n"); goto invalid; } kernel = (void *)mp->dramb; } else if (argc == 2){ bool res; ulong tmp; res = strtoul(argv[1], &tmp, 16); if (!res) goto invalid; kernel = (void *)tmp; } else goto invalid; if (!get_kernel_size(kernel)){ printf(" error: kernel is not exists.\n"); return false; } create_tags(); printf("starting kernel...\n"); kernel(0, 200); return true; invalid : boot_usage(); return false; } 實驗儀器實驗儀器 1 裝有 Linux 作業系統的 PC 一台 ; 2 XSBase270 或 XSBase255 ARM 實驗開發平台一套 實驗內容實驗內容 1 bootloader 程式的編譯為了編譯 Bootloader 程式, 需要事先在目標板上安裝交叉編譯工具 Toolchain ( 參考 linux 使用手冊 Toolchain 安裝部分 ) (1) 利用 tar zxvf Boot-XSBase270.tar.gz 指令解壓 [root@localhost BootLoader]$tar zxvf Boot-XSBase270.tar.gz

27 利用上述命令解壓後,bootloader 程式碼解壓到當前目錄中 Boot-XSBase270 資料夾中 (2) 編譯 在解壓的目錄裡進行 make 編譯 BootLoader]$ cd Boot-XSBase270 Boot-XSBase270]$make 編譯完成後, 在當前目錄下會產生 bootloader 映象檔 boot 2 bootloader 程式的下載 將 bootloader 的映象檔 boot 複製 Jflash-XSBase270 目錄下, 連接好 JTAG 下載器, 並利用 Jflash-XSBase270 目錄中 jflashmm 程式將 bootloader 映象檔 boot 燒寫到開發板上 [root@localhost Boot-XSBase270]$cp boot /Jflash-XSBase270/ [root@localhost Boot-XSBase270]$ cd /Jflash-XSBase270 [root@localhost Boot-XSBase270]$./jflashmm boot 3 bootloader 的使用方法 Bootloader 命令的使用方法 help Load bootp tftp 用法 描述 參數 舉例 用法 描述 幫助 簡短顯示各命令的介紹 無 Bboot> Help load [kernel/ramdisk] 把存放在 FLASH 中的映射檔複製到 SDRAM 中 在 Autoboot 過程中會自動執行, 把核心映射從 FLASH 載入到 SDRAM 中 參數 Kernel - 把核心映射從 FLASH 複製到 SDRAM 中 舉例 用法 描述 參數 舉例 用法 描述 參數 舉例 Ramdisk- Bboot> load kernel Bootp 從 FLASH 中複製 RAMDISK 到 SDRAM 執行 bootp 命令用來獲取 HOST 主機發送的 BOOTP 的資料包, 解析 BOOTP 的資料包, 獲取本機的 IP 位址 無 Bboot> bootp Tftp 檔案名 {address/loader/kernel/root/ramdisk} 通過乙太網路下載主機的資料或檔案到目標平台的 SDRAM 檔案名稱 - 主機平台需要傳輸的檔案名稱 loader - 把傳輸到目標平台的檔案放置在 SDRAM 的 loader 區域 kernel - 把傳輸到目標平台的檔案放置在 SDRAM 的 kernel 區域 root - 把傳輸到目標平台的檔案放置在 SDRAM 的 root 區域 ramdisk - 把傳輸到目標平台的檔案放置在 SDRAM 的 ramdisk 區域 address - 把傳輸到目標平台的檔案放置在 SDRAM 的指定位址 Bboot> tftp zimage kernel

28 flash erase boot set ping reboot EELiod Linux 實驗指導手冊用法 Flash {loader/kernel/root/ramdisk} 描述把 SDRAM 中的資料燒錄到 FLASH 中特定的位址參數 loader - 把 SDRAM 中的資料燒錄到 FLASH 中的 loader 區 kernel 把 SDRAM 中的資料燒錄到 FALSH 中的 kernel 區域 root 把 SDRAM 中的資料燒錄到 FLASH 中的 root 區域 ramdisk 把 SDRAM 中的資料燒錄到 FLASH 中的 ramdisk 的區域舉例 Bboot> flash kernel 用法 erase {loader/kernel/ramdisk/root} 描述清除 FALSH 中的相對應區域參數 loader 清除 FALSH 中 loder 區域 kernel 清除 FLASH 中的 kernel 區域 root 清除 FLASH 中的 root 區域 ramdisk 清除 FLASH 中的 ramdisk 區域舉例 bboot> erase kernel 用法 Boot boot [addr] 描述在 SDRAM 中執行 kernel 通過參數中指定的位址執行 kernel 參數 addr kernel image address 舉例 bboot> boot 用法 set [name] [value] 描述 設定 IP 位址,MAC 位址以及 autoboot 參數 參數 Name [myipaddr] [destipaddr] [myhaddr] [autoboot] Value [ip] [ip] [mac address] [load kernel; boot] 舉例 bboot> set // 輸出設定資訊 bboot> set myipaddr X // 改變目標平台的 IP 位址 bboot> set destipaddr XX // 改變主機平台的 IP 位址 bboot> set myhaddr 00:0E:6F:CE:59:21 // 設定目標平台的 MAC 位址 bboot> set autoboot load kernel; boot // 裝載 kernel 後自動啟動 用法 Ping 描述 檢查目標平台和主機平台的網路連接 參數 Ping 主機平台的 ip 位址 舉例 Ping xx 用法 Reboot 描述 軟體重置 參數 None 舉例 Reboot

29 思考題思考題 1 分析 bootloader 根源程式中的 flash.c 程式, 畫出該程式的流程圖 2 利用實驗二 Makefile 的知識點, 分析 bootloader 源始程式三個 Makefile 的結構與關係 3 某同學在 bootloader 源始程式目錄中, 利用 make 編譯 bootloader 源始程式, 出現如下錯誤 : [root@hostlocal Boot-XSBase270]make compile start.s make[1]: arm-linux-gcc: Command not found make[1]:***[start.o] Error 127 make: *** [all] Error 2 請分析產生錯誤的原因, 並給出解決辦法 4 bootloader 主要功能有哪些? 5 請在閱讀完 bootloader 程式後, 畫出 bootloader 程式框架流程

30 實驗四 Linux 核心編譯實驗 實驗目的實驗目的 1 瞭解 Linux 核心程式碼的目錄結構及各目錄的相關內容 2 瞭解 Linux 核心各設定選項內容和作用 3 掌握 Linux 核心設定檔 config.in 的作用 4 掌握 Linux 核心的編譯過程 5 掌握將新增核心程式加入到 Linux 核心結構中的方法 實驗原理實驗原理 1 核心程式碼核心程式碼目錄介紹 Linux 核心程式碼可以從網路上下載 ( 一般主機平台的 Linux ( 如 Red Hat Linux) 程式碼在根目錄下的 /usr/src/linux 目錄下 核心程式碼的檔案樹狀結構進行組織的, 在程式 碼樹最上層的可以看到如下的一些目錄 : (1) arch:arch 子目錄包括所有與體系結構相關的核心程式 arch 的每一個子目錄都代表一個 Linux 所 支援的體系結構 例如 :arm 目錄下就是 arm 體系架構的處理器目錄, 包含我們使用的 PXA 處理器 (2) ) ) ) include:include 子目錄包括編譯核心所需要的標頭檔 與 ARM 相關的標頭檔在 include/asm-arm 子 目錄下 (3) init: 這個目錄包含核心的初始化程式, 但不是系統的引導程式, 其中所包含 main.c 和 Version.c 檔 是研究 Linux 核心的起點 (4) ) ) ) mm: 該目錄包含所有獨立於 CPU 體系結構的記憶體管理程式, 如頁式儲存管理記憶體的分配和釋 放等 與 ARM 體系結構相關的程式在 arch/arm/mm 中 (5) Kernel: 這裡包括主要的核心程式, 此目錄下的檔實現大多數 Linux 的核心函數, 其中最重要的檔 案是 sched.c 與 Xscale 體系結構相關的程式在 arch/arm-pxa/kernel 目錄中 (6) Drives: 此目錄存放系統所有的設備驅動程式, 每種驅動程式各占一個子目錄 (a) /block: 區塊設備驅動程式 區塊設備包括 IDE 和 scsi 設備 (b) /char: 字元設備驅動程式 如串列埠 滑鼠等 (c) /cdrom: 包含 Linux 所有的 CD-ROM 程式 (d) /pci:pci 卡驅動程式程式, 包含 PCI 子系統映射和初始化程式等 (e) /scsi: 包含所有的 SCSI 程式以及 Linux 所支援的所有的 SCSI 設備驅動程式程式 (f) /net: 網路設備驅動程式 (g) /sound: 音效卡設備驅動程式 (7) lib 目錄放置核心的函式庫程式 ; (8) net 目錄包含核心與網路的相關的程式 ; (9) ipc 目錄包含核心行程通訊的程式 ; (10) ) ) ) fs 目錄是所有的檔案系統程式和各種類型的檔案操作程式, 它的每一個子目錄支援一個檔案系統, 如 JFFS2; (11) scripts 目錄包含用於設定核心的腳本檔案等 每個目錄下一般都有 depend 檔和一個 makefile 檔, 他們是編譯時使用的輔助檔, 仔細閱讀這兩個檔案對弄清各個檔案之間的相互依託關係很有幫助

31 2 核心核心的設定設定的基本結構 Linux 核心的設定系統由四個部分組成 EELiod Linux 實驗指導手冊 (1) Makefile: 分佈在 Linux 核心程式中的 Makefile, 定義 Linux 核心的編譯規則 ; 頂層 Makefile 是整 個核心設定 編譯的整體控制檔案 ; (2) 設定設定檔 (config.in): 給使用者提供設定選擇的功能 ;.config: 核心設定檔, 包括由使用者選擇的設定 選項, 用來存放核心設定後的結果 ; (3) 設定設定工具 : 包括對設定腳本中使用的設定命令進行解釋的設定命令解釋器和設定使用者介面 ( 基於 字元介面 :make config; 基於 Ncurses 圖形介面 :make menuconfig; 基於 xwindows 圖形介面 :make xconfig) (4) Rules.make: 規則檔, 被所有的 Makefile 使用 2.1 編譯規則 Makefile 利用 make menuconfig( 或 make config make xconfig) 對 linux 核心進行設定後, 系統將產生設定檔 (.config) 在編譯時, 頂層 Makefile 將讀取.config 中的設定選擇 頂層 Makefile 完成產生核心檔 (vmlinux ) 和核心模組 (module) 兩個任務, 為了達到此目的, 頂層 Makefile 遞迴進入到核心的各個子目錄中, 分別調用位於這些子目錄中的 Makefile, 然後進行編譯 至於 到底進入哪些子目錄, 取決於核心的設定 頂層 Makefile 中的 include arch/$(arch)/makefile 指定特定 CPU 體系結構下的 Makefile, 這個 Makefile 包含了特定平台相關的資訊 各個子目錄下的 Makefile 同樣也根據設定檔 (.config) 給出的設定資訊, 建造出當前設定下需要的 原始檔案列表, 並在檔最後有 include $(TOPDIR)/Rules.make 頂層 Makefile 定義並向環境中輸出了許多變數, 為各個子目錄下的 Makefile 傳遞一些變數資訊 有 些變數, 比如 SUBDIRS, 不僅在頂層 Makefile 中定義並且賦初值, 而且在 arch/*/makefile 還作了擴充 現對部分主要變數介紹如下 : (1) 版本資訊 : 有關版本資訊變數有 VERSION PATCHLEVEL SUBLEVEL, EXTRAVERSION,KERNELRELEASE 版本變數資訊定義了當前核心的版本, 比如 VERSION=2 PATCHLEVEL=4 SUBLEVEL=18 EXATAVERSION=-rmk7, 它們共同構成核心的發行版本 KERNELRELEASE: rmk7 (2) CPU 體系結構變數 ARCH 在頂層 Makefile 的開頭, 用 ARCH 定義目標 CPU 的體系結構, 比如 ARCH:=arm 等 許多子目 錄的 Makefile 中, 要根據 ARCH 的定義選擇編譯原始檔案的列表 (3) 路徑資訊變數 TOPDIR SUBDIRS TOPDIR 變數定義了 Linux 核心程式碼所在的根目錄 例如, 各個子目錄下的 Makefile 通過 $(TOPDIR)/Rules.make 就可以找到 Rules.make 的位置 SUBDIRS 變數定義了一個目錄列表, 在編譯核心或模組時, 頂層 Makefile 根據 SUBDIRS 變數決定 需要進入哪些子目錄 SUBDIRS 變數的值取決於核心的設定, 在頂層 Makefile 中 SUBDIRS 賦值為 kernel drivers mm fs net ipc lib; 根據核心的設定情況, 在 arch/*/makefile 中對 SUBDIRS 的值進行了擴充 以滿足特定 CPU 體系結構的要求 (4) 核心核心組成資訊變數 :HEAD, CORE_FILES, NETWORKS, DRIVERS, LIBS (5) 編譯資訊變數 :CPP, CC, AS, LD, AR,CFLAGS,LINKFLAGS CROSS_COMPILE 定義了交叉編譯器首碼 arm-linux-, 表明所有的交叉編譯工具都是以 arm-linux- 開頭的, 所以在各個交叉編譯器工具之前都加入了 $(CROSS_COMPILE) 變數引用, 以組成一個完整的交叉 編譯工具檔案名, 比如 arm-linux-gcc CFLAGS 定義了傳遞給 C 編譯器的參數 LINKFLAGS 是鏈結產生 vmlinux 時所使用的參數 LINKFLAGS 在 arm/*/makefile 中定義 (6). ).). 設定變數 CONFIG_*(* 表示通配符 ) 設定檔 (.config) 中有許多的設定變數等式, 用來說明使用者設定的結果 例如 CONFIG_MODULES=y 表明使用者選擇了 Linux 核心的模組功能 設定檔 (.config) 被頂層 Makefile 包含後, 就形成許多的設定變數, 每個設定變數具有四種不同的

32 值 : (a) y 表示本編譯選項對應的核心程式被靜態編譯進 Linux 核心 ; (b) m 表示本編譯選項對應的核心程式被編譯成模組 ; (c) n 表示不選擇此編譯選項 ; (d) 如果根本就沒有選擇, 那麼設定變數的值為空 2.2 設定設定檔 config.in 除了 Makefile 的編寫外, 另外一個重要的工作就是把新增功能加入到 Linux 的設定選項中來提供功能的說明, 讓使用者有機會選擇新增功能項 Linux 所有選項設定都需要在 config.in 檔中用設定語言來編寫設定腳本, 然後頂層 Makefile 調用 scripts/configure, 按照 arch/arm/config.in 來進行設定 命令執行完後產生儲存有設定資訊的設定檔 (.config) 下一次再做 make config 時將產生新的.config 檔案, 原.config 被改名為.config.old 3 編譯編譯核心核心的常用命令 精簡 Linux 核心常用命令包括 :Make Config,dep,clean,mrproper,zImage,bzImage,Modules, Modules_Install (1) ) ) ) Make config: 核心設定, 調用./scripts/Configure 按照 arch/i386/config.in 來進行設定 命令執行後產 生檔.config, 其中儲存著設定資訊 下次在做 make config 時將產生新的.config 檔案, 原檔案 config 更名為 config.old (2) make dep: 尋找依存關係 產生兩個檔. depend 和.hdepend, 其中.hdepend 表示每個.h 檔都包含 其他哪些嵌入檔 而.depend 檔有多個, 在每個會產生目標檔 (.o) 檔的目錄下均有, 它表示每個目標檔都依 賴於哪些嵌入檔 (.h) (3) make clean: 清除以前建構核心所產生的所有的目標檔, 模組檔, 核心以及一些暫存檔案等, 不產 生任何檔 (4) make rmproper: 刪除所有以前在建構核心過程所產生的所有檔, 及除了做 make clean 外, 還要刪 除.config,.depend 等檔, 把核心程式恢復到最原始的狀態 下次建構核心時必須進行重新設定 ; (5) make,make zimage, make bzimage: (a) make: 建構核心 通過各目錄的 Makefile 檔進行, 會在各個目錄下產生一大堆目標檔, 如核心程 式沒有錯誤, 將產生檔 vmlinux, 這就是所建構的核心 並產生映射檔 system.map 通過各目錄的 makefile 檔進行.version 檔中的數加 1, 表示版本號的變化 (b) make zimage : 在 make 的基礎上產生壓縮的核心映射檔./arch/$(ARCH)/boot/zImage 以 及./arch/$(ARCH)/boot/compressed 目錄下產生一些暫存檔案 (c) make bzimage: 在 make 的基礎上產生壓縮比例更大的的核心映射檔./arch/$(ARCH)/boot/bzImage 以 及./arch/$(ARCH)/boot/compressed 目錄下產生一些暫存檔案 在核心太大時進行 4 核心核心編譯過程 (1)make mrproper: 刪除所有以前在構核過程所產生的所有檔 (2)make menuconfig: 核心設定 (3)make dep: 尋找依存關係 (4)make zimage: 產生壓縮的核心映射檔核心編譯完畢之後, 產生 zimage 核心映像檔儲存在程式碼的 arch/arm/boot/ 目錄下 5 核心核心設定設定項介紹首先切換 linux 程式碼所在的目錄, 並終端輸入 make menuconfig, 系統彈出基於 Ncurses 核心設定圖形介面 ( 如圖 4-1 所示 ), 便可進行核心選項的設定 [root@]$make menuconfig

33 5.1 設定設定介面的使用方法 圖 4-1 核心設定介面 (1) 在功能表方式的設定介面上可用上下方向鍵來在各功能表之間移動 (2) 在標有 "---->" 標記的地方按 Enter 鍵進入下級選單 (3) 按兩次 <ESC> 或選擇 <Exit> 則返回到上級功能表 (4) 按 h 鍵或選擇下面的 <Help> 則可看到設定幫助資訊 (5) 按 <Tab> 鍵則在各控制選項之間移動 (6) Y 表示包含該功能選項設定在核心中,M 表示以模組的方式編譯到核心中,N 表示 該功能選項不進行編譯 (7) 設定狀態在 [ ] 或 < > 中以 * ( 選擇 ), M ( 模組 ), 空格 ( 除外 ) 來表示 5.2 設定設定選項的含義 (1) Code maturity level options --->( 圖 4-2) [*] Promprt for development and/or incomplete Code/drivers 選擇 kernel 程式的成熟度的部分, 幫助選擇開發版本層次的程式, 此項提問是否將 arpha 版本包含到 kernel 中

34 (2) Loadable module support --->( 圖 4-3) 圖 4-2 程式的成熟度選項介面 EELiod Linux 實驗指導手冊 [*] Enable Loadable module Support 利用模組可將不常用的設備驅動或功能作為模組放在核心外部, 必要時動態地調用 操作結束後從記憶 體中刪除, 這樣可以有效地使用記憶體, 同時也可減小了核心的大小 模組可以自行編譯並具有獨立的功能, 即使需要改變模組的功能, 也不用對整個核心進行修改 檔案 系統, 設備驅動, 二進位格式等很多功能都支援模組 一定要選擇 [*] [ ] Set version information on all Symbols for modules 利用這個功能能夠讓核心使用其他核心版本模組或沒有包含在此 kernel 的特殊的模組 一般選擇 [N] [*] Kernel module Loader 這個設定使 kernel 對模組處於常備狀態 在不使用 Insmod 或 rmmod 命令情況下,kernel 程式自動將需 要執行的模組調用到記憶體中, 一定時間內不使用該模組時自動將其從記憶體刪除 一般要選擇 [*] (3) System Type --->( 圖 4-4) 圖 4-3 可裝卸模組支援選項介面 (PXA270/210-based) ARM system typ 系統格式中按照 EELIOD 的 CPU 格式選擇 PXA270/210-based

35 (4) General setup --->( 圖 4-5 通用設定 ) 圖 4-4 CPU 體系結構介面 網路, 匯流排協定, 節電功能等影響整個系統的設定 圖 4-5 通用設定介面 (5) Memory Technology Devices (MTD) --->( 圖 4-6) 在嵌入式設備中為了組成固態檔案系統 (solid state filesystem, 即不旋轉的, 沒有磁片的 ) 而需要的快閃 記憶體, RAM, 和其他類似的晶片組等儲存裝置

36 圖 4-6 記憶體設備設定介面 RAM/ROM/Flash chip drivers --->( 圖 4-7 RAM/ROM/Flash 晶片驅動設定介面 ) 圖 4-7 RAM/ROM/Flash 晶片驅動設定介面 Mapping drivers for chip access --->( 圖 4-8 晶片儲存映象驅動設定介面 )

37 圖 4-8 晶片儲存映象驅動設定介面 (6) Block devices --->( 圖 4-9 塊儲存設備設定介面 ) 針對硬碟, CDROM 等以 block 為單位進行操作的儲存裝置 (block device) 選項 <M>Loopback device support 使一個檔案能夠被認為一個檔案系統 例如, 軟碟的 image 檔或複製 CD-ROM 的檔, 可被認為一個 檔案系統, 因而可以查看其內容 圖 4-9 塊儲存設備設定介面 (7) Networking options --->( 圖 4-10 網路設定選項介面 ) [*] Packet Socket 與 tcpdump( 檢查封包的頭部, 按條件列印其內容 ) 類似, 在沒有媒介協定而直接與網路設備通訊的應用 上使用 [*] Packet socket: mmapped IO ( 啟動此選項可使包協定驅動 (packet protocol driver) 支援更快速的 IO 機制

38 [*] Socket filtering <*> Unix domain Sockets EELiod Linux 實驗指導手冊 [*] TCP/IP networking ( 此功能使 Linux 系統成為 TCP/IP 網路 TCP/IP 是區域網路及網路標準協定, 不經過網路的 Standalone 電腦也需要 TCP/IP, 因為 Term 和 XWindow 等程式也使用 TCP/IP 協定 [*] IP: kernel LeveL autoconfiguration : [*] IP: DHCP Support [*] IP: BOOTP Support [*] IP: RARP Support ( 客戶端系統 (client system) 啟動時從 DHCP 或 BOOTP 伺服器索取網路設定資訊的功能 用於啟動時沒 有磁片的系統中, " 通過 NFS 的根檔案系統 (root filesystem)" 項也要選擇 [Y] 圖 4-10 網路設定選項介面 (8) Network device support --->( 圖 4-11 網路設備設定介面 ) [*] Network device support 如果使用者的電腦連接到網路上, 或者想使用 SLIP 或 PPP 的時候選擇 Ethernet (10 or 100Mbit) --->( 圖 4-12 乙太網路設備設定介面 ) <*> SMSC LAN91C111 support for EELiod Board 支援 EELIOD Ethernet 卡中 LAN91C

39 圖 4-11 網路設備設定介面 圖 4-12 乙太網設備設定介面 (9) IrDA (infrared) support( 圖 4-13 紅外線介面設定介面 )

40 圖 4-13 紅外線介面設定介面 (10) Character devices --->( 圖 4-14 字元設備驅動設定設定介面 ) 支援終端機, 視訊適配器, 滑鼠, 印表機等以文字為單位進行操作的設備 [*] VirtuaL terminal 一個物理終端上可執行多個虛擬終端 虛擬終端可支援多個 X session, 也可同時使用多個顯示器 EELIOD 平台可支援兩個,Minicom 和 lcd [*] Support for console on virtual terminal 系統 console 接收所有 kernel 資訊和警告資訊, 允許以單獨使用者 (single user) 模式登錄 [*] Standard/generic (dumb) SeriaLSupport 適用 Modem 和串列滑鼠, 串列設備的功能 [*] Support for console on serial port 可將串列埠用作 console ( 系統 console 是接收並列印 kernel 資訊和警告資訊, 允許以單獨使用者模式 登錄的設備 ) 也可用串列埠印表機等紀錄各個資訊 即使在這裡設定 [Y], 但如果不調整 kernel 參數, 則 /dev/tty0 仍然佔用著系統 console 例如, 欲將第二個串列埠換成系統 console, 需在 kernel 指令行輸入 "console=ttys1" 指令 參考 "man bootparam" 或 bootloader 檔可查到 bootloader(lilo 或 loadlin) 啟動的時候應 選用哪些選項 利用這個選項可執行沒有 VGA 卡的 linux 系統,kernel 自動將 /dev/ttys0 設為系統 console 即使沒有 直接連接到 linux box 的顯示器, 視訊卡, 鍵盤等, 也可以在用串列線連接的其他終端上控制系統 這個 功能常用倒利用 linux 的路由器, 共用機等網路設備 [*] Unix98 PTY Support PTY 是由軟體驅動的虛擬設備 (pseudo terminal) 由 master 和 slave 兩個部分組成, 與物理終端的操作 完全相同,slave 類比終端機 Master 設備從 slave 讀入資料或寫入 slave 典型的 master side 程式是 telnet 伺 服器或 xterm

41 圖 4-14 字元設備驅動設定介面 (11) File systems --->( 圖 4-15 檔案系統設定設定介面 ) 這是對 linux 可接近的各個檔案系統的設定 所有的作業系統都具有固有的檔案系統格式 一般為了 對不同作業系統的檔案系統進行讀寫操作需安裝特殊的應用程式 但是在 Linux 可以同 Kernel 模組完成 這些操作 [*] KerneL automounter Support automounter 是根據要求對遠端檔案系統自動進行 mount 的一種工具 BSD 的 amd 完全是使用者空間的 demon, 但 Linux 的 automounter 在檔案系統已經被 mount 的情況下為了減少 overhead 而部分地依賴於 kernel 如果使用這個功能則 "NFSfiLeSyStem Support" 也被啟動 [*] Kernel automounter version 4 support (also supports v3) 如果使用者的系統沒有連接到大的分散網路, 或者不是需要動態再設定的 lap top 之一的話, 可能不需 要 automounter, 在這裡選擇 [N] 即可 圖 4-15 檔案系統設定介面

42 (12) Console drivers --->( 圖 4-16 終端設備驅動設定設定介面 ) Frame-buffer support ---> [*] Support for frame buffer devices (EXPERIMENTAL) EELiod Linux 實驗指導手冊 [*] PXA LCD support 為了在 Console 中能夠使用圖像功能而支援的功能 設定不妥會造成顯示器或視訊卡的損傷 如果不確 定就選擇 [N] Frame buffer 為使用者提供等同地接近 linux 支援的各種硬體種類的環境, 其應用程式的製 作簡單, 移植性強 為了完整地使用 Frame buffer 的所有功能, 需要一個叫 fbset 的 utility 程式 EELiod 支援 PXA LCD (13) Sound --->( 圖 4-17 音效卡驅動介面 ) 圖 4-16 終端設備驅動設定介面 6 新增新增驅動驅動程式程式到 linux 核心對於一個開發者來說, 將自己開發的核心程式新增到 Linux 核心中, 需要有三個步驟 (1) 確定把自己的開發程式放入到核心的位置 ; (2) 把自己開發的功能增加到 Linux 核心的設定選項中, 讓使用者能夠選擇此功能 (3) 建立子目錄 Makefile, 根據使用者的選擇, 將相對應的程式編譯 Linux 核心中 下面, 我們就通過一個簡單的例子 xsbase driver, 結合前面學到的知識, 來說明如何將前面設計的驅動加入到 Linux 核心 6.1 主要步驟 在確定程式位置的前提下, 建立程式目錄 檔案 Makefile Config.in 等 修改上層的 config.in 檔, 把新增驅動程式加到核心設定系統中 修改上層 Makefile, 將程式新增到核心編譯系統中 6.2 驅動位置和目錄結構假設將 xsbase 驅動儲存到 linux 程式碼的 drivers/xsbase/ 目錄下 : $ cd drivers/xsbase $ tree. -- Config.in -- Makefile -- xsbase.c `-- xsbase_test.c

43 6.3 編輯編輯設定設定檔 (1) 編輯 xsbase 目錄下的設定檔 Config.in 由於 xsbase 驅動程式對於 linux 核心來說是新增加的功能, 所以首先在設定選項上建立一個 XSBASE Driver 功能表, 同時顯示 "XSBASE support" 提示資訊, 等待使用者選擇 ; 接下來判斷使用者是否選擇了 XSBASE Driver, 如果是 (CONFIG_XSBASE=y), 則進一步顯示子功能 : 使用者介面與 CPU 功能支援 ; 由於使用者介面功能可以被編譯成核心模組, 所以這裡的詢問語句使用了 tristate( 因為 tristate 的取值範圍包括 y n 和 m, 其中 m 就是對應著模組 ) # # XSBASE driver configuration # mainmenu_option next_comment comment XSBASE Driver' bool 'XSBASE support' CONFIG_XSBASE if [ "$CONFIG_XSBASE" = "y" ]; then tristate 'TEST user-space interface' CONFIG_TEST_USER bool 'TEST CPU ' CONFIG_TEST_CPU fi endmenu (2) 編輯修改 CPU 體系目錄下的設定檔 由於本實驗採用 ARM 體系結構, 所以應對 arch/arm/config.in 檔進行修, 具體修改方法是 : 在檔的最 後加入 :source drivers/xsbase/config.in, 將 XSBASE Driver 子功能的設定新增到 Linux 核心的設定中 6.4 Makefile 的修改與編輯 (1) 編輯 xsbase 目錄下的設定檔 Makefile 檔 # drivers/xsbase/makefile # # Makefile for the XSBASE TEST. # L_TARGET := xsbase.a export-objs := xsbase.o obj-$(config_xsbase) += xsbase.o include $(TOPDIR)/Rules.make clean: rm -f *.[oa].*.flags drivers/test 目錄下最終產生的目標檔是 xsbase.a 在 xsbase.c 中使用了 EXPORT_SYMBOL 輸出符 號, 所以 xsbase.o 位於 export-objs 列表中 然後, 根據使用者的選擇 ( 具體來說, 就是設定變數的取值 ), 建立各自對應的 obj-* 列表 由於 XSBASE Driver 中包一個子目錄 cpu, 當 CONFIG_TEST_CPU=y( 即 使用者選擇了此功能 ) 時, 需要將 cpu 目錄加入到 subdir-y 列表中 (2)drivers/Makefile subdir-$(config_mmc) subdir-$(config_xsbase) += mmc += xsbase include $(TOPDIR)/Rules.make 在 drivers/makefile 中加入 subdir-$(config_xsbase)+= xsbase, 使得在使用者選擇 XSBASE Driver 功

44 能後, 核心編譯時能夠進入 xsbase 目錄 (3)Makefile EELiod Linux 實驗指導手冊 DRIVERS-$(CONFIG_PLD) += drivers/pld/pld.o DRIVERS-$(CONFIG_MMC) += drivers/mmc/mmcdrivers.o DRIVERS-$(CONFIG_XSBASE) += drivers/xsbase/xsbase.o DRIVERS := $(DRIVERS-y) 在頂層 Makefile 中加入 DRIVERS-$(CONFIG_XSBASE) += drivers/xsbase/xsbase.a 如果使用者選擇 了 XSBASE Driver, 那麼 CONFIG_XSBASE 的值是 y,xsbase.o 就位於 DRIVERS-y 列表中, 然後又被放 置在 DRIVERS 列表中 在前面曾經提到過,Linux 核心檔 vmlinux 的組成中包括 DRIVERS, 所以 xsbase.o 最終可被鏈結到 vmlinux 中 通過本實驗我們從整體上去流覽了核心,2.4 版本的核心程式量很大, 但我們從整體去領會核心的特點 瞭解核心程式碼中各個目錄的關係和內容, 這對瞭解核心很有幫助 除外我們還從另一個角度來瞭解核 心, 就是核心的設定系統結構, 瞭解 Makefile 和設定檔 config.in 的含義, 還詳細介紹核心各個選項的含義 最後通過一個簡單的實驗例子, 具體說明如何將自行開發的程式加入到 Linux 核心中 實驗儀器實驗儀器 1 裝有 Linux 作業系統的 PC 一台 ; 2 XSBase270 或 XSBase255 ARM 實驗開發平台一套 實驗內容實驗內容 1 核心核心編譯實驗 (1) 利用光碟上提供的 Linux 程式碼, 具體分析遞迴性 makefile 的結構, 畫出一個從最頂層 makefile 到最底層所經過的檔路徑和所需要的變數 (2) 利用光碟上提供的 Linux 程式碼, 寫出編譯 Linux 核心的過程 (3) 利用光碟上提供的 Linux 程式碼, 然後用 make menuconfig 命令對核心的設定進行修改, 記下修改的設定選項並儲存退出, 然後用 diff 命令比較.config 和.oldconfig.old 兩個新舊設定的差別, 同時與記下的設定選項進行比較, 根據比較結果, 寫出你的結論 2 驅動驅動程式程式載入實驗 (1) 將光碟上提供的 LED 顯示驅動程式碼加入到 Linux 核心中, 寫出加入新驅動到 Linux 核心中的步驟和所需要修改的檔案 根據修改過程畫出在編譯 Linux 核心某一驅動的流程

45 思考題思考題 1 簡述 Linux 程式碼各目錄中的內容, 2 分析 make config make menuconfig make xconfig 三個 linux 核心設定介面的區別 3 指出 linux 核心編譯命令 make,make zimage, make bzimage 的區別 4 下載一個 Linux 2.6 核心, 查看它們的核心各項設定項的內容 5 請針對核心的目錄繪製一個樹狀結構圖? 請分析 Linux 核心面臨許多新的變化是怎麼將核心組織的很簡潔和具有很好的擴充性 6 簡述將新增設備驅動程式碼新增到 linux 核心中的步驟

46 實驗五嵌入式檔案系統檔案系統的構建 實驗目的實驗目的 1 瞭解嵌入式作業系統中檔案系統的類型和作用 2 瞭解 JFFS2 檔案系統的優點及其在嵌入式系統中的作用 3 掌握利用 BusyBox 軟體製作嵌入式檔案系統的方法 4 掌握嵌入式 Linux 檔案系統的的掛載過程 實驗原理實驗原理 1 Linux 檔案系統的類型 (1) EXT 檔案系統 Ext2fs 是 Linux 的標準檔案系統, 它已經取代了擴充檔案系統 ( 或 Extfs) 擴充檔案系統 Extfs 支援 的檔案大小最大為 2 GB, 支援的最大檔案名稱大小為 255 個字元, 而且它不支援索引節點 ( 包括資料修改 時間標記 ) Ext2fs 取代 Extfs 具有一些優點 : Ext2fs 支援達 4 TB 的記憶體 Ext2fs 檔案名稱最長可以到 1012 個字元 在建立檔案系統時, 管理員可以根據需要選擇儲存邏輯塊的大小 ( 通常大小可選擇 和 4096 位元組 ) Ext2fs 可以實現快速符號鏈結 ( 相當 windows 檔案系統的快捷方式 ), 不需為符號鏈結分配資料塊, 並且可將目標名稱直接儲存在索引節點 (inode) 表中 這使檔案系統的性能有所提高, 特別在存取速 度上 由於 Ext2fs 檔案系統的穩定性 可靠性和健壯性, 所以幾乎在所有基於 Linux 的系統 ( 包括臺式機 伺服器和工作站, 並且甚至一些嵌入式設備 ) 上都使用 Ext2fs 檔案系統 (2) NFS 檔案系統 NFS 是一個 RPC service, 它是由 SUN 公司開發, 並於 1984 年推出 NFS 檔案系統能夠使檔案實現 共用, 它的設計是為了在不同的系統之間使用, 所以 NFS 檔案系統的通訊協定設計與作業系統無關 當使 用者想使用遠端檔案時只要用 mount 命令就可以把遠端檔案系統掛載在自己的檔案系統上, 使遠端的 檔案在使用上和本地機器的檔案沒有區別 NFS 的設定可參考實驗一的網路共享系統 nfs 的設定 (3) JFFS2 檔案系統 JFFS 檔案系統是瑞典 Axis 通訊公司開發的一種基於 Flash 的日誌檔案系統, 它在設計時充分考慮了 Flash 的讀寫特性和電池供電的嵌入式系統的特點, 在這類系統中必需確保在讀取檔案時, 如果系統突然 斷電, 其檔案的可靠性不受到影響 對 Red Hat 的 Davie Woodhouse 進行改進後, 形成了 JFFS2 主要改 善了存取策略以提高 FLASH 的抗疲勞性, 同時也優化了碎片整理性能, 增加了資料壓縮功能 需要注意 的是, 當檔案系統已滿或接近滿時,JFFS2 會大大放慢執行速度 這是因為碎片收集的問題 相對於 EXT2fs 而言,JFFS2 在嵌入式設備中更受歡迎 JFFS2 檔案系統通常用來當作嵌入式系統的檔案系統 JFFS2 克服了 JFFS 的一些缺點 : 使用了基於哈希表的日誌節點結構, 大大加快了對節點的操作速度 支援資料壓縮

47 提供了 寫平衡 支援 支援多種節點類型 提高了對快閃記憶體的利用率, 降低了記憶體的消耗 EELiod Linux 實驗指導手冊 我們只需要在自己的嵌入式 Linux 中加入 JFFS2 檔案系統並做少量的改變, 就可以使用 JFFS 檔案系 統 通過 JFFS2 檔案系統, 可以用 Flash 記憶體來儲存資料, 即將 Flash 記憶體作為系統的硬碟來使用 可 以像操作硬碟上的檔案一樣操作 Flash 晶片上的檔案和資料 同時系統執行的參數可以即時儲存到 Flash 記憶體晶片中, 在系統斷電後資料不會遺失 作為一種 EEPROM,Flash 可分為 NOR Flash 和 NAND Flash 兩種主要類型 一片沒有使用過的 Flash 記憶體, 每一位元的值都是邏輯 1, 對 Flash 的寫操作就是將特定位元的邏輯 1 改變為邏輯 0 而清除就是 將邏輯 0 改變為邏輯 1 Flash 的資料儲存是以區塊 (Block) 為單位進行組織, 所以 Flash 在進行清除操作 時只能進行整區塊清除 Flash 的使用壽命是以清除次數進行計算, 一般是每區塊 100,000 次 為了保證 flash 儲存晶片的某些區塊不早於其他區塊到達其壽命, 有必要將在所有區塊中盡可能地平均分配清除次 數, 這就是 損耗平衡 JFFS2 檔案系統是一種 追加式 的檔案系統, 新的資料總是被追加到上次寫 入資料的後面 這種 追加式 的結構就自然實現了 損耗平衡 1 檔案系統檔案系統的製作 (1) Busybox 介紹 Busybox 是 Debian GNU/Linux 著名的 Bruce Perens 首先開發, 主要使用在 Debian 的安裝程式中 後來 又有許多 Debian 開發者對 Busybox 貢獻力量 Busybox 編譯成一個叫做 busybox 獨立執行程式, 並且可 以根據設定, 執行 ash shell 的功能, 以及幾十個小應用程式 這其中包括一個迷你的 vi 編輯器, 系統不 可或缺的 /sbin/init 程式, 以及其他諸如 sed, ifconfig, halt, reboot, mkdir, mount, ln, ls, echo, cat 等等, 所有 這些都是一個正常的系統必不可少的, 但如果把這些程式的元件拿過來的話, 大小在一個嵌入式系統中無 法承受 busybox 具有全部這些功能, 大小也不過 100K 左右 而且使用者還可以根據自己的需要對 busybox 的應用程式功能進行設定選擇 這樣可以使 busybox 的大小進一步縮小 BusyBox 支援多種體系結構, 它可以靜態或動態鏈結 glic 或者 uclibc 庫, 以滿足不同的需要, 也可以 修改 BusyBox 預設的編譯設定以移除不想使用的命令的支援 (2) busybox 的編譯 從網路上下載 BusyBox 套裝軟體, 這裡下載的是 busybox-1.00.tar.bz2 首先把它放在 /root/xsbase270_linux/filesystem 目錄下並進行解壓縮 [root@localhost]$cd /root/xsbase270_linux/filesystem [root@filesystem]$ tar jxf busybox-1.00.tar.bz2 [root@filesystem]cd busybox-1.00 [root@filesystem]make menuconfig 在 busybox 的頂層目錄下的 Makefile 中包含一些選項來控制 BusyBox 的建立 其中大部分選項是在開發 busybox 時為了調試而使用的 圖 5-1 是 BusyBox 的設定介面

48 圖 5-1 設定 BusyBox 的主介面 在 Build Option 功能表下, 可以選擇靜態庫編譯方式, 設定如下 : [*] Build BusyBox as a static binary (no shared libs) 由於為 ARM 系統製作檔案系統, 所以在交叉編譯選項中需要使用 glibc 函式庫的支援的交叉編譯器 arm-linux-gcc, 設定如圖 5-2 所示 :( 假設 ARM 交叉編譯工具所在的目錄為 /opt/xscalev1/bin) 圖 5-2 設定 BusyBox 交叉編譯選項 busybox 預設的安裝路徑為 _install, 使用者可以根據需要在 Installation Options 設定中輸入自定義路徑 圖 5-3 檔案系統安裝路徑使用者可以根據需要對檔案系統的功能選項進行設定, 這樣可以減少檔案系統的大小, 以節省儲存空間, 圖 5-4 其中一設定選項介面 當使用者對檔案系統的設定選項設定完畢後, 需要對設定選項進行儲存操作, 如圖 5-5 所示

49 圖 5-3 檔案系統安裝路徑 圖 5-4 選擇編譯命令 圖 5-5 儲存設定 設定完成後便可對 BusyBox 進行編譯

50 make dep make make install 編譯和安裝完後產生 _install 目錄 並且可以看到 bin sbin 和 usr 三個目錄, 在這三個目錄, 可以看 到一個 busybox 應用程式和許多符號鏈結, 並且還可以看出所有這些符號鏈結都指向 busybox 應用程式 2 設定設定檔案系統 在 _install 下建立 etc var tmp root 共 4 個資料夾 : [root@localhost _install]# mkdir etc 下面我們要在此 etc 下分別建立 rc,inittab,motd 三個檔案 進入剛新建的 etc, 在其下用 "vi rc" 命令建立 rc 檔案 : #!/bin/sh hostname emdoor mount -t proc proc /proc cat /etc/motd 儲存後退出, 用 chmod 命令改變 rc 檔屬性 [root@localhost etc]$chmod 777 rc 在 etc 下新建一個 inittab 檔, 內容如下 ::sysinit:/etc/init.d/rcs # Start an "askfirst" shell on the console (whatever that may be) ::askfirst:/bin/sh # /sbin/getty invocations for selected ttys tty4::respawn:/sbin/getty tty5 tty5::respawn:/sbin/getty tty6 # Example of how to put a getty on a serial line (for a terminal) #::respawn:/sbin/getty -L ttys vt100 #::respawn:/sbin/getty -L ttys vt100 # # Example how to put a getty on a modem line. #::respawn:/sbin/getty ttys2 # Stuff to do when restarting the init process ::restart:/sbin/init # Stuff to do before rebooting ::ctrlaltdel:/sbin/reboot ::shutdown:/bin/umount -a -r ::shutdown:/sbin/swapoff -a 繼續在 etc 下建立 motd 檔, 其內容使用者隨意 Welcome to ======================================== ARM-LINUX WORLD ======================================== Base on : Xsbase270-EDR Partner : Chhnet( 在 etc 下建立 init.d 目錄, 而後在 init.d 目錄下建立 rc 檔的符號連接檔 rcs [root@localhost etc]$ ls inittab motd rc [root@localhost etc]$ mkdir init.d [root@localhost etc]$cd init.d [root@localhost init.d]$ ln -s../rc rcs

51 在 _install 下建立 dev 目錄, 建立設備檔 在本實驗中一些設備檔是必需的, 比如系統控制臺 console, MTD 區塊設備 mdblock3 等, 可以使用 mknod 命令來建立 #mknod console c 5 1 #mknod mdblock3 b 31 3 除了使用 mknod 命令來手動建立設備檔外, 還可以複製主機平台 /dev 目錄下一些必要的設備檔 /root/xsbase270_linux/filesystem/busybox-1.00/_install/dev 目錄下 : # cp -dpr /dev/* /root/xsbase270_linux/filesystem/busybox-1.00-pre5/_install/dev -dp 參數表示複製過程中保證鏈結檔保持不變, 但不會複製鏈結所指的原檔案, 而且屬性不變, 然後刪除 不必要的設備檔 3 製作 JFFS2 檔映射 將光碟的 filesystem 下的 mkfs.jffs2 複製到 buybox 下 返回到 busybox 的根目錄下, 執行命令 mkfs.jffs2 #./mkfs.jffs2 -o rootfs270.img -e 0x r _install -p -l 產生映射檔 rootfs270.img, 複製到 /tftpboot 中燒寫到 flash 中, 啟動後執行結果 實驗儀器實驗儀器 1 裝有 Linux 作業系統的 PC 一台 ; 2 XSBase270 或 XSBase255 ARM 實驗開發平台一套 實驗內容實驗內容 1 根據系統提供的 busybox 程式碼, 編譯 busybox, 寫出具體編譯過程 2 利用設定檔案系統實例, 設定一個適合開發板的檔案系統, 寫出需要設定檔的功能 3 利用 mkfs.jffs 製作檔案系統映射, 並將檔案系統映射下載到開發板, 寫出系統啟動後的結果 思考題思考題 1 比較 romfs extfs2 jffs2 等檔案系統的優缺點 2 試分析 jffs2 檔案系統的載入過程 3 請製作一個 RamDisk 檔案系統作為系統的根檔案系統 4 某同學在編譯 busybox 時, 出現如下圖所示錯誤, 請分析產生錯誤的原因, 應如何修改 busybox 的設定

52

53 實驗六嵌入式 GUI 應用程式實驗 實驗目的實驗目的 注意 : 由於之後的 QT GUI 程式, 在編譯時都須要用到 cross-compiler 過的 QT lib, 所以, 請先參考及完成補充資料 - QT 移植實驗.pdf, 實驗過程中產生的資料都須保留下來, 之後會用到 1 瞭解嵌入式 GUI 的類型 2 瞭解 Qt 的基本架構 3 掌握 Qt 集成開發平台的使用方法 4 掌握 Qt 應用程式編譯方法 實驗原理實驗原理 Qt 是一種跨平台的 C++ 圖形介面 (GUI) 工具包, 它是 Troll Tech 化公司的標記產品,Qt 工具包括用於商業性質的商業版和用於開發自由軟體的兩種不同的版本, 用自由版開發軟體必須作為自由軟體公佈 1 Qt 架構 面向物件 :Qt 具有模組設計和注重軟體構件或元素的可重用性的特點 一個元件不需要知道它的內容, 而通過 signal 和 slot 與外界通訊 交流, 所有的 Qt 的元件都可通過繼承而序列化 構件支援 :Qt 提供 signal 和 slot 概念, 它是一種安全可靠的方法, 它允許回調, 並支援物件之間在彼此不知道對方資訊的情況下進行合作, 這使得 Qt 非常適合於真正的構件開發 方便性 : 由於 Qt 是一種跨平台性 GUI 工具包, 所以, 它對開發者隱藏了在處理不同視窗系統時潛在問題 為使基於 Qt 程式更加方便,Qt 包括了一系列類別, 這些類別使程式師避免了在檔案處理 時間處理等方面存在的依賴作業系統方面的細節問題 國際化 :Qt 為本地化應用提供了安全的支援, 所有的使用者介面都可以基於消息翻譯表被翻譯成各國語言 另外,Qt 完全支援雙位元組 16bit 國際字元標準 豐富的 API 函數 :Qt 為專業應用提供了 API 函數, 在 Qt API 中大約有 250 個 C++ 類別, 大多數類是基於 GUI 專用 Qt 還提供基於範本的序列化 檔和通用的 I/O 設備, 目錄管理 日期 / 時間類, 常用運算式解析等 良好的說明幫助 :Qt 包括大量的參考檔案, 有超聯結 HTML 方式,Unix/Linux 幫助頁 man 手冊頁和補充的指南 2 Qt 集成開發工具的使用 (1) 新建專案檔利用 Qt 開發應用程式, 首先應建立一個專案檔, 從 File 功能表選中 New, 從對話方塊中選中 C++ Project 圖示, 按 OK 按鈕將新建專案儲存為 test.pro(qt 專案的副檔名為.pro);Qt 集成開發平台的執行介面如圖 6-1 所示 (2) 建立表單和新增控制項選中 File 功能表中的 New 功能表, 雙擊 dialog 圖示, 建立一個對話框圖形介面, 可以在屬性編輯欄中修改表單或控制項的相關屬性 根據設計需要, 在表單上新增一些常用如按鈕 文本框等控制項如圖 6-2 所示 (3) 儲存表單選中 File 功能表中的 Save 功能表或工具條中的儲存圖示將新建的介面表單儲存為 test.ui, 使用者介面

54 表單檔副檔名為.ui EELiod Linux 實驗指導手冊 新建對話方塊表 新建表單部件 新建 Qt 工程 新建主表單新建 C++ 原始檔新建 C++ 頭文件 圖 6-1 Qt 執行介面 工程預覽 常用控制項欄 文本框控制項 表單 按鈕控制項 屬性編輯欄 圖 6-2 新建表單和控制項介面 (4) main.cpp 檔自動設定

55 如果在專案中具有 ui 介面檔,Qt 可以自動設定產生 main.cpp 檔, 選中 File 功能表中的 New 功能表, 雙擊 C++ Main-File 圖示,Qt 自動將當前表單檔作為主介面, 並自動產生 main.cpp 檔案, 如圖 6-3 所示 (5) Qt 的 uic 工具的使用 圖 6-3 main.cpp 的自動設定介面 在嵌入式平台中無法對 ui 介面檔進行編譯, 因此 Qt 提供將 ui 檔轉換成標準的 C++ 標頭檔 (.h) 與實 現檔 (.cpp) 的 uic 工具 uic 工具還可以完成 C++ 子類繼承檔的轉換和將圖片檔轉換成標頭檔的形式 現介 紹利用 uic 工具將前面建立的 test.ui 檔轉換成標準的 C++ 標頭檔和實現檔 (uic 具體使用方法參考 qt 檔案 ) 產生 C++ 標頭檔 [root@localhost test]$uic o test.h test.ui ( 用什麼板本的 Qt designer 建議就用該板本的 uic) 產生 C++ 實現檔 (.cpp 檔案 ) [root@localhost test]$uic o test.cpp impl test.h test.ui 將 ui 檔轉換為標準 C++ 標頭檔和實現檔後, 便可以利用轉換後的 C++ 標頭檔和實現檔替代原來的 ui 檔 在工程預覽中選中 test.ui, 單擊右鍵, 從彈出的選單中選中 remove form from project 功能表, 移除 Qt 介面檔 test.ui, 然後選中 Project 功能表中的 Add File 功能表, 將轉換後的 C++ 標頭檔和實現檔新增到工程中 如圖 6-4 所示

56 (6)Qt 應用程式的編譯 基於 PC 平台的 Qt 應用程式編譯 圖 6-4 新增檔案介面 在 PC 平台編譯 Qt 應用程式, 只需利用 Qt 提供的 qmake 工具產生編譯應用程式所需的 Makefile 檔, 然後利用 make 命令對應用程式進行編譯 test]$qmake o Makefile test.pro [root@localhost test]$make 編譯成功後, 可利用 file 命令查看編譯的應用程式格式 ( 如圖 6-5 所示 ) 並可直接在 PC 終端執行編譯好的 應用程式 ( 如圖 6-6 所示 ) 圖 6-5 基於 PC 的 Qt 應用程式編譯介面

57 圖 6-5 基於 PC 的 Qt 應用程式執行介面 基於 ARM 平台的 Qt 應用程式編譯在編譯基於 ARM 開發板的 Qt 應用程式時, 應確保交叉編譯工具 arm-linux-g++ 在環境參數 PATH 中和 tmake 工具的正確設定 ( 可參考系統提供的 Linux 使用者手冊和 Qt 移植實驗 ) 由於嵌入式平台中無法對 ui 介面檔進行編譯, 除了將 ui 介面檔轉換為標準的 C++ 檔之外, 還要對利用 Qt 集成開發平台產生的專案檔進行修改, 否則無法編譯,Qt 集成開發平台產生的原始專案檔 test.pro 內容為 : SOURCES += main.cpp \ test.cpp HEADERS += test.h unix { UI_DIR =.ui MOC_DIR =.moc OBJECTS_DIR =.obj } TEMPLATE =app CONFIG += qt warn_on release LANGUAGE = C++ 修改後的專案檔內容為 ( 黑體部分為新增內容, 用於支援 qtopia):

58 SOURCES += main.cpp \ test.cpp HEADERS += test.h TEMPLATE =app CONFIG += qtopia qt warn_on release LANGUAGE = C++ 專案檔修改後, 然後利用 tmake 工具產生用於編譯應用程式的 Makefile 檔 [root@localhost test]$tmake o Makefile test.pro 承上或是以絕對路徑 [root@localhost test]$/opt/ //tmake-1.11/bin/tmake o Makefile test.pro 在 make 前指向編譯完成的 arm 格式 QT lib 路徑 [root@localhost test]$export QTDIR=/opt/ /qt [root@localhost test]$export QPEDIR=/opt/ /qt [root@localhost test]$make 編譯後, 可用 file 命令查看編譯的應用程式格式, 如圖 6-5 所示 (7) 嵌入式 Qt 應用程式的執行方法 圖 6-5 基於 ARM 的 Qt 應用程式編譯介面 測試程式下載執行方法一 ( 開發板的 OS 是燒錄 QT 板本時 ) 的屬性 將編譯好的 ARM 格式的應用程式 test 下載到開發板的 /usr/qpe/bin 目錄下, 並利用 chmod 命令修改 test [root@bin]$chmod 755 test 在目標板的 /usr/qpe/applications 目錄下新建一個 test.desktop 檔案 :

59 [Desktop Entry] Comment=A Qt test Program Exec=test Icon=Clock Type=Application Name=Test Name[zh_CN]=Qt 測試程式 重啟目標板, 點擊 qtopia 介面上的 Qt 測試程式 便可執行測試程式 測試程式下載執行方法二 ( 開發板的 OS 是燒錄 TinyX 板本時 ) 當開發板燒錄的是 TinyX 板本 OS 時, 意即缺乏 test 程式執行時所須的 QT 相關函式庫, 所以須另外提 供 將 test 程式, 及 QT 移植實驗的成果 QPE 資料夾整個複製到儲存裝置 ( 以 CF 卡為例 ) 將 CF 卡插入開發板, 掛載 ( 請先確定開發板 /mnt/cf 有這個資料夾 ) [root@localhost test]$mount /dev/hda1 /mnt/cf 宣告 QT 相關路徑 [root@localhost test]$export QTDIR=/mnt/cf/qpe [root@localhost test]$export QPEDIR=/mnt/cf/qpe [root@localhost test]$export LD_LIBRARY_PATH=/mnt/cf/qpe/lib:$LD_LIBRARY_PATH [root@localhost test]$export QWS_MOUSE_PROTO=TPanel:/dev/ts [root@localhost test]$ps aux ( 請找到 xfbdev 這個 process 並記下 PID 的編號 ) [root@localhost test]$kill -9 xxx ( 將該 process 停止 ) [root@localhost test]$./test -qws 實驗儀器實驗儀器 1 裝有 Linux 作業系統的 PC 一台 ; 2 XSBase270 或 XSBase255 ARM 實驗開發平台一套 實驗內容實驗內容 1 在 PC 平台編寫一個 Qt 應用程式, 寫出編譯過程 2 將 PC 平台上編寫的 Qt 應用程式編譯成目標板上能執行的格式, 寫出編譯過程 3 將 ARM 格式的 Qt 應用程式下載到目標板上, 編寫 desktop 檔, 並執行程式, 寫出具體操作過程 4 通過 NFS 方式執行 ARM 格式程式, 寫出具體操作過程 思考題思考題 1 根據 Qt 幫助檔案中的 uic 使用方法, 寫出從 ui 檔中建立一個 C++ 繼承類的具體步驟 2 某同學將在 PC 平台上編寫的 Qt 應用程式編譯成 ARM 格式時, 出現如下錯誤, 請分析產生錯誤的原 因, 應怎樣修改才能編譯?

60 3 某同學在通過 NFS 方式執行編譯好的應用程式時, 出現如下錯誤, 請分析產生錯誤的原因, 應作修改 才能執行?./snake:error while loading libraries:libqpe.so.1:cannot open shared object file:no such file or directory

61 實驗七 驅動程式結構實驗 實驗目的實驗目的 1 瞭解 Linux 驅動程式的結構 2 掌握 Linux 驅動程式常用結構體和操作函數的使用方法 3 初步掌握 Linux 驅動程式的編寫方法及過程 4 掌握 Linux 驅動程式的載入方法 實驗原理實驗原理 1 驅動程式介紹驅動程式負責將應用程式如讀 寫等操作正確無誤的傳遞給相關的硬體, 並使硬體能夠做出正確反應的程式 驅動程式像一個黑盒子, 它隱藏了硬體的工作細節, 應用程式只需要通過一組標準化的介面實現對硬體的操作 2 Linux 設備驅動程式分類 Linux 設備驅動程式在 Linux 的核心程式碼中佔有很大的比例, 程式碼的長度日益增加, 主要是驅動程式的增加 雖然 Linux 核心的不斷升級, 但驅動程式的結構還是相對穩定 Linux 系統的設備分為字元設備 (char device), 區塊設備 (block device) 和網路設備 (network device) 三種 字元設備是指在存取時沒有緩衝的設備, 而區塊設備的讀寫都有緩衝來支援, 並且區塊設備必須能夠隨機存取 (random access) 典型的字元設備包括滑鼠, 鍵盤, 串列埠等 區塊設備主要包括硬碟軟碟設備, CD-ROM 等 網路設備在 Linux 裡做專門的處理 Linux 的網路系統主要是基於 BSD unix 的 socket 機制 在系統和驅動程式之間定義有專用的資料結構 (sk_buff) 進行資料傳遞 系統有支援對發送資料和接收資料的緩衝, 提供流量控制機制, 提供對多協定的支援 3 驅動程式的結構驅動程式的結構如圖 1 所示, 應用程式經過系統調用, 進入核心層, 核心要控制硬體需要通過驅動程式實現, 驅動程式相當於核心與硬體之間的 系統調用

62 圖 7-1 驅動程式的結構核心模組核心模組是 Linux 核心的重要組成要素, 核心模組能在 Linux 系統啟動之後能夠動態進行裝載和卸載, 因此不需對核心進行重新編譯或重啟系統就可將核心的一部分替換掉,Linux 核心的所有設備驅動, 檔案系統, 網路協定等可做成模組的形式來提供 在所有的模組中需記錄編譯的核心版本資訊, 並與當前執行的核心版本一致 即, 模組具有版本依賴性, 如果不一樣就會出錯, 當然可以在模組程式中的 include<linux/module.h> 之前通過巨集定義 #define NO_VERSION 表明不定義模組的版本資訊 核心模組程式與一般應用程式之間主要不同之處是, 模組程式沒有 main() 函數, 模組程式在裝載時調用 init_module(void) 函數新增到核心中, 在卸載時調用 void cleanup_module( ) 函數從核心中卸載 另外一個應用程式從頭到尾只執行一個任務, 但一個模組可以把回應未來請求的事務登記到核心中, 然後等待系統調用, 核心模組程式結構如圖 7-2 所示 Module Kernel insmod init_module( ) register_capability( ) capabilities[] printk( )..... rmmod cleanup_module( ) unregister_capability( ) 圖 7-2 核心模組程式結構

63 4 主 從設備號 EELiod Linux 實驗指導手冊 應用程式通過設備檔案系統 (devfs) 的名字 ( 或節點 ) 存取硬體設備, 所有的設備節點在 /dev 目錄下 利用 mknod 命令產生設備檔案系統的節點, 但只有超級使用者才能產生設備文 Mknod 命令必須要有設備名和設備類型, 主設備號 (Major Number), 次設備號 (Minor Number) 等 3 個參數 主設備號用於核心區分設備驅動程式, 次設備號用於設備驅動程式區分設備 一個設備驅動程式可能控制多個設備 新的設備驅動程式要有新的主設備號 在核心程式碼的 Documentation /devices.txt 中定義了所有設備的主設備號 在建立設備的時候不要與常用的設備衝突 下面 /dev/hda1 是設備名,b 表示 block 設備 (c 表示字元設備 ) 127 是主設備號, 1 是次設備號 次設備號可以是 之間的值, 限制為 8bit [root@localhost]$ mknod /dev/hda1 b [root@localhost]$ ls al /dev/hda1 [root@localhost]$ brw-rw root disk 3 1 Mar 25 12:00 /dev/hda1 5 驅動程式基本框架如果採用模組方式編寫設備驅動程式時, 通常至少要實現設備初始化模組 設備打開模組 資料讀寫與控制模組 中斷處理模組 ( 有的驅動程式沒有 ) 設備釋放模組和 設備卸載模組等幾個部分 下面給出一個典型的設備驅動程式的基本框架, 從中不難體會到這幾個關鍵部分是如何組織起來的

64 /* 打開設備模組 */ static int xxx_open(struct inode *inode, struct file *file) { /* */ } /* 讀設備模組 */ static int xxx_read(struct inode *inode, struct file *file) { /* */ } /* 寫設備模組 */ static int xxx_write(struct inode *inode, struct file *file) { /* */ } /* 控制設備模組 */ static int xxx_ioctl(struct inode *inode, struct file *file) { /* */ } /* 中斷處理模組 */ static void xxx_interrupt(int irq, void *dev_id, struct pt_regs *regs) { /*... */ } /* 設備檔操作介面 */ static struct file_operations xxx_fops = { read: xxx_read, /* 讀設備操作 */ }; write: xxx_write, /* 寫設備操作 */ ioctl: xxx_ioctl, /* 控制設備操作 */ open: xxx_open, /* 打開設備操作 */ release: xxx_release /* 釋放設備操作 */ /*... */ static int init xxx_init_module (void) { } /*... */ static void exit demo_cleanup_module (void) { pci_unregister_driver(&demo_pci_driver); } /* 載入驅動程式模組入口 */ module_init(xxx_init_module); /* 卸載驅動程式模組入口 */ module_exit(xxx_cleanup_module);

65 6 重要結構體打開的設備在核心內部由 file 結構標識, 核心使用 file_operation 結構存取驅動程式函數 file_operation 結構是一個定義在 <linux/fs.h> 中的函數指標陣列 每個檔案都與它自己的函數集相關聯 這個結構中的每一個欄位都必須指向驅動程式中實現特定操作的函數 結構如下, 詳細內容可查閱相關檔案 struct file_operations { struct module *owner; loff_t (*llseek) (struct file *, loff_t, int); ssize_t (*read) (struct file *, char *, size_t, loff_t *); ssize_t (*write) (struct file *, const char *, size_t, loff_t *); int (*readdir) (struct file *, void *, filldir_t); unsigned int (*poll) (struct file *, struct poll_table_struct *); int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long); int (*mmap) (struct file *, struct vm_area_struct *); int (*open) (struct inode *, struct file *); int (*flush) (struct file *); int (*release) (struct inode *, struct file *); int (*fsync) (struct file *, struct dentry *, int datasync); int (*fasync) (int, struct file *, int); int (*lock) (struct file *, int, struct file_lock *); ssize_t (*readv) (struct file *, const struct iovec *, unsigned long, loff_t *); ssize_t (*writev) (struct file *, const struct iovec *, unsigned long, loff_t *); ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int); unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long); }; File 結構 File 結構代表一個打開的檔案 它在 open 時被核心建立, 並傳遞給在該檔案上進行操作的所有函數, 直到最後的 close 函數 在檔案的所有實例都被關閉之後, 核心會釋放這個資料結構 結構在 /linux/fs.h 定義, 詳細內容查閱相關檔案

66 }; struct file { struct list_head f_list; struct dentry *f_dentry; struct vfsmount *f_vfsmnt; struct file_operations *f_op; atomic_t f_count; unsigned int f_flags; mode_t f_mode; loff_t f_pos; unsigned long f_reada, f_ramax, f_raend, f_ralen, f_rawin; struct fown_struct f_owner; unsigned int f_uid, f_gid; int f_error; unsigned long f_version; /* needed for tty driver, and maybe others */ void *private_data; /* preallocated helper kiobuf to speedup O_DIRECT */ struct kiobuf *f_iobuf; long f_iobuf_lock; 驅動程式中常用的函數 int xxx_open(struct inode *inode, struct file *filp); int xxx_release(struct inode *inode, struc file *filp); ssize_t xxx_read(struct file *filp, char *buff,size_t count, loff_t *offp); ssize_t xxx_write(struct file *filp, const char *buff, size_t count, loff_t *offp); 實驗儀器實驗儀器 1 裝有 Linux 作業系統的 PC 一台 ; 2 XSBase270 或 XSBase255 ARM 實驗開發平台一套

67 實驗內容實驗內容 1 hello 模組載入實驗 編寫實驗程式 hello.c #include <linux/module.h> int init_module( void ) { printk("<1>hello, world\n"); return 0; } void cleanup_module( void ) { printk("<1>goodbye cruel world\n") 編寫 Makefile 檔案 CC =/usr/local/xscalev1/bin/arm-linux-gcc INCLUDEDIR = /opt/linux board_edr/include CFLAGS = -D KERNEL -DMODULE -Wall -O2 CFLAGS += -I.. -I$(INCLUDEDIR) DEBUG = TARGET = hello OBJS = $(TARGET).o SRC = hello.c All: hello.o hello.o: hello.c $(CC) $(CFLAGS) $(DEBUG) -c -o hello.o hello.c clean : rm -rf *.o test rm -rf *.o 請注意 Makefile 檔中 Toolchain 及 Kernel 存放的路徑請依各人使用不同自行修改

68 下載目標程式到目標板, 具體的操作參考使用手冊相關部分掛載目標程式, 並查看輸出調試資訊, 本次相關操作均要求到下載的當前目錄 ( 含 hello.o) $insmod hello.o ( 掛載 hello) $lsmod ( 查看當前已掛載模組, 會看到 hello) $dmesg ( 查看模組輸出資訊 :Hello, world) $rmmod hello ( 卸載 dri_arch) $lsmod ( 查看當前已掛載模組, 不再看到 hello) $dmesg ( 查看模組輸出資訊 :Goodbye cruel world) 思考題思考題 1 分析如何解決模組載入過程中的核心版本的相容問題 2 任選某個 linux 核心設備驅動程式進行分析, 總結編寫設備驅動程式的架構

69 實驗八 I/O 介面驅動實驗 實驗目的實驗目的 1 瞭解 PXA270 微處理器 GPIO 的功能 2 熟悉 PXA270 微處理器 GPIO 驅動程式的編寫方法 3 掌握驅動程式的載入過程和方法 實驗原理實驗原理 Linux 以模組的形式載入設備類型, 通常來說一個模組對應一個設備驅動程式, 因此是可以分類的 將模組分成不同的類型或者類型並不是一成不變的, 開發人員可以根據實際工作需要在一個模組中實現不同的驅動程式 一般情況, 一個設備驅動程式對應一類設備的模組方式, 這樣便於多個設備的協調工作也利於應用程式的開發和擴充 設備驅動程式在準備好以後可以編譯到核心中 ( 參考實驗四的內容 ), 在系統啟動時和核心一起啟動, 這種方法在嵌入式 Linux 系統中經常被採用 通常情況下設備驅動的動態載入更為普遍 ( 參考實驗七的內容 ), 開發人員不必在開發過程中頻繁啟動機器就能完成設備驅動的開發工作 設備驅動程式在載入時首先調用入口函數 init_module(), 該函數完成設備驅動的初始化工作, 比如暫存器置位元 結構體賦值等一系列工作, 其中最重要的一個工作就是向核心註冊該設備, 對於字元設備調用 register_chrdev() 完成註冊, 對於區塊設備需要調用 register_blkdev() 完成註冊 註冊成功後, 該設備獲得了系統分配的主設備號 自定義的次設備號, 並建立起於檔案系統的關聯性 設備在卸載時需要回收相對應的資源, 令設備的回應暫存器重置並從系統中登出該設備, 字元設備調用 unregister_chrdev() 區塊設備調用 unregister_blkdev() 系統調用部分則是對設備的操作過程, 比如 open read write ioctl 等 圖 8-1 為一個設備驅動模組動態掛載 卸載和系統調用的全過程

70 圖 8-1 設備驅動在核心中的掛載 卸載和系統調用過程設備驅動程式負責將應用程式如讀 寫等操作正確無誤的傳遞給相關的硬體, 並使硬體能夠做出正確反應的程式, 因此在編寫設備驅動程式時, 必須要瞭解相對應的硬體設備的暫存器 IO 介面及記憶體的設定參數 1 硬體介面電路介紹 (1) LED 和七段顯示器顯示介面電路目標板 LED 和七段顯示器顯示介面電路如圖 8-2 所示,74HC574 為 D 栓鎖器, 在 clock 信號 CLK 作用下, 該鎖存器將輸入信號進行鎖存, 即 xq=xd(x=1~8) 從圖中可以看出,LED 和七段顯示器顯示電路將 74HC574 的 clock 信號輸入端作為晶晶片選擇擇信號, 其中 LED 顯示的晶片選擇信號為 LED_CS4 七段顯示器顯示的晶晶片選擇擇信號為 LED_CS1 在七段顯示器顯示電路中,8 位元資料的高位元 (D7 D15: 即七段顯示器的小數點 dp 段 ) 用作七段顯示器的公共選通訊號, 通過控制 PNP 電晶體來控制七段顯示器的顯示 圖 8-2 LED 和七段顯示器顯示介面電路 顯示電路中的晶晶片選擇擇信號 LED_CSx, 由目標板系統的 PXA270x CPU 的位址信號 BA22~BA

71 通過 3-8 解碼器 LC138 產生 ( 如圖 8-3 所示 ) EELiod Linux 實驗指導手冊 圖 8-3 晶晶片選擇擇信號產生電路由圖可知, 當 BA22 BA21 BA20=101 時產生 LED 顯示電路的晶晶片選擇擇信號 LED_CS4, 當 BA22 BA21 BA20= 時分別產生七段顯示器顯示電路的晶晶片選擇擇信號 LED_CS1 LED_CS2 LED_CS3( 另外 2 組八段顯示電路參考系統提供的總電路圖 ) (2) 鍵盤介面電路目標平台提供了陣列鍵盤 ( 如圖 8-4 所示 ) 和單按鍵鍵盤 ( 如圖 8-5 所示 ) 兩種鍵盤介面電路, 其中陣列鍵盤中行控制信號線 KP-MKIN0~2 分別由 CPU 的通用 IO 介面 GPIO100~102 控制, 列控制信號線 KP-MKOUT0~5 分別由 CPU 的通用 IO 介面 GPIO103~105 和 GPIO108 控制 單按鍵鍵盤的控制信號線 KP-DKIN1~2,KP-DKIN5~6 分別由 CPU 的通用 IO 介面 GPIO94~95 和 GPIO98~99 控制 圖 8-4 陣列鍵盤介面

72 圖 8-5 單按鍵鍵盤介面 (3) 步進馬達控制介面步進馬達控制電路如圖 8-6 所示, 步進馬達的轉動方向控制信號和步進輸入信號 GP1 GP2 分別由 CPU 的通用 IO 介面 GPIO83 和 GPIO84 控制 圖 8-6 步進馬達控制介面電路 2 I/O 驅動程式設備驅動程式執行在核心空間, 而應用程式則執行在使用者空間,Linux 作業系統通過系統調用和硬體中斷完成從使用者空間到核心空間的控制轉移, 執行系統調用的核心程式在行程的上下文中執行, 也就是說代表調用行程操作而且可以存取行程位址空間的資料, 中斷處理程式相對行程而言是非同步的, 而且與任何一個行程都無關 設備驅動模組的功能就是擴充核心的功能, 主要完成兩部分任務 : 一個是系統調用, 另一個是中斷處理 下面分別以七段顯示器顯示驅動模組為例介紹如何在一個字元驅動設備實現對 I/O 驅動程式的編寫方法和過程 ( 程式實驗檔名為 XSB_EDR_8SEG..c) 1) 模組初始化

73 模組初始化 module_init(emdoor_8seg_init) 函數中的參數 Emdoor_8Seg_init 實際上為七段顯示器顯示驅動模組的初始化函數 static int init Emdoor_8Seg_init(void), 該函數主要完成將產生數碼顯示的晶片選擇控制信號的 BA22~BA20 通過 void * ioremap(unsigned long offset, unsigned long size) 函數為 I/O 記憶體區域分配虛擬位址, 這樣設備驅動程式就能存取 I/O 記憶體位址, 同時在模組初始化函數中,register_chrdev() 函數完成字元設備在核心系統中的註冊並建立與檔案系統 (Emdoor_fops) 的關聯 static int init Emdoor_8Seg_init(void) { int ret; cs1_address=ioremap(seg_cs1, 32);// distribute I/O memory map address cs2_address=ioremap(seg_cs2, 4); cs3_address=ioremap(seg_cs3, 4); ret = register_chrdev(61, DEVICE_NAME, &Emdoor_fops);//register device name if (ret < 0) { printk(device_name " can't get major number\n"); return ret; } return 0; } 其中七段步進電機信號 SEG_CS1~3 和設備檔案名在程式中採用 #define 巨集定義進行定義 #define DEVICE_NAME "emdoor_8seg" #define SEG_CS1 0x //A22,A21,A20=010 ->LED_CS1 #define SEG_CS2 0x //A22,A21,A20=011 ->LED_CS2 #define SEG_CS3 0x //A22,A21,A20=100 ->LED_CS3 2) 模組的卸載模組的卸載 module_exit(emdoor_8seg_exit) 函數中參數 Emdoor_8Seg_exit 實際上是模組的從核心卸載時所調用的 static void exit Emdoor_8Seg_exit(void); 設備在卸載時需要回收相對應的資源, 並利用 unregister_chrdev() 函數從核心中將設備登出 static void exit Emdoor_8Seg_exit(void) { iounmap(cs1_address);//release I/O memory map,reclaim system resource iounmap(cs2_address); iounmap(cs3_address); unregister_chrdev(61, DEVICE_NAME); //unregister device } 3) 設備檔操作介面定義 設備檔操作介面定義是使用者使用該設備的關鍵, 合理的定義可簡化應用程式設計, 縮短專案的整體 開發週期 七段顯示器顯示驅動模組定義了 open write release ioctl 等四種設備檔操作, 內容如下所示 : static struct file_operations Emdoor_fops = { open: Emdoor_8Seg_open, //open operation function write: Emdoor_8Seg_write, //write operation function release: Emdoor_8Seg_release, //release operation function ioctl: Emdoor_8Seg_ioctl, //IO control operation function owner: THIS_MODULE, };

74 4) 設備檔操作根據設備檔操作介面定義, 每一個設備檔操作對應一個系統調用, 在使用者程式中利用系統調用對設備檔進行諸如 open/write 等操作時, 系統調用通過設備檔的主設備號找到相對應的設備驅動程式, 然後讀取設備檔操作介面定義的相對應的函數指標, 接著把控制權交給該操作函數 在七段顯示器顯示驅動模組定義了 open write release ioctl 等四種設備檔操作 1. 打開設備操作 static int Emdoor_8Seg_open(struct inode *inode, struct file *filp) { struct seg *seg_7; seg_7=kmalloc(sizeof(struct seg), GFP_KERNEL);//distribute memory in kernel space seg_7->negative=led_module; filp->private_data=seg_7;//private data pointer point to seg_7 MOD_INC_USE_COUNT;//current module counter add 1 return 0; } 2. 寫設備操作 static ssize_t Emdoor_8Seg_write(struct file *file, const char *buffer, size_t count, loff_t * ppos) { int i; struct seg *seg_7=file->private_data; char led_forall[6]; if(count!=6) //LED amount { printk(kern_emerg "the count of input is not six!!"); return 0; } copy_from_user(led_forall, buffer, 6); //copy data from user space to kernel space for(i=1;i<=6;i++){ value_seting(seg_7, i, LED[i-1]); } Updateled( seg_7 );//lighten the LED return 6; } 3. I/O 控制操作 static int Emdoor_8Seg_ioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg) { char val=0x00; struct seg *seg_7=fp->private_data; if (!arg) return -EINVAL; if (copy_from_user(&val, (int *)arg, sizeof(char))) return -EFAULT; switch(cmd){ // control the LED command word case 1: value_seting(seg_7, 1, val); //control the first 8LED

75 break; case 2: value_seting(seg_7, 2, val);//control the second 8LED break; case 3: value_seting(seg_7, 3, val);//control the third 8LED break; case 4: value_seting(seg_7, 4, val); break; case 5: value_seting(seg_7, 5, val); break; case 6: value_seting(seg_7, 6, val);// control the sixth 8LED break; case 0: //clear all LED seg_7->negative = LED_MODULE; break; default: printk(kern_emerg"ioctl parameter input error,please input number 0-6"); break; } Updateled( seg_7 );//lighten LED return 0; } 4. 釋放設備操作 static int Emdoor_8Seg_release(struct inode *inode, struct file *filp) { kfree(filp->private_data);//release memory which distributed by kmalloc MOD_DEC_USE_COUNT; //current module counter subtract 1 return 0; } 5) 內部自定義函數在七段顯示器顯示驅動程式中, 自定義了一個點亮七段顯示器的函數 Updateled(struct seg *seg_7) static void Updateled(struct seg *seg_7) { unsigned short buff=0x00; buff=seg_7->led1_val; buff=buff ( seg_7->led2_val <<8); writew(buff,cs1_address);//write 16bits data into I/O memory buff=0x00; buff=seg_7->led3_val; buff=buff ( seg_7->led4_val<<8); writew(buff,cs2_address);

76 buff=0x00; buff=seg_7->led5_val; buff=buff ( seg_7->led6_val<<8); writew(buff,cs3_address); return; EELiod Linux 實驗指導手冊 } 和設定七段顯示器所顯示數值的函數 value_seting(struct seg *seg_7, char position, char value) void value_seting(struct seg *seg_7, char position, char value) { } if (seg_7->negative==0) else value=~value & ~(0x1<<7); value=(0x1<<7) value; if (position==1) seg_7->led1_val=value; else if(position==2) seg_7->led2_val=value; else if(position==3) seg_7->led3_val=value; else if(position==4) seg_7->led4_val=value; else if(position==5) seg_7->led5_val=value; else if(position==6) seg_7->led6_val=value; 3 驅動模組的編譯在編譯驅動模組程式時, 應當編寫適合於特定目標平台的 Makefile 編譯檔 ( 參考實驗七和實驗二的內容 ), 下面為七段顯示器顯示驅動模組的 Makefile 內容,, 必須注意的是交叉編譯工具變數 CC 和模組將要使用和執行的核心程式的 include 變數 INCLUDEDIR 兩個變數的設定必須根據編譯平台的實際路徑進行修改 CC = /opt/xscalev1/bin/arm-linux-gcc INCLUDEDIR = /XSBase270/2.4/Kernel/xsbase/linux emdoor_EDR/include CFLAGS = -D KERNEL -DMODULE -Wall -O2 CFLAGS += -I.. -I$(INCLUDEDIR) #8SEG TARGET_8SEG = XSB_EDR_8SEG OBJ_8SEG = $(TARGET_8SEG).o SOURCE_8SEG = $(TARGET_8SEG).c all: $(OBJ_8SEG) $(OBJ_8SEG): $(SOURCE_8SEG)

77 $(CC) $(CFLAGS) -c -o $(OBJ_8SEG) $(SOURCE_8SEG) EELiod Linux 實驗指導手冊 clean: rm -rf $(OBJ_8SEG) 4 驅動模組的載入將編譯好的驅動模組下載到目標上, 進入目標板系統後, 利用 mknod 命令在 /dev 目錄下建立該設備的節點 然後利用 insmod 命令裝載驅動模組, 最後在目標平台中執行驅動模組的測試程式 drivertest( 測試程式的下載過程參考實驗六的內容 ), 檢查驅動模組的正確性 [root@51board~]$mknod /dev/xsb_edr_8led c 60 1 [root@51board~]$insmod XSB_EDR_8LED.o 實驗儀器實驗儀器 1 裝有 Linux 作業系統的 PC 一台 ; 2 XSBase270 或 XSBase255 ARM 實驗開發平台一套 實驗內容實驗內容 1 分析 LED 顯示模組驅動程式, 畫出一個設備程式的主要組成部分框圖 ; 2 根據鍵盤模組驅動程式, 畫出採用中斷編寫設備驅動程式的主要組成元件框圖 ; 3 根據實驗原理中七段顯示器顯示的編譯和載入過程, 將 8LED 和鍵盤驅動模組編譯並載入到目標平台的核心中 ; 然後將測試程式下載到目標平台, 測試設備驅動模組的正確性 思考題思考題 1 利用 qt 或 C 語言編寫一個步進馬達驅動模組的使用者程式 ; 2 在編譯設備驅動模組時, 應該注意哪些問題? 3 根據實驗原理中硬體介面和系統提供的 PXA27x 檔案資料, 請分析鍵盤驅動程式, 指出下列程式段中數位 等和 GPIO_ALT_FN_1_IN GPIO_ALT_FN_2_OUT 所表示的意義 ; set_gpio_mode(94 GPIO_ALT_FN_1_IN); set_gpio_mode(95 GPIO_ALT_FN_1_IN); set_gpio_mode(98 GPIO_ALT_FN_1_IN); set_gpio_mode(99 GPIO_ALT_FN_1_IN); set_gpio_mode(100 GPIO_ALT_FN_1_IN); set_gpio_mode(101 GPIO_ALT_FN_1_IN); set_gpio_mode(102 GPIO_ALT_FN_1_IN); set_gpio_mode(103 GPIO_ALT_FN_2_OUT); set_gpio_mode(104 GPIO_ALT_FN_2_OUT); set_gpio_mode(105 GPIO_ALT_FN_2_OUT); set_gpio_mode(108 GPIO_ALT_FN_2_OUT);

78 實驗九 SD 卡驅動程式實驗 實驗目的實驗目的 1 瞭解 PXA27X 微處理器 GPIO 的功能 2 瞭解 SD 卡驅動程式的架構及開發方法 3 掌握 SD 卡的使用方法 實驗原理實驗原理 1 SD/MMC 簡介 SD(Secure Digital Card) 卡, 由松下 東芝和 SanDisk 聯合推出,1999 年 8 月才首次發佈 SD 卡資料傳送和物理規範由 MMC 發展而來, 大小和 MMC 差不多, 尺寸為 32mm x 24mm x 2.1mm 長寬和 MMC 一樣, 只是厚了 0.7mm, 以容納更大容量的存貯單元 SD 卡與 MMC 卡保持著向上相容, 也就是說,MMC 可以被新的 SD 設備存取, 相容性則取決於應用軟體, 但 SD 卡卻不可以被 MMC 設備存取 (SD 卡外型採用了與 MMC 厚度一樣的導軌式設計, 以使 SD 設備可以適合 MMC) SD 介面除了保留 MMC 的 7 Pin 外, 還在兩邊加多了 2 Pin 作為資料線 採用了 NAND 型 Flash Memory, 基本上和 SmartMedia 的一樣, 平均資料傳輸率能達到 2MB/s MMC(MultiMediaCard) 卡由西門子公司和首推 CF 的 SanDisk 於 1997 年推出 MMC 的發展目標主要是針對數位影像 音樂 手機 PDA 電子書 玩具等產品, 號稱是目前世界上最小的 Flash Memory 記憶卡, 尺寸只有 32mm x 24mm x 1.4mm 雖然比 SmartMedia 厚, 但整體體積卻比 SmartMedia 小, 而且也比 SmartMedia 輕, 只有 1.5 克 MMC 也是把記憶單元和控制器一同做到了卡上, 智慧的控制器使得 MMC 保證相容性和靈活性 MMC 記憶卡可以分為 MMC 和 SPI(serial peripheral interface) 兩種工作模式,MMC 模式是標準的預設模式, 具有 MMC 的全部特性 而 SPI 模式則是 MMC 記憶卡可選的第二種模式, 這個模式是 MMC 協定的一個子集, 主要用於只需要小數量的卡 ( 通常是 1 個 ) 和低資料傳輸率 ( 和 MMC 協定相比 ) 的系統, 這個模式可以把設計花費減到最小, 但性能就不如 MMC MMC 被設計作為一種低成本的資料平台和通訊介質, 它的介面設計非常簡單 它的讀寫模式包括流式 多區塊和單區塊 最小的資料傳送是以區塊為單位的, 預設的區塊大小為 512bytes 2 PXA27x 的 MMC/SD/SDIO 控制器 PXA27x 的 MMC/SD/SDIO 控制器在存取 PXA27x 處理器的軟體與 MMC 儲存堆和支援 MMC SD 及 SDIO 通訊協定之間充當聯結作用 PXA27x 的 MMC 控制器協定規範遵守多媒體卡系統規範 V3.2(MultiMediaCard System Specification Version 3.2);SD 控制器支援一個基於 SD 儲存卡規範 V1.01(SD Memory Card Specification Version 1.01)SD 卡或基於 SDIO 卡規範 V1.0( SDIO Card pecification Version 1.0) MMC/SD/SDIO 控制器採用標準的 MMC 傳輸協定或串列通訊介面 SPI 協定模式 存取 PXA27x 的軟體使用 MMC 傳輸協定或 SPI 模式作為與 MMC 控制器通訊的協定 目標板的 SD 驅動程式採用了 MMC 通訊傳輸協定 1) MMC/SD/SDIO 控制器特性 : 1. 在 MMC 1 位元 SD/SDIO 和 SPI 模式中, 資料傳輸速率高達 19.5Mbps; 2. 對於 4 位元 SD/SDIO 的資料傳輸速率高達 78Mbps; 3. 具有兩個接受和發送 FIFO 資料緩衝區 ; 4. 具有 MMC/SD/SDIO 和 SPI 兩種操作模式 ;MMC/SD/SDIO 模式支援 MMC SD 和 SDIO 的通訊協定,SPI 模式支援 SPI 通訊協定 ;

79 5. 在 SD 和 SDIO 通訊協定中, 支援 1 位元和 4 位元資料傳輸 ; 6. 控制器可根據 FIFO 資料緩衝區的狀態關閉和啟動 clock 信號, 防止資料溢出 ; 7. 支援所有有效的 MMC 和 SD/SDIO 資料傳輸協定 ; 8. 基於中斷的應用介面控制軟體交互操作 ; 9. 在資料流程的寫操作中, 允許 10 位元組大小的資料或更大的資料流程 ; 10. 使用 MMC 通訊協定, 支援多個 MMC 卡 ; 11. 使用 SD 或 SDIO 通訊協定, 只支援一個 SD 卡或 SDIO 卡 ; 11. 使用 SPI 通訊協定 ; 可支援兩個 MMC 卡或 SD/SDIO 卡, 也可支援兩者的混合使用 ; 2) MMC/SD/SDIO 控制器的信號功能與對應接腳 : 信號 MMC 和 SD/SDIO SPI 模式 功能 對應接腳 MMCLK 輸出輸出 MMC 和 SD/SDIO 匯流排 clock GPIO32 MMCDM 雙向輸出 MMDAT<0> 雙向輸入 MMDAT<1> 雙向輸入 MMDAT<2>/ MDCCS<0> MMDAT<3>/ MDCCS<1> 雙向 雙向 輸出 輸出 MMC 和 SD/SDIO: 命令和回應標記雙向 IO 介 面 SPI 模式 : 命令和寫資料輸出口 MMC 和 SD/SDIO: 讀寫資料雙向 IO 介面 SPI 模式 : 讀數據和回應標記輸入線 MMC 和 SD/SDIO:SD/SDIO 的 4 位元資料傳輸 線和信號 SDIO 到控制器的中斷信號 SPI 模式 : 信號 SDIO 到控制器的中斷信號 SD/SDIO:4 位資料傳輸線 SPI 模式 :CS0 晶片選擇信號 SD/SDIO:4 位資料傳輸線 SPI 模式 :CS1 晶片選擇信號 GPIO112 GPIO111 GPIO110 GPIO109 GPIO92 3 SD 卡的通訊協定主機與 SD 卡的所有通訊都是由主機發起, 主機發出廣播和點對點兩種類型通訊命令, 在廣播通訊命令中, 主機發出的命令被所有的卡接受, 只有部分命令需要回應 ; 而在點對點通訊命令中, 命令被發送到具體位址的卡中, 並由該卡對所接受的命令做出回應 1) SD 卡認證模圖 9-1 為 SD 卡認證模式命令流程圖, 在認證模式中, 軟體重置命令 GO_IDLE_STATE(CMD0) 將每個卡的當前所處的狀態重置成空閒狀態 (Idle State);SD 儲存卡利用任何一個在最大允許範圍內的工作電壓操作和主機建立通訊聯繫, 因此 SD_SEND_OP_COND (ACMD41) 命令為主機提供了識別一個 SD 卡工作電壓範圍是否符合而進行認證和拒絕的機制 ; 在認證之後, 主機然後向每個卡發出 ALL_SEND_CID (CMD2) 命令以獲取每個卡的唯一的卡號 (CID), 未認證的 SD 卡通過命令線 (MMCMD) 向主機發送自己的 CID 作為回應,SD 卡發送自己的 CID 後編進入認證狀態, 隨後主機發送 SEND_RELATIVE_ADDR (CMD3) 命令要求 SD 卡發送一個相關的卡位址 (RCA), 該位址比 SD 卡的 CID 要短, 而且在資料傳輸模式中該位址用來標識 SD 卡的傳輸位址 一旦主機接受到 RCA,SD 卡便進入等待狀態 如果主機要求卡的另外一個 RCA 資料, 主機便向所要求的卡發送另一個 SEND_RELATIVE_ADDR 命令, 最後一個發送的 RCA 就是 SD 卡的實際 RCA 號 在具有多卡的系統中, 主機會重複認證過程, 直到所有的卡通過認證 在認證模式中,GO_INACTIVE_STATE (CMD15) 命令用於使一個已標識的 SD 卡進入非活動狀態

80 2) SD 卡的資料傳輸模式 圖 9-1 SD 儲存卡狀態圖 ( 認證模式 ) 圖 9-2 為 SD 卡的傳輸模式命令流程圖 在傳輸模式中, 主機發送 SEND_CSD (CMD9) 以獲取 SD 卡所特 有的暫存器 (CSD) 的參數如資料塊長度 卡的儲存容量 最大 clock 速率等 同時通過廣播命令 SET_DSR(CMD4) 設定所有已認證的 SD 卡的驅動 ;CMD7 命令用來選擇一個 SD 卡並使其進入資料傳輸狀 態, 在給定的時間內只有一個卡處於資料傳輸狀態 如果原來被選中的卡還處在資料傳輸狀態, 主機將釋 放和它的連接並使其進入等待狀態, 當 CMD7 命令向 SD 卡發送保留的相關位址 0x0000 時, 所有的卡進入 等待狀態 在傳輸模式, 主機和被選中的 SD 卡之間所用的資料通訊採用點對點的方式進行資料傳送 各種 不同資料傳輸模式的關係如下 : 在停止命令 (CMD12) 作用下, 所有讀操作命令都將放棄操作, 資料傳輸中斷後 SD 卡進入傳輸 狀態 主要的讀操作命令有 : 讀區塊操作命令 (CMD17) 讀多區塊操作命令 (CMD18) 發送防 寫命令 (CMD30) 發送 SD 卡設定暫存器 SCR(SD Configure Register) 命令和讀模式下的通用命 令 (CMD56) 在停止命令 (CMD12) 作用下, 所有讀操作命令都將放棄操作, 寫操作命令在 CMD7 進行取消選 擇 SD 卡之前必須停止 主要的寫操作命令有 : 寫區塊命令 (CMD24 和 CMD25) 寫 CID 命令 (CMD26) 寫 CSD 命令 (CMD27) 加鎖 / 解鎖命令 (CMD42) 和寫模式下的通用命令 (CMD56) 一旦資料傳輸完成,SD 卡退出寫資料狀態, 同時進入開發狀態 ( 傳輸成功 ) 或進入傳輸狀態 ( 傳 輸失敗 ) 如果寫一個資料區塊的操作停止並且區塊的長度和最後一塊的 CRC 都有效, 資料便可進行編寫 ; SD 卡提供區塊寫操作緩衝, 也就是說前一個資料區塊在編寫時, 後一個資料區塊便發送到 SD 卡 中 ; 如果寫緩衝已滿, 並且卡正處於編寫狀態,DAT0 線保持低電壓, 說明系統處於忙的狀態 ; 在寫 CSD CID 防寫和清除操作中沒有緩衝, 也就是說卡只能進行這些操作中一個, 其他的資 料傳輸命令將不會被接受 如果卡處於忙時和編寫狀態,DAT0 線將保持為低電壓 ; 當卡正在進入編寫時, 不允許參數設定命令 參數設定命令有 : 設定區塊的長度命令 (CMD16) 清除區塊開始命令 (CMD32) 和清除區塊結束命令 (CMD33) 使用 CMD7 將另外一張卡從就緒狀態轉換到傳輸狀態, 將不會中止清除和編寫操作, 卡將轉換到非連接狀態並釋放 DAT 線 ;

81 利用 CMD7 命令可重新選擇一個處於非連接狀態的卡, 在這種情況下, 該卡將進入開發狀態並重新處於忙狀態 ; 對卡進行重置 ( 利用 CMD0 或 CMD15) 將中止任何正在進行和即將進行的編寫操作, 這將損壞卡中資料內容, 只有主機才有能力防止這種情況發生 4 目標板的 SD 卡硬體介面 圖 9-2 SD 儲存卡狀態圖 ( 資料傳輸認證模式 ) 目標板的 MMC/SD 卡的硬體介面如圖 9-3 所示, 根據 PXA27x 的 MMC/SD/SDIO 控制器的信號功能以及 PXA27x 的 GPIO 的功能分配, 命令控制線 MMCMD 與 GPIO112 相連, 此時接腳 GPIO112 必須設定成轉換功 能 1(Alternate Function 1) 的輸入或輸出方式 ( 參考 PXA27X 開發手冊 ),clock 端 MMCLK 利用了通用 IO 介 面 GPIO32 轉換功能 1 輸出方式,4 位元匯流排 MMDAT0 到 MMDAT3 分別與 GPIO111 GPIO110 GPIO109 和 GPIO92 相連, 都時使用了通用 IO 介面的轉換功能 1 的輸入或輸出方式 圖 9-4 為 MMC/SD 卡的供電電路圖

82 圖 9-3 目標板的 MMC/SD 卡的硬體介面 圖 9-4 MMC/SD 卡的供電電路圖 5 MMC/SD 卡的驅動程式分析 ( 參考 Linux 程式碼中 /drivers/mmc/mmc-pxa.c pxa.c) 1) MMC/SD 卡模組註冊初始化 : static int devinit mmc_pxa_module_init( void ) { int ret = -ENODEV; #ifdef CONFIG_ARCH_RAMSES RAMSES_MMC_ON(); udelay(1000); #endif host = mmc_register( MMC_REG_TYPE_HOST, &pxa_mmc_controller_tmpl_rec, sizeof( pxa_mmc_hostdata_rec_t ) );//register the SD device if (!host ) {

83 MMC_DEBUG( MMC_DEBUG_LEVEL0, "failed to register with MMC core\n" ); goto error; } ret = 0; error: return ret; } 2) 設備檔操作介面定義 static mmc_controller_tmpl_rec_t pxa_mmc_controller_tmpl_rec = { owner: THIS_MODULE, name: "PXA250", block_size_max: PXA_MMC_BLKSZ_MAX, nob_max: PXA_MMC_NOB_MAX, probe: pxa_mmc_probe, init: pxa_mmc_init, remove: devexit_p( pxa_mmc_remove ), update_acq: pxa_mmc_update_acq, init_card_stack: pxa_mmc_init_card_stack, check_card_stack: pxa_mmc_check_card_stack, setup_card: pxa_mmc_setup_card, stream_read: pxa_mmc_stream_read, read_block: pxa_mmc_read_block, read_mblock: pxa_mmc_read_mblock, stream_write: pxa_mmc_stream_write, write_block: pxa_mmc_write_block, write_mblock: pxa_mmc_write_mblock }; 3) MMC 介面初始化 static int pxa_mmc_init( mmc_controller_t ctrlr ) { int ret = -ENODEV; pxa_mmc_hostdata_t hostdata = (pxa_mmc_hostdata_t)ctrlr->host_data; /* 1. allocate buffer */ hostdata->iobuf.iodata = kmalloc( PXA_MMC_IODATA_SIZE, GFP_ATOMIC );//2K if (!hostdata->iobuf.iodata ) { ret = -ENOMEM; goto error; } /* 2. initialize iobuf */ hostdata->iobuf.blksz = PXA_MMC_BLKSZ_MAX; /* current block size in bytes 1024* / hostdata->iobuf.bufsz = PXA_MMC_IODATA_SIZE; /* buffer size for each transfer */ hostdata->iobuf.nob = PXA_MMC_BLOCKS_PER_BUFFER; /* number of blocks */ /* 3 request irq */ if ( request_irq( IRQ_MMC, pxa_mmc_irq, 0, "MMC", ctrlr ) ) { MMC_ERROR( "failed to request IRQ_MMC\n" );

84 goto error; } /* 4 init GPIO about MMC/SD/SDIO*/ init_gpio( ); CKEN = CKEN12_MMC; /* enable MMC unit clock */ ret = 0; goto out; error: kfree( hostdata->iobuf.iodata ); out: return ret; } EELiod Linux 實驗指導手冊 4) GPIO 初始化函數 static void init_gpio(void) { GPCR1 = 0x1; //clear pin32 GPDR1 = GPDR1 (1<<0); //config pin32 as output GAFR1_L = (GAFR1_L&0xfffffffc) (2<<0);//) pin32 is used for function 2->MMCLK //MMDAT0 PIN92 GPSR2 = 0x ;//pin92 configured as an output, set pin level high (one). GPDR2 = 0x ;//pin92 as output // GPDR2 = GPDR2 & ~(1<<28) ; GAFR2_U = (GAFR2_U & 0xfcffffff) (1<<24) ;//pin32 is used for function 1->MMDAT<0> //MMDAT1 PIN109 GPSR3 = (1<<13); GPDR3 = (1<<13); GAFR3_L = (GAFR3_L & 0xf3ffffff) (1<<26) ; //MMDAT2 PIN110 GPSR3 = (1<<14); GPDR3 = (1<<14); GAFR3_L = (GAFR3_L & 0xcfffffff) (1<<28); //MMDAT3 PIN111 GPSR3 = (1<<15); GPDR3 = (1<<15); GAFR3_L = (GAFR3_L & 0x3fffffff) (1<<30); //MMCMD PIN112 GPSR3 = 0x ; GPDR3 = 0x ; //GPDR3 = GPDR3 & ~(1<<16); GAFR3_U = (GAFR3_U & 0xfffffffc) (1<<0); //function

85 } GPSR3 = 0x0000e000;//PIN111-PIN109 GPDR3 = 0x0000e000; GAFR3_L = (GAFR3_L & 0x03ffffff) 0x ; 5) SD 移除操作函數 //remove the MMC then free system resource static void pxa_mmc_remove( mmc_controller_t ctrlr ) { pxa_mmc_hostdata_t hostdata = (pxa_mmc_hostdata_t)ctrlr->host_data; kfree( hostdata->iobuf.iodata ); /* 1) free buffer(s) */ free_irq( IRQ_MMC, ctrlr ); /* 1) release irq */ CKEN &= ~CKEN12_MMC; /* disable MMC unit clock */ } 6) 讀資料區塊操作 static int pxa_mmc_read_block( mmc_controller_t ctrlr, mmc_data_transfer_req_t transfer ) { int ret = -ENODEV; u16 argh = 0UL, argl = 0UL; /* send CMD16 (SET_BLOCK_LEN) when requested block size is not the default * for the current card */ if ( transfer->blksz!= ctrlr->stack.selected->info.read_bl_len ) { argh = transfer->blksz >> 16; argl = transfer->blksz; if ( (ret = pxa_mmc_stop_bus_clock( ctrlr )) ) goto error; MMC_CMD = CMD(16); /* SET_BLOCK_LEN */ MMC_ARGH = argh; MMC_ARGL = argl; MMC_CMDAT = MMC_CMDAT_R1; MMC_DEBUG( MMC_DEBUG_LEVEL3, "CMD16(0x%04x%04x)\n", argh, argl ); if ( (ret = pxa_mmc_complete_cmd( ctrlr, MMC_R1, FALSE )) ) goto error; } /* CMD17 (READ_SINGLE_BLOCK) */ argh = transfer->addr >> 16; argl = transfer->addr; if ( (ret = pxa_mmc_stop_bus_clock( ctrlr )) ) goto error; MMC_CMD = CMD(17); /* READ_SINGLE_BLOCK */ MMC_ARGH = argh; MMC_ARGL = argl; MMC_CMDAT=MMC_CMDAT_R1 MMC_CMDAT_READ MMC_CMDAT_BLOCK MMC_CMDAT_D ATA_EN ;

86 MMC_NOB = 1; MMC_BLKLEN = transfer->blksz; EELiod Linux 實驗指導手冊 MMC_DEBUG( MMC_DEBUG_LEVEL3, "CMD17(0x%04x%04x)\n", argh, argl ); if ( (ret = pxa_mmc_complete_cmd( ctrlr, MMC_R1, FALSE )) ) goto error; /* transfer the data to the caller supplied buffer */ if ( (ret = pxa_mmc_read_buffer( ctrlr, transfer->blksz )) < 0 ) //transfer->blksz goto error; if ( (ret = pxa_mmc_copy_from_buffer( ctrlr, transfer->type, transfer->buf, ret )) < 0 ) goto error; transfer->buf += ret; transfer->cnt -= ret; transfer->nob -= 1; pxa_mmc_set_state( ctrlr, PXA_MMC_FSM_END_IO ); if ( (ret = pxa_mmc_complete_io( ctrlr, transfer->cmd, transfer->mode )) ) goto error; ret = 0; error: return ret; } 7) 寫資料區塊操作 static int pxa_mmc_write_block( mmc_controller_t ctrlr, mmc_data_transfer_req_t transfer ) { int ret = -ENODEV; u16 argh = 0UL, argl = 0UL; /* send CMD16 (SET_BLOCK_LEN) when requested block size is not the default * for the current card */ if ( transfer->blksz!= ctrlr->stack.selected->info.read_bl_len ) { argh = transfer->blksz >> 16; argl = transfer->blksz; if ( (ret = pxa_mmc_stop_bus_clock( ctrlr )) ) goto error; MMC_CMD = CMD(16); /* SET_BLOCK_LEN */ MMC_ARGH = argh; MMC_ARGL = argl; MMC_CMDAT = MMC_CMDAT_R1 ; MMC_DEBUG( MMC_DEBUG_LEVEL3, "CMD16(0x%04x%04x)\n", argh, argl ); if ( (ret = pxa_mmc_complete_cmd( ctrlr, MMC_R1, FALSE )) ) goto error; } /* CMD24 (WRITE_SINGLE_BLOCK) */ argh = transfer->addr >> 16; argl = transfer->addr; if ( (ret = pxa_mmc_stop_bus_clock( ctrlr )) )

87 goto error; EELiod Linux 實驗指導手冊 MMC_CMD = CMD(24); /* WRITE_BLOCK */ MMC_ARGH = argh; MMC_ARGL = argl; MMC_CMDAT=MMC_CMDAT_R1 MMC_CMDAT_WRITE MMC_CMDAT_BLOCK MMC_CMDAT_D ATA_EN; MMC_NOB = 1; MMC_BLKLEN = transfer->blksz; MMC_DEBUG( MMC_DEBUG_LEVEL3, "CMD24(0x%04x%04x)\n", argh, argl ); if ( (ret = pxa_mmc_complete_cmd( ctrlr, MMC_R1, FALSE )) ) goto error; /* transfer the data to the caller supplied buffer */ if ( (ret = pxa_mmc_copy_to_buffer( ctrlr, transfer->type, transfer->buf, transfer->cnt )) < 0 ) goto error; if ( (ret = pxa_mmc_write_buffer( ctrlr, ret )) < 0 ) goto error; transfer->buf += ret; transfer->cnt -= ret; transfer->nob -= 1; pxa_mmc_set_state( ctrlr, PXA_MMC_FSM_END_IO ); if ( (ret = pxa_mmc_complete_io( ctrlr, transfer->cmd, transfer->mode )) ) goto error; ret = 0; error: return ret; } MMC/SD 驅動的其他操作如多區塊讀寫 串流讀寫 狀態檢測等操作可以參考 Linux 程式碼 /drivers/mmc/mmc-pxa.c 以及相關檔 這裡不再介紹 6 MMC/SD 驅動設定 PXA27x 的 MMC/SD 控制器支援標準的 MMC 卡和 SD 卡 同時目標板提供了 MMC 卡和 SD 卡的驅動 Linux 針對 MMC/SD 核心設定的步驟 : 在主功能表下選擇 General setup > 選擇 Support for hot-pluggable devices, 出現 MMC/SD device drivers

88 點擊 MMC/SD device drivers, 進入下一頁選擇 設定好, 重新編譯核心 7 MMC/SD 卡操作將 SD 或 MMC 儲存卡插入 MMC/SD 卡插槽中, 利用 mount 命令掛載 MMC/SD 卡, 然後可以對 MMC/SD 卡進行操作 [root@51board~]$mount /dev/mmcda1 /mnt/sd 實驗儀器實驗儀器 1 裝有 Linux 作業系統的 PC 一台 ; 2 XSBase270 或 XSBase255 ARM 實驗開發平台一套 3 MMC/SD 儲存卡一塊

89 實驗內容實驗內容 1 將 MMC/SD 卡驅動程式編譯到 Linux 核心中, 寫出編譯過程 ; 2 將 MMC 或 SD 儲存卡掛載目標板上並進行檔的複製操作, 寫出步驟 3 結合 PXA27x 微處理器開發手冊和 MMC/SD 卡驅動程式 (/drivers/mmc/mmc-pxa.c 以及相關檔 ), 分析通用 IO 介面初始化函數 init_gpio(void) 的作用同時並分析 MMC/SD 卡介面中各埠的功能轉換的設定方法 ; 思考題思考題 1 根據 MMC/SD 卡的認證模式命令流程圖, 結合目標板程式提供的 MMC/SD 驅動程式, 畫出認證過程的流程圖 ; 2 根據 MMC/SD 卡的傳輸模式命令流程圖, 結合目標板程式提供的 MMC/SD 驅動程式, 畫出資料傳輸過程的流程圖 ; 3 從網路上下載 MMC/SD 卡的協定標準 (SD Memory Card Specification Version 1.01), 結合驅動程式, 分析各命令的功能

90 實驗十 USB 驅動設定設定實驗 實驗目的實驗目的 1 瞭解 USB 介面的工作原理 2 掌握 USB 記憶體驅動的設定方法 3 掌握 USB 記憶體的使用方法 實驗原理實驗原理 1 USB 介面簡介 USB 的全名是 Universal Serial Bus 最多可連接 127 台裝置, 由於 USB 支援熱插拔, 即插即用, 支援的電子設備多 ( 一般的 PC 都設定了 USB 介面 ) 等優點 目前, 在市場上流行的 USB 介面主要符合 :USB1.1, USB2.0 和 USB OTG 三種規範 目前主流的掌上電腦一般都設定了 USB 介面, 使用者可用廠商提供的 USB 資料線與其他同樣具備 USB 介面的電子設備連接起來使用 USB1.1 規範支援低速 (1.5Mb/s) 和全速 (12Mb/s) 兩種不同速率的資料傳輸和 4 種不同類型的資料傳輸方式 : 控制傳輸 中斷傳輸 批量傳輸和同步傳輸 按照物理介面,USB 介面可以分為主機 (USB host) 端 USB 集線器 (USB hub) 和 USB 設備 (USB device) 端三種類型 USB 集線器其實是一類特殊的 USB 設備, 在一個完整的 USB 拓撲結構上, 必須有且僅有一個 USB 主機, 一個或多個 USB 集線器和 USB 設備 為了滿足語音和圖像傳輸對寬帶的要求,USB2.0 在相容 USB1.1 低速和全速資料傳輸基礎上, 支援高速 (480Mb/s) 資料傳輸 對於 USB2.0 規範, 同樣支援控制傳輸 中斷傳輸 批量傳輸和同步傳輸 4 種類型的資料傳輸方式 在物理結構和拓撲結構上,USB2.0 和 USB1.1 也完全相同 USB OTG 規範是作為對 USB2.0 規範的補充而出現的, 其目的是為了滿足攜帶型設備 ( 如數位相機 ) 對 USB 介面性能的需求 根據 USB OTG 規範, 一個 USB 介面可同時具有 USB 主機和 USB 設備兩種功能, 根據與其連接的其他設備屬性,USB OTG 介面會自動轉換成為適合 USB 匯流排需求的介面類型 比如, 當一個具有 USB OTG 介面的 PDA 直接與印表機相連時, 其充當的角色就是 USB 主機, 而當其與 PC 相連時, 其充當的角色就是 USB 設備 USB 使用一個 4 Pin 插頭作為標準插頭 通過這個標準插頭, 採用菊花鏈形式可以把所有的裝置連接起來, 並且不會損失頻寬 USB 規範中將 USB 分為五個部分 : 控制器 控制器驅動程式 USB 晶片驅動程式 USB 設備以及針對不同 USB 設備的客戶驅動程式 USB 需要主機硬體 作業系統和裝置三個方面的支援才能工作 2 Linux 核心對 USB 規範的支援由於 USB 介面有主機端和設備端的區別, 因而 USB 驅動程式也有 USB 主機端驅動程式和 USB 設備端驅動程式之分 目前, 不同的 Linux 版本對 USB 的支援程度不同, 比如,Linux 以下的版本一般只支援 USB1.1 規範, 而 Linux2.5.xx 版本就支援 USB2.0 規範 在主機控制器方面, 支援 USB1.1 規範的一般都支援通用型主機控制器介面 UHCI(Universal Host Control Interface) 和開放式主機控制器介面 OHCI (Open Host Control Interface) 兩種規範, 而對於支援 USB2.0 規範的 Linux 核心, 則在支援 UHCI 規範和 OHCI 規範的基礎上, 同時支援了增強型主機控制器介面 EHCI(Enhanced Host Control Interface) UHCI 規範和 EHCI 規範都是由 Intel 公式提出, 符號該規範的硬體平台主要以 PC 為主 OHCI 規範是由康柏 微軟 松下等公司聯合提出的開放式主機控制器介面標準, 該規範已經被大量應用到嵌入式系統中

91 由於 USB 介面是一個主 個從方式 多設備連接的樹狀網路結構, 所以 USB 主機必須具有對所有連接在匯流排上的不同類型 USB 設備進行管理的功能 Linux USB 主機驅動程式可以同時支援多 channel USB 匯流排功能, 每 channel USB 匯流排獨立工作 如圖 10-1 所示,Linux USB 主機驅動程式由三部分組成 : USB 主機控制器驅動 (HCD) USB 驅動 (USBD) 和不同的 USB 設備類驅動 圖 10-1 Linux USB 驅動程式結構 USB 主機控制器驅動 (HCD) 是 USB 主機驅動程式中直接與硬體對應的軟體模組, 其主要功能有 : 主機控制器硬體初始化 ; 為 USBD 層提供相對應的介面函數 ; 提供根 HUB(root hub) 設備設定 控制功能 ; 完成 4 種類型的資料傳輸等 Linux2.5.xx 版本支援 USB1.1 和 USB2.0 規範, 其 USB HCD 部分支援 UHCI OHCI 和 ECHI 三種規範 USBD 部分是整個 USB 主機驅動的核心, 其主要實現的功能有 :USB 匯流排管理 ;USB 匯流排設備 USB 匯流排頻寬管理 ;USB 的 4 種類型的資料傳輸 ;USB HUB 驅動 ; 為 USB 設備類驅動提供相關介面 ; 提供應用程式存取 USB 系統的檔介面等 USB 設備類驅動是最終與應用程式交互的軟體模組, 其主要實現的功能有 : 存取特定的 USB 設備 ; 為應用程式提供存取介面等 2 設定 USB 設備要啟用 Linux USB 支援, 首先進入 "USB support" 節並啟用 "Support for USB" 選項 ( 對應模組為 usbcore.o) 如圖 10-2 所示

92 圖 10-2 USB support 設定介面接下來需要設定用於系統的正確 USB 主控制器驅動程式 (USB Host Controller Drivers), 如圖 10-3 所示 用於 USB 主控制器驅動模組主要有 : 增強型主機控制器介面 EHCI 驅動模組 ( 對應模組為 ehci-hcd.o) 通用型主機控制器介面 UHCI 驅動模組 ( 對應模組為 usb-uhci.o) 開放式主機控制器介面 OHCI 驅動模組 ( 對應模組為 usb-ohci.o) 圖 10-3 USB 設定介面要理解 "EHCI" 及其同類是什麼, 首先要知道每塊支援插入 USB 設備的主板或 PCI 卡都需要有 USB 主控制器晶片組 這個特別的晶片組與插入系統的 USB 設備進行相互操作, 並負責處理允許 USB 設備與系統其他部分通訊所必需的所有低層次細節 Linux USB 驅動程式有三種不同的 USB 主控制器選項是因為在主板和 PCI 卡上有三種不同類型的 USB 晶片 增強型主機控制器介面 EHCI 驅動程式設計成為實現新的高速 USB 2.0 協定的晶片提供支援, 開放式主機控制器介面 OHCI 驅動程式用來為非 PC 系統上

93 的 ( 以及帶有 SiS 和 ALi 晶片組的 PC 主板上的 )USB 晶片提供支援 通用型主機控制器介面 UHCI 驅動程式用來為大多數其他 PC 主板 ( 包括 Intel 和 Via) 上的 USB 實現提供支援 在 USB 主機控制器 的設定中, 只需選擇與希望啟用的 USB 支援的類型所對應的 USB 主機控制器驅動程式即可 為保險起 見, 可以啟用 "EHCI" "UHCI" ( 兩者中任選一種, 它們之間沒有明顯的區別 ) 和 "OHCI" 啟用了 "USB support" 和適當的 USB 主控制器驅動程式後, 然後啟用 "Preliminary USB device filesystem", 和啟用所有特定的且將與 Linux 一起使用的實際 USB 週邊設備的驅動程式 例如, 為了啟 用對 USB 遊戲控制器和 USB 記憶體設備的支援, 應啟用 "USB Human Interface Device (full HID) support" 和 "USB Mass Storage support", 然後啟用主 "Input core support" 節下的 "Input core support" 和 "Joystick support" 一旦使用新的已啟用 USB 的核心重新引導後, 若 /proc/bus/usb 下沒有相對應 USB 設備資訊, 應輸入 以下命令將 USB 設備檔案系統手動掛裝到 /proc/bus/usb: [root@localhost xbase]$mount t usbdevfs none /proc/bus/usb 為了在系統引導時自動掛載 USB 設備檔案系統, 請將 none /proc/bus/usb usbdevfs defaults 0 0 新增到 /etc/fstab 中的 /proc 掛載行之後 3 模組的模組的設定設定方法在很多情況下,USB 設備驅動並不包含在核心中, 這時只要根據所需要使用的模組, 逐一載入到核心中就可以使驅動起作用 首先要確保在核心編譯時以模組方式選擇了相對應支援 這樣就應該可以在 /lib/modules/2.4.xx 目錄看到相對應.o 檔案 在載入模組時, 只需要執行 modprobe xxx.o 就可以了 (modprobe 主要載入系統已經通過 depmod 登記過的模組,insmod 一般是針對.o 檔進行載入 ) 對於 USB 設備下面一些模組是關鍵的 模組名稱 usbcore.o usb-uhci.o usb-ohci.o 支援內容要支援 usb 所需要的最基礎模組 UCHI OCHI uhci.o 另一個 UHCI 驅動程式 ( 本系統不採用 ) ehci-hcd.o hid.o usb-storage.o EHCI usb2.0 USB 人機界面設備, 像滑鼠 鍵盤等 USB 儲存設備, 隨身碟等 記憶體相關模組 模組名稱 支援內容 ide-disk.o ide-scsi.o scsi_mod.o sd_mod.o IDE 硬碟把 IDE 設備類比 SCSI 介面 SCSI 支援 SCSI 硬碟

94 sr_mod.o SCSI 光碟 sg.o SCSI 通用支援 ( 在某些探測隨身碟 SCSI 探測中會用到 ) 在進行核心設定時, 其中 Probe all LUNs on each SCSI device 最好選上, 要不某些同時支援多埠的讀卡器只能顯示一個 若以模組方式進行載入, 就要設參數安裝或提前在 /etc/modules.conf 中新增 add options scsi_mod max_scsi_luns=9 來支援多個 LUN 4 Linux 下隨身碟隨身碟的使用如果需要在裝有 Linux 作業系統的目標平台中 USB 記憶體, 必須在利用 make menuconfig 編譯 Linux 核心時啟用 USB 記憶體和 SCSI 的支援 SCSI support ---> <*> SCSI support? <*> SCSI disk support (40) Maximum number of SCSI disks that can be loaded as modules USB support ---> <*> USB Mass Storage support 在目標平台中使用隨身碟, 應按照分區 格式化 掛載和使用四個大步驟進行操作 (1) 分區 ( 將隨身碟插入一般 PC 後操作 ) # fdisk /dev/sda ( 注意有的為 /dev/sdb) # Command (m for help):m a toggle a bootable flag b edit bsd disklabel c toggle the dos compatibility flag d delete a partition l list known partition types m print this menu n add a new partition o create a new empty DOS partition table p print the partition table q quit without saving changes s create a new empty Sun disklabel t change a partition's system id u change display/entry units v verify the partition table w write table to disk and exit x extra functionality (experts only) Command (m for help): 現結合具體過程講解幾個常用的命令 : 先用 p 來查看目前的分區情況 再用 d 刪除分區, 若有多個分區則按提示輸入某個編號, 繼續本行指令, 直到出現 No partition is defined yet! 接著用 n 來新建一個分區

95 輸入 n 後出現 "e p" 兩個分區選擇項, 我們這裡選擇 p, 並在 partition number 項輸入 1, 建立第 1 號分區, 以後連續幾個 Enter 後即可 此時預設的是 ext2 檔案系統類型, 若要更改檔案系統類型可以輸入 t 來更改, 具體的檔案系統類型可以用 l 來查看檔案系統類型列表, 輸入 t 後接著輸入檔案系統編號即可, 如 win95 FAT32 對應的編號為 b 最後輸入 w 儲存剛才分區設定. (2) 格式化分區 ( 將隨身碟插入一般 PC 後操作 ) 格式化為 ext2 分區 [root@51board~]$mkfs.ext2 /dev/sda1 若格式化為 fat 分區, 但需在 /sbin/ 下存在 mkfs.vfat 檔案. [root@51board~]$mkfs.vfat /dev/sda1 (3) 掛載隨身碟 mount ( 將隨身碟插入開發板後操作 ) [root@51board~]$mkdir /mnt/usb [root@51board~]$mount /dev/sda1 /mnt/usb (4) 使用 [root@51board~]$cd /mnt/usb [root@51board~]$mkdir tmp [root@51board~]$ls tmp Command (m for help): n Command action e extended p primary partition (1-4) p Partition number (1-4): 1 First cylinder (1-995, default 1): Using default value 1 Last cylinder or +size or +sizem or +sizek (1-995, default 995): Using default value 995 Command (m for help): 實驗儀器實驗儀器 1 裝有 Linux 作業系統的 PC 一台 ; 2 XSBase270 或 XSBase255 ARM 實驗開發平台一套 3 空白隨身碟一個 實驗內容實驗內容 1 利用 make menuconfig 編譯 Linux 核心, 啟用 Linux 核心對 USB 主機控制器的支援, 寫出編譯過程以及需要選擇的支援項 ; 2 利用手動和自動將 USB 各驅動模組新增到 Linux 核心中, 寫出新增過程 ; 3 在目標板上使用 USB 記憶體, 寫出使用分區和格式化 USB 記憶體的過程及方法 ;

96 思考題思考題 1 在使用隨身碟時, 對核心設定的各項分別起什麼作用? 2 字元設備與區塊設備的使用的區別 3 思考其他 USB 設備的掛接方法, 如印表機

97 實驗十一 QT/E 移植實驗 實驗目的實驗目的 1 瞭解嵌入式 GUI-QT/E 軟體發展平台的構架 2 掌握 QT/E 在 ARM 開發系統中的移植步驟及環境變數的設定方法 ; 3 掌握移植 QT/E 嵌入 GUI 應用程式的基本步驟與方法 4 瞭解 Qt/E 不同平台環境參數的設定和切換 實驗原理實驗原理 1 QT/E 簡介 QT/E 是跨平台的 C++ 圖形使用者介面 (GUI) 工具包, 它是著名的 Qt 開發商 TrollTech 發佈的面向嵌入式系統的 Qt 版本,Qt 是目前 KDE 等專案使用的 GUI 支援函式庫, 許多基於 Qt 的 X Window 程式可以非常方便地移植到嵌入式 Qt/Embedded 版本上 自從 Qt/Embedded 發佈以來, 就有許多嵌入式 Linux 開發商利用 Qt/Embedded 進行嵌入式 GUI 應用開發 Qt/Embedded 是一個多平台的 C++ 圖形使用者介面開發工具包, 它注重於能給使用者提供精美的圖形介面所需的所有元素, 而且其開發過程是基於物件導向的開發思想, 並且 Qt/Embedded 支援真正的元件編譯 2 實驗原理 TrollTech 公司所發佈的導向嵌入式系統的 QT/E 版本只提供程式碼, 使用者必須針對自己的嵌入式硬體平台進行裁剪 編譯和移植 儘管 Qt/Embedded 可以裁剪到 630K, 但它對硬體平台具有較高的要求, 目前 Qt/Embedded 庫主要針對於掌上型資訊終端 本實驗主要完成 Qt/Embedded 在 XSBase270 實驗平台上的移植 實驗儀器實驗儀器 1 裝有 Linux 作業系統的 PC 一台 ; 2 XSBase270 或 XSBase255 ARM 實驗開發平台一套 實驗內容實驗內容 - QT/E 的跨平台平台的移植方法與步驟 1 程式碼的下載使用者可到 TrollTech 主頁上 (ftp://ftp.trolltech.com/qt/source) 下載 Qt/Embedded 的某個版本的程式碼 ( 本實驗主要介紹 qt-2.3.2), 對下載後的程式碼壓縮檔進行解壓 # tar xzvf qt-embedded tar.gz 解壓後在當前目錄上產生 qt 資料夾 2 編譯 Qt/Embedded 的環境參數的設定在編譯 Qt/Embedded 時, 使用者在 PC 上應對編譯時所需的環境變數進行設定 ( 假設 Qt 解壓後目錄為

98 /root/xsbase270_linux/qui/qt/qt-2.3.2), 主要參數包括 : (1) QTDIR-Qt 解壓後的所在的目錄 (2) LD_LIBRARY_PATH-Qt 共用函式庫存放的目錄 EELiod Linux 實驗指導手冊 (3) TMAKEPATH-tmake 編譯工具的路徑 ( 假設 tmake-1.1 所在的目錄為 /root/work) (4) PATH- 交叉編譯工具 arm-linux-gcc 的路徑 [root]$export QTDIR=/root/XSBase270_Linux/qui/qt/qt [root]$export LD_LIBRARY_PATH=$QTDIR/lib:$LD_LIBRARY_PATH [root]$export TMAKEPATH=/root/work/tmake-1.1/lib/qws/linux-arm-g++ [root]$export PATH=/usr/local/xscalev1/bin:$PATH 3 Qt/Embedded 的編譯設定 Qt/Embedded 的編譯設定主要通過 configure 命令進行設定 使用者可通過./configure help 查看設定選 項, 下面介紹幾個主要的設定選項功能 (* 表示預設選項 ) (1) * -release... 編譯成發佈版本 ; -debug... 編譯具有除錯資訊的版本 (2) * -shared... 編譯產生和使用共用函式庫 (libqte.so);-static.... 編譯產生和使用靜態庫 (libqte.a) (3) * -no-thread... 不支援執行緒編譯 ;-thread... 支援執行緒編譯 如果在編譯時選擇 -thread 選項,Qt/Embedded 編譯後產生 libqte-mt.so 共用函式庫或 libqte-mt.a 靜態庫 (4) -platform target... 編譯平台的選擇, 在編譯時, 對 Qt 的程式碼編譯所採用的目標平台,Qt 預 設為 linux-x86-g++ -shared, 一般情況下對該項無需進行設定 (5) -xplatform target... 交叉編譯平台的選擇 如果將 Qt 編譯成不同的平台, 該選項必須進行選項 設定, 針對 ARM 開發平台, 該選項應設定為 linux-arm-g++ -shared (6)-qconfig local... 使用使用者自定義的 qconfig.h 使用者可以將自定義的設定選項 ( 主要是預編 譯巨集的定義 ), 檔案應儲存在 qt 資料夾的 src/tools 目錄下 詳細設定選項內容和功能可以參考 qt 目錄下的 PLATFORMS 檔案 4 針對 ARM 開發平台的 Qt/Embedded 的編譯步驟 : (1) 根據編譯 Qt/Embedded 的環境變數的設定方法設定環境變數 ; (2) 觸控螢幕共用函式庫的編譯和 Qt/Embedded 程式碼的修改 Qt/Embedded 只支援滑鼠和鍵盤的操作, 但在大部分嵌入式系統中利用觸控螢幕, 所以使用者必須對觸控螢幕的相關操作編譯成共用函式庫或靜態庫 下面介紹觸控螢幕共用函式庫的編譯過程 ( 假設 tslib.tar.bz2 儲存在 /root/work) 請先確定 PC 已安裝 libtool 套件 1 解壓實驗光碟提供的 tslib.tar.bz2 檔案 ; 2 編譯觸控螢幕函式庫 ; 3 將觸控螢幕相關的標頭檔複製到 qt-2.3.2/include 資料夾中 ; 4 將編譯好的觸控螢幕函式庫檔複製 qt-2.3.2/lib 資料夾中 ; [root@work]$tar -jxf tslib.tar.bz2 [root@work]$export CC=arm-linux-gcc 修改 原始 改為../tslib/plugins/Makefile 其中一行 LDFLAGS:=$(LDFLAGS) -rpath $(PLUGIN_DIR) LDFLAGS:=$(LDFLAGS) rpath `cd $(PLUGIN_DIR) && pwd`

99 修改 改成 EELiod Linux 實驗指導手冊../tmake-1.11/lib/qws/linux-arm-g++/tmake.conf 的部份內容 TMAKE_LINK=arm-linux-g++ TMAKE_LINK_SHLIB=arm-linux-g++ tslib host=arm-linux a src/.libs/* /root/work/qt/qt-2.3.2/lib/ [root@work]$cp a plugins/.libs/*.so /root/work/qt/qt-2.3.2/lib/ [root@work]$cp f src/*.h /root/work/qt/qt-2.3.2/include/ 5 修改 qt 交叉編譯環境參數檔使其增加對觸控螢幕的支援 ; 用文書編輯器 vi 或 gedit 打開 qt 目錄下的 configs/linux-arm-g++-shared 檔, 將 SYSCONF_LIBS = -lm 修改為 SYSCONF_LIBS = -lm -lts stdc++, 然後儲存修改後的檔 在編譯 qt 程式碼過程中使用觸控螢幕共用函式庫 6 修改 qt 滑鼠操作程式碼 src/kernel/qwsmouse_qws.cpp 雖然 qt 支援滑鼠操作, 但是程式碼 src/kernel/qwsmouse_qws.cpp 中讀取滑鼠資料函數 readmousedata() 讀取的資料與開發板的觸控螢幕設備驅動輸出的資料不匹配, 所以使用者必須修改讀取滑鼠資料函數 readmousedata() 具體需要修改的部分請參考 Qt/Embedded 程式碼 qwsmouse_qws.cpp 檔與實驗光碟中提供的修補檔 qwsmouse_qws.cpp 的區別 (2) 執行 configure 命令產生編譯時所需的 Makefile #./configure xplatform linux-arm-g++ -shared 在執行上述 configure 命令時, 系統會問到如下幾個問題 1 是否同意 license? 選 yes 2 編譯設定特性選擇: 1. Minimal (630 kb)" 2. Small (960 kb)" 3. Medium (1.5 MB)" 4. Large (3 MB)" 5. Everything (5 MB)" 6. Your own local configuration (src/tools/qconfig-local.h) 選擇第 5 項 Everything, 表示選中所有項, 實際上在嵌入式系統中 Qt/Embedded 部分功能根本用不了或用不上, 所以為了減小編譯庫的大小, 使用者可以根據需要對 Qt/Embedded 進行適當的裁剪 具體可以參考 qt-2.3.2/src/tools/qconfig-xxx.h 檔中的巨集定義 ( xxx 表示有幾個類似的檔 ) 或 qt-2.3.2/doc/html/features.html 3 像素深度選擇: v. VGA-16 - also enables 8bpp 4. 4bpp grayscale - also enables 8bpp 8. 8bpp bpp bpp - also enables 32bpp bpp

100 預設選擇為 8,16, 可以根據 LCD 的象素特性進行選擇, 可使用預設選項 EELiod Linux 實驗指導手冊 4 是否支援 Qt Virtual Framebuffer? 在 ARM 開發平台上, 可以選擇 no 如果將 Qt/Embedded 編譯成 能在 X windows 執行的程式, 應選擇 yes 設定選擇結束後,Qt/Embedded 會輸出對不同選項的設定選擇結果 同時產生編譯時所需要的 Makefile 檔 Building on: 5 編譯 #make 在設定完成後, 通過執行 Make 實現對 Qt/Embedded 的編譯 如果編譯成功, 系統輸出 : 編譯產生的共用函式庫 libqte.so 儲存在 Qt 目錄的 /lib 資料夾中, 通過查看 /lib 資料夾的檔可以確認編譯是否成功 #cd $QTDIR/lib #ls libqte.so libqte.so.2 libqte.so.2.3 libqte.so 利用 file 命令確認產生的共用函式庫是否適合目標平台即 ARM 平台的二進制目標檔 #file libqte.so linux-x86-g++-shared Building for: linux-arm-g++-shared Thread support... no GIF support... no MNG support... no JPEG support... no Creating makefiles... Qt is now configured for building. Just run make. To reconfigure, run make clean and configure The Qt library is now built in./lib The Qt examples are built in the directories in./examples The Qt tutorials are built in the directories in./tutorial Enjoy! - the Trolltech team libqte.so.2.3.2:elf 32-bit LSB shared object,arm,version 1(ARM),not stripped 二 Qt/Embedded 應用程式的移植 通過上述編譯過程, 我們只是將編譯和執行 Qt/Embedded 應用程式所需的一些庫函數編譯成共用函式庫的形式, 編譯的最終目的是在 ARM 開發平台執行使用者開發的應用程式 這需要將 Qt/Embedded 的應用程式移植到 ARM 開發平台上 使用者可以通過兩種不同的方法完成 Qt/Embedded 共用函式庫和應用程式的移植 一種方法是將 Qt/Embedded 共用函式庫和應用程式新增檔案系統中, 然後重新產生檔案系統的映射檔, 這種方法必須每次重新產生和下載檔案系統 ; 另一種方法通過網路共享系統 (NFS) 把 Qt/Embedded 的共用函式庫和應用程式移植到 ARM 目標板的檔案系統中, 下面重點介紹通過 NFS 移植 Qt/Embedded 共用函式庫和應用程式的步驟 (NFS 的具體使用方法參照使用手冊 ) 1 將 PC 上的 qt 資料夾 mount 到目標板上 ;

101 /mnt mkdir qt t nfs :/root/work/qt/qt /mnt/qt 在目標板上設定執行 Qt/Embedded 應用程式的環境變數 [root@51board~]$export QTDIR=/mnt/qt [root@51board~]$export LD_LIBRARY_PATH=/mnt/qt-2.3.2/lib:$LD_LIBRARY_PATH 3 在目標上執行 Qt/Embedded 的應用程式 [root@51board~]$cd /mnt/qt-2.3.2/examples/hello [root@51board~]$./hello qws 使 用者在執行上述應用程式時, 可以看到應用程式已經在目標板執行, 現在使用者可以利用 Qt/Embedded 來編寫應用程式了 三 Qt/Embedded 的環境參數的自動載入通過命令行設定的 Qt/Embedded 環境參數在切換命令行終端或重啟系統後這些環境參數便不復存在, 如果使用者想在 Linux 作業系統啟動時自動設定 Qt/Embedded 的環境參數, 可以將 Qt/Embedded 的環境參數新增到 ~/.bash_profile 腳本中 利用文書編輯器 vi 或 gedit 打開 ~./bash_profile 腳本, 將 Qt/Embedded 的環境參數 QTDIR LD_LIBRARY_PATH 新增到 ~./bash_profile 腳本中 #.bash_profile PATH=$PATH:$HOME/bin BASH_ENV=$HOME/.bashrc USERNAME= root # Cross compile tools path PATH=$PATH:/usr/local/ :/usr/local/xscalev1 xscalev1/bin # qt environment parameter QTDIR=/root /root/work work/qt/qt /qt/qt LD_LIBRARY_PATH=$QTDIR/lib:$LD_LIBRARY_PATH #tmake tools PATH TMAKEPATH=/root/work/tmake-1.1/lib/qws/linux 1.1/lib/qws/linux-arm arm-g++ export USERNAME BASH_ENV PATH QTDIR LD_LIBRARY_PATH TMAKEPATH 重新啟動 Linux 作業系統,Qt/Embedded 的環境參數便自動進行設定 使用者可以通過系統環境參數查看命令 env 進行查看 Qt/Embedded 的環境參數是否已經設定成功 思考思考題 1 如果在 PC 上通過 qvfb 工具模擬執行採用 Qt/Embedded 編寫的程式, 應該怎樣對 Qt/Embedded 進行編譯? 2 在 ARM 開發平台中, 如果採用 Qt 編寫的應用程式利用了 Qt 執行緒類 (qthread), 採用上述編譯方法 產生的共用函式庫是否能夠對應用程式進行編譯, 如果不能, 應該怎樣重新編譯 Qt/Embedded 程式碼? 3 某同學在編譯 Qt 應用程式 hello 時, 出現如錯誤提示 :

102 arm-linux-gcc -o hello hello.o main.o moc_hello.o -L/root/XSBase270_Linux/qui/qt/qt-2.3.2/lib -lm -lqte /root/xsbase270_linux/qui/qt/qt-2.3.2/lib/libqte.so: undefined reference to `ts_close' /root/xsbase270_linux/qui/qt/qt-2.3.2/lib/libqte.so: undefined reference to `ts_config' /root/xsbase270_linux/qui/qt/qt-2.3.2/lib/lib/libqte.so: undefined reference to `ts_read' /root/xsbase270_linux/qui/qt/qt-2.3.2/lib/libqte.so: undefined reference to `ts_open' collect2: ld returned 1 exit status make: *** [hello] Error 1 請分析產生錯誤的原因是什麼? 應該怎樣解決? 4 某同學通過 NFS 執行編譯好的 Qt 應用程式 hello, 出現如下錯誤提示 : [root@emdoor]$./hello qws./hello: error while loading shared libraries: libqte.so: cannot open shared object file: No such file or directory 請分析產生錯誤的原因是什麼, 應怎樣解決?

103 實驗十二串列埠通訊實驗 實驗目的實驗目的 1 瞭解串列埠設備檔案系統的使用方法 ; 2 掌握 Qt 編譯方法與技巧 3 掌握 Qtopia 應用程式的設定過程 實驗原理實驗原理 在 Linux 作業系統中對底層終端的處理是一個非常複雜的過程, 需要處理許多不同類型的設備 ( 包括 數據機 終端模擬 虛擬終端等 ) Linux 系統處理終端的方法是通過串列介面連接的控制台與系統通訊並 執行程式 由於越來越多的廠商都參與終端的生產, 而且每個廠商都是為自己的終端設計自己的命令集, 所以需要有一種方法對終端的存取進行一般化處理 Linux 系統使用一個能力資料庫 terminfo 來描述每個 終端的能力以及調用這些功能的方法 1 終端控制函數介紹在對底層終端操作中有一個用於查詢和操作終端的標準介面結構體 termios, 該結構體對終端的輸 入 輸出 硬體特性 控制協定等方面進行了定義, 定義形式如下 : struct termios{ tcflag_t c_iflag; tcflag_t c_oflag; tcflag_t c_cflag; tcflag_t c_lflag; cc_t; cc_t c_cc[nccs]; }; 其中參數 c_iflag 用來控制輸入處理選項 ;c_oflag 控制輸出資料的處理 ;c_cflag 設定決定終端硬體特性的 控制標記 ;c_lflag 存放本地模式標記, 用來操縱終端特性 ;c_line 表示控制協定 ;c_cc 包含特殊字元序列 的值以及它們所代表的操作 終端有兩種工作模式, 分別為規範模式 ( 或稱為 cooked 模式 ) 和非規範模式 ( 或稱為原始模式 ) 在 規範模式下, 終端設備驅動程式處理特殊字元並以一次一行的方式將輸入發送給程式使用, 而在非規範模 式下, 大多數鍵盤輸入得不到處理, 也不緩衝 (1) 終端屬性控制函數 對終端的操作主要通過屬性設定函數 tcsetattr() 和屬性獲取函數 tcgetattr() 來實現 其中 tcsetattr() 函數用 來初始化一個 termios 資料結構, 並設定用來表示該終端特性和設定的屬性值,tcgetattr() 獲取和查詢終端 屬性的資料結構, 當改變操作完成後, 通過使用 tcsetattr() 函數將用到的新值更新終端 tcsetattr() 和 tcgetattr() 的調用形式如下 : int tcsetattr(int fd, int action, struct termios *tp) 函數 tcsetattr() 使用由 tp 引用的 termios 資料結構來設定與檔描述符 fd 相關聯的終端參數, 參數 action 控制設定參數什麼時候發生改變, 如果取 TASANOW 表示立即改變所設參數屬性 ; 如果取 TCSADRAIN 表示 fd 上的輸出已經發送到終端後才改變所設定的參數屬性 ; 如果取 TCSAFLUSH 表示 fd 上的輸出完全 被發送到終端後, 任何掛起的輸入將被丟棄

104 int tcgetattr(int fd, struct termios *tp) 查詢和檔描述符相關聯的終端參數, 並將參數儲存到由 tp 所引用的 termios 資料結構體中, 調用成功 返回 0, 發生錯誤返回 -1 (2) 終端速度控制函數終端速度控制函數用來設定終端設備的輸入 輸出速度, 速度以串列傳輸速率來定義 這些函數都是 成對出現, 其中的兩個用來獲取和設定輸入的速度, 另兩個用來獲取和設定輸出線路的速度, 它們定義形 式如下 : int cfgetispeed (struct termios *tp) int cfsetispeed (struct termios *tp, speed_t speed) int cfgetospeed (struct termios *tp) int cfsetospeed (struct termios *tp, speed_t speed) 其中函數 cfgetispeed() 返回由 tp 指標指向的 termios 資料結構中所儲存的輸入線路速度值 函數 cfsetispeed() 將由 tp 指標指向的 termios 資料結構中儲存的輸入線路速度設定為 speed 函數 cfgetospeed() 返回由 tp 指標指向的 termios 資料結構中所儲存的輸出線路速度值 函數 cfsetospeed() 將由 tp 指標指向的 termios 資料結構中儲存的輸出線路速度設定為 speed 以上四個函數調用成功則返回 0, 發生錯誤則返回 -1 (3) 行控制函數行控制函數是用來查詢和設定各種與資料操作方式 時間等相關的特徵 它們的定義如下 : int tcdrain(int fd) int tcflush(int fd, int queue) int tcflow (int fd, int action) 其中函數 tcdrain() 將使所有掛起的輸出操作完成, 並將一直保持等待, 直到所有輸出都已經寫到檔案 描述字 fd 指向的檔為止 而函數 tcflush() 將更新最新排在檔案描述字 fd 佇列中的輸入和輸出 參數 queue 用來指定要更新的資 料, 如果 queue 取值為 TCIFUSH, 更新接收到但尚未讀取的輸入資料 ; 如果取值為 TCOFLUSH, 更新被 改寫但尚未傳送的輸出資料 ; 如查取值為 TCILFLUSH, 則兩者都更新 函數 tcflow() 是流量控制函數, 用來啟動或停止對檔案描述字 fd 的資料傳送和接收, 參數 action 如果 為 TCOON, 表示啟動輸出, 為 TCOOFF 時表示停止輸出 ; 為 TCION 時啟動輸入 ; 為 TCIOFF 時停止輸 入 2 串列埠串列埠通訊通訊類別的封裝在 Qt 開發軟體中, 沒有專門用於對終端設備進行操作的類別或控制項, 為了對終端設備進行操作, 一種方法就是利用 Linux 底層終端函數直接在應用程式中對終端設備進行開發操作, 但這樣開發比較麻 煩, 而且無法實現程式重用 另一種方法就是將終端設備的操作函數封裝成類的形式, 這樣不僅開發方便 而且可以實現程式重用 下面具體介紹串列埠類別的封裝 在對串列埠進行開發操作時, 可能涉及到打開串列埠, 設定串列埠參數 讀取串列埠資料 向串列埠 寫資料及關閉串列埠等操作函數, 因此在封裝串列埠類別時, 必須具有以上幾個操作函數 另外, 希望在 應用程式退出後不改變串列埠原參數, 應對原參數進行儲存, 待關閉串列埠時恢復串列埠原參數 串列埠類的實現函數 (1) 打開串列埠函數, 返回操作標記 int Serial::OpenSerialPort(const char *port) { int fd=::open( port, O_RDWR O_NOCTTY,O_NONBLOCK); if ( fd<0) return -1; // 打開失敗 fcntl(fd, F_SETFL,FNDELAY); tcgetattr(fd, &termios_old);// 將原來串列埠參數儲存到 termios_old 結構體中 return fd; // 返回成功操作標記

105 } (2) 關閉串列埠副程式, 返回操作標記 void Serial::CloseSerialPort(int serialfd) { tcsetattr (serialfd, TCSADRAIN, &termios_old); // 恢復串列埠參數 int fd =::close (serialfd); return fd; // 返回操作標記 // 關閉串列埠 } (3) 向串列埠寫資料, 返回寫入串列埠的總長度 int Serial::WriteSerialPort (int serialfd, const char *data, int datalength) { int len, total_len; // 定義寫入長度和總長度變數 for (total_len = 0 ; total_len < datalength;) { len = 0; len = ::write(serialfd, &data[total_len], datalength - total_len);// 寫串列埠 if (len > 0) else total_len += len; tcflush (serialfd, TCOFLUSH); } return (total_len); // 返回總長度 break; EELiod Linux 實驗指導手冊 } (4) 設定串列埠參數, 主要設定資料位元 停止位元 奇偶校驗位元 速度 逾時設定等 參數, 返回操作標記 int Serial::SetSerialPara(int serialfd,int databits, int stopbits,char parity, int speed, int vtime) { bzero( &termios_new, sizeof(termios_new));// 對新結構體 termios_new 清空 cfmakeraw(&termios_new); termios_new.c_cflag= speed; termios_new.c_cflag = CLOCAL CREAD; termios_new.c_cflag &= ~CSIZE; switch (databits) // 設定數據位元 { case 8: } case 7: case 6: termios_new.c_cflag = CS8; termios_new.c_cflag = CS7; termios_new.c_cflag = CS6; case 5: termios_new.c_cflag = CS5; default: switch (parity) { case N : termios_new.c_cflag = CS8; // 設定串列埠串列傳輸速率 break; break; break; break; // 設定奇偶校驗 break; termios_new.c_cflag &= ~PARENB; case E : termios_new.c_cflag = PARENB; break;

106 } } case O : termios_new.c_cflag &= ~PARODD; termios_new.c_cflag = PARENB; termios_new.c_cflag = ~PARODD; default: break; termios_new.c_cflag &= ~PARENB; break; switch (stopbits) { case 1: case 2: default: // 設定停止位 termios_new.c_cflag &= ~CSTOPB; termios_new.c_cflag = CSTOPB; break; break; break; termios_new.c_cflag &= ~CSTOPB; break; termios_new.c_cc[vtime] = vtime; termios_new.c_cc[vmin] = 0; // 設定逾時時間 tcflush (serialfd, TCIFLUSH); return tcsetattr(serialfd,tcsanow,&termios_new); // 立即更新設定參數 } (5) 讀取串列埠數據 EELiod Linux 實驗指導手冊 因為 Linux 作業系統採用一種特殊的設備檔案系統 devfs, 使設備作為一種檔案存在, 因此讀取設備資 料同讀取一般檔案的方法相同, 為了靈活使用已封裝好的串列埠類別, 因此在封裝串列埠類別時, 將讀取 串列埠資料的函數放在串列埠類別外面, 便於使用者控制 讀取串列埠資料的函數採用 Linux 底層函數 read() 進行操作, 調用方法如下 : int read (int fd, char *, int length ) 其中 fd 為設備號 ;char * 為數據緩衝區 ;length 每次讀取數據的長度 ; 返回值為實際讀取資料的長度 3 串列埠串列埠通訊通訊程式碼程式碼的編譯 (1)PC 平台的串列埠通訊程式編譯 將光碟提供的 serialpc 的程式碼複製到硬碟中 ( 假設將程式複製在 /root/work 目錄下 ) 對程式進行編譯 [root@work]$cd serialpc [root@serialpc]$make 在 PC 上執行 serial 程式, 執行介面如圖 12-1 所示 [root@serialpc]$./serial

107 圖 12-1 串列埠執行介面 (2) ARM 平台的串列埠通訊程式的編譯 將光碟提供的 serialarm 的程式碼複製到硬碟中 ( 假設將程式複製在 /root/work 目錄下 ) 設定交叉編譯工具參數 (arm-linux-g++) 對程式碼進行編譯 [root@work]$cd serialarm [root@work]$export QTDIR=/root/work/qt/qt [root@work]$export QPEDIR=root/work/qt/qtopia-free [root@serialarm]$make 將編譯好的程式 serial 下載到開發板的 /usr/qpe/bin 目錄下 在目標板上利用 chmod 命令修改 serial 的屬性 [root@bin]$ chmod 755 serial 在開發板的 /usr/qpe/application 目錄下新建 serial.desktop 檔 ( 內容如下 ), 或將 serialarm 目錄下的 serialarm.desktop 檔下載到開發板的 /usr/qpe/application 目錄下 [Desktop Entry] Comment=A serial Program Exec=serial Icon=Clock Type=Application Name=Clock Name[zh_CN]= 串列埠測試

108 實驗儀器實驗儀器 1 裝有 Linux 作業系統的 PC 一台 ; 2 XSBase270 或 XSBase255 ARM 實驗開發平台一套 實驗內容實驗內容 1 編譯基於 PC 和 ARM 平台的串列埠通訊程式碼, 寫出編譯過程 2 將編譯好的基於 ARM 的串列埠通訊程式和 serial.desktop 檔下載到開發板中, 重啟開發板系統, 觀察程式執行情況並分析 serial.desktop 的作用 3 分析串列埠通訊程式的程式碼, 畫出串列埠通訊的流程圖 4 寫出將應用程式新增到 qtopia 的過程和步驟 思考題思考題 1 比較基於 PC 和 ARM 的串列埠程式的 Makefile 檔, 分析兩者的區別 ; 2 利用 tmake 工具重新產生用於編譯基於 ARM 的程式碼的 Makefile 檔 ; 3 根據系統提供的程式碼, 分析利用 qt 開發工具開發應用程式的技巧

109 實驗十三 GPS 和 GSM 通訊實驗 實驗目的實驗目的 1 瞭解 GPS 資料格式及開發應用 2 瞭解 GSM 資料格式及 AT 指令集的使用方法 3 掌握 Qt 開發方法與技巧 4 掌握 Qtopia 應用程式的設定過程 實驗原理實驗原理 1 GPS 資料格式 NMEA-0183 是美國國家海洋電子協會 (National Marine Electronics Association) 制定的 GPS 介面協 定標準 這種介面協定採用 ASCII 碼輸出, 協定定義了若干代表不同含義的語句, 語句格式如表 13-1 所示 [38] 表 13-1 NMEA-0183 語句格式 符號 (ASCII) 定義 HEX DEX 說明 $ 起始位 語句起始位 aaccc 位址域前兩位為位識別符, 後三位為語句名, 域分隔符 號 2C 44 域分隔符號 ddd ddd 資料塊發送的資料內容 * 校驗和符 2A 42 Hh 校驗和校驗和 <CR>/<LF> 終止符 0D,0A 13,10 Enter, 換行 星號分隔符號, 表明後面的兩位數是校驗 和 NMEA-0183 介面協定定義的主要語句有 :GGA GLL GSA GSV MSS RMC VTG ZDA 等 表 13-2 介紹這些語句所包含的具體內容 語句 [38] 表 13-2 常見 NMEA-0183 語句內容 語句內容 GGA GLL GSA GSV MSS UTC 時間 緯度值 經度值 定位狀態 ( 無效 單點定位 差分 ) 觀測的 GPS 衛星個數 HDOP 值 GPS 橢球高 天線架設高度 差分數據齡期 差分基準站編號 校驗和 UTC 時間 緯度值 經度值 定位狀態 ( 無效 單點定位 差分 ) 校驗和 定位模式 (M- 手動, 強制二維或三維定位 ;A- 自動, 自動二維或三維定位 ) 定位中使用的衛星 ID 號 PDOP 值 HDOP 值 VDOP 值 視野中的 GPS 衛星顆數 PRN 編號 衛星仰角 距正北的角度 ( 方位角 ) 信噪比 信標台的信號強度 信噪比 信標頻率 串列傳輸速率 通道號

110 RMC VTG ZDA EELiod Linux 實驗指導手冊 UTC 時間 定位狀態 (A- 可用,V- 可能有錯誤 ) 緯度值 經度值 對地速度 日期等 對地速度等 UTC 時間 年 月 日 當地時區 時區的分鐘值等 2 SMS 資料格式 ] GSM 規範對短訊息傳輸定義了三種控制協定 : 即二進位協定 ( 區塊模式 ), 基於字元的 AT 命令介面協 定 ( 文本模式 ) 和基於字元的十六進位編碼二進位傳輸塊介面協定 (PDU 模式 ) 區塊模式 (Block mode) 是使用二進位編碼來傳輸使用者資料的介面協定 為了提高可靠性, 它 帶有差錯保護, 適合於鏈結不完全可靠的地區, 尤其是要求控制遠端設備的情況 它屬於 GSM 第一階段的 短訊息傳輸介面協定 目前,PDU 已取代了區塊模式 文本模式 (Text mode) 是使用 AT 命令傳輸文本資料的介面協定 該模式適合於非智慧型終端 終端模擬器等 PDU 模式相當於電腦網路中的分組交換介面協定 這種傳送方式能夠很平穩地過渡到 GPRS, 因此 GSM 規範要求使用者盡可能地使用 PDU 模式處理短訊息 PDU 格式分為收短訊息和發短訊息兩種基本格式如圖 13-1 和 13-2 所示 圖 13-1 收短訊息訊息格式 圖 13-2 發短訊息訊息格式 SCA: 短訊息服務中心的號碼 PDU Type:PDU 的消息類型 MR: 短訊息的連續編號 ( 一般短訊息終端會對每次發送的 SMS-SUBMIT 類型的短訊息進行編號, 從 1 開始到 255 結束, 然後重新從 1 開始 ) OA: 短訊息發送端的位址, 即電話號碼 DA : 短訊息發送目的端的位址 PID : 協定指示參數 這個參數主要是提供給 SMSC 用於判斷如何處理這條短訊息 DCS : 資料編碼方案 指示了使用者資料 (User Data) 所使用的編碼方式 SCTS: 端消息中心的時間戳 指示了 SMSC 收到這條短訊息的時間

111 VP : 有效期 超過這段時間後, 短訊息在 SMSC 中不再有效 UDL : 使用者資料長度 指示了 UD 段的長度 UD : 使用者資料段 RP: 回覆路徑指示 標示存在著回覆路徑 UDHI : 使用者資料段報頭指示 標示 UD 段存在著資料報頭 SRI : 狀態報告指示 標示對方端消息實體是否要求有狀態報告 SRR : 狀態報告請求 標示本端要求有狀態報告 VPF: 有效期的格式 標示有效期欄位是否出現 MMS : 更多消息指示 標示是否有更多短訊息要發送 RD 拒絕重複指示 後文會有詳細說明 MTI : 消息類型指示 標示消息的類型 00 為 SMS-DELIVER 類型 01 為 SMS-SUBMIT 類型 下面以實例說明 PDU 串的結構和編碼方式 : 發送時資料格式 : 假設短訊息中心號碼是 : , 對方號碼是 : , 消息內容是 Hello! 從 終端發出的 PDU 串為 : F B F C8 32 9B FD 0E 01 對照規範, 具體的分析如表 13-3 所示 : 表 13-3 發送 PDU 時的資料格式 分段 含義 說明 08 SMSC 位址資訊的長度 共 8 個八位元位元組 ( 包括 91) 91 SMSC 位址格式 (TON/NPI) 用國際格式號碼 ( 在前面加 + ) F0 SMSC 位址 , 補 F 湊成偶數個 11 基本參數 (TP-MTI/VFP) 發送,TP-VF 用相對格式 00 消息基準值 (TP-MR) 0 0B 目標位址數位個數 共 11 位, 不包括補足的 F 91 目標位址格式 (TON/NPI) 用國際格式號碼 ( 在前面加 + ) F9 目標位址 (TP-DA) , 補 F 湊成偶數個 00 協定標識 (TP-PID) 是普通 GSM 類型, 點到點方式 00 使用者資訊編碼方式 (TP-DCS) 7-bit 編碼 00 有效期 (TP-VP) 5 分鐘 06 使用者資訊長度 (TP-UDL) 實際長度 6 個位元組 C8 32 9B FD 0E 01 使用者資訊 (TP-UD) Hello! 接受時 SMS 資料格式假設短訊息中心號碼是 : , 對方號碼是 , 消息內容是 華東! 手機接收到的 PDU 串 F0 84 0D F E 4E 1C 對照規範, 分析如表 13-4 所示 : 表 13-4 接收 PDU 時的資料格式

112 分段 含義 說明 08 SMSC 位址資訊的長度 共 8 個八位元位元組 ( 包括 91) 91 SMSC 位址格式 (TON/NPI) 用國際格式號碼 ( 在前面加 + ) F0 SMSC 位址 , 補 F 湊成偶數位 84 基本參數 (TP-MTI/MMS/RP) 接收, 無更多消息, 有回重置址 0B 回重置址數字個數 共 11 個十進位數字 ( 不包括 F ) 91 回覆位址格式 (TON/NPI) 用國際格式號碼 ( 在前面加 + ) F8 回覆位址 (TP-RA) , 補 F 湊成偶數位 00 協定標識 (TP-PID) 是普通 GSM 類型, 點到點方式 08 使用者資訊編碼方 (TP-DCS) UCS2 編碼 時間戳 (TP-SCTS) :36:45 +8 時區 06 使用者資訊長度 (TP-UDL) 實際長度 6 個位元組 53 4E 4E 1C 使用者資訊 (TP-UD) 華東! 下面介紹 7-bit 編碼的過程 例如 : 對英文短信 Hello! 進行編碼, 如表 13-5 所示 表 13-5 PDU 7-bit 編碼 源串 H e l l o! 源十六進位 0x48 0x65 0x6c 0x6c 0x6f 0x21 源二進位 編碼過程 目標二進位 目標十六進位 0xC8 0x32 0x9B 0xFD 0x0E 0x01 目標串 C8 32 9B FD 0E 01 需要指 出的是, 7-bit 的字 元集與 ANSI 標準字元集 不完全一 致, 在 0x20 以下有一些 可列印字元, 但英文字母 阿拉伯數字和常用符號的位置形式一樣 採用上面演算法收發純英文短訊息, 一般情況應該是夠用了 下面給出在嵌入式 Linux 系統嵌入式 Qt 開發平台中 7-bit 的 PDU 編解碼程式 7-bits 的 PDU 編碼副程式 int GSMCode::gsmEncode7bit(const char *psrc, unsigned char *pdst, int nsrclength) { int nsrc; // 原始字串的計數值 int ndst; // 目標編碼串的計數值 int nchar; // 當前正在處理的組內字元位元組的序號, 範圍是 0-7 unsigned char nleft=0; // 上一位元組殘餘的資料 nsrc = 0; // 計數值初始化 ndst = 0; while(nsrc<nsrclength) // 將原始串每 8 個位元組分為一組, 壓縮成 7 個位元組 { nchar = nsrc & 7; // 取原始字串的計數值的最低 3 位 if(nchar == 0)

113 } else { } psrc++; nsrc++; EELiod Linux 實驗指導手冊 nleft = *psrc; // 組內第一個位元組, 只是儲存起來, 待處理下一個位元組時使用 // 組內其他位元組, 將其左邊部分與殘餘資料相加, 得到一個目標編碼位元組 *pdst = (*psrc << (8-nChar)) nleft; nleft = *psrc>> nchar; // 將該位元組剩下的右邊部分, 作為殘餘資料儲存起來 pdst++; ndst++; } return ndst; // 返回目標串長度 // 修改目標串的指標和計數值 // 修改原始串的指針和計數值 如果短訊息中含有中文字符, 則必須採用 PDU 模式的 UCS2 編碼方式 按照 ISO/IEC10646 的規定,UCS2 編碼是將每個字元 (1-2 個位元組 ) 轉換為 16 位元 Unicode 寬字元 例如 : 短訊 息內容為 師大 A 的 UCS2 編碼, 如表 13-6 表 13-6 師大 A 的 GB2312 與 Unicode 編碼表 字元 GB2312 編碼 GB2312 編碼 (BIN) GB2312 編碼 Unicode 編碼 (BIN) 師 大 A CA E A B B A 在嵌入式 Qt 中, 中文是用兩個位元組表示 而英文只用一個位元組表示 因此在進行 PDU 編碼時, 需要進行中英文字元的識別, 若為英文字元在編碼時則前面加 00 即可, 而對中文字元進行 PDU 編碼, 把 單個位元組轉換成 16 進制 Unicode 碼實現 PDU 編碼, 解碼過程中英字元按相反的方法進行 下面給出嵌 入式 Linux 作業系統下嵌入式 Qt 中 PDU 編解碼的程式 : UCS2 的 PDU 編碼 Qt 副程式 : QString GSMCode:: gsmencodetounicode(qstring strsrc) { const QChar *qchar; QChar qtmp; QString str0, strout; ushort num; qchar=strsrc.unicode();// 將字元型資料轉換為 Unicode 碼 int strlength=strsrc.length();// 獲取字元資料的長度 for(int i=0;i<strlength;i++) { qtmp =(QChar)*qchar++;

114 } } num= qtmp.unicode();// 將字元型資料轉換為短無符號數 if(num<255) strout+="00"; // 英文字元前加 "00" str0=str0.setnum(num,16);// 變成十六進位數 strout+=str0; return strout; 常用的與短訊息有關的 AT 指令可參見表 13-7: [42][43] 表 13-7 常用與短訊息相關的 AT 指令 AT 指令功能 AT+CMGC Send an SMS command( 發出一條短訊息命令 ) AT+CMGD Delete SMS message( 刪除 SIM 卡記憶體的短訊息 ) EELiod Linux 實驗指導手冊 AT+CMGF Select SMS message formate( 選擇短訊息資訊格式 :0-PDU;1- 文本 ) AT+CMGL List SMS message from preferred store( 列出 SIM 卡中的短訊息 PDU/text: 0/ REC UNREAD - 未讀,1/ REC READ - 已讀,2/ STO UNSENT - 待發,3/ STO SENT - 已發,4/ ALL - 全部的 ) AT+CMGR Read SMS message( 讀短訊息 ) AT+CMGS Send SMS message( 發送短訊息 ) AT+CMGW Write SMS message to memory( 向 SIM 記憶體中寫入待發的短訊息 ) AT+CMSS Send SMS message from storage( 從 SIM 記憶體中發送短訊息 ) AT+CNMI New SMS message indications( 顯示新收到的短訊息 ) AT+CPMS Preferred SMS message storage( 選擇短訊息記憶體 ) AT+CSCA SMS service center address( 短訊息中心位址 ) AT+CSCB Select cell broadcast messages( 選擇蜂巢廣播消息 ) AT+CSMP Set SMS text mode parameters( 設定短訊息文本模式參數 ) AT+CSMS Select Message Service( 選擇短訊息服務 ) 3 GSM 和 GPS 程式碼的編譯 (1) 將光碟提供的 GSM_GPS 目錄下的程式碼複製到硬碟中 ( 假設將程式複製在 /root/work 目錄下 ) (2) 設定交叉編譯工具參數 (arm-linux-g++) (3) 對程式碼進行編譯 [root@localhost work]$cd GSMtest [root@localhost GSMtest]$make (4) 將編譯好的程式 GSMtest 下載到開發板的 /usr/qpe/bin 目錄下 (5) 在目標板上利用 chmod 命令修改 GSMtest 的屬性 [root@bin]$ chmod 755 GSMtest (6) 在開發板的 /usr/qpe/application 目錄下新建 GSMtest.desktop 檔 ( 內容如下 ), 或將 GSM_GPS 目錄下的 GSMtest.desktop 檔下載到開發板的 /usr/qpe/application 目錄下

115 [Desktop Entry] Comment=A GSM and GPS Program Exec=GSMtest Icon=Clock Type=Application Name=Clock Name[zh_CN]=GSM 和 GPS 測試程式 實驗儀器實驗儀器 1 裝有 Linux 作業系統的 PC 一台 ; 2 XSBase270 或 XSBase255 ARM 實驗開發平台一套 實驗內容實驗內容 5 編譯基於 ARM 開發板平台的 GSM 和 GPS 通訊程式碼, 寫出編譯過程 6 將編譯好的基於 ARM 開發板的 GSM 和 GPS 通訊程式碼和 GSMtest.desktop 檔下載到開發板中, 將 GPS 模組連接到串列埠 2,GSM 模組連接到串列埠 3, 重啟開發板系統, 觀察程式執行情況, 並分析 GSMtest.desktop 的作用 7 分析 GPS 通訊程式的資料格式解析程式碼, 畫出程式流程圖 8 寫出將應用程式新增到 qtopia 的過程和步驟 9 分析 GSM 資料 7-bits 的 PDU 解碼副程式和 UCS2 的 PDU 解碼 Qt 副程式, 分別畫出程式流程圖 思考題思考題 1 根據 GSMtest 程式中的程式和 AT 指令集, 編寫一個對已經讀過的短信內容進行刪除操作的函數 2 根據 GSP 資料格式, 編寫一個將格林維治標準時間轉換為北京標準時間的轉換函數, 並在開發板上進行測試 3 分析 Unicode 編碼和 7bits 八位元編碼的區別

116 實驗十四 Webserver 的移植與網路通訊實驗 實驗目的實驗目的 1 瞭解 Webserver 在目標平台的移植 2 瞭解 TCP/IP 協定格式 3 掌握網路通訊的開發方法 4 掌握 Qt 開發方法及技巧 實驗原理實驗原理 1 Web 基本原理介紹 Web 伺服器也被稱為 HTTP 伺服器, 它通過 HTTP 協定與使用者端通訊,HTTP 協定的作用原理包括四個步驟 : 1. 連接 :Web 流覽器與 Web 伺服器建立連接 ; 2. 請求 :Web 流覽器通過 socket 向 Web 伺服器提交請求 ; 3. 應答 :Web 流覽器提交請求後, 通過 HTTP 傳送給 Web 伺服器,Web 伺服器接到請求後, 進行事務處理, 處理結果又通過 HTTP 傳回給 Web 流覽器, 從而在 Web 流覽器上顯示出所請求的頁面 ; 4. 關係連接 : 當應答結束後,Web 流覽器與 Web 伺服器必須斷開, 以保證其他 Web 流覽器能夠與 Web 伺服器建立連接 例如 : 如果客戶機與 Web 伺服器 建立連接, 就會向 Web 伺服器發送 GET 命令 :GET /mydir/index.html HTTP/1.0, 同時主機名為 的 Web 伺服器從它的檔案空間中搜索子目錄 mydir 的檔 index.html 如果找到該檔,Web 伺服器把該檔內容傳送給相對應的 Web 流覽器 為了告知 Web 流覽器傳送內容的類型,Web 伺服器首先傳送一些 HTTP 頭資訊, 然後傳送具體內容 ( 即 HTTP 體資訊 ),HTTP 頭資訊和 HTTP 體資訊之間用一個空行分開 (1) 常用的 HTTP 標頭資訊 1. HTTP OK: 這是 Web 伺服器應答的第一行, 列出伺服器正在執行的 HTTP 版本號和應答程式 程式 200 OK 表示請求完成 ; 2. MIME_Version:1.0: 指示 MIME 類型的版本 ; 3. content_type: 指示 HTTP 體資訊的 MIME 類型 如 :content_type:text/html 指示傳送的資料是 HTML 檔案 ; 4. content_length: 指示 HTTP 體資訊的長度 ( 位元組 ); (2)HTTP 請求一個 HTTP 請求包含三個部分 : 1. Method-URI-Protocol/Version 方法 - 位址 - 版本 ; 2. Request header 請求標頭 ; 3. Entity body 請求實體 (3)HTTP 回應與 HTTP 請求相似,HTTP 回應也由三部分組成 : 1. Protocol-Status / code-description 協定狀態 / 描述程式 ;

117 2. Response headers 回應標頭 ; 3. Entity body 回應實體 2 webserver 的移植 (1) 下載 webserver 程式碼資源 EELiod Linux 實驗指導手冊 從 網站上下載 Webserver 程式碼資源壓縮檔 webs216.tar.gz, 利用 tar 命令解壓 web216.tar.gz 後產生 ws 資料夾 [root@localhost work]$tar xvzf webs216.tar.gz (2) 編譯 webserver 進入 ws030325/linux 目錄 ; [root@localhost work]$cd ws [root@localhost ws030325]$cd LINUX 修改編譯檔 Makefile, 1) 增加交叉編譯器 arm-linux-gcc 和交叉編譯歸檔器 arm-linux-ar CC=arm-linux-gcc AR=arm-linux-ar 2) 將 Makefile 中 cc 編譯器改為交叉編譯器 ; 即將 Makefile 中 cc -c -o $@ $(DEBUG) $(CFLAGS) $(IFLAGS) $< 修改為 $(CC) -c -o $@ $(DEBUG) $(CFLAGS) $(IFLAGS) $< 利用 make 工具進行編譯, 並可利用 file 命令查看產生的目標檔 webs 的屬性 ( 如圖 14-1 所示 ) [root@localhost LINUX]$make [root@localhost LINUX]$file webs 3 下載與下載與執行 圖 14-1 webs 的檔案屬性 (1) 返回上級目錄並對 web 目錄的檔打包, 在 ws 目錄下得到 web.tar 壓縮檔 ; [root@localhost LINUX]$cd.. [root@localhost ws030325]$tar cvf web.tar web/* (2) 檔案下載 利用 minicom 進入目標平台, 用 zmodem 工具將壓縮檔 web.tar 和 LINUX 目錄下的二進位檔 webs 下 載到目標板根目錄下 ; 在目標板上利用 tar 命令對 web.tar 檔進行解壓, 可以在目標平台的根目錄下得到 web 的資料夾 ; 並用 chmod 命令修改 webs 的檔屬性

118 xvf web.tar 755 webs (3) 網路設定 分別利用 ifconfig 和 hostname 命令檢查目標板的 IP 位址和目標板名稱 ; [root@51board~]$ifconfig [root@51board~]$hostname 開發板預設 ip 為 輸入 hostname 指令後開發板會回應目前的主機名稱例如 : 51Board 修改開發板的 /etc/hosts 檔案新增一行 EELiod Linux 實驗指導手冊 Board 在目標板或主機 (PC) 上利用 ping 命令檢查兩者之間的網路連接情況 ( 假設主機的 IP 位址為 ); [root@51board~]$ping (4) webserver 的執行 在目標板上執行 webs, 開啟 webserver 服務 ; [root@51board~]./webs 在主機上通過 Web 流覽器輸入目標板的 IP 位址, 就可以看到 webserver 主頁中的內容 ; 4 基於 qt 的網路開發 Qt 提供的網路開發類相當豐富, 有基於 TCP 套接字的 QSocket 類和 QserverSocket 類 ;QSocket 類提 供了一個有緩衝的 TCP 連接, 該類與網路傳輸有關的主要信號有 : 網路連接信號 connected() 網路斷開 信號 connectionclosed() 讀數據信號 readyread() 發現主機信號 hostfound() 資料寫到網路信號 byteswritten ( int nbytes ) 連接出錯信號 error(int) 延遲關閉完成信號 delayedclosefinished (), 一旦網路的某一種狀態發生 ( 如網路斷開 ), 信號就會發送 (connectionclosed()), 再通過信號與槽函數相關聯進行處理 QSocket 類主要成員函數介紹 : connecttohost ( const QString & host, Q_UINT16 port ), 試圖連接主機 host 的指定埠 port 並 且立即返回 任何連接或者正在進行的連接被立即關閉, 同時 QSocket 進入 HostLookup 狀態 當查 詢成功, 它發射 hostfound(), 開始一個 TCP 連接, 並且進入 Connecting 狀態 最後, 當連接成功時, 它發射 connected() 並且進入 Connected 狀態 如果在任何一個地方出現錯誤, 它發射 error() host 可以是一個字串形式的 IP 位址, 也可以是一個 DNS 名稱 如果需要 QSocket 將會進行一個普通的 DNS 查找 bytesavailable () const, 返回可以讀取的進入資料的位元組數 waitformore ( int msecs ) const, 為了得到更多的可用資料, 等待 msecs 毫秒 如果 msecs 為 -1, 這個調用將會不確定地阻塞 bytestowrite () const, 返回正在等待被寫的資料的位元組數 ; readblock ( char * data, Q_ULONG maxlen ), 從套接字中讀取最多 maxlen 位元組到 data 中並且返回讀取的位元組數 如果發 生錯誤, 返回 -1; writeblock ( const char * data, Q_ULONG len ), 從 data 中向套接字中寫入 len 位元組並且返回 所寫的位元組數 如果發生錯誤, 返回 -1 QServerSocket 類提供了基於 TCP 連接的伺服器, 在構造函數中設定 IP 位址和埠號, 一旦設定好 IP 位址和埠號,QServerSocket 能偵聽所有連到伺服器的使用者, 由成員函數 newconnection(int socket) 對最新連接到的服務使用者作出反應 可以通過 QSocket 類的 readblock( char * data, Q_ULONG maxlen ) 和 writeblock ( const char * data, Q_ULONG len ) 實現網路資料傳輸, 也可利用 QDataStream 類的 readrawbytes ( char * s, uint len ) writerawbytes ( const char * s, uint len ) 操作重載函 數 << 和 >> 等函數實現網路資料傳輸

119 在嵌入式 Qt 開發基於 Linux 的網路資料傳輸時, 先要對網路套接字 qsocket 和用於服務端的 qsocketserver 進行定義和關聯, 如果伺服器已處於執行時, 使用者端可以通過 TCP/IP 協定資料傳送 (1) 基於 PC 平台的 server 網路程式編譯 將光碟提供的 server 的程式碼複製到硬碟中 ( 假設將程式複製在 /root/work 目錄下 ) 對程式進行編譯 [root@ localhos work]$cd server [root@localhost server]$make 在 PC 上執行 server 程式, 執行介面如圖 14-1 所示 [root@localhost server]$./server 圖 14-2 server 執行介面 (2) 基於目標平台的 client 網路程式編譯 ( 若想修改預設的 ip 請修改 frmclient.cpp) 將光碟提供的 client.tar 的程式碼複製到硬碟中 ( 假設將程式複製在 /root/work 目錄下 ) 設定交叉編譯工具參數 (arm-linux-g++) 對程式碼進行編譯 [root@localhost work]$cd client [root@localhost work]$export QPEDIR=/root/work/qt/qtopia-free [root@client]$make 將編譯好的程式 client 下載到開發板的 /usr/qpe/bin 目錄下 在目標板上利用 chmod 命令修改 client 的屬性 [root@bin]$ chmod 755 client 在開發板的 /usr/qpe/apps/applications 目錄下新建 client.desktop 檔 ( 內容如下 ); [Desktop Entry] Comment=A network Program Exec=client Icon=Clock Type=Application Name=Clock Name[zh_CN]= 網路通訊測試 (3) 網路通訊程式測試

120 用交叉網路線 ( 或利用無線網路 ) 將主機和目標板的網路連通 ( 程式設定主機的 IP 位址為 , 如果不是該 IP 位址, 可通過 ifconfig 進行修改 ); 在主機上執行 server 程式 ; 在目標板上執行 client 程式 ; 點擊目標板 client 程式介面的 connect Net 按鈕, 進行網路連接 ; 點擊目標板 client 程式介面的 Send Text 按鈕,client 程式將文本框中的內容通過網路傳輸到主機上, 並在 server 程式介面上的文本框上顯示 ; 在文本框中輸入圖片檔的位置, 點擊目標板 client 程式介面的 Send Picture 按鈕,client 程式將圖片檔通過網路傳輸到主機上, 並在 server 程式介面上顯示 ; 實驗儀器實驗儀器 1 裝有 Linux 作業系統的 PC 一台 ; 2 XSBase270 或 XSBase255 ARM 實驗開發平台一套 實驗內容實驗內容 1 將 webserver 程式碼移植到目標平台上, 寫出編譯過程 ; 2 將系統提供的 client 根源程式編譯到目標板上, 寫出編譯過程 ; 3 分析系統提供的 server 根源程式, 寫出利用 qt 進行網路開發的基本步驟 ; 4 將編譯好的 client 程式下載到目標板上, 進行無線網路通訊測試實驗 思考題思考題 1 分析 client 根源程式, 如果需要從文本框中手動輸入主機 ( 伺服器 ) 的 IP, 應怎樣修改根源程式 ; 2 對網路進行怎樣的設定才能實現無線網路通訊 ; 3 分析 client 和 server 程式碼, 如果需要 server 和 client 程式相互進行接受與發送資料, 應怎樣修改根源程式?( 根源程式架構不能改變 )

121 實驗十五 USB 攝影機影機實驗 實驗目的實驗目的 1 掌握 USB 攝影機和 V4L 視訊驅動的設定方法 2 瞭解 OpenCV 的移植過程及開發方法 3 掌握 Qt 開發技巧 實驗原理實驗原理 USB 攝影機以其良好的性能和低廉的價格得到廣泛應用 同時因其靈活 方便的特性, 易於集成到嵌入式系統中, 現有的符合 Video for Linux 標準的驅動程式配合通用應用程式, 可以實現 USB 攝影機視訊資料的採集及應用開發 攝影機屬於視訊類設備 在目前的 Linux 核心中, 視訊部分的標準是 Video for Linux( 簡稱 V4L) 這個標準其實定義了一套介面, 核心 驅動 應用程式以這個介面為標準進行交流 目前的 V4L 涵蓋了視 音頻流捕捉及處理等內容,USB 攝影機也屬於它支援的範疇 1 Video4Linux 和 USB 攝影機驅動驅動設定如果需要在 Linux 作業系統中使用 USB 攝影機進行視訊資料獲取, 則必須在進行核心設定時, 應檢查 Linux 核心中是否已經新增了對 Video4Linux 驅動和對 USB 攝影機驅動模組的支援 利用 Linux 核心設定 make menuconfig 命令對 Video4Linux 支援驅動進行設定, 選中多媒體設備選項 Multimedia device-> ( 如圖 15-1 所示 ) 按 Enter, 進入多媒體設備設定介面 ( 如圖 15-2 所示 ), 在多媒體設定介面中, 選中 Video For Linux, 就可以使核心實現對 Video4Linux 驅動的支援, 為視訊採集設備提供開發介面

122 圖 15-1 核心設定主介面 EELiod Linux 實驗指導手冊 圖 15-2 核心設定 - 多媒體設備設定介面 設定好核心對 Video4Linux 驅動後, 返回核心設定主介面, 選中 USB 支援選項 ( 如圖 15-3 所示 ) USB support > 按 Enter, 進入 USB 支援設定介面 圖 15-3 核心設定主介面 -USB 支援 在 USB 支援設定介面中, 選中 USB Multimedia device 選項下的 USB OV511 Camera support, 使核心中加入 OV511 介面晶片的 USB 數位攝影機的驅動支援 ( 如圖 15-4 所示 )

123 圖 15-4 OV511 USB 攝影機驅動設定介面 2 PC 端 OpenCV 的安裝自網路下載 open tar.gz 以及修正 patch opencv ffmpeg.patch 解壓縮後, 先上 patch, 再編譯安裝 3 OpenCV 移植 OpenCV(Intel Open Source Computer Vision Library) 是 Intel 公司面向應用程式開發者開發的電腦視覺庫 相對於其他圖像函式庫,OpenCV 是一種程式開放式的函式庫, 對非商業用途和商業用途都免費, 開發者可以自由地調用函式庫中的相關處理函數 OpenCV 中包含 300 多個處理函數, 具備強大的圖像和矩陣運算能力, 可以大大減少開發者的開發工作量, 有效提高開發效率和程式執行的可靠性 另外, 由於 OpenCV 具有很好的移植性, 開發者可以根據需要在 MS-Windows 和 Linux 兩種平台進行開發 (1) configure 檔的修改由於 OpenCV 中用於圖像顯示的表單採用 GTK+2.0 編寫的, 而在目標平台中只有 GTK+1.2 共用函式庫, 為避免交叉編譯錯誤, 應將 configure 檢查 GTK+2.0 的語句注釋掉 實際上, 通過對 OpenCV 程式的分析, 發現只有 highgui 的 ShowImage 函數用到了 GTK+2.0 中表單控制項, 該函數主要完成將圖像顯示在 GTK 表單上 通過實驗發現, 注釋掉檢查 GTK+2.0 的語句後, 只是在開發時不能使用 ShowImage 函數, 對 OpenCV 的其他功能並沒有受影響 ( 具體注釋掉的內容參考光碟所提供的實驗十五程式中的 opencv-arm 檔中的 configure.patch 檔內容 ) (2) 交叉編譯請使用光碟提供的 opencv-arm( 有修正過 ) 壓縮檔解壓到工作目錄中, 並加上 patchopencv-0.97-ffmpeg.patch 將 cv.h 及 constants.h copy 到 opencv-0.9.7/interfaces/swig/filtered/ 底下接下來利用 configure 對系統進行設定, 然後執行編譯和安裝命令 [root@localhost opencv-arm]$./configure - host=arm-linux [root@ocalhost opencv-arm]$export QTDIR=/root/work/qt/qt [root@ocalhost opencv-arm]$export QPEDIR=/root/work/qt/qtopia-free [root@ocalhost opencv-arm]$make [root@ocalhost opencv-arm]$make install

124 執行 make install 命令後,OpenCV 將編譯好的的函式庫檔儲存在 /usr/local/lib 目錄下, 標頭檔被複製 在 /usr/local/include/opencv 目錄中 主要的函式庫檔 :libhighgui.so libhighgui.la libcxcore.so libcxcore.la libcvaux.so libcvaux.la libcv.so libcv.la 及相對應的符號鏈結 (3) 函式庫檔案的下載 將編譯好的函式庫檔下載到目標平台上 /usr/qpe/lib 目錄中, 並設定 OpenCV 所需的環境參數 LD_LIBRARY_PATH=/usr/qpe/lib:$LD_LIBRARY_PATH (4) 基於 OpenCV 的視訊採集 OpenCV 提供了 cvcapturefromcam 函數用作初始化攝影機 其函數原形為 : CvCapture* cvcapturefromcam( int index ), 其中參數 index 為系統的 USB 攝影機的序號, 如果只有一個攝影機, 則 index 為 0; 分配好 CvCapture 後, 便可用 cvsetcaptureproperty 來設定 USB 攝影機的屬性, 其原形為 :int cvsetcaptureproperty( CvCapture* capture, int property_id, double value ), 實例如下 : capture = cvcapturefromcam(index); if (!capture) 攝影機初始化成功後, 便可使用 cvgrabframe 函數從攝影機抓取圖像資料框,cvGrabFrame 原形為 int cvgrabframe( CvCapture* capture ); 再利用 cvretrieveframe 函數取回獲取的框,cvRetrieveFrame 函數返回 的資料為 OpenCV 自定義的 IplImage 結構體, cvretrieveframe 的原型為 IplImage* cvretrieveframe( CvCapture* capture ) 由於 IplImage 裡的圖像資料是 24 位真彩的三通道 BGR, 而在 QImage 為 32 位真彩的四通道 ( 除 BGR 外, 還有一個 a 通道 ), 所以在 Qt 中, 必須要對 IplImage 圖像資料結構進行轉換才能進行顯示處理 轉換函數 char *frmtest::bgr24_bgr32(int width,int height, char *src) { char *dst=0, *tmp; } return FALSE; result=cvsetcaptureproperty(capture,cv_cap_prop_frame_width, 160); if (result < 0) return FALSE; result = cvsetcaptureproperty(capture, CV_CAP_PROP_FRAME_HEIGHT, 120); if (result < 0) return FALSE; dst=(char *)malloc(width*height*4); tmp=dst; for(int y=0; y<height;y++) { for(int x=0; x<width; x++){ } } return(tmp); for(int i=0;i<3;i++) 4 USB 攝影機程式程式編譯 *dst++=*src++; *dst++=0; (1) 在 /usr/local/ 目錄下新建 opencvlib_arm 目錄 ; 將編譯好的基於目標平台的 OpenCV 的函式庫檔及相 關符號鏈結複製到 opencvlib_arm 目錄下或將光碟提供的 opencvlib_arm.tar.gz 檔複製到 /usr/local/ 目錄下並

125 解壓 ; EELiod Linux 實驗指導手冊 (2) 將光碟提供的實驗十五程式碼 USBcamera-arm.tar.gz 複製到 linux 作業系統中的某一目錄下並解壓, 然後利用 tmake 產生 Makefile 編譯檔 ( 假設交叉編譯環境參數已設定設定 ); [root@localhost work]$tar zxvf USBcamera-arm.tar.gz [root@localhost work]$cd USBcamera-arm [root@localhost USBcamera-arm]$tmake o Makefile OpenCVcam.pro (3) 修改 Makefile 檔, 增加 OpenCV 共用函式庫和標頭檔目錄搜索路徑和共用函式庫的鏈結 ; LIBS = -L/usr/local/opencvlib_arm -lcxcore -lcv -lhighgui -lcvaux INCPATH = -I/usr/local/include/opencv (4) 利用 make 命令編譯程式碼 [root@localhost USBcamera_arm]$make (5) USB 攝影機程式測試 將編譯好的 USB 攝影機程式 OpenCVcam 下載目標板的 /usr/qpe/bin 目錄下 ; 在目標板上利用 chmod 命令修改 OpenCVcam 的屬性 [root@bin]$ chmod 755 OpenCVcam 將基於 ARM 開發平台的 OpenCV 共用函式庫下載到目標板的 /usr/qpe/lib 目錄下 ; 在開發板的 /usr/qpe/apps/applications 目錄下新建 OpenCVcam.desktop 檔 ( 內容如下 ) ; [Desktop Entry] Comment=A USB camera Program Exec=OpenCVcam Icon=Clock Type=Application Name=Clock Name[zh_CN]=USB 攝影機 重新啟動目標平台, 接上 OV511 晶片組的 USB 攝影機, 執行 USB 攝影機程式 實驗儀器實驗儀器 1 裝有 Linux 作業系統的 PC 一台 ; 2 XSBase270 或 XSBase255 ARM 實驗開發平台一套 實驗內容實驗內容 1 在 linux 核心中設定 USB 攝影機和 V4L 視訊驅動, 寫出設定過程 2 編譯基於 PC 和目標平台的 OpenCV 程式碼, 寫出編譯過程和注意事項 ; 3 編譯光碟提供的基於目標平台的 USB 攝影機測試程式, 並下載到目標板上執行, 寫出編譯和環境參數設定過程 ; 思考題思考題 1 利用 qt 編寫一個基於 PC 平台的 USB 攝影機測試程式, 並編譯執行 ; 2 將上述編好的 USB 攝影機測試程式移植到目標平台上執行 ; 3 Windows 版本的 OpenCV 中有個專門針對攝影機的程式 cvcam, 嘗試將其交叉編譯到目標平台

126 實驗十六嵌入式資料庫移植實驗 實驗目的實驗目的 1 瞭解嵌入式資料在嵌入式設備中應用 2 瞭解 SQLite 的移植和編譯過程 3 掌握嵌入式資料庫的開發方法 實驗原理實驗原理 1 SQLite 介紹 SQLite 是 D. Richard Hipp 用 C 語言編寫的開放嵌入式資料庫引擎 它是完全獨立的, 不具有外部 依賴性 佔用資源非常低, 在嵌入式設備中, 只需要幾百 K 的記憶體就夠了 它能夠支援 Windows/Linux 等主流作業系統, 可與 TCL PHP Java 等程式語言相結合, 提供 ODBC 介面, 其處理速度甚至令開放世 界著名的資料庫管理系統 Mysql PostgreSQL 望塵莫及 SQLite 對 SQL92 標準的支援包括索引 限制 觸發和查看, 支援原子的 一致的 獨立和持久 (ACID) 的事務 在內部,SQLite 由 SQL 編譯器 核心 後端以及附件幾個元件組成, 如圖 16-1 所示 SQLite 通 過利用虛擬機和虛擬資料庫引擎 (VDBE), 使調試 修改和擴充 SQLite 的核心變得更加方便 所有 SQL 語句都被編譯成易讀的 可以在 SQLite 虛擬機中執行的程式集 2 sqlite 的移植 (1) 程式碼程式碼的下載 圖 16-1 SQLite 的內部結構 從 下載 sqlite 的程式 sqlite tar.gz, 將下載的程式包解開,

127 將產生 sqlite 目錄 (2) 對設定設定檔 configure 的修改 EELiod Linux 實驗指導手冊 在交叉編譯 sqlite 時, 編譯工具檔的編譯器採用的是 gcc, 而不是 arm-linux-gcc, 如果直接採用./configure --host=arm-linux 命令對系統進行編譯設定,configure 設定檔在檢查編譯器時會錯, 所以應將 configure 設定 檔中的交叉編譯的檢查語句注釋掉, 然後再手動增加編譯工具檔的編譯器 gcc 將 configure 檔中的如下交叉編譯器的檢查語句注釋掉 ( 前面加 # 字元 ): # if test "$cross_compiling" = "yes"; then # { { echo "$as_me:$lineno: error: unable to find a compiler for building build tools" &5 #echo "$as_me: error: unable to find a compiler for building build tools" >&2;} # { (exit 1); exit 1; }; } # fi --- #else # test "$cross_compiling" = yes && # { { echo "$as_me:$lineno: error: cannot check for file existence when cross compiling" &5 #echo "$as_me: error: cannot check for file existence when cross compiling" >&2;} # { (exit 1); exit 1; }; } --- #else # test "$cross_compiling" = yes && # { { echo "$as_me:$lineno: error: cannot check for file existence when cross compiling" &5 #echo "$as_me: error: cannot check for file existence when cross compiling" >&2;} # { (exit 1); exit 1; }; } 修改完畢後, 在程式碼目錄下執行編譯設定命令 [root@localhost sqlite-3.3.5]$./configure --host=arm-linux --disable-tcl (3) 修改 Makefile 檔 將 Makefile 檔中編譯工具的編譯器修改為 gcc, 即將 Makefile 中的 BCC = arm-linux-gcc -g -O2 修改為 BCC = gcc -g -O2 (4) 編譯和安裝 將 Makefile 檔修改後, 在程式碼目錄中執行 make 編譯命令, 編譯後的函式庫檔和可執行檔儲存在當 前目錄下的隱藏資料夾.libs 中, 然後執行 make install 安裝命令, 共用函式庫檔 libsqlite3.so 及相關的 符號鏈結檔複製在 /usr/local/lib 目錄下, 標頭檔 sqlite3.h 複製在 /usr/local/include 目錄中 [root@localhost sqlite-3.3.5]$make [root@localhost sqlite-3.3.5]$make install (5) 編譯腳本的編寫 為了不修改設定檔 configure 和編譯檔 Makefile, 可以將編譯過程寫成腳本的形式 Makefile.sh 或自己 重寫編譯檔 Makefile.mk, 下麵給出編譯腳本 Makefile.sh 和 Makefile.mk 的具體內容 ( 見光碟中實驗十六程 式碼目錄下 sqlite arm.tar.gz 中的內容 ) 和使用方法 編譯腳本的使用方法 編譯腳本是一個可執行的檔, 在程式碼所在的目錄下利用文書編輯器新建編譯腳本檔 Makefile.sh( 內 容如下 ), 然後利用 chmod 命令將其屬性改成可執行檔並執行腳本即可完成上述編譯的全過程 [root@localhost sqlite-3.3.5] chmod 755 Makfile.sh [root@localhost sqlite-3.3.5]./makfile.sh Makefile.sh 的內容 :

128 #!/bin/sh #compile script for sqlite echo "config..." export config_build_cc=gcc && \ export config_target_cc=arm-linux-gcc && \ export ARCH=arm &&\ echo ac_cv_header_readline_h=yes >$ARCH-linux.cache && \./configure --host=$arch-linux --disable-tcl --cache-file=$arch-linux.cache && \ echo "config done" make && make install && \ echo "build done" arm-linux-strip.libs/libsqlite3.so.* if [ -e Makefile ]; then make distclean; fi && \ echo "clean done" 編譯檔 Makefile.mk 的使用方法本系統編寫的編譯檔 Makefile.mk 是一個類似於 Makefile 的編譯檔 在程式碼所在的目錄下利用文書編輯器新建編譯檔 Makefile.mk( 內容如下 ), 然後利用 make all f Makefile.mk 即可完成上述編譯的全過程, 也可根據 Makefile 的偽目標編譯方法逐項進行編譯 ( 參考 Makfile 實驗 ) [root@localhost sqlite-3.3.5] make all f Makfile.mk Makefile.mk 的內容 : #compile file Makefile.mk for sqlite all: clean config build config: echo "config parament..." export config_build_cc=gcc && \ export config_target_cc=arm-linux-gcc && \ export ARCH=arm &&\ echo ac_cv_header_readline_h=yes >$$ARCH-linux.cache && \./configure --host=$$arch-linux --disable-tcl --cache-file=$$arch-linux.cache && \ echo "config done" build : make && make install && \ echo "build done" arm-linux-strip.libs/libsqlite3.so.* clean: if [ -e Makefile ]; then make distclean; fi && \ echo "clean done" 3 sqlite 使用方法 (1) 重要函數的介紹利用 sqlite 編寫資料庫程式, 首先應利用打開資料庫函數 int sqlite3_open( const char *filename, sqlite3 **ppdb ) 將資料函式庫檔打開, 如果該資料函式庫檔不存在, 則建立一個空資料庫, 並返回對應資料庫的

129 控制碼參數 ppdb, 同時如果打開資料庫返回 SQLITE_OK 則表示成功打開資料庫, 否則操作失敗 成功打開資料庫後, 便可利用執行 SQL 語句的函數 int sqlite3_exec( sqlite3*, const char *sql, sqlite3_callback, void *,char **errmsg) 對資料庫進行建立資料庫表 資料庫查詢 刪除和更新資料庫記錄等 等操作, 也可利用獲取資料庫記錄內容的 SQL 執行函數 int sqlite3_get_table(sqlite3*,const char *sql,char ***resultp,int *nrow, int*ncolumn, char **errmsg ) 對資料庫記錄內容進行相對應的顯示操作 在對資料庫操作完畢後, 應利用關閉資料庫函數 int sqlite3_close(sqlite3 *) 將先前打開的資料庫關閉 有關 SQLite 的其他操作參考 SQLite 相關檔案 (2) sqlite 的使用方法 利用 Qt 編寫基於 ARM 開發板的 SQLite 資料庫管理程式, 可以先在 PC 上完成仿真執行, 然後再利用 交叉編譯工具進行編譯, 下面以實例具體介紹基於 PC 和 ARM 的兩種不同平台的編譯方法 基於 PC 平台的編譯步驟 : a 在 /usr/local/ 目錄下新建 sqlitelib_pc 目錄 ; 將編譯好的基於 PC 平台的 sqlite 的函式庫檔及相關符號鏈結複製到 sqlitelib_pc 目錄下或將光碟提供的 sqlitelib_pc.tar.gz 檔複製到 /usr/local/ 目錄下並解壓 ; [root@localhost local]$tar xzvf sqlitelib_arm.tar.gz b 將光碟提供的實驗十六程式碼 database_pc.tar.gz 複製到 linux 作業系統中的某一目錄下並解壓, 然後利用 qmake 產生 Makefile 編譯檔 ; [root@localhost work]$tar zxvf database_pc.tar.gz [root@localhost work]$cd database_pc [root@localhost database_pc]$qmake o Makefile dbtest.pro c 修改 Makefile 檔, 增加 sqlite 共用函式庫目錄搜索路徑和共用函式庫的鏈結 ; LIBS = -L/usr/local/sqlitelib_pc -lsqlite3 d 利用 make 命令編譯程式碼 [root@localhost database_pc]$make e 設定 sqlite 執行參數, 並在 PC 平台執行資料庫測試程式, 如圖 16-2 所示 [root@localhost database_pc]$export LD_LIBRARY_PATH=/usr/local/sqlitelib_pc:$LD_LIBRARY_PATH [root@localhost database_pc]$./dbtest

130 圖 16-2 sqlite 執行介面 基於 ARM 平台的編譯步驟 a 在 /usr/local/ 目錄下新建 sqlitelib_arm 目錄 ; 將編譯好的基於 ARM 平台的 sqlite 的函式庫檔及相關符號鏈結複製到 sqlitelib_arm 目錄下或將光碟提供的 sqlitelib_arm.tar.gz 檔複製到 /usr/local/ 目錄下並解壓 ; b 將光碟提供的實驗十六程式碼 database_arm.tar.gz 複製到 linux 作業系統中的某一目錄下並解壓, 然後利用 tmake 產生 Makefile 編譯檔 ( 假設交叉編譯環境參數已設定設定 ); [root@51board~]$tar zxvf database_arm.tar.gz [root@51board~]$cd database_arm [root@localhost database_arm]$tmake o Makefile dbtest.pro c 修改 Makefile 檔, 增加 sqlite 共用函式庫和標頭檔目錄搜索路徑和共用函式庫的鏈結 ; LIBS = -L/usr/local/sqlitelib_arm -lsqlite3 INCPATH = -I/usr/local/include d 利用 make 命令編譯程式碼 [root@localhost database_arm]$make e ARM 程式的測試執行 將編譯好的資料庫程式 dbtest 和資料函式庫檔 test.db 下載目標板的 /usr/qpe/bin 目錄下 ; 在目標板上利用 chmod 命令修改 dbtest 的屬性 [root@bin]$ chmod 755 dbtest 將基於 ARM 開發平台的 sqlite 共用函式庫下載到目標板的 /usr/qpe/lib 目錄下 ; 在開發板的 /usr/qpe/app/applications 目錄下新建 dbtest.desktop 檔 ( 內容如下 ) ;

Microsoft PowerPoint - 9-Linux Kernel.ppt

Microsoft PowerPoint - 9-Linux Kernel.ppt Building Linux Kernel Outline Linux 核心程式碼的目錄結構及各目錄的相關內容 Linux 核心各設定選項內容和作用 Linux 核心設定檔 config.in 的作用 Linux 核心的編譯過程 將新增核心程式加入到 Linux 核心結構中的方法 核心程式碼目錄介紹 (1) arch:arch 子目錄包括所有與體系結構相關的核心程式 arch 的每一個子目錄都代表一個

More information

Abstract arm linux tool-chain root NET-Start! 2

Abstract arm linux tool-chain root NET-Start! 2 Lab III - Embedding Linux 1 Abstract arm linux tool-chain root NET-Start! 2 Part 1.4 Step1. tool-chain 4 Step2. PATH 4 Part 2 kernel 5 Step1. 5 Step2... 6 Step3...8 Part 3 root. 8 Step1. 8 Step2. 8 Part

More information

华恒家庭网关方案

华恒家庭网关方案 LINUX V1.5 1 2 1 2 LINUX WINDOWS PC VC LINUX WINDOWS LINUX 90% GUI LINUX C 3 REDHAT 9 LINUX PC TFTP/NFS http://www.hhcn.com/chinese/embedlinux-res.html minicom NFS mount C HHARM9-EDU 1 LINUX HHARM9-EDU

More information

The golden pins of the PCI card can be oxidized after months or years

The golden pins of the PCI card can be oxidized after months or years Q. 如何在 LabWindows/CVI 編譯 DAQ Card 程式? A: 請參考至下列步驟 : 步驟 1: 安裝驅動程式 1. 安裝 UniDAQ 驅動程式 UniDAQ 驅動程式下載位置 : CD:\NAPDOS\PCI\UniDAQ\DLL\Driver\ ftp://ftp.icpdas.com/pub/cd/iocard/pci/napdos/pci/unidaq/dll/driver/

More information

CC213

CC213 : (Ken-Yi Lee), E-mail: feis.tw@gmail.com 9 [P.11] : Dev C++ [P.12] : http://c.feis.tw [P.13] [P.14] [P.15] [P.17] [P.23] Dev C++ [P.24] [P.27] [P.34] C / C++ [P.35] 10 C / C++ C C++ C C++ C++ C ( ) C++

More information

Microsoft Word - PS2_linux_guide_cn.doc

Microsoft Word - PS2_linux_guide_cn.doc Linux For $ONY PlayStatioin2 Unofficall General Guide Language: Simplified Chinese First Write By Beter Hans v0.1 Mail: hansb@citiz.net Version: 0.1 本 人 是 菜 鸟 + 小 白 欢 迎 指 正 错 误 之 处, 如 果 您 有 其 他 使 用 心 得

More information

<4D6963726F736F667420576F7264202D20C7B6C8EBCABD6C696E7578BBF9B4A1CAB5D1E92E646F63>

<4D6963726F736F667420576F7264202D20C7B6C8EBCABD6C696E7578BBF9B4A1CAB5D1E92E646F63> 嵌 入 式 linux 基 础 实 验 1 内 核 配 置 及 编 译 1. 进 入 内 核 所 在 目 录 /opt/ruiva/xscale/linux-2.6.26 #cd /opt/ruiva/xscale/linux-2.6.26 2. 键 入 make menuconfig, 根 据 需 要 适 当 配 置 内 核 #make menuconfig 这 里 先 使 用 默 认 的 配 置,

More information

1

1 SDT Uclinux SDT.alf.c 44blib.alf 44blib.c jtag ADS.alf.c make menuconfig make dep make clean make lib_only make user_only make romfs make image make uclinux ext2 cash lcd frambuffer 1 armsys-c uclinux

More information

Windows 2000 Server for T100

Windows 2000 Server for T100 2 1 Windows 95/98 Windows 2000 3.5 Windows NT Server 4.0 2 Windows DOS 3.5 T200 2002 RAID RAID RAID 5.1 Windows 2000 Server T200 2002 Windows 2000 Server Windows 2000 Server Windows 2000 Server 3.5 for

More information

自由軟體教學平台

自由軟體教學平台 NCHC Opensource task force DRBL steven@nchc.gov.tw, c00hkl00@nchc.gov.tw National Center for High-Performance Computing http://www.nchc.gov.tw Jan, 2003 1 2003/1/28 ( ) 09:00-10:30 10:40-12:00 Linux 13:00-14:30

More information

TPM BIOS Infineon TPM Smart TPM Infineon TPM Smart TPM TPM Smart TPM TPM Advanced Mode...8

TPM BIOS Infineon TPM Smart TPM Infineon TPM Smart TPM TPM Smart TPM TPM Advanced Mode...8 Smart TPM Rev. 1001 Smart TPM Ultra TPM Smart TPM TPM...3 1. BIOS... 3 2. Infineon TPM Smart TPM... 4 2.1. Infineon TPM...4 2.2. Smart TPM...4 3. TPM... 5 3.1. Smart TPM TPM...5 3.2. Advanced Mode...8

More information

ebook140-9

ebook140-9 9 VPN VPN Novell BorderManager Windows NT PPTP V P N L A V P N V N P I n t e r n e t V P N 9.1 V P N Windows 98 Windows PPTP VPN Novell BorderManager T M I P s e c Wi n d o w s I n t e r n e t I S P I

More information

05_資源分享-NFS及NIS.doc

05_資源分享-NFS及NIS.doc 5 NFS NFS Server NFS Client NIS NIS 5-0 (Network File System, NFS) Unix NFS mount NFS... Network Information Service NIS Linux NIS NIS NIS / / /etc/passwd /etc/group NFS NIS 5-1 NFS 5-1-1 NFS NFS Network

More information

ARM JTAG实时仿真器安装使用指南

ARM JTAG实时仿真器安装使用指南 ARM JTAG Version 1.31 2003. 11. 12 ARM JTAG ARM JTAG.3 ARM 2.1.4 2.2.4 ARM JTAG 3.1 18 3.2 18 3.2.1 Multi-ICE Server.18 3.2.2 ADS..21 ARM JTAG 4.1 Multi-ICE Server 33 4.1.1 Multi-ICE Server..... 33 4.1.2

More information

EK-STM32F

EK-STM32F STMEVKIT-STM32F10xx8 软 件 开 发 入 门 指 南 目 录 1 EWARM 安 装... 1 1.1 第 一 步 : 在 线 注 册... 1 1.2 第 二 步 : 下 载 软 件... 2 1.3 第 三 步 : 安 装 EWARM... 3 2 基 于 STMEVKIT-STM32F10xx8 的 示 例 代 码 运 行... 6 2.1 GPIO Demo... 6 2.2

More information

ebook140-8

ebook140-8 8 Microsoft VPN Windows NT 4 V P N Windows 98 Client 7 Vintage Air V P N 7 Wi n d o w s NT V P N 7 VPN ( ) 7 Novell NetWare VPN 8.1 PPTP NT4 VPN Q 154091 M i c r o s o f t Windows NT RAS [ ] Windows NT4

More information

RTX3.2.0标准版 - 技术白皮书

RTX3.2.0标准版 - 技术白皮书 一 铭 操 作 系 统 技 术 白 皮 书 广 西 一 铭 软 件 股 份 有 限 公 司 版 权 声 明 本 书 版 权 归 广 西 一 铭 软 件 股 份 有 限 公 司 所 有, 并 保 留 对 本 文 档 及 声 明 的 最 终 解 释 权 和 修 改 权 本 文 件 中 出 现 的 任 何 文 字 叙 述 文 档 格 式 插 图 照 片 方 法 过 程 等 内 容, 除 另 有 特 别 说

More information

一个开放源码的嵌入式仿真环境 ― SkyEye

一个开放源码的嵌入式仿真环境 ― SkyEye SkyEye SkyEye http://hpclab.cs.tsinghua.edu.cn/~skyeye/ I hear and I forget, I see and I remember, I do and I understand. SkyEye SkyEye SkyEye SkyEye SkyEye 1. SkyEye PC pervasive computing PC I O PDA

More information

2004 Sun Microsystems, Inc Network Circle, Santa Clara, CA U.S.A. Sun Sun Berkeley BSD University of California UNIX X/Open Company, Ltd.

2004 Sun Microsystems, Inc Network Circle, Santa Clara, CA U.S.A. Sun Sun Berkeley BSD University of California UNIX X/Open Company, Ltd. Java Desktop System 2 Sun Microsystems, Inc. 4150 Network Circle Santa Clara, CA 95054 U.S.A. : 817 7758 10 2004 9 2004 Sun Microsystems, Inc. 4150 Network Circle, Santa Clara, CA 95054 U.S.A. Sun Sun

More information

0 0 = 1 0 = 0 1 = = 1 1 = 0 0 = 1

0 0 = 1 0 = 0 1 = = 1 1 = 0 0 = 1 0 0 = 1 0 = 0 1 = 0 1 1 = 1 1 = 0 0 = 1 : = {0, 1} : 3 (,, ) = + (,, ) = + + (, ) = + (,,, ) = ( + )( + ) + ( + )( + ) + = + = = + + = + = ( + ) + = + ( + ) () = () ( + ) = + + = ( + )( + ) + = = + 0

More information

Cygwin Cygwin windows Linux Cygwin.dll Windows Linux API Linux Windows Linux 2

Cygwin Cygwin windows Linux Cygwin.dll Windows Linux API Linux Windows Linux 2 uclinux 1 Cygwin Cygwin windows Linux Cygwin.dll Windows Linux API Linux Windows Linux 2 Cygwin Cygwin GNU gccgdbxfree86bashtetexopengl perlpython Linux Windows Cygwin Linux GNU Windows 3 Cygwin Cygwin

More information

epub

epub 3 Cisco 3.1 S e t u p C i s c o C i s c o Cisco IOS C i s c o 3.2 Te l n e t T F T P 3-1 3-1 configure terminal configure memory Configure network t e l n e t < C t r l - Z > conf t N V R A M T F T P I

More information

untitled

untitled 年度 路 IVI 劉 隆 年 597 598 IVI 錄... 601 行... 601... 601 1.... 601 2. 路... 602 3.... 603... 604 1.IPv4 to IPv6... 604 2.IPv6 to IPv4... 605 -... 606 ( )IVI Server... 606 ( )IVI Server... 610 ( )IVI DNS Server...

More information

使用手冊

使用手冊 使用手冊 版權所有 2013 年 Microtek International, Inc. 保留所有權利 商標 Microtek MII MiiNDT ScanWizard Microtek International, Inc. Windows Microsoft Corporation 重要須知 Microtek Microtek Windows Microsoft Windows I49-004528

More information

IP505SM_manual_cn.doc

IP505SM_manual_cn.doc IP505SM 1 Introduction 1...4...4...4...5 LAN...5...5...6...6...7 LED...7...7 2...9...9...9 3...11...11...12...12...12...14...18 LAN...19 DHCP...20...21 4 PC...22...22 Windows...22 TCP/IP -...22 TCP/IP

More information

05 01 X Window X Window Linux Linux X Window X Window Webmin Web Linux Linux X Window X Window Notebook PC X Window X Window module Linux Linux kernel

05 01 X Window X Window Linux Linux X Window X Window Webmin Web Linux Linux X Window X Window Notebook PC X Window X Window module Linux Linux kernel Linux sub bash test2.sh sub bash test.sh test2.sh sub bash var1 123 123 test.sh test2.sh var1 bash sub bash var1 bash 01 5-4 X Window X Window X Window Linux Server X Window CPU2006 Linux X Window benchmark

More information

本文由筱驀釹贡献

本文由筱驀釹贡献 本 文 由 筱 驀 釹 贡 献 ppt 文 档 可 能 在 WAP 端 浏 览 体 验 不 佳 建 议 您 优 先 选 择 TXT, 或 下 载 源 文 件 到 本 机 查 看 Linux 操 作 系 统 Linux 操 作 系 统 第 一 部 分 介 绍 与 安 装 Linux 的 由 来 : Linux 的 由 来 : 的 由 来 Linus Torvalds 1.Linux 的 版 本 1.Linux

More information

Microsoft Word - linux命令及建议.doc

Microsoft Word - linux命令及建议.doc Linux 操 作 系 统 命 令 集 1 基 本 命 令 查 看 系 统 信 息 : uname -a 修 改 密 码 : passwd 退 出 : logout(exit) 获 取 帮 助 : man commands 2 文 件 和 目 录 命 令 显 示 当 前 工 作 目 录 : pwd 改 变 所 在 目 录 : cd cd - 切 换 到 上 一 次 使 用 的 目 录 cd 切 换

More information

P4VM800_BIOS_CN.p65

P4VM800_BIOS_CN.p65 1 Main H/W Monitor Boot Security Exit System Overview System Time System Date [ 17:00:09] [Fri 02/25/2005] BIOS Version : P4VM800 BIOS P1.00 Processor Type : Intel (R) Pentium (R) 4 CPU 2.40 GHz Processor

More information

ebook71-13

ebook71-13 13 I S P Internet 13. 2. 1 k p p p P P P 13. 2. 2 1 3. 2. 3 k p p p 1 3. 2. 4 l i n u x c o n f P P P 13. 2. 5 p p p s e t u p 13. 2. 6 p p p s e t u p P P P 13. 2. 7 1 3. 2. 8 C a l d e r a G U I 13.

More information

Serial ATA ( Nvidia nforce430)...2 (1) SATA... 2 (2) B I O S S A T A... 3 (3) RAID BIOS RAID... 6 (4) S A T A... 9 (5) S A T A (6) Microsoft Win

Serial ATA ( Nvidia nforce430)...2 (1) SATA... 2 (2) B I O S S A T A... 3 (3) RAID BIOS RAID... 6 (4) S A T A... 9 (5) S A T A (6) Microsoft Win Serial ATA ( Nvidia nforce430)...2 (1) SATA... 2 (2) B I O S S A T A... 3 (3) RAID BIOS RAID... 6 (4) S A T A... 9 (5) S A T A... 11 (6) Microsoft Windows 2000... 14 Ác Åé å Serial ATA ( Nvidia nforce430)

More information

Windows 2000 Server for T100

Windows 2000 Server for T100 T200 3020 Windows 2000 Advanced Server /Windows NT 4.0 Server /Redhat Linux7.3 SCO UnixWare7.1.1 Novell NetWare5.0 1. Windows 2000 Advanced Server / 2. Windows NT 4.0 Server / 3. Redhat Linux7.3 4. SCO

More information

Oracle Solaris Studio makefile C C++ Fortran IDE Solaris Linux C/C++/Fortran IDE "Project Properties" IDE makefile 1.

Oracle Solaris Studio makefile C C++ Fortran IDE Solaris Linux C/C++/Fortran IDE Project Properties IDE makefile 1. Oracle Solaris Studio 12.2 IDE 2010 9 2 8 9 10 11 13 20 26 28 30 32 33 Oracle Solaris Studio makefile C C++ Fortran IDE Solaris Linux C/C++/Fortran IDE "Project Properties" IDE makefile 1. "File" > "New

More information

Serial ATA ( nvidia nforce4 Ultra/SLI)...2 (1) SATA... 2 (2) B I O S S A T A... 3 (3) RAID BIOS RAID... 6 (4) S A T A... 9 (5) S A T A (6) Micro

Serial ATA ( nvidia nforce4 Ultra/SLI)...2 (1) SATA... 2 (2) B I O S S A T A... 3 (3) RAID BIOS RAID... 6 (4) S A T A... 9 (5) S A T A (6) Micro Serial ATA ( nvidia nforce4 Ultra/SLI)...2 (1) SATA... 2 (2) B I O S S A T A... 3 (3) RAID BIOS RAID... 6 (4) S A T A... 9 (5) S A T A... 11 (6) Microsoft Windows 2000... 14 Ác Åé å Serial ATA ( nvidia

More information

ebook70-22

ebook70-22 2 2 L i n u x f s t a b X 11 L i n u x L i n u x L i n u x D O S Wi n d o w s L i n u x O p e n L i n u x / u s r / m a n / m a n 5 f s t a b m o u n t m o u n t L i n u x 22.1 OpenLinux L i n u x U N

More information

Autodesk Product Design Suite Standard 系統統需求 典型使用用者和工作流程 Autodesk Product Design Suite Standard 版本為為負責建立非凡凡產品的設計師師和工程師, 提供基本概念設計計和製圖工具, 以取得令人驚驚嘆

Autodesk Product Design Suite Standard 系統統需求 典型使用用者和工作流程 Autodesk Product Design Suite Standard 版本為為負責建立非凡凡產品的設計師師和工程師, 提供基本概念設計計和製圖工具, 以取得令人驚驚嘆 Autodesk Product Design Suite Standard 20122 系統統需求 典型使用用者和工作流程 Autodesk Product Design Suite Standard 版本為為負責建立非凡凡產品的設計師師和工程師, 提供基本概念設計計和製圖工具, 以取得令人驚驚嘆的產品設計計 Autodesk Product Design Suite Standard 版本中中包括以下軟體體產品

More information

Oracle Oracle Solaris Studio IDE makefile C C++ Fortran makefile IDE Solaris Linux C/C++/Fortran Oracle IDE "P

Oracle Oracle Solaris Studio IDE makefile C C++ Fortran makefile IDE Solaris Linux C/C++/Fortran Oracle IDE P Oracle Solaris Studio 12.3 IDE 2011 12 E26461-01 2 7 8 9 9 Oracle 10 12 14 21 26 27 29 31 32 33 Oracle Solaris Studio IDE makefile C C++ Fortran makefile IDE Solaris Linux C/C++/Fortran Oracle IDE "Project

More information

NEXT SDT2.51 C:\ARM251 SDT2.51 ARM SDT 2.51 ARM PROJECT MANAGER SDT 2

NEXT SDT2.51 C:\ARM251 SDT2.51 ARM SDT 2.51 ARM PROJECT MANAGER SDT 2 S3C44B0 SDT DRAGNBOY MICROSTAR ARM 51 ARM S3C44B0 ARM SDT2.51 IAR ADS SDT2.51 S3C44B0 LEDTEST SDT ARM 1 2 SDT embed.8800.org SDT2.51 SDT2.51 ARM ARM CPU ARM SDT ADS ADS MULTI-ICE SDT JTAG JTAG SDT SDT2.51

More information

Microsoft Word - 正文.doc

Microsoft Word - 正文.doc 1 2 1 2 3 4 5 6 7 8 9 10 3 1 150 2 150 1 1 1.1 1.1.1 1.2 1.2.1 1.2.2 1.2.3 1.3 1.3.1 1.3.2 1.4 1.4.1 CPU 1.4.2 I/O 1.4.3 I/O 1.5 1.5.1 CISC RISC 1.5.2 1.5.3 1.6 1.6.1 1.6.2 N 1.6.3 2 2.1 2.1.1 2.1.2 2.1.3

More information

static struct file_operations gpio_ctl_fops={ ioctl: gpio_ctl_ioctl, open : gpio_open, release: gpio_release, ; #defineled1_on() (GPBDAT &= ~0x1) #def

static struct file_operations gpio_ctl_fops={ ioctl: gpio_ctl_ioctl, open : gpio_open, release: gpio_release, ; #defineled1_on() (GPBDAT &= ~0x1) #def Kaise s 2410 Board setting [1]. Device Driver Device Driver Linux s Kernel ARM s kernel s3c2410_kernel2.4.18_r1.1_change.tar.bz2 /usr/src (1) #cd /usr/src (2) #tar xfj s3c2410_kernel2.4.18_r1.1_change.tar.bz2

More information

1 Project New Project 1 2 Windows 1 3 N C test Windows uv2 KEIL uvision2 1 2 New Project Ateml AT89C AT89C51 3 KEIL Demo C C File

1 Project New Project 1 2 Windows 1 3 N C test Windows uv2 KEIL uvision2 1 2 New Project Ateml AT89C AT89C51 3 KEIL Demo C C File 51 C 51 51 C C C C C C * 2003-3-30 pnzwzw@163.com C C C C KEIL uvision2 MCS51 PLM C VC++ 51 KEIL51 KEIL51 KEIL51 KEIL 2K DEMO C KEIL KEIL51 P 1 1 1 1-1 - 1 Project New Project 1 2 Windows 1 3 N C test

More information

ebook8-30

ebook8-30 3 0 C C C C C C++ C + + C++ GNU C/C++ GNU egcs UNIX shell s h e l l g a w k P e r l U N I X I / O UNIX shell awk P e r l U N I X C C C C C C U N I X 30.1 C C U N I X 70 C C U N I X U N I X U N I X C Dennis

More information

Ác Åé å Serial ATA ( Sil3132) S A T A (1) SATA (2) BIOS SATA (3)* RAID BIOS RAID (4) SATA (5) SATA (a) S A T A ( S A T A R A I D ) (b) (c) Windows XP

Ác Åé å Serial ATA ( Sil3132) S A T A (1) SATA (2) BIOS SATA (3)* RAID BIOS RAID (4) SATA (5) SATA (a) S A T A ( S A T A R A I D ) (b) (c) Windows XP Serial ATA ( Sil3132)...2 (1) SATA... 2 (2) B I O S S A T A... 3 (3) RAID BIOS RAID... 6 (4) S A T A... 10 (5) S A T A... 12 Ác Åé å Serial ATA ( Sil3132) S A T A (1) SATA (2) BIOS SATA (3)* RAID BIOS

More information

简 介 本 白 皮 书 高 度 概 述 了 支 持 移 动 互 联 网 设 备 (Mobile Internet Device) 的 Intel C++ Software Development Tool Suite for Linux* OS, 目 标 读 者 主 要 是 技 术 决 策 制 订

简 介 本 白 皮 书 高 度 概 述 了 支 持 移 动 互 联 网 设 备 (Mobile Internet Device) 的 Intel C++ Software Development Tool Suite for Linux* OS, 目 标 读 者 主 要 是 技 术 决 策 制 订 白 皮 书 Robert Müller-Albrecht 开 发 人 员 产 品 部 门 支 持 移 动 互 联 网 设 备 的 Intel C++ Software Development Tool Suite for Linux* OS 文 档 编 号 :319332-001US 简 介 本 白 皮 书 高 度 概 述 了 支 持 移 动 互 联 网 设 备 (Mobile Internet Device)

More information

Symantec™ Sygate Enterprise Protection 防护代理安装使用指南

Symantec™ Sygate Enterprise Protection 防护代理安装使用指南 Symantec Sygate Enterprise Protection 防 护 代 理 安 装 使 用 指 南 5.1 版 版 权 信 息 Copyright 2005 Symantec Corporation. 2005 年 Symantec Corporation 版 权 所 有 All rights reserved. 保 留 所 有 权 利 Symantec Symantec 徽 标 Sygate

More information

mvc

mvc Build an application Tutor : Michael Pan Application Source codes - - Frameworks Xib files - - Resources - ( ) info.plist - UIKit Framework UIApplication Event status bar, icon... delegation [UIApplication

More information

1

1 磁軌式讀卡機 1288 系列 使用手冊 Version 1.0 1 2 3 4 5 6 7 8 9 10 11 12 1288 MSR Micro controller : With Decoder Open Visual COM port to read data (UART Interface) From 1288 Or direct control 1288 by sending Command

More information

目 录

目 录 1 Quick51...1 1.1 SmartSOPC Quick51...1 1.2 Quick51...1 1.3 Quick51...2 2 Keil C51 Quick51...4 2.1 Keil C51...4 2.2 Keil C51...4 2.3 1 Keil C51...4 2.4 Flash Magic...9 2.5 ISP...9 2.6...10 2.7 Keil C51...12

More information

P4V88+_BIOS_CN.p65

P4V88+_BIOS_CN.p65 1 Main H/W Monitor Boot Security Exit System Overview System Time System Date [ 17:00:09] [Wed 12/22/2004] BIOS Version : P4V88+ BIOS P1.00 Processor Type : Intel (R) Pentium (R) 4 CPU 2.40 GHz Processor

More information

ebook62-1

ebook62-1 1 Red Hat Linux R e d Hat Linux L i n u x X Wi n d o w Red Hat L i n u x 1.1 Red Hat Linux Red Hat 16 M 120 M 3. 5 Intel 386 C D - R O M C D - R O M We b / 1.1.1 L i n u x L i n u 4 Primary Partition Extended

More information

Guide to Install SATA Hard Disks

Guide to Install SATA Hard Disks SATA RAID 1. SATA. 2 1.1 SATA. 2 1.2 SATA 2 2. RAID (RAID 0 / RAID 1 / JBOD).. 4 2.1 RAID. 4 2.2 RAID 5 2.3 RAID 0 6 2.4 RAID 1.. 10 2.5 JBOD.. 16 3. Windows 2000 / Windows XP 20 1. SATA 1.1 SATA Serial

More information

46 2011 11 467 數位遊戲式學習系統 7 2011 11 467 47 3 DBGameSys 48 2011 11 467 正規化資料模組 如何配置並儲存電子化資料 以 便減少資料被重覆儲存的程序 DBGameSys的主要功能模組包 學習者 審核評分模組 含 正規化資料模組 審核評分 模組 高分列表模組3大區塊 系統資料庫 在正規化資料模組的執行 高分列表模組 過程中 先要求學習者瀏覽遊戲

More information

(Load Project) (Save Project) (OffLine Mode) (Help) Intel Hex Motor

(Load Project) (Save Project) (OffLine Mode) (Help) Intel Hex Motor 1 4.1.1.1 (Load) 14 1.1 1 4.1.1.2 (Save) 14 1.1.1 1 4.1.2 (Buffer) 16 1.1.2 1 4.1.3 (Device) 16 1.1.3 1 4.1.3.1 (Select Device) 16 2 4.1.3.2 (Device Info) 16 2.1 2 4.1.3.3 (Adapter) 17 2.1.1 CD-ROM 2 4.1.4

More information

投影片 1

投影片 1 資料庫管理程式 ( 補充教材 -Part2) 使用 ADO.NET 連結資料庫 ( 自行撰寫程式碼 以實現新增 刪除 修改等功能 ) Private Sub InsertButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles InsertButton.Click ' 宣告相關的 Connection

More information

TCP/IP TCP/IP OSI IP TCP IP IP TCP/IP TCP/IP

TCP/IP TCP/IP OSI IP TCP IP IP TCP/IP TCP/IP TCP/IP : TCP/IP TCP/IP OSI IP TCP IP IP TCP/IP TCP/IP 1. ASCII EBCDIC Extended Binary-Coded Decimal Interchange Code 2. / (1) (2) Single System Image SSI) (3) I/O (4) 3.OSI OSI Open System Interconnection

More information

Simulator By SunLingxi 2003

Simulator By SunLingxi 2003 Simulator By SunLingxi sunlingxi@sina.com 2003 windows 2000 Tornado ping ping 1. Tornado Full Simulator...3 2....3 3. ping...6 4. Tornado Simulator BSP...6 5. VxWorks simpc...7 6. simulator...7 7. simulator

More information

Sun StorEdge 3000 系列安装、操作和维护手册 (3310)

Sun StorEdge 3000 系列安装、操作和维护手册 (3310) Sun StorEdge 3000 系 列 安 装 操 作 和 维 护 手 册 Sun StorEdge 3310 SCSI 阵 列 Sun Microsystems, Inc. 4150 Network Circle Santa Clara, CA 95054 U.S.A. 650-960-1300 部 件 号 816-7960-11 2003 年 6 月, 修 订 版 A 有 关 本 文 档 的

More information

QLOGIC QLA22OO 使用手冊

QLOGIC QLA22OO 使用手冊 QLOGIC QLA23XX HBA 1.0 2002 ...5 1....5 2.?...5 3....5...7 1....7 2....7 3....99...122 1....122 2....122 3....133 4....133 FAST!UTIL...144 1....144 2. CONFIGURATION SETTINGS...144 3. SCAN FIBRE CHANNEL

More information

Red Flag Linux Desktop 4.0 Red Flag Linux Desktop 4.0 1

Red Flag Linux Desktop 4.0 Red Flag Linux Desktop 4.0 1 Red Flag Linux Desktop 4.0 68 6 Red Flag Software Co., Ltd. http://www.redflag-linux.com Red Flag Linux Desktop 4.0 Red Flag Linux Desktop 4.0 1 1 Red Flag Linux Desktop 4.0 1.1 Red Flag Linux Desktop

More information

ebook35-2

ebook35-2 2 2.1 Linux login Login: < > Password: < > Linux r o o t l o g o u t 2.2 Linux X Window Linux Linux Bourne ( b s h ) C ( c s h ) Korn ( k s h ) Bourne Steven Bourne UNIX Bourne bash Bourne C Bill Joy Bourne

More information

A Preliminary Implementation of Linux Kernel Virus and Process Hiding

A Preliminary Implementation of Linux Kernel Virus and Process Hiding 邵 俊 儒 翁 健 吉 妍 年 月 日 学 号 学 号 学 号 摘 要 结 合 课 堂 知 识 我 们 设 计 了 一 个 内 核 病 毒 该 病 毒 同 时 具 有 木 马 的 自 动 性 的 隐 蔽 性 和 蠕 虫 的 感 染 能 力 该 病 毒 获 得 权 限 后 会 自 动 将 自 身 加 入 内 核 模 块 中 劫 持 的 系 统 调 用 并 通 过 简 单 的 方 法 实 现 自 身 的

More information

網路安全:理論與實務 第二版

網路安全:理論與實務 第二版 第 10 章 :Wireshark 封 包 分 析 軟 體 10-1 Wireshark 簡 介 10-2 Wireshark 的 安 裝 方 法 10-3 Wireshark 的 使 用 Wireshark 簡 介 - 發 展 歷 史 Wireshark (http://www.wireshark.org/) 是 一 個 開 放 原 始 碼 (open source software) 軟 體,

More information

软件测试(TA07)第一学期考试

软件测试(TA07)第一学期考试 一 判 断 题 ( 每 题 1 分, 正 确 的, 错 误 的,20 道 ) 1. 软 件 测 试 按 照 测 试 过 程 分 类 为 黑 盒 白 盒 测 试 ( ) 2. 在 设 计 测 试 用 例 时, 应 包 括 合 理 的 输 入 条 件 和 不 合 理 的 输 入 条 件 ( ) 3. 集 成 测 试 计 划 在 需 求 分 析 阶 段 末 提 交 ( ) 4. 单 元 测 试 属 于 动

More information

AL-M200 Series

AL-M200 Series NPD4754-00 TC ( ) Windows 7 1. [Start ( )] [Control Panel ()] [Network and Internet ( )] 2. [Network and Sharing Center ( )] 3. [Change adapter settings ( )] 4. 3 Windows XP 1. [Start ( )] [Control Panel

More information

f2.eps

f2.eps 前 言, 目 录 产 品 概 况 1 SICAM PAS SICAM 电 力 自 动 化 系 统 配 置 和 使 用 说 明 配 置 2 操 作 3 实 时 数 据 4 人 机 界 面 5 SINAUT LSA 转 换 器 6 状 态 与 控 制 信 息 A 版 本 号 : 08.03.05 附 录, 索 引 安 全 标 识 由 于 对 设 备 的 特 殊 操 作 往 往 需 要 一 些 特 殊 的

More information

51 C 51 isp 10 C PCB C C C C KEIL

51 C 51 isp 10   C   PCB C C C C KEIL http://wwwispdowncom 51 C " + + " 51 AT89S51 In-System-Programming ISP 10 io 244 CPLD ATMEL PIC CPLD/FPGA ARM9 ISP http://wwwispdowncom/showoneproductasp?productid=15 51 C C C C C ispdown http://wwwispdowncom

More information

Ác Åé å Serial ATA ( nvidia nforce4 SLI) S A T A (1) SATA (2) BIOS SATA (3)* RAID BIOS RAID (4) SATA (5) SATA (a) S A T A ( S A T A R A I D ) (b) (c)

Ác Åé å Serial ATA ( nvidia nforce4 SLI) S A T A (1) SATA (2) BIOS SATA (3)* RAID BIOS RAID (4) SATA (5) SATA (a) S A T A ( S A T A R A I D ) (b) (c) Serial ATA ( nvidia nforce4 SLI)...2 (1) SATA... 2 (2) B I O S S A T A... 3 (3) RAID BIOS RAID... 6 (4) S A T A... 9 (5) S A T A... 11 (6) Microsoft Windows 2000... 14 Ác Åé å Serial ATA ( nvidia nforce4

More information

1 LINUX IDE Emacs gcc gdb Emacs + gcc + gdb IDE Emacs IDE C Emacs Emacs IDE ICE Integrated Computing Environment Emacs Unix Linux Emacs Emacs Emacs Un

1 LINUX IDE Emacs gcc gdb Emacs + gcc + gdb IDE Emacs IDE C Emacs Emacs IDE ICE Integrated Computing Environment Emacs Unix Linux Emacs Emacs Emacs Un Linux C July 27, 2016 Contents 1 Linux IDE 1 2 GCC 3 2.1 hello.c hello.exe........................... 5 2.2............................... 9 2.2.1 -Wall................................ 9 2.2.2 -E..................................

More information

Basic System Administration

Basic System Administration 基 本 系 统 管 理 ESX Server 3.5 ESX Server 3i 版 本 3.5 Virtual Center 2.5 基 本 管 理 指 南 基 本 管 理 指 南 修 订 时 间 :20080410 项 目 :VI-CHS-Q208-490 我 们 的 网 站 提 供 最 新 的 技 术 文 档, 网 址 为 : http://www.vmware.com/cn/support/

More information

PowerPoint 演示文稿

PowerPoint 演示文稿 Linux 操 作 系 统 基 础 介 绍 课 程 目 标 及 要 求 了 解 Linux 操 作 系 统 的 登 入 方 式 掌 握 常 用 命 令 的 基 本 用 法 能 够 熟 练 在 各 个 目 录 转 换 Outline 1. Linux 操 作 系 统 简 介 2. Linux 操 作 系 统 的 登 录 3. Linux 操 作 系 统 的 目 录 结 构 4. 常 用 命 令 5.

More information

投影片 1

投影片 1 軟體說明書繁體中文 RGB A 目錄 - CONTENTS 01 09 15 17 22 軟體主介面 巨集設定說明 主介面概觀 個人設定檔 (Profiles) 一般模式 / 遊戲模式 按鍵功能分配 巨集管理器概觀 巨集管理器 巨集錄製設定 巨集錄製時間列表 插入指令 閃移系統 - I.S.S (Instant Shift System) 燈光設定更新韌體 閃移系統啟動鈕設定說明 燈光設定介面 介面區域一

More information

untitled

untitled V3041A-J/V3042A-J IP-SAN/NAS Infinova Infinova Infinova Infinova www.infinova.com.cn Infinova Infinova Infinova 1 2 1 2 V3041A-16R-J V3041A-24R-J V3042A-16R-J V3042A-24R-J V3049-EXD-R16 V3049-EXD-R24 ...

More information

Sun Fire V440 Server Administration Guide - zh_TW

Sun Fire V440 Server Administration Guide - zh_TW Sun Fire V440 Server 管 理 指 南 Sun Microsystems, Inc. 4150 Network Circle Santa Clara, CA 95054 U.S.A. 650-960-1300 文 件 號 碼 :817-2818-10 2003 年 7 月, 修 訂 版 A 將 您 對 此 文 件 的 意 見 傳 送 到 :http://www.sun.com/hwdocs/feedback

More information

K7VT2_QIG_v3

K7VT2_QIG_v3 ............ 1 2 3 4 5 [R] : Enter Raid setup utility 6 Press[A]keytocreateRAID RAID Type: JBOD RAID 0 RAID 1: 2 7 RAID 0 Auto Create Manual Create: 2 RAID 0 Block Size: 16K 32K

More information

Microsoft Word - 100118002.htm

Microsoft Word - 100118002.htm 100 年 度 11800 電 腦 軟 體 應 用 乙 級 技 術 士 技 能 檢 定 學 科 測 試 試 題 本 試 卷 有 選 擇 題 80 題, 每 題 1.25 分, 皆 為 單 選 選 擇 題, 測 試 時 間 為 100 分 鐘, 請 在 答 案 卡 上 作 答, 答 錯 不 倒 扣 ; 未 作 答 者, 不 予 計 分 准 考 證 號 碼 : 姓 名 : 選 擇 題 : 1. (3)

More information

epub83-1

epub83-1 C++Builder 1 C + + B u i l d e r C + + B u i l d e r C + + B u i l d e r C + + B u i l d e r 1.1 1.1.1 1-1 1. 1-1 1 2. 1-1 2 A c c e s s P a r a d o x Visual FoxPro 3. / C / S 2 C + + B u i l d e r / C

More information

Data Server_new_.doc

Data Server_new_.doc 0i B/C Data Server Windows 2000 Window XP Windows XP FTP FANUC Data Server FTP liwei@beijing-fanuc 1 06-10-8 Content 1. /...3 1.1...3 1.2...3 1.3 CNC...3 2....5 2.1 STORAGE...5 2.2 FTP...6 2.3 BUFFER...7

More information

HighPoint产品的FAQ手册

HighPoint产品的FAQ手册 一 引 言 首 先 承 蒙 贵 公 司 赐 顾, 使 用 HighPoint ( 简 称 HPT) 系 列 产 品 以 下 是 根 据 多 年 来 合 作 的 客 户 所 提 出 的 问 题 而 总 结 出 的 有 关 HighPoint 系 列 产 品 的 FAQ, 欢 迎 您 随 时 提 出 批 评 建 议 以 便 我 们 及 时 改 进 谢 谢! 二 HighPoint RAID 产 品 技

More information

快 速 入 门 (Linux) 概 述 文 档 目 的 本 文 档 介 绍 了 如 何 快 速 创 建 Linux 系 统 实 例 远 程 连 接 实 例 部 署 环 境 等 旨 在 引 导 您 一 站 式 完 成 实 例 的 创 建 登 录 和 快 速 环 境 部 署 云 服 务 器 ECS 实

快 速 入 门 (Linux) 概 述 文 档 目 的 本 文 档 介 绍 了 如 何 快 速 创 建 Linux 系 统 实 例 远 程 连 接 实 例 部 署 环 境 等 旨 在 引 导 您 一 站 式 完 成 实 例 的 创 建 登 录 和 快 速 环 境 部 署 云 服 务 器 ECS 实 云 服 务 器 ECS 快 速 入 门 (Linux) 快 速 入 门 (Linux) 概 述 文 档 目 的 本 文 档 介 绍 了 如 何 快 速 创 建 Linux 系 统 实 例 远 程 连 接 实 例 部 署 环 境 等 旨 在 引 导 您 一 站 式 完 成 实 例 的 创 建 登 录 和 快 速 环 境 部 署 云 服 务 器 ECS 实 例, 有 时 候 也 被 称 为 阿 里 云

More information

untitled

untitled \ \ \ DOP11B 06/2011 16929837 / ZH SEW-EURODRIVE Driving the world 1 5 1.1 5 1.2 5 1.3 6 1.4 6 1.5 6 1.6 6 1.7 6 2 7 2.1 7 2.2 7 2.3 8 2.4 8 2.5 8 2.6 9 2.7 / 11 2.8 11 2.9 11 2.10 11 2.11 12 3 (DOP11B-10

More information

RAID RAID 0 RAID 1 RAID 5 RAID * ( -1)* ( /2)* No Yes Yes Yes A. B. BIOS SATA C. RAID BIOS RAID ( ) D. SATA RAID/AHCI ( ) SATA M.2 SSD ( )

RAID RAID 0 RAID 1 RAID 5 RAID * ( -1)* ( /2)* No Yes Yes Yes A. B. BIOS SATA C. RAID BIOS RAID ( ) D. SATA RAID/AHCI ( ) SATA M.2 SSD ( ) RAID RAID 0 RAID 1 RAID 5 RAID 10 2 2 3 4 * (-1)* (/2)* No Yes Yes Yes A. B. BIOS SATA C. RAID BIOS RAID ( ) D. SATA RAID/AHCI ( ) SATA M.2 SSD ( ) ( ) ( ) Windows USB 1 SATA A. SATASATAIntel SATA (SATA3

More information

User ID 150 Password - User ID 150 Password Mon- Cam-- Invalid Terminal Mode No User Terminal Mode No User Mon- Cam-- 2

User ID 150 Password - User ID 150 Password Mon- Cam-- Invalid Terminal Mode No User Terminal Mode No User Mon- Cam-- 2 Terminal Mode No User User ID 150 Password - User ID 150 Password Mon- Cam-- Invalid Terminal Mode No User Terminal Mode No User Mon- Cam-- 2 Mon1 Cam-- Mon- Cam-- Prohibited M04 Mon1 Cam03 Mon1 Cam03

More information

輕鬆學 Dreamweaver CS5 網頁設計..\Example\Ch0\ \.html..\example\ch0\ \mouse.txt..\example\ch0\ \ _Ok.html 學習重點 JavaScript 複製程式碼 mouse.txt Ctrl+C Ctrl+C 0-4

輕鬆學 Dreamweaver CS5 網頁設計..\Example\Ch0\ \.html..\example\ch0\ \mouse.txt..\example\ch0\ \ _Ok.html 學習重點 JavaScript 複製程式碼 mouse.txt Ctrl+C Ctrl+C 0-4 JAVA Extension 0..\Example\Ch0\ \ T.html..\Example\Ch0\ \ T.txt T.txt..\Example\Ch0\ \ T_Ok.html 提示 :. Marquee Marquee Font Color #FFFFFF BG Color #867bf Width 90 Height 50. T.txt Ctrl+C your scrolling

More information

untitled

untitled V3049A-EXD IP-SAN/NAS Infinova Infinova Infinova Infinova www.infinova.com.cn Infinova Infinova Infinova 1 2 1 2 V3049A-EXD-R16 V3049A-EXD-R24 ... 1 1.1... 1 1.2... 1 1.3... 1... 2 2.1... 2 2.2... 3...

More information

, 7, Windows,,,, : ,,,, ;,, ( CIP) /,,. : ;, ( 21 ) ISBN : -. TP CIP ( 2005) 1

, 7, Windows,,,, : ,,,, ;,, ( CIP) /,,. : ;, ( 21 ) ISBN : -. TP CIP ( 2005) 1 21 , 7, Windows,,,, : 010-62782989 13501256678 13801310933,,,, ;,, ( CIP) /,,. : ;, 2005. 11 ( 21 ) ISBN 7-81082 - 634-4... - : -. TP316-44 CIP ( 2005) 123583 : : : : 100084 : 010-62776969 : 100044 : 010-51686414

More information

Microsoft Word - 第5章.doc

Microsoft Word - 第5章.doc 目 录 及 权 限 管 理 随 着 的 不 断 发 展, 越 来 越 多 的 人 开 始 使 用, 对 于 那 些 刚 接 触 的 人 来 说, 恐 怕 最 先 感 到 困 惑 的 就 是 那 些 不 明 不 白 的 目 录 了 同 样, 系 统 是 一 个 典 型 的 多 用 户 系 统 为 了 保 护 系 统 的 安 全 性, 系 统 对 不 同 用 户 访 问 同 一 文 件 或 目 录 的

More information

untitled

untitled TS-411U Turbo Server TS-411U Turbo Server ( : 1.0.0) 2005 2005 12 8-2 - 1. 2. TS-411U Turbo Server - 3 - ... 7 1.1... 7 1.2... 8 1.3... 9 TS-411U... 10 2.1... 10 2.2... 14 2.3 TS-411U... 15 LCD... 17...

More information

华恒家庭网关方案

华恒家庭网关方案 uclinuxblackfin www.hhcn.com 1 Blackfin Why uclinux HHBF561 2 Blackfin New generation of high performance, low power ADI Processors Industrial Controls VoIP VoIP 3 BlackfinBF533 System Peripherals Dynamic

More information

ICD ICD ICD ICD ICD

ICD ICD ICD ICD ICD MPLAB ICD2 MPLAB ICD2 PIC MPLAB-IDE V6.0 ICD2 usb PC RS232 MPLAB IDE PC PC 2.0 5.5V LED EEDATA MPLAB ICD2 Microchip MPLAB-IDE v6.0 Windows 95/98 Windows NT Windows 2000 www.elc-mcu.com 1 ICD2...4 1.1 ICD2...4

More information

Microsoft Word - 把时间当作朋友(2011第3版)3.0.b.06.doc

Microsoft Word - 把时间当作朋友(2011第3版)3.0.b.06.doc 2 5 8 11 0 13 1. 13 2. 15 3. 18 1 23 1. 23 2. 26 3. 28 2 36 1. 36 2. 39 3. 42 4. 44 5. 49 6. 51 3 57 1. 57 2. 60 3. 64 4. 66 5. 70 6. 75 7. 83 8. 85 9. 88 10. 98 11. 103 12. 108 13. 112 4 115 1. 115 2.

More information

LSI U320 SCSI卡用户手册.doc

LSI U320 SCSI卡用户手册.doc V1.0 Ultra320 SCSI SCSI 2004 7 PentiumIntel MS-DOS Windows Novell Netware Novell Sco Unix Santa Cruz Operation LSI U320 SCSI SCSI SCSI Integrated Mirroring/Integrated Striping BIOS Firmware LSI U320 SCSI

More information

雲端 Cloud Computing 技術指南 運算 應用 平台與架構 10/04/15 11:55:46 INFO 10/04/15 11:55:53 INFO 10/04/15 11:55:56 INFO 10/04/15 11:56:05 INFO 10/04/15 11:56:07 INFO

雲端 Cloud Computing 技術指南 運算 應用 平台與架構 10/04/15 11:55:46 INFO 10/04/15 11:55:53 INFO 10/04/15 11:55:56 INFO 10/04/15 11:56:05 INFO 10/04/15 11:56:07 INFO CHAPTER 使用 Hadoop 打造自己的雲 8 8.3 測試 Hadoop 雲端系統 4 Nodes Hadoop Map Reduce Hadoop WordCount 4 Nodes Hadoop Map/Reduce $HADOOP_HOME /home/ hadoop/hadoop-0.20.2 wordcount echo $ mkdir wordcount $ cd wordcount

More information

IT (1) IDE... 2 (2) BIOS IDE RAID... 3 (3) RAID BIOS RAID... 5 (4) R A I D (5) ID E RA ID... 15

IT (1) IDE... 2 (2) BIOS IDE RAID... 3 (3) RAID BIOS RAID... 5 (4) R A I D (5) ID E RA ID... 15 IT8212...2 (1) IDE... 2 (2) BIOS IDE RAID... 3 (3) RAID BIOS RAID... 5 (4) R A I D... 13 (5) ID E RA ID... 15 Ác Åé å IT8212 (1) IDE (2) BIOS IDE RAID (3) RAID BIOS RAID (4) RAID (5) RAID (a) ( )IDE (

More information

投影片 1

投影片 1 Linux Kernel 的安裝與編譯實習 ( 代號 : 303) (Part I) DOC Number : RM-033-04-303 DOC Version : V1.00 Release Date : 2007-03-16 Module Name : Linux Kernel 的安裝與編譯實習 Platform : Creator XScale-PXA270 Category : embedded

More information

lect03.ppt

lect03.ppt Linux 操 作 系 统 Linux 基 础 主 要 内 容 q 使 用 Linux q Linux 的 两 种 登 录 方 式 q 字 符 操 作 环 境 和 X Windows 系 统 q Linux 图 形 界 面 基 本 操 作 q Linux 命 令 的 使 用 方 式 q Linux 一 些 常 用 命 令 1 2 一 些 基 本 术 语 u 命 令 (Command) 给 计 算 机

More information

工程师培训

工程师培训 .1 TCP/IP TCP/IP 1 .2.2.1 Host 1960 S 1970 S Host Low Speed Lines 1970 S 1980 S pc Server Local Interneting 1980 S 1990 S Branch. pc Branch. WAN Branch. pc pc IBM SNA IBM X.25 2 .2.2 OSI OSI Application

More information

Chapter 2

Chapter 2 2 (Setup) ETAP PowerStation ETAP ETAP PowerStation PowerStation PowerPlot ODBC SQL Server Oracle SQL Server Oracle Windows SQL Server Oracle PowerStation PowerStation PowerStation PowerStation ETAP PowerStation

More information

1 IT IT IT IT Virtual Machine, VM VM VM VM Operating Systems, OS IT

1 IT IT IT IT Virtual Machine, VM VM VM VM Operating Systems, OS IT 1 IT IT IT IT Virtual Machine, VM VM VM VM Operating Systems, OS IT Chapter 1 了解虛擬化技術種類 硬體 / 平台 / 伺服器虛擬化 VM VM VM CPU Hypervisor VMM Virtual Machine Manager VM Host OS VM VM Guest OS Host OS CPU VM Hyper-V

More information