劉遠(yuǎn)峰,陳志華
(暨南大學(xué) 信息技術(shù)研究所,廣東 廣州 510075)
C6000系列沒(méi)有自帶的Flash,一般程序要燒寫到外擴(kuò)的Flash中,再由Flash引導(dǎo)自啟動(dòng)。由于Flash的讀取速度比較慢,一般在上電復(fù)位之后,通過(guò)Boot?loader程序把Flash中的應(yīng)用程序代碼引導(dǎo)到DSP的內(nèi)部RAM中去執(zhí)行,實(shí)現(xiàn)系統(tǒng)高速運(yùn)行。在C6000系列的DSP上電復(fù)位之后,DSP會(huì)直接由EDMA模塊采用默認(rèn)的ROM讀/寫時(shí)序從CE1空間起始地址上拷貝1 kbyte的代碼到DSP的內(nèi)部RAM起始地址0x00,然后DSP的CPU才開始運(yùn)行,CPU從地址0x00開始執(zhí)行程序,這是DSP的Flash引導(dǎo)自啟動(dòng)的基礎(chǔ),也是Bootloader程序能夠被復(fù)制進(jìn)入DSP內(nèi)部RAM起始地址運(yùn)行的關(guān)鍵。傳統(tǒng)的Flash引導(dǎo)自啟動(dòng)往往用兩個(gè)項(xiàng)目文件,一個(gè)用來(lái)調(diào)試應(yīng)用程序,一個(gè)用來(lái)把應(yīng)用程序燒寫到Flash中去,這樣比較繁瑣。本文只用一個(gè)項(xiàng)目文件完成應(yīng)用程序的調(diào)試和燒寫,方便可靠。
在上電復(fù)位之后,DSP6713B會(huì)自動(dòng)去搬移Flash起始地址開始的1 kbyte內(nèi)容,這1 kbyte內(nèi)容搬移到DSP6713B的內(nèi)部RAM起始地址開始的1kbyte內(nèi)存中,當(dāng)DSP開始執(zhí)行程序時(shí),首先從內(nèi)部RAM的起始地址開始執(zhí)行程序,這樣就等于開始執(zhí)行Flash起始地址開始的1 kbyte的內(nèi)容,這就是存放DSP的啟動(dòng)程序Bootloader。Bootloader是一個(gè)復(fù)制程序,主要功能是把Flash中存放的應(yīng)用程序代碼復(fù)制到DSP的RAM中去執(zhí)行。首先,Bootloader程序編寫時(shí)是存放在DSP的起始地址開始的1 kbyte RAM中,然后再和應(yīng)用程序代碼一起燒寫到Flash中去,Bootloader程序代碼是被指定燒寫到Flash起始地址開始的1 kbyte空間中,應(yīng)用程序代碼則被燒寫到Flash起始地址開始的1 kbyte空間之外,通常是緊跟在這1 kbyte地址空間之后,這樣就把Bootloader程序燒寫到Flash起始地址開始的1 kbyte空間中去,同時(shí),應(yīng)用程序代碼也被燒寫到Flash中。
由于DSP上電復(fù)位之后,自動(dòng)加載Flash起始地址開始的1 kbyte內(nèi)容,而這1 kbyte內(nèi)容存放的就是Bootload?er程序,這樣就把Bootloader程序加載到DSP起始地址開始的1 kbyte空間中去,DSP開始執(zhí)行Bootloader程序,而Bootloader的功能就是把Flash中存放的應(yīng)用程序代碼復(fù)制到DSP的RAM中,當(dāng)Bootloader程序在DSP的RAM中執(zhí)行完成后,所有的應(yīng)用程序也就從Flash中復(fù)制到DSP的RAM中,然后DSP跳到c_int00()復(fù)位中斷去執(zhí)行,開始執(zhí)行應(yīng)用程序,這樣就實(shí)現(xiàn)了DSP的Flash引導(dǎo)自啟動(dòng)。
傳統(tǒng)DSP6713B的Flash自啟動(dòng)往往需要把應(yīng)用程序加載和程序燒寫到Flash中去,分別用兩個(gè)項(xiàng)目文件去完成,這樣很不方便。為了避免覆蓋已經(jīng)下載到DSP的RAM中的應(yīng)用程序和Bootloader程序,燒寫Flash程序的項(xiàng)目文件的cmd文件配置還要進(jìn)行重新設(shè)置。設(shè)計(jì)方案進(jìn)行了改進(jìn),開始地址0x00的1 kbyte空間用來(lái)存放Bootloader程序,考慮到應(yīng)用程序和燒寫程序都是存放在DSP的程序代碼.text中,如果編寫在同一個(gè)項(xiàng)目文件中,在項(xiàng)目文件下載時(shí),DSP會(huì)自動(dòng)分給應(yīng)用程序和Flash燒寫程序在.text地址空間分配地址,兩者并不會(huì)相互影響和相互覆蓋。
首先,調(diào)試應(yīng)用程序,完成之后,在應(yīng)用程序項(xiàng)目文件中再加入燒寫程序,燒寫程序放在DSP初始化,并在DSP編譯,運(yùn)行之后,就直接執(zhí)行了燒寫程序,燒寫程序只運(yùn)行一次,這樣就把Bootloader程序和應(yīng)用程序同時(shí)燒寫入Flash中。由于Flash有燒寫次數(shù)壽命限制,因此,該設(shè)計(jì)只讓Flash燒寫一次,通過(guò)在燒寫程序中加入一個(gè)標(biāo)志位就可以控制Flash燒寫一次。當(dāng)DSP第一次運(yùn)行燒寫程序時(shí),改變標(biāo)志位,通過(guò)判別標(biāo)志位,可以控制燒寫程序在運(yùn)行第一次之后就不再運(yùn)行了。其次,在上電復(fù)位之后,Bootloader程序把燒寫程序和應(yīng)用程序都拷貝進(jìn)入DSP的RAM中運(yùn)行,由于燒寫程序標(biāo)志位改變,所以被直接跳過(guò),執(zhí)行應(yīng)用程序,避免了多次燒寫程序,這樣就完成應(yīng)用程序的Flash自啟動(dòng)。本設(shè)計(jì)可以避免燒寫程序另外建立一個(gè)項(xiàng)目文件的麻煩,只要在調(diào)試好應(yīng)用程序之后,直接在本項(xiàng)目文件加入燒寫程序,編譯運(yùn)行,就把程序下載到Flash中。
對(duì)于TMS320C671X系列的DSP,在芯片復(fù)位之后,CPU處于“停轉(zhuǎn)”狀態(tài),EDMA模塊采用默認(rèn)的ROM讀/寫時(shí)序從CE空間起始地址拷貝1 kbyte的地址代碼到地址0x00,可以根據(jù)自己需要片選CE空間的起始地址,當(dāng)EDMA模塊拷貝代碼完畢,CPU就會(huì)轉(zhuǎn)入“運(yùn)行”狀態(tài),從地址0x00開始執(zhí)行程序。
DSP的EMIF引導(dǎo)啟動(dòng)是DSP的Flash自啟動(dòng)的基礎(chǔ),EMIF引導(dǎo)啟動(dòng)實(shí)現(xiàn)了將Flash中的1 kbyte地址空間復(fù)制進(jìn)入DSP的RAM中,這樣就實(shí)現(xiàn)了將Bootloader程序復(fù)制進(jìn)入了DSP的RAM中去執(zhí)行,再通過(guò)Bootloader程序復(fù)制應(yīng)用程序,從而實(shí)現(xiàn)了應(yīng)用程序在掉電、上電的重新載入DSP的RAM中去執(zhí)行,完成了DSP的Flash自啟動(dòng)。
如圖1所示,DSP外擴(kuò)的是一個(gè)16位寬的Flash,DSP的地址輸出引腳EA[21~2]與Flash的地址引腳A[20~1]對(duì)應(yīng),由于C671x系列DSP的最低有效位地址總是從外部地址管腳EA2輸出,因此,在對(duì)SST36VF1601進(jìn)行讀/寫時(shí),DSP的地址位必須左移1位,這樣才能與SST36VF1601的地址位對(duì)應(yīng),正確操作該款Flash的地址命令,從而正確地讀/寫Flash。
cmd文件負(fù)責(zé)DSP的內(nèi)存分配,配置好DSP的內(nèi)存才能使應(yīng)用程序和Bootloader程序合理的分配到DSP的內(nèi)存空間中去。首先,將Bootloader程序代碼分配到DSP的0x00起始地址空間的1 kbyte的RAM空間中,在Flash燒寫程序代碼時(shí),直接將Bootloader程序燒寫進(jìn)入Flash起始地址開始的1 kbyte地址空間中,這樣在上電復(fù)位之后就能夠由EMIF引導(dǎo)啟動(dòng),將Bootloader程序重新復(fù)制到DSP起始地址開始的1 kbyte空間中執(zhí)行。其次,將應(yīng)用程序代碼也分配到L2內(nèi)部RAM地址空間中,應(yīng)用程序代碼存放地址緊跟著Bootloader程序代碼存放的地址之后,便于在Flash燒寫程序代碼時(shí),連續(xù)燒寫B(tài)ootloader程序代碼和應(yīng)用程序代碼,同時(shí),這樣可以使得Bootload?er程序代碼和應(yīng)用程序代碼占用最少的L2空間,以免影響到程序運(yùn)行時(shí)的速度和被其他動(dòng)態(tài)分配內(nèi)存的變量覆蓋。
圖2是DSP的cmd文件,Bootloader程序被指定存放在0x00000000~0x00000400的1 kbyte的地址空間中,應(yīng)用程序代碼被指定存放在0x00000400的1 kbyte地址空間之后L2(內(nèi)部RAM)的192 kbyte地址空間中,而一些要分配內(nèi)存的常量、全局變量和靜態(tài)變量跟程序代碼分配在同一塊內(nèi)存地址空間中,這些都是程序運(yùn)行時(shí)所必須用到的數(shù)據(jù),而一些動(dòng)態(tài)分配內(nèi)存變量數(shù)據(jù)和堆棧跟程序代碼占用的地址空間分開存放,以免影響程序的正常運(yùn)行和覆蓋程序代碼。
Bootloader程序一般用匯編編寫,這樣DSP能夠更準(zhǔn)確地執(zhí)行程序代碼。Bootloader程序功能就是把燒寫在Flash中的程序代碼和有用信息全部復(fù)制到DSP內(nèi)部RAM(L2)中去執(zhí)行,然后指向_c_int00中斷去執(zhí)行程序??梢源蜷_項(xiàng)目文件中的.map文件,觀察所有程序用到的地址空間的大小,然后再根據(jù)復(fù)制.map文件去復(fù)制所用到的地址塊,也可以直接將整個(gè)的L2地址空間中存放程序代碼地址空間數(shù)據(jù)全部復(fù)制到DSP的RAM中去執(zhí)行,這樣就避免了每次寫程序時(shí)改動(dòng)Bootloader程序需要所要復(fù)制的地址塊大小。如圖2所示,Bootloader程序需要復(fù)制的地址塊大小就等于BOOT_RAM和PMEM指定的地址塊大小,而BMEM是變量存放空間,不必復(fù)制和燒寫。
如圖3所示,首先,DSP初始化csl_init,也即初始化TI自帶的DSP API庫(kù)函數(shù)。在csl_init初始化之后,用戶就可以使用TI公司提供的標(biāo)準(zhǔn)API庫(kù)函數(shù),直接調(diào)用API庫(kù)函數(shù)對(duì)DSP的二級(jí)緩存L2進(jìn)行配置,即配置DSP內(nèi)部Cache L2的大小。接著初始化PLL鎖相環(huán)時(shí)鐘模塊,這是為了提供DSP的CPU、外部存儲(chǔ)器接口EMIF和外部時(shí)鐘源的工作時(shí)鐘源,因此,PLL初始化是DSP啟動(dòng)的關(guān)鍵。在PLL時(shí)鐘配置好之后,初始化EMIF,EMIF是SDRAM和Flash的控制接口,通過(guò)EMIF初始化配置就可以配置和啟動(dòng)SDRAM和Flash。最后是中斷初始化,主要是開啟全局中斷和硬件中斷,設(shè)置好要中斷的映射。這樣,整個(gè)DSP的初始化完成。
3.5.1 測(cè)試程序定時(shí)器的流程
如圖4所示,在DSP初始化之后,開始初始化定時(shí)器和GPIO口,定時(shí)器初始化主要是設(shè)置計(jì)數(shù)初始值和周期,GPIO口初始化主要是將GPIO映射為輸出口,用來(lái)控制LED顯示燈的點(diǎn)亮。當(dāng)定時(shí)器開始中斷,進(jìn)入中斷子程序,由中斷子程序控制GPIO口點(diǎn)亮LED燈,以顯示定時(shí)器定時(shí)效果,在程序被燒寫到Flash后,上電重新由Flash自啟動(dòng)時(shí),就可以觀察LED燈的顯示定時(shí)效果,判斷整個(gè)Flash自啟動(dòng)是否正確。
3.5.2 加入燒寫程序的定時(shí)器項(xiàng)目文件的流程
如圖5所示,在定時(shí)器程序調(diào)試完成之后,接下來(lái)就是把定時(shí)器程序和Bootloader程序燒寫到Flash對(duì)應(yīng)的地址空間當(dāng)中去,燒寫程序只運(yùn)行一次,通過(guò)判斷Flash燒寫程序標(biāo)志位是否等于N來(lái)控制,在第一次燒寫時(shí),F(xiàn)lash燒寫程序標(biāo)志位等于N,然后改變標(biāo)志位,以免Flash多次燒寫,然后開始把定時(shí)器程序和Bootloader程序燒寫到Flash對(duì)應(yīng)位置,最后判斷在L2中存放的定時(shí)器程序和Bootload?er程序代碼的地址空間數(shù)據(jù)是否和Flash中燒寫的程序代碼地址空間數(shù)據(jù)一致,如果一致,則燒寫完成,否則燒寫錯(cuò)誤,這可能是cmd文件配置內(nèi)存錯(cuò)誤和燒寫程序把存放動(dòng)態(tài)變量的地址空間內(nèi)容也燒錄到Flash中。如果是cmd文件配置錯(cuò)誤,則重新配置好cmd文件,適當(dāng)?shù)胤糯蟪绦虼a存放的空間就行了。如果是燒寫程序把存放動(dòng)態(tài)變量的地址空間內(nèi)容也燒錄到Flash中,由于動(dòng)態(tài)變量是動(dòng)態(tài)分配內(nèi)存的,所以在不斷的變化中,這時(shí)只要根據(jù)cmd文件,改變Flash燒寫程序中要燒寫的程序代碼的長(zhǎng)度,只要把固定分配內(nèi)存空間的程序代碼存放的空間燒寫到Flash中去就可以了。
仿真圖見圖6~圖9,存放在內(nèi)部RAM(L2)起始地址的1 kbyte空間中的Bootloader程序代碼已經(jīng)被燒寫到Flash起始地址的1 kbyte地址空間中,存放在內(nèi)部RAM(L2)起始地址1 kbyte之后的定時(shí)器程序代碼也被燒寫到Flash起始地址1 kbyte之后的地址空間中,程序燒寫結(jié)果可靠、正確,在DSP上電復(fù)位之后,DSP調(diào)制到Flash自啟動(dòng),LED燈能夠正確顯示定時(shí)器程序設(shè)定的定時(shí)點(diǎn)亮LED顯示效果,整個(gè)設(shè)計(jì)方法方便、穩(wěn)定、可靠。
運(yùn)用DSP在上電復(fù)位時(shí)會(huì)由EMIF引導(dǎo)自動(dòng)搬移CE1起始地址1 kbyte的程序代碼到地址0x00,使用CE1來(lái)擴(kuò)展外部Flash,再將Bootloader引導(dǎo)程序燒寫到Flash起始地址1 kbyte空間中,從而實(shí)現(xiàn)了DSP上電復(fù)位后Bootloader引導(dǎo)程序被直接加載到DSP的地址空間中,再由Bootloader引導(dǎo)程序直接引導(dǎo)加載Flash中的應(yīng)用程序代碼,完成了定時(shí)器的Flash引導(dǎo)自啟動(dòng)。該方案設(shè)計(jì)在一個(gè)項(xiàng)目文件中完成應(yīng)用程序的調(diào)試和燒寫,比傳統(tǒng)方法用兩個(gè)項(xiàng)目文件去完成更方便、簡(jiǎn)單,具有很好的實(shí)用性。
[1]卞紅雨,紀(jì)祥春,喬鋼.TMS320C6000系列DSP的CPU與外設(shè)[M].北京:清華大學(xué)出版社,2007.
[2]劉向宇.DSP嵌入式常用模塊與綜合系統(tǒng)設(shè)計(jì)實(shí)例精講[M].北京:電子工業(yè)出版社,2009.
[3]蒲中奇,張偉,施克仁,等.TI TMS320 C6000系列DSP的BOOT LOAD程序設(shè)計(jì)[J].工業(yè)儀表與自動(dòng)化裝置,2004(6):52-54.
[4]何正軍,朱善安.TMS320DM642 DSP二級(jí)引導(dǎo)程序的設(shè)計(jì)與實(shí)現(xiàn)[J].電子器件,2006,29(1):260-263.
[5]韋照川,鄭展恒,孫希延,等.一種基于DSP的自適應(yīng)盲均衡器[J].電視技術(shù),2011,35(13):76-78