《uCOOS-II原理與ARM應(yīng)用程序設(shè)計(jì)》課件第7章_第1頁(yè)
《uCOOS-II原理與ARM應(yīng)用程序設(shè)計(jì)》課件第7章_第2頁(yè)
《uCOOS-II原理與ARM應(yīng)用程序設(shè)計(jì)》課件第7章_第3頁(yè)
《uCOOS-II原理與ARM應(yīng)用程序設(shè)計(jì)》課件第7章_第4頁(yè)
《uCOOS-II原理與ARM應(yīng)用程序設(shè)計(jì)》課件第7章_第5頁(yè)
已閱讀5頁(yè),還剩118頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

第七章動(dòng)態(tài)內(nèi)存配置與Bootloader

7.1動(dòng)態(tài)存儲(chǔ)OS_MEM.C7.2Bootloader設(shè)計(jì)7.3本章小結(jié)在程序編譯鏈接時(shí)分配的存儲(chǔ)空間稱為靜態(tài)空間,在程序執(zhí)行過(guò)程中分配的程序空間稱為動(dòng)態(tài)空間。例如,使用malloc函數(shù)開辟的存儲(chǔ)空間就是動(dòng)態(tài)空間。程序中定義的各種變量和數(shù)組均是靜態(tài)空間,與動(dòng)態(tài)空間相比,靜態(tài)空間地址是固定的。動(dòng)態(tài)空間在程序執(zhí)行過(guò)程中地址是不固定的,因此,多次調(diào)用malloc函數(shù)后,會(huì)造成大量的內(nèi)存碎片,并且開辟空間所用的時(shí)間也不確定。本節(jié)將介紹μC/OS-Ⅱ中如何在任務(wù)執(zhí)行過(guò)程中請(qǐng)求動(dòng)態(tài)空間,以及如何釋放這些動(dòng)態(tài)空間。本節(jié)的另一個(gè)內(nèi)容是介紹Bootloader方法,即在《ARM原理與C程序設(shè)計(jì)》第七章的基礎(chǔ)上,進(jìn)一步介紹基于μC/OS-Ⅱ嵌入式系統(tǒng)的工程目標(biāo)文件自舉啟動(dòng)的方法。有C/C++語(yǔ)言程序設(shè)計(jì)經(jīng)驗(yàn)的程序員大都知道,動(dòng)態(tài)分配內(nèi)存可以有效地節(jié)省存儲(chǔ)空間。每個(gè)函數(shù)運(yùn)算產(chǎn)生的中間結(jié)果使用動(dòng)態(tài)內(nèi)存保存,計(jì)算出最終結(jié)果后,當(dāng)從函數(shù)返回時(shí)把動(dòng)態(tài)內(nèi)存釋放掉,這樣一個(gè)動(dòng)態(tài)內(nèi)存空間可用于多個(gè)函數(shù)共同使用,而互不干擾。動(dòng)態(tài)內(nèi)存來(lái)自堆。當(dāng)函數(shù)內(nèi)部產(chǎn)生大量中間變量時(shí),使用動(dòng)態(tài)存儲(chǔ)方式比使用局部變量更好一些,因?yàn)榫植孔兞看蠖鄟?lái)自棧,變量空間不能太多。7.1動(dòng)態(tài)存儲(chǔ)OS_MEM.C動(dòng)態(tài)存儲(chǔ)相關(guān)的函數(shù)有6個(gè),即OSMemCreate、OSMemGet、OSMemPut、OSMemQuery、OSMemNameGet和OSMemNameSet,列于第一章表1-12中。在μC/OS-Ⅱ中使用動(dòng)態(tài)內(nèi)存的方法為:使用動(dòng)態(tài)內(nèi)存前需要調(diào)用OSMemCreate函數(shù)創(chuàng)建它,動(dòng)態(tài)內(nèi)存以內(nèi)存分區(qū)的形式存在,可以創(chuàng)建多個(gè)動(dòng)態(tài)內(nèi)存分區(qū),每個(gè)分區(qū)由大小相同的內(nèi)存塊組成,內(nèi)存塊的大小以字節(jié)為單位;在使用動(dòng)態(tài)內(nèi)存時(shí),調(diào)用OSMemGet從內(nèi)存分區(qū)中取得一塊內(nèi)存塊,通過(guò)多次調(diào)用OSMemGet獲得多個(gè)內(nèi)存塊使用,獲得的內(nèi)存塊本質(zhì)上是這個(gè)內(nèi)存塊的首地址,可以對(duì)它賦各種類型數(shù)據(jù);內(nèi)存塊使用完后,必須調(diào)用OSMemPut將內(nèi)存塊釋放掉,即還回到內(nèi)存分區(qū)中,這個(gè)函數(shù)必須與OSMemGet配對(duì)使用,保證內(nèi)存分區(qū)中內(nèi)存塊的“供需平衡”??梢哉{(diào)用OSMemNameSet為內(nèi)存分區(qū)命名,調(diào)用OSMemNameGet獲得內(nèi)存分區(qū)的名稱,這個(gè)名稱主要用于調(diào)試中。調(diào)用OSMemQuery可以查詢內(nèi)存分區(qū)的信息。

第7.1.1節(jié)的工程ex7_1使用了內(nèi)存分區(qū)相關(guān)的函數(shù),以解釋這些函數(shù)的用法。但是,正如上文所言,內(nèi)存分區(qū)主要用于函數(shù)運(yùn)行過(guò)程中會(huì)占用大量存儲(chǔ)空間的程序中,相比之下,工程ex7_1完全不具備這個(gè)特性,只能用來(lái)說(shuō)明這些內(nèi)存分區(qū)函數(shù)如何使用。7.1.1內(nèi)存分區(qū)實(shí)例

在第六章工程ex6_1的基礎(chǔ)上,新建工程ex7_1,保存目錄為D:\ZYUCOSII\ex7_1,此時(shí)的工程ex7_1與工程ex6_1完全相同,只是工程文件名更名為ex7_1。需要修改的文件有app.h和appfun.c,其中,在文件app.h的末尾添加以下兩行語(yǔ)句:

MY_APPOS_MEM*myMem;//Memorypartition

MY_APPINT32UmyBuf[10][30];

即定義內(nèi)存分區(qū)myMem和二維數(shù)組myBuf,內(nèi)存分區(qū)建立在全局?jǐn)?shù)組myBuf的基礎(chǔ)上。文件appfun.c需要修改AppTaskStart函數(shù)和AppTask_2函數(shù),AppTask_2函數(shù)在第7.1.2節(jié)介紹,在AppTaskStart函數(shù)中添加以下語(yǔ)句:

1myMem=OSMemCreate(&myBuf[0][0],10,30*sizeof(INT32U),&err);

2if(err==OS_ERR_NONE)

3{

4OSMemNameSet(myMem,"MyMemPart",&err);

5Str_Uart0("Partition\"myMem\"CreateOK!\n\n");

6}這些語(yǔ)句可添加到創(chuàng)建信號(hào)量LedSem的語(yǔ)句“LedSem=OSSemCreate(0);”前面。第1行為調(diào)用OSMemCreate創(chuàng)建內(nèi)存分區(qū)myMem,包含4個(gè)參數(shù):第1個(gè)參數(shù)為內(nèi)存分區(qū)首地址;第2個(gè)參數(shù)為內(nèi)存分區(qū)中包含的內(nèi)存塊數(shù)量;第3個(gè)參數(shù)為每個(gè)內(nèi)存塊的大小,以字節(jié)為單位;第4個(gè)參數(shù)為函數(shù)調(diào)用情況的返回信息,如果為OS_ERR_NONE則表示創(chuàng)建內(nèi)存分區(qū)成功。第4行將內(nèi)存分區(qū)命名為“MyMemPart”。

工程ex7_1如圖7-1所示,調(diào)試窗口如圖7-2所示。從圖7-2中C-SPY窗口可以看到內(nèi)存分區(qū)的信息。串口調(diào)試助手顯示的信息如圖7-3所示。圖7-1工程ex7_1界面圖7-2工程ex7_1調(diào)試窗口圖7-3串口調(diào)試助手顯示信息窗口7.1.2工程ex7_1注解

文件appfun.c中函數(shù)AppTask_2的內(nèi)容如下:

1voidAppTask_2(void*pdata)

2{

3INT8Uerr;

4INT8Ui;

5

6INT32UtickCur; //Timetick'scurrentval

7INT8U*pmsg; //ablock

69}

70

71OSTimeDlyHMSM(0,0,2,0);

72}

73}

第10行OS_MEM_DATA類型定義位于ucos_ii.h的第493~500行,其中成員OSNFree、OSNUsed和OSNBlks分別用于表示內(nèi)存分區(qū)中空閑的內(nèi)存塊、使用了的內(nèi)存塊和全部?jī)?nèi)存塊數(shù)量,都是INT32U型變量成員,用于第57行取得內(nèi)存塊的信息。任務(wù)2執(zhí)行后,第19行取得當(dāng)前時(shí)鐘節(jié)拍值,如果小于30秒,則調(diào)用OSMemGet從內(nèi)存分區(qū)中取得第一塊內(nèi)存塊(第22行)。第23行判斷是否取得了內(nèi)存塊,如果取得了,則第25行向取得的內(nèi)存塊(實(shí)際上是內(nèi)存分區(qū)的第一個(gè)內(nèi)存塊)寫入字符串,然后第26行輸出這個(gè)字符串到串口調(diào)試助手。第28行調(diào)用OSMemPut釋放這個(gè)內(nèi)存塊。第29~35行重復(fù)這個(gè)過(guò)程,只是向內(nèi)存塊中寫入的字符串不同了;同理,第36~42行和第43~49行又重復(fù)了這個(gè)過(guò)程兩次。串口調(diào)試助手的輸出結(jié)果參看圖7-3。當(dāng)運(yùn)行時(shí)間大于30秒小于60秒時(shí),第51行為真,則52~69行的代碼得到執(zhí)行,第53~56行從內(nèi)存分區(qū)中取得5個(gè)內(nèi)存塊。然后,第57行調(diào)用OSMemQuery函數(shù)查詢內(nèi)存塊的信息,第58行調(diào)用OSMemNameGet函數(shù)獲得內(nèi)存分區(qū)的名稱,第59行向串口調(diào)試助手輸出內(nèi)存分區(qū)的名稱。之后,第60~64行輸出內(nèi)存分區(qū)的信息,第65~68行調(diào)用OSMemPut釋放已使用完的5個(gè)內(nèi)存塊。任務(wù)2延時(shí)2秒重復(fù)執(zhí)行(第71行)。

由分析可見,程序員必須清楚內(nèi)存分區(qū)中有多少個(gè)內(nèi)存塊及每個(gè)內(nèi)存塊的大小,μC/OS-Ⅱ不檢測(cè)內(nèi)存分區(qū)中內(nèi)存塊的越界。如果使用不當(dāng),會(huì)造成整個(gè)工程程序的癱瘓。讀者可參考Labrosse的《嵌入式實(shí)時(shí)操作系統(tǒng)μC/OS-Ⅱ(第2版)》第12章“內(nèi)存管理”,了解內(nèi)存控制塊及其管理。一般地,將程序下載到ARM芯片內(nèi)部的FLASH存儲(chǔ)區(qū)或下載到ARM外擴(kuò)的FLASH芯片內(nèi),ARM板上電復(fù)位后自動(dòng)從FLASH中讀取程序目標(biāo)代碼,完成程序啟動(dòng)的過(guò)程通稱為Bootloader,或稱自舉啟動(dòng),以區(qū)別于帶有仿真器的程序仿真運(yùn)行。Bootloader是ARM嵌入式項(xiàng)目開發(fā)過(guò)程中必須實(shí)現(xiàn)的一步,從嚴(yán)格意義上來(lái)講,Bootloader相關(guān)的內(nèi)容與μC/OS-Ⅱ沒有關(guān)系,但作者還是把這部分內(nèi)容添加到本書中,以使本書成為一個(gè)完整的基于μC/OS-Ⅱ的嵌入式項(xiàng)目開發(fā)整體解決方案。7.2Bootloader設(shè)計(jì)這里需要區(qū)分三個(gè)概念,即模擬運(yùn)行、仿真運(yùn)行及自舉運(yùn)行。模擬運(yùn)行主要是針對(duì)算法的處理,使用一些仿真軟件和環(huán)境,對(duì)算法的實(shí)現(xiàn)進(jìn)行模擬,以了解算法的運(yùn)算量和優(yōu)缺點(diǎn),有時(shí)模擬運(yùn)行也可模擬一些芯片的外設(shè)與時(shí)序。仿真運(yùn)行本質(zhì)上就是程序的執(zhí)行,仿真運(yùn)行時(shí),程序通過(guò)仿真器下載到目標(biāo)芯片中,程序是在芯片上運(yùn)行,因此,仿真運(yùn)行的程序一定可以完全脫離仿真器運(yùn)行。例如,工程ex6_1仿真調(diào)試時(shí),退出調(diào)試環(huán)境,串口調(diào)試助手仍然接收到UP-Star實(shí)驗(yàn)板串口0發(fā)送的信息,說(shuō)明程序還在芯片內(nèi)部執(zhí)行。模擬運(yùn)行的程序一般做不到百分之百地仿真運(yùn)行。相對(duì)于仿真運(yùn)行來(lái)說(shuō),自舉運(yùn)行就是程序脫離仿真器而工作的過(guò)程,本書第二章至第7.1節(jié)的程序均是仿真運(yùn)行的。

Bootloader過(guò)程可以分為三步,即首先編寫對(duì)NAND型FLASH的讀寫操作工程,實(shí)現(xiàn)對(duì)FLASH的編程,這部分內(nèi)容將在第7.2.1節(jié)介紹;然后,生成Boot表,即要寫入到FLASH中的目標(biāo)代碼數(shù)據(jù),這部分內(nèi)容在第7.2.2節(jié)介紹;最后一步是關(guān)閉UP-Star實(shí)驗(yàn)板電源,取下仿真器,重新上電,觀察程序運(yùn)行情況。7.2.1讀寫FLASH工程

UP-Star實(shí)板板上集成了型號(hào)為K9F1208C的FLASH芯片,該芯片的讀寫方法請(qǐng)參考《ARM原理與C程序設(shè)計(jì)》第7.2節(jié),以下摘錄其中第7.2.1節(jié)關(guān)于K9F1208C的內(nèi)容。

K9F1208U0C的存儲(chǔ)陣列如圖7-4所示。圖7-4K9F1208U0C存儲(chǔ)陣列由圖7-4知,一片K9F1208U0C芯片包含4096個(gè)存儲(chǔ)塊,每個(gè)存儲(chǔ)塊分為32個(gè)存儲(chǔ)頁(yè),每個(gè)存儲(chǔ)頁(yè)為528字節(jié),其中,512字節(jié)用于存儲(chǔ)數(shù)據(jù),16字節(jié)用于存儲(chǔ)校驗(yàn)信息。這樣,一片K9F1208U0C的存儲(chǔ)空間大小為4096×32×(512+16)B=(64+2)MB=66MB,其中,1MB=1024KB,1KB=1024B。用戶可用存儲(chǔ)空間為64MB,對(duì)其完全尋址,至少需要26根地址線。IO0~I(xiàn)O7作為地址輸入時(shí),至少占用4個(gè)周期,每個(gè)周期的地址輸入如圖7-4所示:第一個(gè)周期輸入的A0~A7作為列地址;第2至4周期輸入的A9~A25作為行地址,即頁(yè)地址,因此,一片K9F1208U0C有217=128K個(gè)存儲(chǔ)頁(yè)面。每個(gè)512B的頁(yè)面由A8分為上、下兩部分(Read1命令),每部分為256個(gè)字節(jié),可以被8位列地址尋址,即A0~A7尋址。每個(gè)存儲(chǔ)頁(yè)最后的16字節(jié)(512~527)使用A0~A3尋址,A4~A7忽略,對(duì)應(yīng)于不同的訪問命令(Read2命令)。現(xiàn)在,有充分理由相信,NAND型FLASH這種“分而治之”的存儲(chǔ)尋址方式比NOR型FLASH的“一統(tǒng)天下”在芯片制造上更容易實(shí)現(xiàn)。

K9F1208U0C共有4個(gè)存儲(chǔ)柱面(Plane),它的4096個(gè)存儲(chǔ)塊分布在不同的存儲(chǔ)柱面上,不同的存儲(chǔ)柱面可以同時(shí)讀寫。塊序號(hào)被4整除的存儲(chǔ)塊,例如塊0、4、8、…、4092位于面0上;而塊序號(hào)除以4余1的存儲(chǔ)塊,例如,塊1、5、9、…、4093位于面1上;塊2、6、10、…、4094位于面2上;塊3、7、11、…、4095位于面3上,如圖7-5所示。每個(gè)柱面上有528字節(jié)的數(shù)據(jù)寄存器,位于存儲(chǔ)單元陣列和外部I/O口之間,用于緩沖讀寫的數(shù)據(jù)。查閱S3C2410A手冊(cè)可知,NAND型FLASH操作寄存器位于0x4E000000至0x4E000014。由第一章圖1-22和圖1-26可知,K9F1208U0C的I/O0~I(xiàn)/O7接S3C2410A的DATA0~DATA7,其控制管腳接S3C2410A的NANDFLASH控制器相應(yīng)管腳。

通過(guò)S3C2410A訪問K9F1208的一般步驟為:

(1)初始化S3C2410ANAND型FLASH控制器。

(2)讀K9F1208的芯片ID號(hào)。

(3)整片擦除K9F1208,然后對(duì)K9F1208的存儲(chǔ)塊進(jìn)行有效性檢驗(yàn),把無(wú)效存儲(chǔ)塊標(biāo)記。

(4)編程K9F1208芯片,并讀取寫入的數(shù)據(jù)進(jìn)行ECC校驗(yàn)。圖7-5存儲(chǔ)器配置表

K9F1208僅支持基于塊的擦除和基于頁(yè)的編程,針對(duì)FLASH來(lái)說(shuō),編程是指向其中寫入數(shù)據(jù)。由于S3C2410A具有硬件ECC校驗(yàn)發(fā)生器,因此用戶不需要編寫ECC校驗(yàn)碼產(chǎn)生函數(shù)。

上述內(nèi)容是編程K9F1208的基礎(chǔ)知識(shí),下面介紹讀寫K9F1208C的工程ex7_2。

在第二章工程ex2_1的基礎(chǔ)上,新建工程ex7_2,此時(shí)的工程ex7_2與工程ex2_1完全相同,只是工程文件名改為ex7_2。需要修改的文件有zyMain.c和zyDef2410.h,并且添加一個(gè)新文件flashRW.c(這個(gè)文件來(lái)自《ARM原理與C程序設(shè)計(jì)》),完成后的工程ex7_2如圖7-6所示。圖7-6為工程ex7_2的調(diào)試圖,其中flashDat為要寫入FLASH中的數(shù)據(jù),flashCp為從FLASH讀出的數(shù)據(jù),長(zhǎng)度均為1000,可以看出寫入與讀出的數(shù)據(jù)完全相同,說(shuō)明讀寫K9F1208C成功。圖7-6工程ex7_2工程ex7_2是芯片級(jí)的程序。在文件zyDef2410.h的開頭添加如下語(yǔ)句:

1#ifdefMY_APP_GLOBALS

2#defineMY_APP

3#else

4#defineMY_APPextern

5#endif

在文件zyDef2410.h的末尾添加如下語(yǔ)句:

1MY_APPunsignedintflashID;

2MY_APPunsignedcharflashWhat[1200];

3MY_APPunsignedcharflashDat[1000];

4MY_APPunsignedcharflashCp[1000];zyMain.c文件的內(nèi)容如下:

1/*FileName:zyMain.c

2**Byzhnyong@21

3**@2009-4-4

4**MainSubroutine

5**CopyrightReserved

6*/

7

8#include"zyDef2410.h"

9

10unsignedintFCLK,HCLK,PCLK;第18行讀取K9F1208C的ID號(hào),調(diào)試時(shí)可用Watch窗口觀察變量flashID的值為0xEC765A3F。第19~20行初始化要寫入的數(shù)據(jù),由于每個(gè)數(shù)組元素為無(wú)符號(hào)整型,所以只能存儲(chǔ)0~255間的數(shù)值。第20行取模247,表示初始化數(shù)值從0至246。第21~24行擦除了K9F1208的10個(gè)塊的空間,約160KB的空間大小。第25行將flashDat的值寫入FLASH中,寫入首地址為0x0。第26行從FLASH中讀出1200個(gè)值,讀出首地址為0x0。第28~32行將讀出的值中的有效數(shù)據(jù)值寫入flashCp數(shù)組中,于是flashCp數(shù)組的內(nèi)容應(yīng)該與flashDat的內(nèi)容完全相同,這一點(diǎn)可從圖7-6中看出。文件flashRW.c的內(nèi)容如下:

1/*FileName:flashRW.h

2**Byzhnyong@21

3**@2009-4-4

4**CopyrightReserved

5*/

6

7#defineMY_APP_GLOBALS

8#include"zyDef2410.h"

9

10//InitNANDControllerReg

11voidinitFlash()文件flashRW.c的內(nèi)容全部來(lái)自《ARM原理與C程序設(shè)計(jì)》一書,包含了對(duì)FLASH的讀寫操作函數(shù),具體實(shí)現(xiàn)細(xì)節(jié)不再贅述。需要注意的是,仿真工程ex7_2要用配置稍好一些的計(jì)算機(jī),如果要用Watch窗口查看讀出的大容量數(shù)組,建議不要用裝有英特爾賽揚(yáng)處理器的計(jì)算機(jī)進(jìn)行仿真。第7.2.3節(jié)的工程中將繼續(xù)使用文件flashRW.c。7.2.2用于自舉的工程ex7_3

這里修改一下第六章工程ex6_1startup.s的文件,使之成為能自舉的工程。

在工程ex6_1的基礎(chǔ)上新建工程ex7_3,保存目錄為D:\ZYUCOSII\ex7_3,這時(shí)的工程ex7_3與工程ex6_1完全相同,只是工程文件名更改為ex7_3。需要修改的文件只有startup.s,同時(shí)要更改ex7_3的配置。下面首先介紹ex7_3配置的更改。在工程ex7_3窗口中點(diǎn)擊菜單“Project|Options…”,進(jìn)入如圖7-7所示的窗口。圖7-7在OutputConverter中填寫輸出文件ex7_3.hex

再進(jìn)入到Linker選項(xiàng)頁(yè),在圖7-8中點(diǎn)擊“Edit…”按鈕,在彈出的窗口中設(shè)置各頁(yè)如圖7-9所示。圖7-8Linker選項(xiàng)頁(yè)圖7-9工程鏈接配置從圖7-9中的“MemoryRegions”可以看出ROM空間為0x1000~0x3FFFF(約256KB),RAM空間為0x40000~0x7FFFF(256KB),這兩段空間在UP-Star實(shí)驗(yàn)板上沒有RAM和SDRAM,所以,在startup.s中需要將位于0x30000000地址處的SDRAM重定位于0x0開始的空間。

如圖7-10所示,點(diǎn)擊左上角的下拉框可以將工程ex7_3設(shè)置為Release編譯模式,這時(shí)要重新設(shè)置工程選項(xiàng)卡(即“Project|Options”菜單彈出的配置窗口)。本章講述Bootloader使用的是Debug模式下編譯鏈接成的目標(biāo)文件ex7_3.hex,作為練習(xí),讀者可試著把Release模式下編譯鏈接成的目標(biāo)文件下載到UP-Star實(shí)驗(yàn)板上。圖7-10編譯模式選擇

下面列出了修改后的文件startup.s的代碼,并在其后作了注解。

1;Filename:startup.s

2;Byzhnyang@21

3;@2009-4-4

4;ForS3C2410A(RunafterReset)

5;CopyrightReserved

6

7;Note:@LittleEndian

8

注意第84行,這里是ROOT,而不是NOROOT,ROOT指示符將該段程序的地址定位于0x0;第89行添加了_iar_program_start標(biāo)號(hào),這個(gè)標(biāo)志符是EWARM用于指示程序開始的缺省標(biāo)示符;第90行使用B跳轉(zhuǎn);第101行注釋掉;第157~164行用于點(diǎn)亮第3個(gè)LED燈,如果該燈被點(diǎn)亮,說(shuō)明程序已經(jīng)完成了芯片初始化。

第166~239行用于將K9F1208中地址0x0~0x100000(1MB)空間內(nèi)的數(shù)據(jù)拷貝到內(nèi)存0x30000000~0x30100000處,即完成代碼從FLASH到SDRAM的搬移工作。這些代碼比較簡(jiǎn)單,供感興趣的讀者自己閱讀。第241~245行將位于0x30000000~0x32000000處的SDRAM映射到0x0處,即完成了內(nèi)存的重映射。

第248~272行用于設(shè)置各種工作模式的堆棧指針。

第273~278行是點(diǎn)亮第2個(gè)LED燈(關(guān)閉第3個(gè)LED燈),該燈用于指示程序完成重定位和堆棧配置工作。

第280~281行用于跳轉(zhuǎn)到主程序運(yùn)行。

第283~290行是一個(gè)匯編子函數(shù),用于判斷NANDFLASH數(shù)據(jù)有沒有準(zhǔn)備好。需要補(bǔ)充一點(diǎn):NANDFLASH的讀不如NORFLASH穩(wěn)定。雖然NANDFLASH讀數(shù)據(jù)時(shí)地址具有自動(dòng)增加功能,但實(shí)際使用中不太穩(wěn)定。一般的做法是每幾頁(yè)(甚至一頁(yè))復(fù)位一下NAND型FLASH。所以,在文件startup.s中讀K9F1208時(shí),每讀完一頁(yè)都復(fù)位了該芯片。

完成上述工作后,重新編譯鏈接工程ex7_3,在目錄D:\ZYUCOSII\ex7_3\Debug\Exe下得到目標(biāo)文件ex7_3.hex,可用UltraEdit軟件打開閱讀。打開ex7_3.map文件,如圖7-11所示,intvec段起始地址必須位于0x0處。

接下來(lái)的工作是如何將工程ex7_3的目標(biāo)代碼(ex7_3.hex)下載到FLASH芯片K9F1208中。這里介紹兩種下載的方法:其一為自己編寫下載程序,參見第7.2.3~7.2.4節(jié),這種方法比較繁瑣,但有助于提高程序設(shè)計(jì)水平;其二為借助于H-JTAG等軟件,參見第7.2.5節(jié)。圖7-11工程ex7_3的Map表7.2.3目標(biāo)代碼轉(zhuǎn)化為C頭文件flash.h

文件ex7_3.hex的內(nèi)容如下(由于代碼太長(zhǎng),這里僅列出了文件頭和尾,中間代碼沒有列出):

1:10000000210000EA0000A0E10000A0E10000A0E162

2:100010000000A0E10000A0E10000A0E10000A0E1DC

3:1000200000000000000000000000000000000000D0

4:1000300000000000000000000000000000000000C0

5:1000400010111111FC7F0000FC7F00000007000070

6:1000500000070000502E0000502E00000580010017

7:100060000580010000008C00B0000000300000009E8:1000700030000000FFFFFF000300000011800500BA

9:100080002380070004000000F0FF07005304A0E3F2

10:10009000A4119FE5A4219FE5082080E5042080E5C8

11:1000A000001080E54C04A0E33C804FE27E0098E81D

12:1000B000001080E5142080E5043080E5084080E5EC

13:1000C000105080E50C6080E590E04FE2FF1F9EE855

14:1000D00048E4A0E3FF1F8EE864019FE5541CA0E301

15:1000E000001080E55C019FE5CF10A0E3001080E5E3

16:1000F00054019FE50010E0E3001080E54C019FE50E

17:100100004C119FE5001080E55604A0E30010E0E3E9

18:10011000001080E54E04A0E338119FE5001080E553

19:100120003F0000EB0050A0E30000A0E3C015A0E3F720:1001300024819FE5FF90A0E3009088E5380000EB64

21:1001400014819FE50090A0E3009088E50C819FE575

22:10015000FF6005E2006088E500819FE5A564A0E1FD

23:10016000FF6006E2006088E5F0809FE5A568A0E1F9

24:10017000FF6006E2006088E5E0809FE5A56CA0E1F5

25:10018000016006E2006088E5250000EBD0209FE5D5

26:100190000030A0E30040D2E50140C1E4013083E239

27:1001A000800F53E3FAFFFF1A0040D2E5013083E2EB

28:1001B000840F53E3FBFFFF1A190000EB805F85E219

29:1001C000010080E2800E50E3D8FFFF1AC005A0E3D3

30:1001D000100F0DEE101F1DEE0000A0E1DBF021E37B

31:1001E00080D09FE5D7F021E37CD09FE5D1F021E3DB

32:1001F00078D09FE5D2F021E374D09FE5D3F021E3DE33:1002000070D09FE538009FE5541CA0E3001080E506

34:1002100030009FE5AF10A0E3001080E558009FE597

35:1002200010FF2FE154809FE5009098E5019009E2CE

36:10023000000059E3FBFFFF0A0EF0A0E1187C00006C

37:100240003075000020000056240000560800004AC7

38:100250000C00004CF0FF0700779700000400004EF0

39:100260000800004E0C00004E00230400002404008F

40:10027000002204000021040000200400A4720000F9

41:040280001000004E1C

42:10100000F8402DE90060B0E10140B0E10250B0E1EC

43:101010000070A0E3C4019FE50000D0E5010050E3AB

44:101020000200003A1200A0E30000C5E51E0000EA3D

45:101030000000D6E5010050E30500000A1000003A68

46:10104000030050E30200000A0100003A040050E3EC

47:101050000B00001AC50F00EB0070B0E10400B0E116

48:10106000200300EBFF0010E2100050E30700003AFD

49:101070000700B0E1C10F00EB0B00A0E30000C5E5E5

50:10108000090000EA0100A0E30000C5E5060000EA4F

51:101090000410B0E12C0096E2030300EB0700B0E17E

52:1010A000B60F00EB0000A0E30000C5E5F140BDE88D

53:1010B0001EFF2FE100502DE9681200EBEB0100EB61

54:1010C000130200EB660200EBC20100EBF50300EB3C

55:1010D0001A0400EB3F0400EB2D0200EB460200EB8C

56:1010E000C20600EB721200EB101300EB0140BDE8EA

57:1010F0001EFF2FE110402DE90040A0E34C039FE5C758:101100000000D0E5010050E33000001A970F00EB1B

59:101110000040B0E1C4009FE50000D0E5010050E3CD

60:101120000400003AB4009FE50000D0E5010050E261

61:10113000A8109FE50000C1E5A0009FE50000D0E5F4

1685:1076B00020546D72000000004170705461736B5F64

1686:1076C000310000004170705461736B5F3200000044

1687:1076D0004170705461736B5F330000004F532D5441

1688:1076E0006D724C6F636B00004F532D546D72536974

1689:1076F000670000000010B0E101C0B013FFFEFFEA18

1690:107700004C65645F53656D005461736B5F310000BD1691:107710005461736B5F3200005461736B5F33000020

1692:10772000686A6C747A4C0000785634121EFF2FE1A0

1693:107730001EFF2FE1010001000A0010003C0058026A

1694:10774000010001001C001400020005001000FE00F2

1695:1077500001000100050010002400B4000100040035

1696:1077600001000400180010000100040001000100E5

1697:1077700001008000010016001000010080000100DF

1698:107780000100FF006000640001001E010100100004

1699:10779000100008000A003400400308004000271AC7

1700:0400000500000000F7

1701:00000001FF該Hex文件每行的含義請(qǐng)參考《ARM原理與C程序設(shè)計(jì)》第267頁(yè)。從上述代碼可以看出,第1~41行的數(shù)據(jù)要寫入到FLASH芯片的地址0x0~0x283處,而第42~1699行的數(shù)據(jù)要寫入到FLASH芯片的地址0x1000~0x779F處,按字節(jié)(地址)寫入。

筆者使用《ARM原理與C程序設(shè)計(jì)》第七章的工程Hex2H(使用C#語(yǔ)言,VisualStudio2008平臺(tái)),并稍作修改,生成一個(gè)新的可執(zhí)行文件Hex2H.exe(詳細(xì)方法不再贅述),用這個(gè)可執(zhí)行文件將ex7_3.hex轉(zhuǎn)化為C語(yǔ)言的頭文件flash.h。文件flash.h的內(nèi)容如下:對(duì)比文件flash.h和ex7_3.hex,可以看出這兩個(gè)文件的關(guān)系,即文件flash.h中的數(shù)組FlashDat包含了ex7_3.hex中的第1~41行的數(shù)據(jù),這些數(shù)據(jù)寫入FLASH的首地址為0x0;文件flash.h中的數(shù)組FlashDat2包含了ex7_3.hex中第42~1699行的數(shù)據(jù),這些數(shù)據(jù)寫入FLASH的首地址為0x1000。根據(jù)這種對(duì)應(yīng)關(guān)系,讀者可用自己熟悉的語(yǔ)言編寫實(shí)現(xiàn)工程Hex2H功能的程序,生成的文件flash.h用于第7.2.4節(jié)工程ex7_4中。7.2.4Bootloader工程ex7_4

這里將新建一個(gè)工程ex7_4,用于將第7.2.3節(jié)的flash.h文件中的數(shù)據(jù)寫入到芯片K9F1208中。在工程ex7_2的基礎(chǔ)上新建工程ex7_4,保存目錄為D:\ZYUCOSII\ex7_4,這時(shí)的工程ex7_4與工程ex7_2完全相同(注意,這是一個(gè)芯片級(jí)的程序)。需要做的修改為:將flash.h拷貝到D:\ZYUCOSII\ex7_4\user目錄下,然后將該文件添加到工程ex7_4中,并修改文件zyMain.c。工程ex7_4如圖7-12所示。圖7-12工程ex7_4其中,文件zyMain.c的內(nèi)容如下:

1/*FileName:zyMain.c

2**Byzhnyong@21

3**@2009-4-4

4**MainSubroutine

5**CopyrightReserved

6*/

7

8#include"zyDef2410.h"

9#include"flash.h"

10

11unsignedintFCLK,HCLK,PCLK;

12unsignedintval;13

14voidmain(void)

15{

16inti,n=0;

17//initializeNANDController

18initFlash();

19readFlashID();

20//for(i=0;i<1000;i++)

21//flashDat[i]=(i+89)%247;

22for(i=0;i<64;i++)//Erase16K*64

23{

24flashErase(i<<14);

25}

26flashWr(0x0,iDatN,FlashDat);

27flashWr(0x1000,iDatN2,FlashDat2);

28flashRd(0x429C,1000,flashWhat);

29//Flashdata,except16Bper528

30for(i=0;i<668;i++)

31{

32n=i/512;

33flashCp[i]=flashWhat[i+n*16];

34}

35//AboveisNandFlashoperator

36

37//Clock=192MHz?

38val=MPLLCON;上述代碼第26行將FlashDat數(shù)組寫入到K9F1208芯片的地址0x0開始的空間內(nèi);第27行將FlashDat2數(shù)組寫入到K9F1208芯片的地址0x1000開始的空間內(nèi)。

工程ex7_4是仿真執(zhí)行的,即仿真運(yùn)行工程ex7_4,就可以把工程ex7_3生成的ex7_3.hex(flash.h)寫入到K9F1208中?,F(xiàn)在,回顧一下已做的工作:第一步,在第7.2.1節(jié)介紹了讀寫K9F1208的方法,并給出一個(gè)演示工程ex7_2;第二步,在第7.2.2節(jié)中修改第六章工程ex6_1成為新的工程ex7_3,這步所做的修改目的是為了使工程ex7_3具有自舉特性,即其文件startup.s能完成上電Bootloader功能;第三步,在第7.2.3節(jié)將工程ex7_3(Debug模式)生成的ex7_3.hex文件轉(zhuǎn)換為C語(yǔ)言的頭文件flash.h;第四步,即本節(jié)工程ex7_4將flash.h文件寫入到K9F1208的適當(dāng)位置,當(dāng)flash.h寫入成功后,可以看到三個(gè)LED燈滾動(dòng)閃爍。這些工作都正確無(wú)誤地完成后,可以關(guān)閉UP-Star實(shí)驗(yàn)板電源,把J-LINK仿真器取下來(lái)(也可以不取);然后,打開串口調(diào)試助手,設(shè)置波特率為115200bps;最后,再給UP-Star實(shí)驗(yàn)板上電,此時(shí)串口調(diào)試助手會(huì)顯示如第六章圖6-2所示的界面。如果按下JOYSTICK按鍵,串口調(diào)試助手將顯示按鍵的信息,同時(shí)LED燈閃爍。至此,Bootloader工作完成了。7.2.5H-JTAG下載方式

上面的方法過(guò)于繁瑣了,向FLASH中寫入程序有大量現(xiàn)成的方案可以選取

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(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)論