天天看點

DM365視訊處理流程/DM368 NAND Flash啟動揭秘

出自http://blog.csdn.net/maopig/article/details/7029930

DM365的視訊處理涉及到三個相關處理器,分别是視訊采集晶片、ARM處理器和視訊圖像協處理器(VICP),整個處理流程由ARM核協調。視訊處理主要涉及三個處理流程,分别是視訊采集、視訊編碼和對編碼後的視訊的處理,為了提高性能,通常為每個處理流程提供一個處理線程。

視訊采集

  TVP5146将采集到的視訊資料轉化為數字信号,并将這些資料送入DM365的BT656接口,然後通過Resize得到所需要的分辨率,然後将這些資料寫入到指定的記憶體中,這些記憶體空間由cmem子產品配置設定。cmem子產品用于配置設定連續的存儲空間,連續的存儲空間可以提高資料的讀寫效率。

視訊編碼

   VICP從指定的存儲空間中讀入視訊資料,并将這些資料編碼為指定的視訊/圖像格式,然後将編碼後的資料寫入到指定的存儲空間,這些存儲空間通常也是由cmem子產品配置設定。

編碼資料處理

  ARM從指定的記憶體空間中擷取編碼後的視訊資料,可以将這些編碼後的資料儲存到本地或遠端,也可以使用RTP協定發送到網絡。

整個過程由ARM核協調,為了提高效率,大量使用DMA操作和cmem子產品配置設定的連續存儲空間。

作者:德州儀器現場技術支援工程師 孟海燕

概要:

本文介紹了DM368 NAND Flash啟動的原理,并且以DM368 IPNC參考設計軟體為例,介紹軟體是如何配合硬體實作啟動的。

關鍵字:NAND Flash啟動,RBL,UBL

晶片上電後是如何啟動實作應用功能的?這是許多工程師在看到處理器運作的時候,通常都會問的一個問題。下面我們就以德州儀器的多媒體處理晶片TMS320DM368為例,介紹它的NAND Flash啟動原理以及實作。

一.NAND Flash啟動原理

德州儀器的多媒體處理晶片TMS320DM368可以實作1080P30 h264的編碼,已經廣泛的使用在了網絡錄影機的應用中。DM368可以支援NOR Flash, NAND Flash, UART, SD Card啟動等多種啟動方式。對于NAND啟動,DM365支援的特性如下:

1.   不支援一次性全部固件下載下傳啟動。相反的,需要使用從NAND flash把第二級啟動代碼(UBL)複制到ARM的記憶體(AIM),将控制轉交給使用者定義的UBL。

2.   支援最大4KB頁大小的NAND。

3.   支援特殊數字标志的錯誤檢測,在加載UBL的時候會嘗試最多24次。例如在NAND的第1個block沒有找到特殊數字标志,會到下一個block繼續查找,一直到查找到第24個block。

4.   支援30KB大小的UBL(DM365有32KB的記憶體,其中2KB用作了RBL的堆棧,剩下的空間可以放UBL)

5.   使用者可以選擇在RBL執行的時候是否需要支援DMA,I-cache(例如,加載UBL的時候)

6.   使用并且需要4位硬體ECC(支援每512位元組需要ECC位數小于或等于4位的NAND Flash)。

7.   支援需要片選信号在Tr讀時間為低電平的NAND Flash。

在網絡網絡錄影機的應用中為了節約成本,有一些使用者使用了NAND Flash啟動方式。圖1 就是從上電到Linux啟動的一個概要的流程圖。首先RBL(ROM boot loader)從NAND上讀取UBL(user boot loader)并且複制到ARM的記憶體裡面。UBL運作在ARM的記憶體裡,初始化系統,例如初始化DDR。然後UBL從NAND Flash裡面讀取U-Boot的内容并且複制到DDR裡運作。DDR裡面運作的U-Boot又從NAND Flash裡面讀取Linux核心代碼,并且複制到DDR上,然後啟動核心。這樣DM365的系統就從上電到完成Linux核心啟動,然後就可以運作相應的應用程式了。

DM365視訊處理流程/DM368 NAND Flash啟動揭秘

圖1 NAND Flash啟動流程

下面我們會一步一步的介紹從上電到Linux啟動是如何實作的。

首先我們需要提到的一個概念是RBL,也就是ROM Boot Loader (ROM啟動代碼)。在DM368晶片上有一塊ROM的區域(位址從0x00008000到 0x0000 BFFF),這塊區域就是存放RBL代碼的地方。ROM上的代碼是在晶片出廠前就燒寫好的,使用者是不能修改的。在DM368上,除了AEMIF (Nor Flash)啟動,其他的啟動方式都需要運作RBL。

無論是上電複位,熱複位,還是看門狗複位,在複位信号由低到高的時候,DM368晶片會檢測BTSEL[2:0]引腳(啟動選擇引腳)。隻要檢測到電平不是001,也就是不是AEMIF (NOR Flash)啟動,ARM程式就會從ARM的ROM的位址0x00008000位址開始執行。

RBL首先會讀取BOOTCFG寄存器裡面的BTSEL資訊,如果發現BTSEL的狀态是000,就會得知配置的是NAND Flash啟動,NAND啟動模式開始執行。注意:為了保證NAND啟動正常運作,需要保證在複位的時候DEEPSLEEPZ/GIO0引腳拉高。在确認啟動是NAND後,首先RBL會初始化最高2KB的記憶體為堆棧并且關閉是以中斷。然後RBL會讀取NAND的ID資訊,然後在RBL的代碼裡面的NAND ID 清單,進而得知更詳細的NAND Flash的資訊,例如頁(page)大小等,對EMIF做好相應的配置。DM368支援啟動的NAND的ID資訊可以在參考文檔1(ARM子系統使用者手冊)裡面找到。硬體選型時,請務必選擇在NAND ID清單裡面支援的NAND晶片。

接下來,RBL會在NAND Flash的第1塊的第0個頁開始查找UBL的描述符。如果沒有找一個合法的UBL的特殊數字标志,RBL會繼續到下一個塊的第0個頁查找描述符,最多第24個塊。RBL會到多個塊裡面查找描述符是根據NAND Flash本身容易與壞塊的特點而設計的。24塊應該足以避免NAND Flash壞塊的影響。

如RBL在某塊裡面找到了合法的UBL描述符,這個塊号(block number)就會寫到ARM記憶體最後的32位(0x7FFC~0x8000)用于調試時候使用,然後UBL描述符的具體内容将被讀取并且處理。UBL描述符告訴RBL關于下載下傳和将控制權交給UBL所需要的資訊,具體見表1.

第0頁位址 32位 描述
0xA1AC Edxx 特殊數字标志
4 UBL入口位址 使用者啟動代碼的入口位址(絕對位址)
8 UBL使用的頁數 頁數(使用者啟動diamond的大小)
12 UBL開始的塊号 開始存放使用者啟動代碼的塊号(block number)
16 UBL開始的頁數 開始存放使用者啟動代碼的頁數
20 PLL設定-M PLL設定- 倍率(僅在特殊數字标準表示PLL使能的時候有效)
24 PLL設定-N PLL設定- 分率(僅在特殊數字标準表示PLL使能的時候有效
28 快速EMIF設定 快速EMIF設定(僅在特殊數字标準表示快速EMIF啟動的時候有效)

表1 NAND UBL描述符

一旦使用者需要的啟動設定配置好,RBL就會從0x0020第位址開始把UBL搬移到ARM記憶體。在從NAND讀取UBL的過程中中,RBL會使用4位的硬體ECC對NAND Flash上的資料進行檢錯和糾錯。如果因為其他原因讀失敗,複制會立即停止,RBL會在下個塊裡面繼續尋找特殊數字标志。

對于UBL的描述符有幾點注意事項:

1.   入口位址必須在0x0020到0x781C之間

2.   存放UBL的頁必須是連續的頁,可以分布在多個塊内,總共大小必須小于30KB。

3.   UBL的起始塊号(block number)可以是和存放UBL描述符的塊号一樣。

4.   如果UBL的起始塊号是和存放UBL描述符的塊号一樣, 那UBL的起始頁數一定不可以和UBL描述符存放的頁數一樣。

但RBL根據UBL描述符裡提供的UBL大小資訊将UBL全部成功複制到ARM記憶體後,RBL會跳到UBL起始位址,這樣晶片的控制權就交給了UBL,UBL開始在ARM記憶體裡運作了。

也許你會問,既然RBL可以把NAND Flash上的内容複制到ARM記憶體裡運作,為什麼我們不直接把U-Boot複制到記憶體運作?原因是ARM記憶體太小。一般的U-Boot都是大于100KB,而DM365上可以用于啟動的記憶體隻有30KB。也許你又要問了,那為什麼不把U-Boot直接複制到DDR上運作,DDR有足夠大的空間?這個原因是,晶片上電後并無法知道使用者在DM365的DDR2接口上接的DDR資訊,RBL也就無法初始化DDR,在RBL運作的階段DDR是不可用的。這也是為什麼UBL裡面初始化DDR是它的一項重要任務。

當NAND啟動失敗的時候,RBL會繼續嘗試MMC/SD啟動方式。如果你系統使用NAND啟動,但NAND上的内容損壞了,如果你的闆子上有SD卡接口,也可以改變啟動方式,那你可以用SD卡先把系統啟動起來,然後重新燒寫NAND Flash上的内容。這可以作為産品失效後在客戶側的一個補救方法。

二.NAND Flash啟動的軟體配合實作

現在我們知道了DM368 NAND Flash啟動的原理,下面我們來看看軟體是如何根據并配合硬體的要求實作啟動的。在DM368 IPNC的軟體包裡面有一個工具的目錄,裡面有預先編譯好的燒寫NAND的CCS的可執行檔案, UBL的二進制檔案以及相關源碼。

剛才在介紹NAND Flash啟動原理的時候,我們提到了RBL需要到NAND Flash上面搜尋特殊數字标志。這個特殊數字标志就是由燒寫NAND的CCS的工程寫到Flash上的。在flash_utils_dm36x_1.0.0\flash_utils_dm36x\DM36x\CCS\NANDWriter\src\nandwriter.c裡面的LOCAL_writeHeaderAndData()函數就是用來寫描述符的。

// Setup header to be written

headerPtr = (Uint32 *) gNandTx;

headerPtr[0] = nandBoot->magicNum; //Magic Number

headerPtr[1] = nandBoot->entryPoint; //Entry Point

headerPtr[2] = nandBoot->numPage; //Number of Pages

#if defined(IPNC_DM365) || defined(IPNC_DM368)

headerPtr[3] = blockNum+3; //Starting Block Number

headerPtr[4] = 0; //Starting Page Number - always start data in page 1 (this header goes in page 0)

對比表1,你可看到headerPtr[3]的内容是用來存放UBL代碼的起始塊号。這裡+3的意思就是UBL是存放在UBL描述符所放塊号後面的第三塊裡面。headerPtr[4] = 0表示是從第0頁開始存放。當然這個值使用者是可以修改的。隻要你燒寫UBL代碼的位置和描述符裡面的起始塊/頁數一緻就可以了。

在IPNC的代碼裡面UBL的描述符是會從NAND Flash的第1個塊開始寫,如果塊是好的,就放在第1塊的第0頁。如果第1塊是壞的,就會把UBL的描述符寫入到下一個塊的第0頁。IPNC的代碼裡面沒有将UBL描述符可能有的塊号從1到24塊(這是RBL搜尋的範圍),它隻是從第1塊到第3塊。如果UBL描述符放在第1塊,那如果第4塊是好的話,UBL的代碼就從第4塊的第0頁開始放。

#elif defined(IPNC_DM368)

// Defines which NAND blocks the RBL will search in for a UBL image

#define DEVICE_NAND_RBL_SEARCH_START_BLOCK (1)

#define DEVICE_NAND_RBL_SEARCH_END_BLOCK (3)

在nandwriter.c裡面你還可以看到UBL的入口位址是固定的0x100。

gNandBoot.entryPoint = 0x0100; // This fixed entry point will work with the UBLs

要了解為什麼是0x100,你就必須要看一下UBL的源碼。在UBL源碼的UBL.cmd檔案裡面,你可以看到下面的定義,将入口位址放在boot的地方,而boot的運作位址就是0x100。

-e boot //指定入口位址為boot

...

MEMORY

{

...

UBL_I_TEXT (RX) : origin = 0x00000100 length = 0x00004300

...

UBL_F_TEXT (R) : origin = 0x020000E0 length = 0x00004300

...

}

SECTIONS

{

...

.text : load = UBL_F_TEXT, run = UBL_I_TEXT, LOAD_START(FLASHTEXTStart), LOAD_SIZE(FLASHTEXTSize)

{

*(.boot)

. = align(4);

*(.text)

. = align(4);

}

....

}

在UBL的源碼boot.c裡面有強制把啟動的最初代碼放在了boot的section裡面。

#if defined(__TMS470__)

...

#pragma CODE_SECTION(boot,".boot");

#endif

void boot(void)

{

...

}

這樣從cmd的配置以及代碼指定代碼段,UBL的程式就能確定是從0x100的位址開始運作。

UBL啟動U-Boot的過程,借鑒了RBL啟動UBL的原理。燒寫描述符也是用同樣的LOCAL_writeHeaderAndData()函數。在nandwriter.c裡面,我們把U-Boot的代碼叫做應用代碼(APP)。

// Defines which NAND blocks are valid for writing the APP data

#define DEVICE_NAND_UBL_SEARCH_START_BLOCK (8)

#define DEVICE_NAND_UBL_SEARCH_END_BLOCK (10)

下面是IPNC啟動後序列槽最初的列印。

Valid magicnum, 0xA1ACED66, found in block 0x00000008.

DONE

Jumping to entry point at 0x81080000.

我們可以看到UBL是指第8塊的地方找到了U-Boot的描述符,這個DEVICE_NAND_UBL_SEARCH_START_BLOCK的定義是一緻的。

IPNC代碼支援在U-Boot裡面更新UBL或者U-Boot自己。下面是燒寫ubl和U-Boot在U-Boot下的指令。

燒寫ubl:

nand write 0x80700000 0x080000 0x08000

燒寫U-Boot:

nand write 0x80700000 0x160000 0x28000

要了解為什麼NAND Flash的燒寫位址是0x80000和0x160000,這還是需要了解nandwriter.c裡面的燒寫流程。從前面的内容我們可以得知,nandwriter.c燒寫UBL是從1+3=4塊開始的,而燒寫U-Boot是從8+3=11塊。在IPNC上使用的NAND Flash是2K一個頁,每個塊128KB。是以UBL燒寫的位址是128KBx4=0x80000,而燒寫U-Boot的位址是128Kx11=0x160000。

是以如果在沒有NAND Flash壞塊的情況下,nandwriter.c會把UBL的描述符燒寫在第1塊第0頁上,把UBL的代碼燒寫在第4塊第0頁上,把U-Boot(APP)的描述符燒寫在第8塊第0頁上,把U-Boot的代碼燒寫在第11塊第0頁上。這樣晶片在上電确認是NAND Flash啟動後,RBL在執行的時候就會找到UBL相應的描述符,把UBL加載的ARM記憶體裡運作。而UBL又找到了U-Boot的描述符,把U-Boot加載到DDR上運作。最後U-Boot加載uImage并啟動了Linux,完成了從上電到Linux啟動的整個過程。

三.結束語

每個晶片一般都有多種啟動方式,各個晶片的啟動方式都有所不同,但又有類似的地方。上面的介紹也可以作為學習其他晶片其他啟動方式的一個參考。

最後感謝李斌在本文整理過程中的幫助!

參考文獻

1. TMS320DM36x Digital Media System-on-Chip (DMSoC) ARM Subsystem User's Guide Literature Number: SPRUFG5A

2. TMS320DM368 datasheet Literature Number: SPRS668C