熟悉 S3C44B0X 開發(fā)板的開發(fā)流程
一. Bootloader
1. 建立 Cygwin 虛擬 linux 環(huán)境
(1) 點(diǎn)擊 setup.exe 開始安裝
(2) 點(diǎn)擊下一步,進(jìn)入選擇安裝方法的界面:
圖 1 安裝界面
圖二選擇安裝途徑界面
在這里,如果你的安裝文件沒有下載到本地,你可以選擇從 Internet 安裝。我們選擇從本地安裝,點(diǎn)擊下一步繼續(xù)。
圖三選擇安裝路徑等
圖四選擇 Cygwin 安裝程序路徑
(3) 選擇好 Cygwin 安裝程序的路徑后點(diǎn)擊下一步繼續(xù)安裝。
圖五選擇安裝模塊
(4) 選擇好自己需要的模塊后,點(diǎn)擊下一步繼續(xù)安裝
圖六選擇自己需要的模塊安裝
圖七拷貝文件過程
圖 8 結(jié)束安裝
接下來 Cygwin 會進(jìn)行自解壓過程
圖 9Cygwin 自解壓過程
圖 10 環(huán)境變量設(shè)置
安裝好 Cygwin 后,我們還需要設(shè)置一下環(huán)境變量。打開系統(tǒng)屬性對話框,點(diǎn)擊高級 - 56518. 環(huán)境變量,打開環(huán)境變量設(shè)置窗口。
圖 11 新建環(huán)境變量
點(diǎn)擊新建按鈕增加一個環(huán)境一個用戶級的環(huán)境變量 PATH=C:/Cygwin/bin ,將 Cygwin/bin 目錄加入到用戶的 PATH 環(huán)境變量中,這樣用戶可以在任何路徑下都可以執(zhí)行 Cygwin/bin 目錄中的命令。
圖 12 設(shè)置新的環(huán)境變量
至此 Cygwin 在 Windows 下安裝就已經(jīng) OK 了。
2. 安裝基于 Cygwin 的 ARM 平臺交叉編譯器
在Windows下安裝好Cygwin后,我們需要建立編譯arm程序的環(huán)境,也即安裝arm-tools工具。
將光盤目錄光盤:/工具/編程工具/armtools/windows版本復(fù)制到本地硬盤(在這里我們在D:盤建立一個armtools的目錄,然后將光盤:/工具/編程工具/armtools/windows版本復(fù)制到這里),然后在dos環(huán)境下進(jìn)入此目錄,執(zhí)行unpack.bat批處理命令,解壓縮過程開始,不用關(guān)心在解壓縮的最后出現(xiàn)錯誤提示。請參看以下截圖:
最后添加將armtools的命令路徑添加到Windows的環(huán)境變量Path中。注意在上一步解壓的過程中,armtools被解壓到Cygwin的安裝目錄下,在這里Cygwin是安裝在C:/根目錄下的。這樣armtools交叉編譯環(huán)境就安裝好了。
3. u-boot 簡介
U-BOOT是一個開源bootloader,是由德國的工程師WolfgangDenk從8XXROM代碼發(fā)展而來的,它支持很多處理器,比如PowerPC、ARM、MIPS和x86。目前,U-BOOT源代碼在sourceforge網(wǎng)站的社區(qū)服務(wù)器中,Internet上有一群自由開發(fā)人員對其進(jìn)行維護(hù)和開發(fā),它的項(xiàng)目主頁是http://sourceforge.net/projects/U-BOOT。U-BOOT的最新版本源代碼可以在Sourceforge的CVS服務(wù)器中匿名獲得。由于其成熟和穩(wěn)定,已經(jīng)在許多嵌入式系統(tǒng)開發(fā)過程中被采用。
為什么我們需U-BOOT?顯然可以將ucLinux直接燒入flash,從而不需要額外的引導(dǎo)裝載程序(bootloader)。但是從軟件升級的角度以及程序修補(bǔ)的來說,軟件的自動更新非常重要。
4. 編譯 u-boot
a) 在linux(或其他linux虛擬環(huán)境下,如cygwin)解壓源碼包,在這里我們選擇在Windows系統(tǒng)下的Cygwin環(huán)境下來編譯。先將光盤中的u-boot包拷貝到系統(tǒng)的一個目錄下,在這里我們拷貝到D:盤的s3c44b0目錄下
tarzxvfu-boot-xxxxxxxx.tar.gz
b) 解壓后進(jìn)入u-boot目錄,輸入 makedistclean 清除上一次編譯的輸出文件
C) 輸入 makeITSN_s3c44b0_config ,以產(chǎn)生一些編譯配置文件(.mk文件)和相應(yīng)的一些頭文件(.h文件)
d) 編譯,執(zhí)行 make 。
這一步驟生成了三個文件,其中:
u-boot,ELF文件格式,使用Flashpgm工具來打開此文件編程到Flash當(dāng)中
u-boot.bin是二進(jìn)制文件,使用Fluted工具來將此文件編程到Flash當(dāng)中
5. U- BOOT 下載
在這里我們介紹兩種方法來將編譯好的U-Boot編程Flash,一種是使用Flashpgm工具,另外一種是Fluted工具。
a) FlashPgm
FlashPgm是什么公司的,是一個GUI界面的Flash編成工具。由于其友好的編程界面,更快的編程速度和更高的編程成功率使其被大家普遍使用。在使用FlashPgm編程Flash的時候注意使用JTAG板的Wiggler接口連接到目標(biāo)板上,F(xiàn)lashPgm不支持STD的JTAG接口。打開Configuration菜單下的Communications可以設(shè)置設(shè)置FlashPgm的連接方式,在這里我使用,同時確保JTAG板的J5條線到Wiggler接口狀態(tài)。
們
點(diǎn)擊菜單File-Open選擇.ocd文件。Ooc文件是一個硬件系統(tǒng)的配置文件,設(shè)置了CPU,Flash類型,F(xiàn)lash接口的位寬等具體的參數(shù),可通過FlashPgm生成。光盤上已經(jīng)帶有兩個已經(jīng)配置好的.ocd文件,在光盤:/工具/Flash編程工具/目錄,其中包含兩個.ocd文件。
44B0X_SST.ocd —— 配有SST39VF160Flash的學(xué)習(xí)板使用
44B0X_AMD.ocd —— 配有AM29LV160Flash的學(xué)習(xí)板使用
點(diǎn)擊FlashID按鈕檢測一下FlashID能夠讀取到,以測試JTAG連接是否正常。如果能夠正常讀取出來,表示JTAG連接沒有問題
點(diǎn)擊Program按鈕,在出現(xiàn)的對話框中選擇編譯好的u-boot文件(ELF格式的),然后選擇在編程前先擦除選型,點(diǎn)擊Program。首先將會擦除相應(yīng)的Flash區(qū)域,然后編程和校驗(yàn)。進(jìn)度條將顯示當(dāng)前編程進(jìn)度。
正在擦除 Flash
編程,校驗(yàn)成功
這時候超級中斷將顯示 U-BOOT 打印輸出,通過 FlashPgm 成功的將 U-BOOT 燒寫到 Flash 當(dāng)中。
B) Fluted.exe
Fluted.exe是一個基于命令行方式的Flash編程工具,其只支持STD方式的JTAG鏈接。以下是其運(yùn)行的參數(shù):
命令:(大小寫無關(guān))
R —— 讀Flash
W —— 寫Flash
E —— 擦除Flash
V —— 校驗(yàn)Flash
T —— 測試掃描線
A —— 擦除+寫Flash
選項(xiàng):(大小寫無關(guān))
-V校驗(yàn)(默認(rèn)是關(guān)閉的,也就是說默認(rèn)不校驗(yàn))
-DDebug模式(默認(rèn)關(guān)閉)
-C指定配置文件(默認(rèn)是default.fcd)
-F指定數(shù)據(jù)文件
-S指定Flash起始地址(十進(jìn)制方式)
-L指定寫入的數(shù)據(jù)長度(256或者文件的大小,十進(jìn)制方式)
一般我們使用Fluted.exe的方法如下,
allowio.exeFluted/aA – Fu-boot.bin-V-S0
此命令將u-boot.bin文件(二進(jìn)制)寫入到Flash,從地址0開始,使用默認(rèn)的default.fcd文件,通常編寫將上述命令放在一個.bat批處理文件來方便執(zhí)行。
Fluted.exe工具編程的速度相對FlashPgm要慢得多,參看下圖實(shí)際的編程過程。
Fluted.exe 工具編程過程
6. U-BOOT的使用
系統(tǒng)上電后,U-BOOT開始執(zhí)行,在串口超級終端軟件上將有答應(yīng)輸出,在3秒鐘內(nèi)按任意鍵,將進(jìn)入U(xiǎn)-BOOT命令提示符,如下圖。其中輸出信息提示SDRAM是8M字節(jié),F(xiàn)lash是2M字節(jié)。
執(zhí)行help指令,將顯示U-BOOT支持命令,常用U-BOOT指令有:
命令 |
功能 |
go |
執(zhí)行指定地址上的程序 |
bootm |
引導(dǎo)應(yīng)用程序或者操作系統(tǒng)(壓縮格式) |
tftp |
通過太網(wǎng)調(diào)入指定的文件到指定的內(nèi)存地址 |
loadb |
通過串口以kermit方式下載文件 |
md |
Memorydisplay,顯示指定地址的值 |
mm |
ModifyMemory,修改內(nèi)存指定地址的值 |
mw |
MemoryWrite,寫內(nèi)存 |
cp |
數(shù)據(jù)復(fù)制,如果目的地址空間在Flash中,就可以通過cp來寫Flash |
printenv |
顯示環(huán)境變量,如IP地址等 |
setenv |
設(shè)置環(huán)境變量 |
Saveenv |
保存環(huán)境變量 |
erase |
擦除指定地址的Flash |
flinfo |
顯示Flash的信息 |
reset |
復(fù)位CPU |
version |
顯示版本信息 |
?/help |
顯示幫助信息 |
二. uClinux 編譯與下載
1 .建立編譯環(huán)境
與在 Windows 的 Cygwin 環(huán)境下編譯 U-BOOT 類似,我們在 linux 下編譯運(yùn)行在 ARM 上的程序同樣需要使用交叉編譯工具 armtools 。將光盤: / 工具 / 編程工具 /armtools/linux 版本 /arm-elf-tools-20040427.sh 拷貝到硬盤后執(zhí)行這個程序?qū)詣影惭b此 armtools 交叉編譯器。
2. 編譯 uClinux
將 uClinux 的壓縮包拷貝到 linux 主機(jī)上,然后通過下列命令解壓縮源碼包,這樣會在當(dāng)前的目錄下面生成 uClinux-dist 目錄。(在這里,我們通過通過 SecureCRT 超級終端工具用 ssh 登陸到 Linux 主機(jī)的 , 因?yàn)樵? Cygwin 的虛擬 Linux 環(huán)境下不能使用 makemenuconfig 。)
tarzxvfuClinux-dist-xxxxxxxx.tar.gz
進(jìn)入 uClinux-Distru 目錄執(zhí)行 makemenuconfig ,將彈出以下的配置 uClinux 界面,如下。
選擇
Vendor/ProductSelection--->
進(jìn)入下級菜單,我們的配置如下:
選擇 Exit 返回上級界面,然后選擇 Kernel/Library/DefaultsSelection---> ,界面如圖:在這里我們我們選擇了使用的 linux 內(nèi)核版本 linux-2.4.x , Libc 版本選擇 uClibc ,然后選中 CustomizeKernelSettings( 內(nèi)核配置 ) 和 CustomizeVendor/UserSettings(NEW)( 廠商 / 用戶程序設(shè)置 ) 進(jìn)行更進(jìn)一步的配置。
退出后選擇Yes保存配置信息,如下圖。
我們在上面配置的時候選擇了CustomizeKernelSettings和CustomizeVendor/UserSettings(NEW)選項(xiàng)。所以程序會自動進(jìn)入KernelSettings和Vendor/UserSettings界面。
注:makemenuconfig將打開上一次的配置選項(xiàng),如果希望重新構(gòu)建一個全新的內(nèi)核,可以在makemenuconfig之前先運(yùn)行makemrproper。
KernelSettings
,內(nèi)核配置界面
Vendor/UserSettings界面
這樣完成了上面兩個配置后,整個uClinux的配置就結(jié)束了。接下來編譯uClinux。依次執(zhí)行如下指令:
makedep
makeclean
makelib_only
makeuser_only
makeromfs
makeimage (這一步報(bào)錯不用管,只要下一步?jīng)]有錯就行)
make
完成所有的操作后,在uClinux-dist/images/目錄下將生成uclinux_rom.bin(二進(jìn)制壓縮文件)。接下來我們可以通過U-BOOT配合串口或者網(wǎng)口來將此文件下載到Flash當(dāng)中。
3. 將 uClinux 下載到 Flash
我們這里通過U-BOOT提供的幾種方式來將編譯好的uClinux下載到Flash當(dāng)中運(yùn)行。
a )串口下載(下載速度慢):
在 U-BOOT 命令提示符下輸入 loadb0xC500000 命令 (0xC500000 是下載文件存放的地址, SDRAM 中 ) , U-BOOT 將等待用戶傳送文件。然后我們啟動超級終端的文件發(fā)送,點(diǎn)擊菜單傳送 -> 發(fā)送文件,出現(xiàn)發(fā)送文件對話框。選擇好發(fā)送協(xié)議為 Kermit 協(xié)議,選擇發(fā)送的文件,然后點(diǎn)擊發(fā)送。這時候出現(xiàn)發(fā)送進(jìn)度對話框
文件發(fā)送完后, uClinux 的壓縮的二進(jìn)制文件就存放在地址 0xC500000 ( SDRAM 空間)上了。
如果我們要測試新編譯的 uClinux 運(yùn)行情況,可以直接輸入 bootm 命令,這樣 U-BOOT 就會在當(dāng)前放置下載的程序的地方 ( 這里是 0xC500000) 解壓縮代碼到指定地址,然后跳轉(zhuǎn)到這個地址開始運(yùn)行程序
接下來我們通過cp命令將數(shù)據(jù)從0xC500000寫入到Flash中的0x50000開始的地方。在復(fù)制數(shù)據(jù)之前,先將Flash對應(yīng)的區(qū)域刪除。拷貝數(shù)據(jù)的長度是按照雙字來操作的,所以我們需要將字節(jié)長度/4+1來得到最終要輸入的長度參數(shù)(16進(jìn)制)。
數(shù)據(jù)寫入到Flash空間的0x50000后,我們可以重啟我們的系統(tǒng),就可以看到這個啟動過程了。U-Boot啟動后,3秒鐘內(nèi)如果超級終端沒有任何輸入,就會自動從Flash0x50000(0x50000這個地址是U-B0OT程序編程固定的,可以根據(jù)需要修改)的地址上將壓縮的uClinux解壓縮到0xc008000(SDRAM)上,然后跳轉(zhuǎn)到這個地址上,開始uClinux的啟動。
b) 網(wǎng)口下載(下載速度快):
網(wǎng)口下載是通過tftp協(xié)議的,在下載之前先確認(rèn)一下U-BOOT的環(huán)境變量配置是否正確,在U-BOOT的命 令提示符下輸入printenv顯示環(huán)境變量(啟動參數(shù)),如下圖:
其主要的環(huán)境參數(shù)包括:
bootcmd —— 啟動命令,也就是U-Boot啟動后如果在指定時間內(nèi)沒有按下任何按鍵后執(zhí)行的指令。
bootdelay —— 指定自動啟動的等待時間,單位為秒
baudrate —— 串口波特率
etheaddr —— 以太網(wǎng)芯片的MAC地址
stdin —— 指定標(biāo)準(zhǔn)輸入設(shè)備
stdout —— 指定標(biāo)準(zhǔn)輸出設(shè)備
stderr —— 指定標(biāo)準(zhǔn)錯誤輸出設(shè)備
bootfile —— 通過tftp從服務(wù)器上獲取的文件名
ipaddr —— 本機(jī)(S3C44B0板)的IP地址
serverip —— 運(yùn)行tftp服務(wù)器程序的PC機(jī)IP地址
我們在使用tftp下載的時候要關(guān)心的參數(shù)是bootfile,ipaddr,serverip三個。
需要保證服務(wù)器的IP與目標(biāo)板的IP在同一個網(wǎng)段內(nèi)。如果需要修改參數(shù)可以通過setenv命令修改,例如:
=>setenvipaddr192.168.1.104//設(shè)置本級的IP為192.168.1.104
=>setenvserverip192.168.1.100//設(shè)置Server的IP為192.168.1.100
=>setenvbootfile “ uclinux_rom.bin ” //設(shè)置tftp獲取uclinux_rom.bin文件
注意在使用的時候不要使用 “ = ” ,例如setenvipaddr=192.168.1.104是錯誤。
先將PC機(jī)的tftp服務(wù)器軟件啟動,在這里我們使用的CiscoTFTPServer(安裝文件在光盤:/工具/FTP軟件/tftpserver/TFTPServer1-1-980730.exe)。第一次啟動我們需要設(shè)置tftp服務(wù)器的本地路徑,點(diǎn)擊view->Options彈出tftp設(shè)置窗口,如圖6-13所示。在這里我們主要設(shè)置tftp的服務(wù)器路徑(就是包含你需要下載到學(xué)習(xí)板的文件的目錄路徑)。單擊確定后,tftp服務(wù)器就設(shè)置好了,這時候我們可以使用U-Boot來下載uclinux到目標(biāo)板上了。
然后在U-BOOT命令提示符下輸入tftp0xC500000命令,下載就開始了。下載完后界面如下:
tftp 下載完界面
同時CiscoTFTPServer也將打印相應(yīng)的信息,如下圖。
后續(xù)的操作如同串口下載一樣,我們可以通過bootm直接解壓縮代碼執(zhí)行,也可以先將Flash擦除,然后通過cp命令將壓縮代碼寫入Flash,這樣每次U-BOOT都能夠在啟動的時候自動解壓并運(yùn)行這個程序。
我們也可以使用光盤:/工具/FTP軟件/tftpserver/tftpd32.exe這一個tftp服務(wù)器端軟件,其使用方法很簡單,無需安裝,直接啟動后設(shè)置下載文件的服務(wù)器路徑(此路徑包含了我們需要下載的文件)就好了。下載界面參看下圖
三. 應(yīng)用程序
lo 1 . Helloworld
建立 helloworld 應(yīng)用程序步驟如下:
在 uClinux-dist/user 目錄下新建目錄: Myapp
1 . 1 編寫 Helloworld 程序
編寫 demo.c 文件,代碼如下:
#include<stdlib.h>
#include<stdio.h>
intmain(void)
{
printf( “ HelloWorld!Thisismyfirstapplication./n ” );
return0;
}
保存在 Myapp 目錄下。
1 . 2 編寫 Makefile 文件
內(nèi)容如下:
EXEC=demo
OBJS=demo.o
all:$(EXEC)
$(EXEC):$(OBJS)
$(CC)$(LDFLAGS)-o$@$(OBJS)$(LDLIBS)
romfs:
$(ROMFSINST)/bin/$(EXEC)
clean:
-rm-f$(EXEC)*.elf*.gdb*.o
同樣放在 Myapp 目錄下。
1 . 3 修改 user/Makefile
為了讓編譯器編譯上述添加的內(nèi)容,在 user/Makefile 中添加一句(一般按照字母
排列):
dir_$(CONFIG_USER_MYAPP_DEMO)+=Myapp
1 . 4 修改 config/config.in
config/config.in 文件中添加的內(nèi)容會在對用戶選項(xiàng)進(jìn)行配置時反映出來。在文件
的最后,增加一條:
###################################################################
mainmenu_optionnext_comment
comment'MyNewApplication'
bool'demo'CONFIG_USER_MYAPP_DEMO
endmenu
###################################################################
輸入 makemenuconfig
選擇
然后 exit 保存,自動進(jìn)入下一個畫面
選擇 Myapplication 回車,出現(xiàn)
選中,然后退出,保存。
接著執(zhí)行:
makedep
makeclean
makelib_only
makeuser_only
makeromfs
makeimage
make
下載到開發(fā)板,可以通過串口終端在 teraterm 看到 bin 下面多了一個 demo 程序。
輸入 ./demo 啟動演示程序
輸出: HelloWorld!Thisismyfirstapplication.
四. 驅(qū)動程序的編寫
一個簡單的驅(qū)動程序
一個典型的驅(qū)動程序 , 大體上可以分為以下兩個方面 :
1) 注冊設(shè)備 : 在系統(tǒng)初啟時 , 必須將設(shè)備登記到相應(yīng)的設(shè)備數(shù)組 , 例如 : 對于字符驅(qū)動設(shè)備來說 , 要使用 register-chrdev() 來注冊設(shè)備的驅(qū)動號 , 然后對這個設(shè)備的所有調(diào)用都用這個設(shè)備號來實(shí)現(xiàn) ;
2) 定義功能函數(shù) : 對于每一個驅(qū)動函數(shù)來說 , 都有一些和此設(shè)備密切相關(guān)的功能函數(shù) , 就最常用的字符設(shè)備來說 , 都存在著諸如 open() 、 read() 、 write() 、 ioctrol() 這一類的操作。當(dāng)系統(tǒng)調(diào)用這些操作時 , 將自動的使用 file-operations 結(jié)構(gòu)中對應(yīng)的函數(shù)來實(shí)現(xiàn)具體的操作 ; 在編寫驅(qū)動程序前 , 不得不提 file-operations 這個結(jié)構(gòu) , 每個設(shè)備都有自己的 file-operations 結(jié)構(gòu) , 它定義了設(shè)備的基本入口
點(diǎn) , 即上面提到的功能函數(shù)。下面以一個簡單的演示例子 , 說明編寫字符設(shè)備驅(qū)動程序的具體過程 , 設(shè)備取名為“ test ” , 設(shè)備號定為 254, 當(dāng)然這個設(shè)備并沒有涉及真正的硬件 , 僅是從內(nèi)核空間拷貝了一些特定數(shù)據(jù)到用戶空間。
第一步 : 在目錄 /linux-2 . 4 .x /drives/char 編寫源
程序 test.c, 源碼如下 :
頭文件和全局變量 :
#include<linux/module.h>
#include<linux/kernel.h>
#include<linux/types.h>
#include<linux/fs.h>
#include<linux/mm.h>
#include<linux/errno.h>
#include<asm/uaccess.h>
inttest_major=254;
// 讀函數(shù) , 僅向用戶緩沖區(qū)填入數(shù)據(jù) 1
staticssize_tread_test(structfile*file,char*buf,ssize_tcount,loff_t*f_pos)
{
intleft,ret;
chardata=0x41;
for(left=count;left>0;left--)
{
put_user(data,buf);buf++;}
returncount;
}
// 寫函數(shù) , 空操作
staticssize_twrite_test(structfile*file,char*buf,ssize_tcount,loff_t*f_pos)
{returncount;
}
// 打開函數(shù)
staticintopen_test(structinode*inode,structfile*file)
{
MOD_INC_USE_COUNT;return0;}
// 釋放函數(shù)
staticvoidrelease_test(structinode*inode,structfile*file)
{
MOD_DEC_USE_COUNT;}
structfile_operationstest_fops={
read:read_test,
write:write_test,
open:open_test,
release:release_test,
};
// 注冊函數(shù)
inttest_init(void)
{
intresult;
result=register_chrdev(254,"test",&test_fops);
if(result<0){printk("test:cannotgetmajornumber!/n");
returnresult;}
return0;
}
// 撤消函數(shù)
voidcleanup_module(void)
{unregister_chrdev(test_major,"test");}
第二步 : 添加設(shè)備 ;
1) 修改 l in ux-2 . 4.x/driver/char/Makefile 在適當(dāng)位置添加一行 :obj - $ (CONFIG - TEST)+=test.o
2)linux-2 1 4.x/driver/char/Config.in, 添加一行 :bool ’ testdevice ’ CONFIG - TEST
3) 修改 linux-2 1 4.x/driver/char/mem.c 在適當(dāng)位置添加 :
#ifdefCONFIG - TEST
externvoidtest - init(void);
#endif
同時在 chr - dev - init() 函數(shù)中添加 :
#ifdefCONFIG - TEST
test - init();
#endif
4) 修改 vendor/Samsung/44bb0/Makefile 建立設(shè)備節(jié)點(diǎn) :
在 12---35 行間 ,DEVICE 部分添加如下內(nèi)容 test,c,254,0
5)makemenuconfig, 在 characterdevice 選中 testdevice
重新編譯內(nèi)核 , 在控制臺輸入
/proc>catdevices
Characterdevices:
1mem
2pty
3ttyp
4ttyS
5cua
10misc
162raw
180usb
254test
Blockdevices:
1ramdisk
31Blkmem
/proc>
就包含了名為“ test ”的設(shè)備驅(qū)動 , 下面的例子是用于驗(yàn)證這個設(shè)備驅(qū)動程序 .
B. 應(yīng)用程序的編寫
在μ CLinux 的 /user 目錄下提供許多資源供開發(fā)者參考。下面以上節(jié)提到的源程序?yàn)槔? , 說明在μ CLinux 中加入自己應(yīng)用程序的過程。第一步 : 首先在 /user/ 目錄下建立自己的文件夾如 , 取名 apptest, 然后在新建文件夾 (apptest) 下編輯自己的應(yīng)用程序 apptest.c( 源碼為上面的設(shè)備驅(qū)動驗(yàn)證程序 ), 然后參照 user 目錄下其他應(yīng)用程序編寫自己的 makefile, 同樣保存
在文件 apptest 下 ;
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<fcntl.h>
#include<sys/types.h>
#include<sys/stat.h>
main()
{
intfd,i,j;
charbuf[10];
fd=open("/dev/test",O_RDWR);
if(fd<0)
{
printf("cannotopenfile/n");
exit(0);
}
j=read(fd,buf,10);
for(i=0;i<j;i++)
printf("%d/n",buf[i]);
close(fd);
}
第二步 : 在 /user/Makefile 中適當(dāng)位置加入下行語句 :
dir - $ (CONFIG - USER - APPTEST)+=apptest
第三步 : 在 /config/Configure.help 的適當(dāng)位置添加以下語句 :
CONFIG - USER - APPTEST
ThisprogramdoesAPPTESTthingstoyourbars.
第四步 : 在 /config/config.in 的適當(dāng)位置添加以下語句 :
bool ’ apptest ’ CONFIG - USER - APPTEST
最后再重新編譯內(nèi)核 , 在 makemenuconfig 時 , 選中自己的應(yīng)用程序 , 完成后在 /
bin 目錄可以看見 ap2ptest 的可執(zhí)行文件 , 通過控制臺直接輸入該文件名即可
運(yùn)行該程序 ! 當(dāng)然也可以在文件 vendor/Samsung/44B0/rc 中添加文件名
apptest, 重新編譯 , 在 uclinux 啟動后自動執(zhí)行該應(yīng)用程序 .
字符設(shè)備的另一種做法
(這個設(shè)備驅(qū)動程序是讓蜂鳴器叫)
這里不采用前面提到的 file 結(jié)構(gòu)中的 readwrite 等,而使用 IOCTL 來實(shí)現(xiàn)。
首先修改前面給出的 test.c ,添加 Port_init 函數(shù),這個函數(shù)用來初始化 I/O 配置寄存器。然
后就是修改
structfile_operationstest_fops={
ioctl:ledman_ioctl,/*ledman_ioctl*/
};
去除原先的內(nèi)部結(jié)構(gòu),最后定義 ledman_ioctl 函數(shù)。整個驅(qū)動程序的結(jié)構(gòu)如下,
#include<linux/module.h>
#include<linux/kernel.h>
#include<linux/types.h>
#include<linux/fs.h>
#include<linux/mm.h>
#include<linux/errno.h>
#include<asm/uaccess.h>
#include<asm/arch/s3c44b0x.h>
inttest_major=254;
#defineNon_Cache_Start(0x2000000)
#defineNon_Cache_End(0xc000000)
#defineBEEP_CMD_SIGNAL0
/*************************PORTS****************************/
staticintledman_ioctl(structinode*inode,structfile*file,unsignedintcmd,unsignedlongarg);
voidPort_Init(void)
{
(*(volatileunsigned*)S3C44B0X_PCONA)=0x1ff;
(*(volatileunsigned*)S3C44B0X_PDATB)=0x3ff;
(*(volatileunsigned*)S3C44B0X_PCONB)=0x3ff;
(*(volatileunsigned*)S3C44B0X_PDATC)=0xffff;//AllI/OIsHigh
(*(volatileunsigned*)S3C44B0X_PCONC)=0x0f05ff55;
(*(volatileunsigned*)S3C44B0X_PUPC)=0x30f0;//PULLUPRESISTORshouldbeenabledtoI/O
(*(volatileunsigned*)S3C44B0X_PDATD)=0xff;
(*(volatileunsigned*)S3C44B0X_PCOND)=0x0;
(*(volatileunsigned*)S3C44B0X_PUPD)=0x0;
(*(volatileunsigned*)S3C44B0X_PDATE)=0x1ff;
(*(volatileunsigned*)S3C44B0X_PCONE)=0x25568;
(*(volatileunsigned*)S3C44B0X_PUPE)=0x0df;pull-upresistor.
(*(volatileunsigned*)S3C44B0X_PDATF)=0x1ff;//AllI/OIsHigh
(*(volatileunsigned*)S3C44B0X_PCONF)=0x20900a;//AllNCisINPUT
(*(volatileunsigned*)S3C44B0X_PUPF)=0x163;
(*(volatileunsigned*)S3C44B0X_PDATG)=0xff;
(*(volatileunsigned*)S3C44B0X_PCONG)=0x00ff;
(*(volatileunsigned*)S3C44B0X_PUPG)=0x0;//shouldbeenabled
(*(volatileunsigned*)S3C44B0X_SPUCR)=0x7;//D15-D0pull-updisable
(*(volatileunsigned*)S3C44B0X_EXTINT)=0x0;//AllEXTINT0-7Lowlevelinterrupt
(*(volatileunsigned*) S3C44B0X_NCACHBE0)=0;//((Non_Cache_End>>12)<<16)|(Non_Cache_Start>>12);
}
voidBeep(intBeepStatus)
{
//PE5Lowavailable
if(BeepStatus==0)
(*(volatileunsigned*)S3C44B0X_PDATE)=(*(volatileunsigned*)S3C44B0X_PDATE)&0x1df;
else
(*(volatileunsigned*)S3C44B0X_PDATE)=(*(volatileunsigned*)S3C44B0X_PDATE)|0x020;
}
staticint ledman_ioctl(
structinode*inode,structfile*file,unsignedintcmd,unsignedlongarg)
{
inti;
if(cmd==BEEP_CMD_SIGNAL){
printk("beep0/n");
Beep(0);
return(0);
}
e lse
{
printk("beep1/n");
Beep(1);
}
return0;
}
structfile_operationstest_fops={
ioctl:ledman_ioctl,/*ledman_ioctl*/
};
inttest_init(void)
{
intresult;
result=register_chrdev(254,"test",&test_fops);
if(result<0){printk("test:cannotgetmajornumber!/n");
returnresult;}
return0;
}
voidcleanup_module(void)
{unregister_chrdev(test_major,"test");}
其余文件不要動,將 test.c 存盤到 44b0 當(dāng)前目錄下的 /linux-xxx/driver/char 然后在 44b0 目
錄下面 Make 進(jìn)行編譯。
接著修改應(yīng)用程序 apptest ,這個比較簡單,程序如下:
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<fcntl.h>
#include<sys/types.h>
#include<sys/stat.h>
main()
{
intfd,i,j;
charbuf[10];
fd=open("/dev/test",O_RDWR);
if(fd<0){printf("cannotopenfile/n");
exit(0);
}
ioctl(fd,1,0);// 第 2 個參數(shù) 1 表示喇叭叫 ,0 表示不叫
close(fd);
}
其中把原先的 read,write 等調(diào)用改為 IOCTL 函數(shù)調(diào)用。
存盤后,執(zhí)行 makeuser_only 進(jìn)行編譯。
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
