S3C2440完全開發(fā)流程_第1頁
S3C2440完全開發(fā)流程_第2頁
S3C2440完全開發(fā)流程_第3頁
S3C2440完全開發(fā)流程_第4頁
S3C2440完全開發(fā)流程_第5頁
已閱讀5頁,還剩67頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、s3c2440 開發(fā)流程 ocean university of china s3c2440完全開發(fā)流程完全開發(fā)流程 作者: 2009-11-3 一簡(jiǎn)介一簡(jiǎn)介.3 二建立開發(fā)環(huán)境二建立開發(fā)環(huán)境 .4 1、編譯器、編譯器arm-linux-gcc- 2、jflash-s3c2440:s3c2440 芯片的芯片的 jtag 工具工具.4 3、安裝、安裝gdb調(diào)試工具調(diào)試工具 .5 4、usb 下載工具下載工具 .6 5、ubuntu開發(fā)環(huán)境建立開發(fā)環(huán)境建立.6 三三s3c2440 基礎(chǔ)實(shí)驗(yàn)基礎(chǔ)實(shí)驗(yàn).8 1、實(shí)驗(yàn)一:、實(shí)驗(yàn)一:led_on.8 2、實(shí)驗(yàn)二:、實(shí)驗(yàn)二:led_on_c.9

2、 3、實(shí)驗(yàn)三:、實(shí)驗(yàn)三:i/o ports.11 5、實(shí)驗(yàn)五:、實(shí)驗(yàn)五:memory controller.15 6、實(shí)驗(yàn)六:、實(shí)驗(yàn)六:nand flash controller.17 7、實(shí)驗(yàn)七:、實(shí)驗(yàn)七:uart.20 8、實(shí)驗(yàn)八:、實(shí)驗(yàn)八:printf、scanf.24 9、實(shí)驗(yàn)九:、實(shí)驗(yàn)九:interrupt controller .24 10、實(shí)驗(yàn)十:、實(shí)驗(yàn)十:timer.29 11、實(shí)驗(yàn)十一:、實(shí)驗(yàn)十一:mmu.32 12、實(shí)驗(yàn)十二:、實(shí)驗(yàn)十二:clock .39 四四bootloader vivi.43 1、階段、階段 1:arch/s3c2440/head.s.43 2、階段、

3、階段 2:init/main.c.45 1)、step 1:reset_handler().45 2)、step 2:board_init().46 3)、step 3:建立頁表和啟動(dòng)mmu.47 4)、step 4:heap_init().50 5)、step 5:mtd_dev_init().52 6)、step 6:init_priv_data().56 7)、step 7:misc()和init_builtin_cmds().57 8)、step 8:boot_or_vivi().58 五五附錄一附錄一 vi 命令解釋命令解釋.65 1、help命令命令.65 2、mem命令命令.65

4、 3、load命令命令.66 4、param命令命令 .67 5、part命令命令.69 6、boot命令命令.70 e-mail: qq: 389658188 http:/ 2 7、bon命令命令 .71 e-mail: qq: 389658188 http:/ 3 一簡(jiǎn)介一簡(jiǎn)介 本書面向由傳統(tǒng)51單片機(jī)轉(zhuǎn)向arm嵌入式開發(fā)的硬件工程師、由硬件轉(zhuǎn)嵌入式 軟件開發(fā)的工程師、沒有嵌入式開發(fā)經(jīng)驗(yàn)的軟件工程師,本書開發(fā)板基于天嵌科技 的tq s3c2440開發(fā)板,其官方網(wǎng)站為:http:/ 1、開發(fā)環(huán)境建立 2、s3c2440功能部件介紹與實(shí)驗(yàn)(含實(shí)驗(yàn)代碼) 3、bootloader vivi詳細(xì)注

5、釋 4、linux移植 5、linux驅(qū)動(dòng) 6、yaffs文件系統(tǒng)詳解 7、調(diào)試工具 8、gui開發(fā)簡(jiǎn)介 9、uc/os移植 通過學(xué)習(xí)第二部分,即可了解基于arm cpu的嵌入式開發(fā)所需要的外圍器件 及其接口。對(duì)應(yīng)的實(shí)驗(yàn)代碼實(shí)現(xiàn)了對(duì)這些接口的操作,這可以讓硬件工程師形成一 個(gè)嵌入式硬件開發(fā)的概念。這部分也可以當(dāng)作s3c2440的數(shù)據(jù)手冊(cè)來使用。 一個(gè)完整的嵌入式linux系統(tǒng)包含4部分內(nèi)容: bootloader、parameters、kernel、root file system。3、4、5、6部分詳細(xì)介紹了這4 部分的內(nèi)容,這是linux底層軟件開發(fā)人員應(yīng)該掌握的。通過學(xué)習(xí)這些章節(jié),您可以

6、 詳細(xì)了解到如何在一個(gè)裸板上裁減、移植linux,如何構(gòu)造自己的根文件系統(tǒng),如何 編寫適合客戶需求的驅(qū)動(dòng)程序驅(qū)動(dòng)程序這章將結(jié)合幾個(gè)經(jīng)典的驅(qū)動(dòng)程序進(jìn)行講 解。您還可以了解到在用在nand flash上的非常流行的yaffs文件系統(tǒng)是如何工作的, 本書將結(jié)合yaffs代碼詳細(xì)介紹yaffs文件系統(tǒng)。 第7部分介紹了嵌入式linux開發(fā)中使用gdb進(jìn)行調(diào)試的詳細(xì)過程。 此文檔目前完成了1、2、3部分,后面部分將陸續(xù)完成。希望能對(duì)各位在嵌入式 開發(fā)方面獻(xiàn)上棉力。 歡迎來信指出文中的不足與錯(cuò)誤,歡迎來信探討技術(shù)問題。 email : qq :389658188 e-mail: qq: 389658188

7、 http:/ 4 二建立開發(fā)環(huán)境二建立開發(fā)環(huán)境 1、編譯器、編譯器arm-linux-gcc-3.4.1 下載地址: /projects/toolchain/arm-linux-gcc-3.4.1.tar.bz2 執(zhí)行如下命令安裝: bunzip2 arm-linux-gcc-3.4.1.tar.bz2 tar xvf arm-linux-gcc-3.4.1.tar -c / 生成的編譯工具在目錄/usr/local/arm/3.4.1/bin下,修改/etc/profile,增加如下一 行。這可以讓我們直接運(yùn)行arm-linux-gcc,而不必將

8、其絕對(duì)路徑都寫出來,不過這 得重新啟動(dòng)后才生效: pathmunge /usr/local/arm/3.4.1/bin 這個(gè)交叉編譯器已經(jīng)比較老舊,對(duì)于新版本的編譯器我們有很多選擇,如下表: 表1.常用交叉編譯器 編譯器編譯器地址地址備注備注 crosstool-chain-0.43http:/ 天嵌編譯器(推薦)http:/ codesourceryhttp:/ arm-none-linux-gnueabi ronetix-arm-linuxhttp:/www.ronetix.at/software.html主要針對(duì)at91芯片,可參考 友善編譯器(推薦)http:/ 注注:ronetix-

9、arm-linux-4.3.3.tar.bz2-沒有太多研究 codesourcery的c編譯器,這是arm官方指定的編譯器,可以下載免費(fèi)版本。 codesourcery的編譯器對(duì)于新手來說可能不知如何配置,那么沒有關(guān)系,可以到下載 友善已經(jīng)制作好的基于codesourcery的編譯器。 2、jflash-s3c2440:s3c2440芯片的芯片的jtag工具工具 我們的第一個(gè)程序就是通過它下載到開發(fā)板上的nor flash或者nand flash上去的。 把它放到/usr/local/bin目錄下。 下載地址: e-mail: qq: 389658188 http:/ 5 ftp:/ 注意:

10、步驟3您現(xiàn)在不必理會(huì),可以等進(jìn)行到“調(diào)試”部分時(shí)再回過頭來看。 jlink-v7 如果手頭有這個(gè)調(diào)試工具,那么使用起來會(huì)非常方便,而且支持 ads,mdk,iar,下載速度遠(yuǎn)遠(yuǎn)高于并口jtag小板,由于jlink使用的是usb接口, 對(duì)于沒有并口的本本來說無疑又是一大優(yōu)點(diǎn)。 3、安裝、安裝gdb調(diào)試工具調(diào)試工具 下載地址: /software/gdb/download/ /gnu/gdb/gdb-6.3.tar.gz a、執(zhí)行如下命令安裝: a.安裝在主機(jī)上運(yùn)行的arm-linux-gdb工具: tar xvzf gdb-6.

11、3.tar.gz cd gdb6.3 ./configure -target=arm-linux make make install 此時(shí),在/usr/local/bin中生成arm-linux-gdb等工具 b.繼續(xù)上面的步驟,安裝gdbserver。需要將此工具下載到開發(fā)板上運(yùn)行,這在后 面會(huì)詳細(xì)描述: cd gdbserver export cc=/usr/local/arm/3.4.1/bin/arm-linux-gcc ./configure arm-linux make 此時(shí)在當(dāng)前目錄中生成了gdbserver工具,當(dāng)我們講到如何調(diào)試時(shí),會(huì)把這個(gè)文 件下載到開發(fā)板上去。 b、lin

12、ux程序的調(diào)試也可以使用圖形界面,如果用的是ubuntu,那么可以先安裝ddd 如下命令: sudo apt-get install ddd e-mail: qq: 389658188 http:/ 6 編譯程序時(shí)加入-g參數(shù),然后啟動(dòng)ddd 生成目標(biāo)文件進(jìn)行圖形程序調(diào)試,非常 方便。 4、usb下載工具下載工具 win平臺(tái): 除了通過串口下載程序外,還可以使用usb來下載,速度比串口要快上百倍。 常用的也是三星公司推薦的工具是dnw,目前各大開發(fā)板商已經(jīng)推出自己的升級(jí)版 本dnw,比如友善推出了增加備份功能的dnw,天嵌推出了漢化版的dnw,用起 來會(huì)更方便。這里要注意的是usb驅(qū)動(dòng),如果用

13、三星官方提供的驅(qū)動(dòng),那么會(huì)經(jīng)常 出現(xiàn)死機(jī)藍(lán)屏現(xiàn)象,但是友善已經(jīng)將驅(qū)動(dòng)做了改進(jìn),藍(lán)屏現(xiàn)象得到修改。 linux平臺(tái): 對(duì)于linux平臺(tái),好多人抱怨無法像在win下面那樣下載方便。但是,國內(nèi)的高 手們已經(jīng)將dnw移植到了linux平臺(tái)上,常見的有兩個(gè)版本,一個(gè)是字符模式版本, 一個(gè)是gui版本(基于qt),后者要自己編譯,當(dāng)然也可以使用編譯好的二進(jìn)制文 件,前提是主機(jī)安裝了qt,并用要在root用戶下運(yùn)行程序。 對(duì)于調(diào)度工具,linux下也可以用jlink,相關(guān)驅(qū)動(dòng)可以去segger官方下載驅(qū)動(dòng),不過 只有字符模式。 5、ubuntu開發(fā)環(huán)境建立開發(fā)環(huán)境建立 系統(tǒng)安裝: 將分區(qū)作如下調(diào)整,一個(gè)根

14、目錄,一個(gè)交換分區(qū),一個(gè)工作目錄 / /work /swap 5g10g 1g 更改升級(jí)源: sudo gedit /etc/apt/source.list 一般情況下,國內(nèi)比較好的源有重慶電子,北京交通,上海交通這些教育網(wǎng)資 源,另外臺(tái)灣那邊速度也不錯(cuò)。 安裝必要工具: (1)vsftpd sudo apt-get install vsftpd 配置:將write_enable=no改為write_enable=yes e-mail: qq: 389658188 http:/ 7 將local_enable=no改為local_enbale=yes 然后將服務(wù)配置重新啟動(dòng)一下: sudo /

15、etc/init.d/vsftpd restart (2)ssh sudo apt-get install openssh-server (3)nfs service sudo apt-get install nfs-kernel-server portmap 配置:打開/etc/exports,添加如下內(nèi)容: /work/nfs_root *(rw,sync,no_root_squash) 然后將服務(wù)重新啟動(dòng)一下: sudo /etc/init.d/nfs-kernel-server restart (4)安裝二進(jìn)制工具包 sudo apt-get install build-essenti

16、al/語法詞法分析器 sudo apt-get install bison flex/同上 sudo apt-get install manpages-dev/man手冊(cè) (5)將下載好的交叉編譯器安裝到系統(tǒng)中 一般情況下,要將編譯器放到/usr/local/arm/4.3.2/目錄下,然后在/.bashrc中將 編譯器的環(huán)境變量加入其中,如果在終端中輸入arm-none-linux-gcc v出現(xiàn)相應(yīng)的版 本信息,那么說明已經(jīng)安裝成功。 (6)安裝ncurses 官方下載地址:/software/ncurses/ 下載源碼,然后手工編譯安裝: cd /wor

17、k/tools tar xzf ncurses.tar.gz cd ncurses-5.6 ./configure with-shared prefix=/usr make sudo make install e-mail: qq: 389658188 http:/ 8 三三s3c2440基礎(chǔ)實(shí)驗(yàn)基礎(chǔ)實(shí)驗(yàn) 本章將逐一介紹s3c2440各功能模塊,并結(jié)合簡(jiǎn)單的程序進(jìn)行上機(jī)實(shí)驗(yàn)。您不 必將本章各節(jié)都看完,完全可以看了一、兩節(jié),得到一個(gè)大概的印象之后,就開始 下一章。本章可以當(dāng)作手冊(cè)來用。 注意:了解s3c2440各部件最好的參考資料是它的數(shù)據(jù)手冊(cè)。本文不打算翻譯該手 冊(cè),在進(jìn)行必要的講解后,進(jìn)行實(shí)

18、際實(shí)驗(yàn)這才是本文的重點(diǎn)。 1、實(shí)驗(yàn)一:、實(shí)驗(yàn)一:led_on led_on.s只有7條指令,它只是簡(jiǎn)單地點(diǎn)亮發(fā)光二極管led1。本實(shí)驗(yàn)的目的是讓 您對(duì)開發(fā)流程有個(gè)基本概念。 實(shí)驗(yàn)步驟: a把pc并口和開發(fā)板jtag接口連起來、確保插上“boot sel”跳線、上電(呵 呵,廢話,如果以后實(shí)驗(yàn)步驟中未特別指出,則本步驟省略) b進(jìn)入led_on目錄后,執(zhí)行如下命令生成可執(zhí)行文件led_on:make c執(zhí)行如下命令將led_on寫入nand flash: i. jflash-s3c2440 led_on /t=5 ii.當(dāng)出現(xiàn)如下提示時(shí),輸入0并回車: iii. 當(dāng)出現(xiàn)如下提示時(shí),輸入0并回車:

19、 iv. 當(dāng)再次出現(xiàn)與步驟ii相同的提示時(shí),輸入2并回車 d按開發(fā)板上reset鍵后可看見led1被點(diǎn)亮了 實(shí)驗(yàn)步驟總地來說分3類:編寫源程序、編譯/連接程序、燒寫代碼。 先看看源程序led_on.s: .text .global _start _start: ldr r0,=0 x56000010 r0設(shè)為gpbcon寄存器。此寄存器 用于選擇端口b各引腳的功能: 是輸出、是輸入、還是其他 mov r1,#0 x00004000 e-mail: qq: 389658188 http:/ 9 str r1,r0 設(shè)置gpb7為輸出口 ldr r0,=0 x56000014 r0設(shè)為gpbdat

20、寄存器。此寄存器 用于讀/寫端口b各引腳的數(shù)據(jù) mov r1,#0 x00000000 此值改為0 x00000080, 可讓led1熄滅 str r1,r0 gpb7輸出0,led1點(diǎn)亮 main_loop: b main_loop 對(duì)于程序中用到的寄存器gpbcon、gpbdat,我稍作描述,具體寄存器的操 作可看實(shí)驗(yàn)三:i/o ports。gpbcon用于選擇port b的11根引腳的功能:輸出、 輸入還是其他特殊功能。每根引腳用2位來設(shè)置:00表示輸入、01表示輸出、10表示 特殊功能、11保留不用。led1-3的引腳是gpb7-gpb10,使用gpbcon中位12:13、 13:14

21、、15:16、17:18來進(jìn)行功能設(shè)置。gpbdat用來讀/寫引腳:gpb0對(duì)應(yīng)位 0、gpb1對(duì)應(yīng)位1,諸如此類。當(dāng)引腳設(shè)為輸出時(shí),寫入0或1可使相應(yīng)引腳輸出低電 平或高電平。 程序很簡(jiǎn)單,第4、5、6行3條指令用于將led1對(duì)應(yīng)的引腳設(shè)成輸出引腳;第 7、8、9行3條指令讓這條引腳輸出0;第11行指令是個(gè)死循環(huán)。 實(shí)驗(yàn)步驟b中,指令“make”的作用就是編譯、連接led_on.s源程序。makefile的內(nèi)容 如下: led_on:led_on.s arm-linux-gcc -g -c -o led_on.o led_on.s arm-linux-ld -ttext 0 x0000000

22、 -g led_on.o -o led_on_tmp.o arm-linux-objcopy -o binary -s led_on_tmp.o led_on clean: rm -f led_on rm -f led_on.o rm -f led_on_tmp.o make指令比較第1行中文件led_on和文件led_on.s的時(shí)間,如果led_on的時(shí)間比 led_on.s的時(shí)間舊(led_on未生成時(shí),此條件默認(rèn)成立),則執(zhí)行第2、3、4行的指令更 新led_on。您也可以不用指令make,而直接一條一條地執(zhí)行2、3、4行的指令但 是這樣多累啊。第2行的指令是預(yù)編譯,第3行是連接,第4行

23、是把elf格式的可執(zhí)行 文件led_on_tmp.o轉(zhuǎn)換成二進(jìn)制格式文件led_on。執(zhí)行“make clean”時(shí)強(qiáng)制執(zhí)行 6、7、8行的刪除命令。 注意:makefile文件中相應(yīng)的命令行前一定有一個(gè)制表符(tab) 匯編語言可讀性太差,現(xiàn)在請(qǐng)開始實(shí)驗(yàn)二,我用c語言來實(shí)現(xiàn)了同樣的功能,而 以后的實(shí)驗(yàn),我也盡可能用c語言實(shí)現(xiàn)。 2、實(shí)驗(yàn)二:、實(shí)驗(yàn)二:led_on_c e-mail: qq: 389658188 http:/ 10 c語言程序執(zhí)行的第一條指令,并不在main函數(shù)中。當(dāng)我們生成一個(gè)c程序的可 執(zhí)行文件時(shí),編譯器總是在我們的代碼前加一段固定的代碼crt0.o,它是編譯器 自帶的一個(gè)

24、文件。此段代碼設(shè)置c程序的堆棧等,然后調(diào)用main函數(shù)。很可惜,在 我們的裸板上,這段代碼無法執(zhí)行,所以我們得自己寫一個(gè)。這段代碼很簡(jiǎn)單,只 有3條指令。 crt0.s代碼: .text .global _start _start: ldr sp, =1024*4 設(shè)置堆棧,注意:不能大于4k nand flash中的代碼在復(fù)位后會(huì) 移到內(nèi)部ram中,它只有4k bl main 調(diào)用c程序中的main函數(shù) halt_loop: b halt_loop 現(xiàn)在,我們可以很容易寫出控制led的程序了,led_on_c.c代碼如下: #define gpbcon (*(volatile unsigne

25、d long *)0 x56000010) #define gpbdat (*(volatile unsigned long *)0 x56000014) int main() gpbcon = 0 x00004000; /設(shè)置gpb7為輸出口 gpbdat = 0 x00000000; /令gpb7輸出0 return 0; 最后,我們來看看makefile: led_on_c : crt0.s led_on_c.c arm-linux-gcc -g -c -o crt0.o crt0.s arm-linux-gcc -g -c -o led_on_c.o led_on_c.c arm-li

26、nux-ld -ttext 0 x0000000 -g crt0.o led_on_c.o -o led_on_c_tmp.o arm-linux-objcopy -o binary -s led_on_c_tmp.o led_on_c clean: rm -f led_on_c rm -f led_on_c.o rm -f led_on_c_tmp.o rm -f crt0.o 第2、3行分別對(duì)源程序crt0.s、led_on_c.c進(jìn)行預(yù)編譯,第4行將預(yù)編譯得到的結(jié)果連 接起來,第5行把連接得到的elf格式可執(zhí)行文件led_on_c_tmp.o轉(zhuǎn)換成二進(jìn)制格式 文件led_on_c。 e-

27、mail: qq: 389658188 http:/ 11 好了,可以開始上機(jī)實(shí)驗(yàn)了: 實(shí)驗(yàn)步驟: a進(jìn)入led_on_c目錄后,執(zhí)行如下命令生成可執(zhí)行文件led_on_c: make b執(zhí)行如下命令將led_on_c寫入nand flash: i. jflash-s3c2440 led_on_c /t=5 ii.當(dāng)出現(xiàn)如下提示時(shí),輸入0并回車: k9s1208 nand flash jtag programmer ver 0.0 0:k9s1208 program 1:k9s1208 pr blkpage 2: exit select the function to test : iii.當(dāng)

28、出現(xiàn)如下提示時(shí),輸入0并回車: input target block number: iv.當(dāng)出現(xiàn)與步驟ii相同的提示時(shí),輸入2并回車 c按開發(fā)板上reset鍵后可看見led1被點(diǎn)亮了 目錄leds中的程序是使用4個(gè)led從0到15輪流計(jì)數(shù),您可以試試: a進(jìn)入目錄后make bjflash-s3c2440 leds /t=5 creset運(yùn)行 另外,如果您有興趣,可以使用如下命令看看二進(jìn)制可執(zhí)行文件的反匯編碼: arm-linux-objdump -d -b binary -m arm xxxxx(二進(jìn)制可執(zhí)行文件名) 注意:本文的所有程序均在source目錄中,各程序所在目錄均為大寫,其可

29、 執(zhí)行文件名為相應(yīng)目錄名的小寫,比如leds目錄下的可執(zhí)行文件為leds。以后不再 贅述如何燒寫程序:直接運(yùn)行jflash-s3c2440即可看到提示。 3、實(shí)驗(yàn)三:、實(shí)驗(yàn)三:i/o ports 請(qǐng)打開s3c2440數(shù)據(jù)手冊(cè)第9章io/ ports,i/o ports含 gpa、gpb、gph八個(gè)端口。它們的寄存器是相似的:gpxcon用于選擇引 腳功能,gpxdat用于讀/寫引腳數(shù)據(jù),gpxup用于確定是否使用內(nèi)部上拉電阻(x為 a、b、h,沒有g(shù)paup寄存器)。 1、port a與port b-h在功能選擇方面有所不同,gpacon中每一位對(duì)應(yīng)一根引 腳(共23根引腳)。當(dāng)某位設(shè)為0時(shí),

30、相應(yīng)引腳為輸出引腳,此時(shí)我們可以在 gpadat中相應(yīng)位寫入0或1讓此引腳輸出低電平或高電平;當(dāng)某位設(shè)為1時(shí),相 應(yīng)引腳為地址線或用于地址控制,此時(shí)gpadat無用。一般而言gpacon通常 設(shè)為全1,以便訪問外部存儲(chǔ)器件。port a我們暫時(shí)不必理會(huì)。 2、port b-h在寄存器操作方面完全相同。gpxcon中每?jī)晌豢刂埔桓_:00表 示輸入、01表示輸出、10表示特殊功能、11保留不用。gpxdat用于讀/寫引腳: e-mail: qq: 389658188 http:/ 12 當(dāng)引腳設(shè)為輸入時(shí),讀此寄存器可知相應(yīng)引腳的狀態(tài)是高是低;當(dāng)引腳設(shè)為輸 出時(shí),寫此寄存器相應(yīng)位可令此引腳輸出低

31、電平或高電平。gpxup:某位為0時(shí), 相應(yīng)引腳無內(nèi)部上拉;為1時(shí),相應(yīng)引腳使用內(nèi)部上拉。 其他寄存器的操作在后續(xù)相關(guān)章節(jié)使用到時(shí)再描述;port a-h中引腳的特殊功 能比如串口引腳、中斷引腳等,也在做相關(guān)實(shí)驗(yàn)時(shí)再描述。 目錄key_led中的程序功能為:當(dāng)k1-k4中某個(gè)按鍵按下時(shí),led1-led4中相應(yīng) led點(diǎn)亮。 key_led.c代碼: #define gpbcon (*(volatile unsigned long *)0 x56000010) #define gpbdat (*(volatile unsigned long *)0 x56000014) #define gpf

32、con (*(volatile unsigned long *)0 x56000050) #define gpfdat (*(volatile unsigned long *)0 x56000054) /* led1-4對(duì)應(yīng)gpb7-10 */ #define gpb7_out (1(7*2) #define gpb8_out (1(8*2) #define gpb9_out (1(9*2) #define gpb10_out (1(10*2) /* k1-k3對(duì)應(yīng)gpf1-3 k4對(duì)應(yīng)gpf7 */ #define gpf1_in (3(1*2) #define gpf2_in (3(2*2

33、) #define gpf3_in (3(3*2) #define gpf7_in (3(7*2) int main() /led1-led4對(duì)應(yīng)的4根引腳設(shè)為輸出 gpbcon =gpb7_out | gpb8_out | gpb9_out | gpb10_out ; /k1-k4對(duì)應(yīng)的4根引腳設(shè)為輸入 gpfcon while(1) /若kn為0(表示按下),則令ledn為0(表示點(diǎn)亮) gpbdat = (gpfdat 0 xc 4: e59ff000 ldr pc, pc, #0 ; 0 xc 8: eafffffe b 0 x8 8: eafffffe b 0 x8 c: 00000

34、008 andeq r0, r0, r8c: 30000008 tsteq r0, #8 ; 0 x8 先看看b跳轉(zhuǎn)指令:它是個(gè)相對(duì)跳轉(zhuǎn)指令,其機(jī)器碼格式如下: 31:28位是條件碼;27:24位為“1010”時(shí),表示b跳轉(zhuǎn)指令,為“1011”時(shí),表示bl跳轉(zhuǎn) 指令;23:0表示偏移地址。使用b或bl跳轉(zhuǎn)時(shí),下一條指令的地址是這樣計(jì)算的:將指令 中24位帶符號(hào)的補(bǔ)碼立即數(shù)擴(kuò)展為32(擴(kuò)展其符號(hào)位);將此32位數(shù)左移兩位;將得到的值加 到pc寄存器中,即得到跳轉(zhuǎn)的目標(biāo)地址。我們看看第一條指令“b step1”的機(jī)器碼eaffffff: 124位帶符號(hào)的補(bǔ)碼為0 xffffff,將它擴(kuò)展為32得到

35、:0 xffffffff 2將此32位數(shù)左移兩位得到:0 xfffffffc,其值就是-4 3pc的值是當(dāng)前指令的下兩條指令的地址,加上步驟2得到的-4,這恰好是第二條 指令step1的地址 各位不要被被反匯編代碼中的“b 0 x4”給迷惑了,它可不是說跳到絕對(duì)地址0 x4處 執(zhí)行,絕對(duì)地址得像上述3個(gè)步驟那樣計(jì)算。您可以看到b跳轉(zhuǎn)指令是依賴于當(dāng)前pc 寄存器的值的,這個(gè)特性使得使用b指令的程序不依賴于代碼存儲(chǔ)的位置即不管 我們連接命令中“-ttext”為何,都可正確運(yùn)行。 再看看第二條指令ldr pc, =step2:從反匯編碼“l(fā)dr pc, pc, #0”可以看出,這條指令 從內(nèi)存中某個(gè)

36、位置讀出數(shù)據(jù),并賦給pc寄存器。這個(gè)位置的地址是當(dāng)前pc寄存器的 值加上偏移值0,其中存放的值依賴于連接命令中的“-ttext”選項(xiàng)。執(zhí)行這條指令后, 對(duì)于ttt.s,pc=0 x00000008;對(duì)于ttt2.s, pc=0 x30000008。于是執(zhí)行第三條指令“b step2”時(shí),它的絕對(duì)地址就不同了:對(duì)于ttt.s,絕對(duì)地址為0 x00000008;對(duì)于ttt.s,絕 對(duì)地址為0 x30000008。 ttt2.s上電后存放的位置也是0,但是它連接的地址是0 x30000000。我們以后會(huì)經(jīng) 常用到“存儲(chǔ)地址和連接地址不同”(術(shù)語上稱為加載時(shí)域和運(yùn)行時(shí)域)的特性:大多 機(jī)器上電時(shí)是從地

37、址0開始運(yùn)行的,但是從地址0運(yùn)行程序在性能方面總有很多限制, 所以一般在開始的時(shí)候,使用與位置無關(guān)的指令將程序本身復(fù)制到它的連接地址處, 然后使用向pc寄存器賦值的方法跳到連接地址開始的內(nèi)存上去執(zhí)行剩下的代碼。在 實(shí)驗(yàn)5、6中,我們將會(huì)作進(jìn)一步介紹。 e-mail: qq: 389658188 http:/ 15 arm-linux-ld命令中選項(xiàng)“-ttext”也可以使用選項(xiàng)“-tfilexxx”來代替,在文件filexxx 中,我們可以寫出更復(fù)雜的參數(shù)來使用arm-linux-ld命令在實(shí)驗(yàn)6中,我們就是 使用這種方法來指定連接參數(shù)的。 5、實(shí)驗(yàn)五:、實(shí)驗(yàn)五:memory controll

38、er s3c2440提供了外接rom、sram、sdram、nor flash、nand flash的接口。 s3c2440外接存儲(chǔ)器的空間被分為8 banks,每bank容量為128m:當(dāng)訪問 bankx(x從0到7)所對(duì)應(yīng)的地址范圍(x*128m到(x+1)*128m-1,bank6、7有稍微差 別,請(qǐng)參考下面第5點(diǎn)banksize寄存器的說明)時(shí),片選信號(hào)ngcsx有效。本文所 用的開發(fā)板,使用了64m的nand flash和64m的sdram:nand flash不對(duì)應(yīng)任何 bank,它是通過幾組寄存器來訪問的,在上電后,nand flash開始的4k數(shù)據(jù)被自 動(dòng)地復(fù)制到芯片內(nèi)部一個(gè)被

39、稱為“steppingstone”的ram上。steppingstone被映射為地 址0,上面的4k程序完成必要的初始化;sdram使用bank6,它的物理起始地址為 6*128m=0 x30000000。請(qǐng)您打開s3c2440數(shù)據(jù)手冊(cè),第5章的圖“figure 5-1. s3c2440x memory map after reset”可讓您一目了然。 在開始下面內(nèi)容前,如果您對(duì)sdram沒什么概念,建議先看看這篇文章高手 進(jìn)階,終極內(nèi)存技術(shù)指南完整/進(jìn)階版。當(dāng)然,不看也沒關(guān)系,照著做就行了。 此文鏈接地址: http:/ 0 x1000 2 4: eb00000b bl 0 x38 3 8:

40、 eb000011 bl 0 x54 4 c: eb000042 bl 0 x11c . 5 1000: e1a0c00d mov ip, sp 6 1004: e92dd800 stmdb sp!, fp, ip, lr, pc 7 1008: e24cb004 sub fp, ip, #4 ; 0 x4 8 100c: e59f1058 ldr r1, pc, #88 ; 0 x106c . 上面的第1-4行與head.s中的前面4行代碼對(duì)應(yīng),第2-4行調(diào)用init.c中的函數(shù) disable_watch_dog、memsetup、init_nand;再看看第5行,“1000”的得來正是由

41、于設(shè) 置了“at(4096)”,這行開始的是main.c中的第一個(gè)函數(shù)rand()。 如果您想進(jìn)一步了解連接腳本如何編寫,請(qǐng)參考using ld the gnu linker(在目 錄“參考資料”下)。 上面的幾個(gè)程序都是在擺弄那幾個(gè)led,現(xiàn)在來玩點(diǎn)有意思的: 7、實(shí)驗(yàn)七:、實(shí)驗(yàn)七:uart uart的寄存器有11x3個(gè)(3個(gè)uart)之多,我選最簡(jiǎn)單的方法來進(jìn)行本實(shí)驗(yàn), 用到的寄存器也有8個(gè)。不過初始化就用去了5個(gè)寄存器,剩下的3個(gè)用于接收、發(fā)送 數(shù)據(jù)。如此一來,操作uart倒也不復(fù)雜。本板使用uart0: 1、初始化: a、把使用到的引腳gph2、gph3定義為txd0、rxd0: gp

42、hcon |= 0 xa0 gphup |= 0 x0c (上拉) bulcon0 ( uart channel 0 line control register ):設(shè)為0 x03 此值含義為:8個(gè)數(shù)據(jù)位,1個(gè)停止位,無校驗(yàn),正常操作模式(與之相對(duì)的 是infra-red mode,此模式表示0、1的方式比較特殊)。 cucon0 (uart channel 0 control register ):設(shè)為0 x05 e-mail: qq: 389658188 http:/ 21 除了位3:0,其他位都使用默認(rèn)值。位3:0=0b0101表示:發(fā)送、接收都使 用“中斷或查詢方式”本實(shí)驗(yàn)使用查詢查詢

43、方式。 dufcon0 (uart channel 0 fifo control register ):設(shè)為0 x00 每個(gè)uart內(nèi)部都有一個(gè)16字節(jié)的發(fā)送fifo和接收fifo,但是本實(shí)驗(yàn)不使 用fifo,設(shè)為默認(rèn)值0 eumcon0 (uart channel 0 modem control register ):設(shè)為0 x00 本實(shí)驗(yàn)不使用流控,設(shè)為默認(rèn)值0 fubrdiv0 ( r/w baud rate divisior register 0 ):設(shè)為12 本實(shí)驗(yàn)未使用pll, pclk=12mhz,設(shè)置波特率為57600,則由公式 ubrdivn = (int)(pclk / (

44、bps x 16) ) 1 可以計(jì)算得ubrdiv0 = 12,請(qǐng)使用s3c2440數(shù)據(jù)手冊(cè)第314頁的誤差公式驗(yàn)算一下 此波特率是否在可容忍的誤差范圍之內(nèi),如果不在,則需要更換另一個(gè)波特率(本實(shí) 驗(yàn)使用的57600是符合的)。 2、發(fā)送數(shù)據(jù): autrstat0 ( uart channel 0 tx/rx status register ): 位2:無數(shù)據(jù)發(fā)送時(shí),自動(dòng)設(shè)為1。當(dāng)我們要使用串口發(fā)送數(shù)據(jù)時(shí),先讀此位以 判斷是否有數(shù)據(jù)正在占用發(fā)送口。 位1:發(fā)送fifo是否為空,本實(shí)驗(yàn)未用此位 位0:接收緩沖區(qū)是否有數(shù)據(jù),若有,此位設(shè)為1。本實(shí)驗(yàn)中,需要不斷查詢此 位一判斷是否有數(shù)據(jù)已經(jīng)被接收。

45、 butxh0 (uart channel 0 transmit buffer register ): 把要發(fā)送的數(shù)據(jù)寫入 此寄存器。 3、接收數(shù)據(jù): autrstat0:如同上述“2、發(fā)送數(shù)據(jù)”所列,我們用到位0 burxh0 (uart channel 0 receive buffer register ): 當(dāng)查詢到utrstat0 位0=1時(shí),讀此寄存器獲得串口接收到的數(shù)據(jù)。 串口代碼在uart目錄下的serial.c文件中,包含三個(gè)函數(shù):init_uart,putc,getc。代 e-mail: qq: 389658188 http:/ 22 碼如下: void init_uart(

46、 ) /初始化uart gphcon |= 0 xa0; /gph2,gph3 used as txd0,rxd0 gphup = 0 x0c; /gph2,gph3內(nèi)部上拉 ulcon0 = 0 x03;/8n1(8個(gè)數(shù)據(jù)位,無校驗(yàn)位,1個(gè)停止位) ucon0 = 0 x05; /查詢方式 ufcon0 = 0 x00;/不使用fifo umcon0 = 0 x00; /不使用流控 ubrdiv0 = 12; /波特率為57600 void putc(unsigned char c) /不斷查詢,直到可以發(fā)送數(shù)據(jù) while(!(utrstat0 utxh0 = c;/發(fā)送數(shù)據(jù) unsign

47、ed char getc() /不斷查詢,直到接收到了數(shù)據(jù) while(!(utrstat0 return urxh0; /返回接收到的數(shù)據(jù) 本實(shí)驗(yàn)將串口輸入的數(shù)字、字母加1后再從串口輸出,比如輸入a就輸出b。 實(shí)驗(yàn)步驟: 1、進(jìn)入uart目錄運(yùn)行“make”命令生成可執(zhí)行文件uart,下載到開發(fā)板上 2、在主機(jī)上運(yùn)行串口工具minicom: a在終端上運(yùn)行“minicom s”啟動(dòng)minicom,出來如下界面: e-mail: qq: 389658188 http:/ 23 b進(jìn)入“serial port setup”: 鍵入相應(yīng)字母設(shè)置各項(xiàng),比如:我用的是串口1,所以在a項(xiàng)設(shè)置為“/dev

48、/ttys0”; 按“e”,設(shè)置波特率為57600,8n1;按f、g,設(shè)置無流控。最后回車退出, 回到步驟a所示的界面。 c可以選擇“save setup as dfl”,這樣下次啟動(dòng)minicom時(shí)可以不再進(jìn)行步驟b的 設(shè)置。 d選擇“exit”退出設(shè)置界面。 3、復(fù)位開發(fā)板后,您可以在minicom上體驗(yàn)一下本程序了。 e-mail: qq: 389658188 http:/ 24 8、實(shí)驗(yàn)八:、實(shí)驗(yàn)八:printf、scanf 本實(shí)驗(yàn)利用串口實(shí)現(xiàn)兩個(gè)很常用的函數(shù):printf和scanf。 試驗(yàn)代碼存放在stdio目錄下,其中l(wèi)ib目錄中包含了實(shí)現(xiàn)printf和scanf函數(shù)的主要 文件

49、。大部分文件摘自linux2.6內(nèi)核,本試驗(yàn)主要在vsprintf.c文件的基礎(chǔ)上,封裝了 printf和scanf函數(shù)(print.c文件中)。在vsprintf.c文件中,需要用到一些乘法和除法操作, 文件lib1funcs.s實(shí)現(xiàn)除法、求模操作;div64.h和div64.s實(shí)現(xiàn)64位的除法操作;muldi3.c 實(shí)現(xiàn)乘法操作。另外,stdio目錄下的serial.c文件實(shí)現(xiàn)了putc和getc函數(shù),這兩個(gè)函數(shù) 與具體板子的情況相關(guān),所以我沒把它們放入lib目錄下。 此試驗(yàn)的makefile文件將lib目錄里的文件生成靜態(tài)庫文件libc.a,現(xiàn)在,你把stdio.h 文件包含進(jìn)你的代碼后

50、,就可以非常方便地實(shí)現(xiàn)輸入、輸出了請(qǐng)參考本試驗(yàn)代 碼。 實(shí)驗(yàn):與試驗(yàn)7類似,以波特率57600 8n1打開串口,將make后生成的可執(zhí)行文 件exe燒入開發(fā)板,可在minicom上觀察到結(jié)果:程序從minicom中接收字串,從這些 字串中檢出數(shù)字,分別以10進(jìn)制和16進(jìn)制方式打印出來。 另外,您可以參考stdio_test_lib目錄下的代碼,寫出自己的測(cè)試程序。這個(gè)目錄里面 的文件基本與本試驗(yàn)一樣,只是在lib目錄下僅僅保留了libc.a庫文件。 最后,sys/lib/stdio目錄中存放的是標(biāo)準(zhǔn)輸入、輸出的代碼,其中的makefile可以生成 libc.a文件并存放在sys/lib目錄下,

51、以后本人編寫的庫函數(shù)都也將存放在此目錄下。 9、實(shí)驗(yàn)九:、實(shí)驗(yàn)九:interrupt controller s3c2440數(shù)據(jù)手冊(cè)354頁“figure 14-1. interrupt process diagram”非常簡(jiǎn)潔地概括了 中斷處理的流程,我把這個(gè)圖搬過來,然后結(jié)合用到的寄存器用文字解釋一下。 圖1 interrupt process diagram subsrcpnd和srcpnd寄存器表明有哪些中斷被觸發(fā)了,正在等待處理 (pending);submask(intsubmsk寄存器)和mask(intmsk寄存器)用于屏蔽某 些中斷。圖中的“request sources(wi

52、th sub -register)”表示的是int_rxd0、int_txd0 等11個(gè)中斷源,它們不同于“request sources(without sub -register)”: e-mail: qq: 389658188 http:/ 25 1、“request sources(without sub -register)”中的中斷源被觸發(fā)之后,srcpnd寄存 器中相應(yīng)位被置1,如果此中斷沒有被intmsk寄存器屏蔽、或者是快中斷(fiq)的 話,它將被進(jìn)一步處理 2、對(duì)于“request sources(with sub -register)”中的中斷源被觸發(fā)之后, subsr

53、cpnd寄存器中的相應(yīng)位被置1,如果此中斷沒有被intsubmsk寄存器屏蔽 的話,它在srcpnd寄存器中的相應(yīng)位也被置1,之后的處理過程就和“request sources(without sub -register)”一樣了。 繼續(xù)沿著圖1前進(jìn):在srcpnd寄存器中,被觸發(fā)的中斷的相應(yīng)位被置1,等待 處理: 1、如果被觸發(fā)的中斷中有快中斷(fiq)mode(intmod寄存器)中為1的位 對(duì)應(yīng)的中斷是fiq,則cpu的fiq中斷函數(shù)被調(diào)用。注意:fiq只能分配一個(gè),即 intmod中只能有一位設(shè)為1。 2、對(duì)于一般中斷irq,可能同時(shí)有幾個(gè)中斷被觸發(fā),未被intmsk寄存器屏蔽 的中斷

54、經(jīng)過比較后,選出優(yōu)先級(jí)最高的中斷此中斷在intpnd寄存器中的相應(yīng) 位被置1,然后cpu調(diào)用irq中斷處理函數(shù)。中斷處理函數(shù)可以通過讀取intpnd寄 存器來確定中斷源是哪個(gè),也可以讀intoffset寄存器來確定中斷源。 請(qǐng)打開s3c2440數(shù)據(jù)手冊(cè)357頁,“figure 14-2. priority generating block”顯示了各中斷 源先經(jīng)過6個(gè)一級(jí)優(yōu)先級(jí)仲裁器選出各自優(yōu)先級(jí)最高的中斷,然后再經(jīng)過二級(jí)優(yōu)先級(jí) 仲裁器選從中選出優(yōu)先級(jí)最高的中斷。irq的中斷優(yōu)先級(jí)由riority寄存器設(shè)定, 請(qǐng)參考數(shù)據(jù)手冊(cè)365頁,riority寄存器中arb_seln(n從0到6)用于設(shè)定仲

55、裁器n各 輸入信號(hào)的中斷優(yōu)先級(jí),例如arb_sel620:19(0最高,其后各項(xiàng)依次降低): 00 = req 0-1-2-3-4-5 01 = req 0-2-3-4-1-5 10 = req 0-3-4-1-2-5 11 = req 0-4-1-2-3-5 riority寄存器還有一項(xiàng)比較特殊的功能,如果arb_moden設(shè)為1,則仲裁器 n中輸入的中斷信號(hào)的優(yōu)先級(jí)別將會(huì)輪換。例如arb_mode6設(shè)為1,則仲裁器6的6 個(gè)輸入信號(hào)的優(yōu)先級(jí)將如下輪換(見數(shù)據(jù)手冊(cè)358頁): if req0 or req5 is serviced, arb_sel bits are not changed

56、at all. if req1 is serviced, arb_sel bits are changed to 01b. if req2 is serviced, arb_sel bits are changed to 10b. if req3 is serviced, arb_sel bits are changed to 11b. if req4 is serviced, arb_sel bits are changed to 00b. 意思即是: req0和req5的優(yōu)先級(jí)不會(huì)改變 當(dāng)req1中斷被處理后,arb_sel6 = 0b01,即req1的優(yōu)先級(jí)變成本仲裁器中最低 的(除去r

57、eq5) e-mail: qq: 389658188 http:/ 26 當(dāng)req2中斷被處理后,arb_sel6 = 0b10,即req2的優(yōu)先級(jí)變成本仲裁器中最低 的(除去req5) 當(dāng)req3中斷被處理后,arb_sel6 = 0b11,即req3的優(yōu)先級(jí)變成本仲裁器中最低 的(除去req5) 當(dāng)req4中斷被處理后,arb_sel6 = 0b00,即req4的優(yōu)先級(jí)變成本仲裁器中最低 的(除去req5) 現(xiàn)在來總結(jié)一下使用中斷的步驟: 1、當(dāng)發(fā)生中斷irq時(shí),cpu進(jìn)入“中斷模式”,這時(shí)使用“中斷模式”下的堆棧; 當(dāng)發(fā)生快中斷fiq時(shí),cpu進(jìn)入“快中斷模式”,這時(shí)使用“快中斷模式”下

58、的堆棧。所 以在使用中斷前,先設(shè)置好相應(yīng)模式下的堆棧。 2、對(duì)于“request sources(without sub -register)”中的中斷,將intsubmsk寄存器 中相應(yīng)位設(shè)為0 3、將intmsk寄存器中相應(yīng)位設(shè)為0 4、確定使用此的方式:是fiq還是irq。 a如果是fiq,則在intmod寄存器設(shè)置相應(yīng)位為1 b如果是irq,則在riority寄存器中設(shè)置優(yōu)先級(jí) 5、準(zhǔn)備好中斷處理函數(shù), a中斷向量: 在中斷向量設(shè)置好當(dāng)fiq或irq被觸發(fā)時(shí)的跳轉(zhuǎn)函數(shù), irq、fiq的中斷向 量地址分別為0 x00000018、0 x0000001c(數(shù)據(jù)手冊(cè)79頁“table 2-

59、3. exception vectors”) b對(duì)于irq,在跳轉(zhuǎn)函數(shù)中讀取intpnd寄存器或intoffset寄存器的值 來確定中斷源,然后調(diào)用具體的處理函數(shù) c對(duì)于fiq,因?yàn)橹挥幸粋€(gè)中斷可以設(shè)為fiq,無須判斷中斷源 d中斷處理函數(shù)進(jìn)入和返回時(shí)需要花點(diǎn)心思: i對(duì)于irq,進(jìn)入和返回的代碼如下: sub lr, lr, #4 計(jì)算返回地址 stmdb sp!, r0-r12,lr 保存使用到的寄存器 ldmia sp!, r0-r12,pc 中斷返回 e-mail: qq: 389658188 http:/ 27 表示將spsr的值賦給cpsr ii對(duì)于fiq,進(jìn)入和返回的代碼如下: sub lr, lr, #4 計(jì)算返回地址 stmdb sp!, r0-r7,lr 保存使用到的寄存器 ldmia sp!, r0-r7,pc 快中斷返回, 表示將spsr的值賦給cpsr iii. 中斷返回之前需要清中斷:往subsrcpnd(用到的話)、 srcpnd、intpnd中相應(yīng)位寫1即可。對(duì)于intpnd,最簡(jiǎn)單的方法就是 “intpnd=intpnd”。 6、設(shè)置cpsr寄存器中的f-bit(對(duì)于fiq)或i-bit(對(duì)于irq)為0,開中斷 本實(shí)驗(yàn)使用按鍵k1-k4作為4個(gè)外部中斷eint1-3、eint7,當(dāng)kn按下時(shí), 通過串口輸出“e

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論