1. 類(lèi)似51,AVR這類(lèi)的單片機(jī),程序只能在ROM或FLASH里運(yùn)行。STC的芯片一般是標(biāo)準(zhǔn)51或增強(qiáng)51,用的是FLASH,程序只能在FLASH中運(yùn)行。
2. ARM的程序即可以在FLASH里運(yùn)行也可以在RAM里運(yùn)行,不過(guò)能運(yùn)行程序的FLASH只能使NorFlash,因?yàn)镹ANDFLASH的接口決定了其無(wú)法掛載在地址空間內(nèi)。
3. 也就是說(shuō)只要能掛載到ARM的程序地址空間的設(shè)備都可以直接放運(yùn)行程序。否則其他存儲(chǔ)設(shè)備只能存儲(chǔ)程序或數(shù)據(jù)。如一般帶LINUX或Wince的ARM板,一般會(huì)把主系統(tǒng)程序放在NorFlash或NANDFLASH中,上電后用Loader程序吧主系統(tǒng)程序加載到RAM或SDRAM的可執(zhí)行地址去,然后跳到主程序去執(zhí)行。
4. 計(jì)算機(jī)一般情況下系統(tǒng)存在硬盤(pán)里,系統(tǒng)啟動(dòng)時(shí)BIOS程序(在ROM里)先運(yùn)行,然后從硬盤(pán)的系統(tǒng)分區(qū)里找到加載程序,加載到內(nèi)存中(SDRAM),然后再由這段加載程序從磁盤(pán)中把系統(tǒng)加載進(jìn)來(lái)。系統(tǒng)其實(shí)還可以存在光盤(pán)(所以可以從光盤(pán)啟動(dòng))或網(wǎng)絡(luò)計(jì)算機(jī)中(網(wǎng)吧里一般是這樣)。大致就這個(gè)過(guò)程吧。具體的去網(wǎng)上查一下。
如果你有研究過(guò)單片機(jī)編程的分散加載機(jī)制,在編程中寫(xiě)過(guò)分散加載腳本。你問(wèn)的第一個(gè)問(wèn)題就解決了。
如果你有寫(xiě)過(guò)nand flash的驅(qū)動(dòng)程序,你問(wèn)的第二個(gè)問(wèn)題就解決了。
STM32中的code可以不用拷貝到RAM中運(yùn)行,也可拷貝到RAM中運(yùn)行,這些不是技術(shù)問(wèn)題,而是要看這段code
有沒(méi)有加載到RAM中運(yùn)行的必要。后面再解釋。
nand flash不支持片上執(zhí)行,不能在nand flash中執(zhí)行程序,但nor flash支持。
但不能因此就斷定STM32用的外置flash都是nor的。只要STM32帶nand flash的控制器,就可以把nand中的code加載到RAM中運(yùn)行。至于能不能用IO模擬nand 的接口協(xié)議,我沒(méi)搞過(guò)不清楚。
首先,應(yīng)該所有的單片機(jī)都是片內(nèi)集成RAM和ROM(在加載域和運(yùn)行域的角度看,F(xiàn)lash就是ROM)。
一般容量小的單片機(jī),RAM和ROM都小,不會(huì)把flash中的代碼加載到RAM中。
但有時(shí)確實(shí)需要加載,怎么辦呢。就把code中比較關(guān)鍵的,調(diào)用很頻繁的,對(duì)響應(yīng)速度有要求的,就會(huì)加載到RAM中。
例如高頻率中斷的定時(shí)器中斷ISR,就可以在分散加載腳本中修改這段code的運(yùn)行域到RAM中。程序在剛上電后會(huì)在main函數(shù)之前加載這段code到RAM中。這樣做的好處就是,這段code的執(zhí)行速度快,我們知道ROM和RAM執(zhí)行代碼的速度比差距是很大的。RAM比ROM中執(zhí)行速度快得多!
當(dāng)然,如果你的RAM很大,你甚至可以把全部的Code加載到RAM中運(yùn)行。
nand flash不是直接接到CPU的三總線(xiàn)上的,所以CPU不能直接從nand中取得可執(zhí)行的指令,而是通過(guò)nand的控制器!
而nor是在總線(xiàn)上的,所以nor中的code可以直接執(zhí)行。(nor的這個(gè)觀點(diǎn)僅是我個(gè)人看法,僅供參考)。
再說(shuō)外置RAM的問(wèn)題,單片機(jī)在帶SDRAM的控制器之后,就可以支持SDRAM了。
SDRAM在初始化好之后,SDRAM的使用方法和內(nèi)置的SRAM沒(méi)有差別。
如果你的單片機(jī)支持SDRAM和Nand flash,你可以把nand flash中的code加載到SDRAM中運(yùn)行。
如果你知道怎么寫(xiě)分散加載腳本,這個(gè)功能分分鐘就能實(shí)現(xiàn)。
對(duì)于x86的pc機(jī)和單片機(jī)等嵌入式開(kāi)發(fā)系統(tǒng)程序的存儲(chǔ)是截然相反的,
即:
x86的pc機(jī)cpu在運(yùn)行的時(shí)候程序是存儲(chǔ)在RAM中的,而單片機(jī)等嵌入式系統(tǒng)則是存于flash中
x86cpu和單片機(jī)讀取程序的具體途徑
pc機(jī)在運(yùn)行程序的時(shí)候?qū)⒊绦驈耐獯妫ㄓ脖P(pán))中,調(diào)入到RAM中運(yùn)行,cpu從RAM中讀取程序和數(shù)據(jù)
而單片機(jī)的程序則是固化在flash中,cpu運(yùn)行時(shí)直接從flash中讀取程序,從RAM中讀取數(shù)據(jù)
造成這種差別的具體原因分析
x86構(gòu)架的cpu是基于馮.諾依曼體系的,即數(shù)據(jù)和程序存儲(chǔ)在一起,而且pc機(jī)的RAM資源相當(dāng)豐富,從幾十M到幾百M(fèi)甚至是幾個(gè)G,客觀上能夠承受大量的程序數(shù)據(jù)。
單片機(jī)的構(gòu)架大多是哈弗體系的,即程序和數(shù)據(jù)分開(kāi)存儲(chǔ),而且單片的片內(nèi)RAM資源是相當(dāng)有限的,內(nèi)部的RAM過(guò)大會(huì)帶來(lái)成本的大幅度提高。
單片機(jī)的程序能存儲(chǔ)在RAM中嗎 ?
通過(guò)上面的分析可得知:?jiǎn)纹瑱C(jī)的程序能存儲(chǔ)于flash中是基于兩點(diǎn)考慮,即體系結(jié)構(gòu)和RAM資源的多少。因此,在技術(shù)不但進(jìn)步片內(nèi)RAM容量不斷增多的今天,RAM資源已經(jīng)不再是制約這種差別的主要因素,而對(duì)于體系機(jī)構(gòu)我們只要更改cpu讀取程序的方式就可以。
將嵌入式系統(tǒng)的程序存于RAM中的具體做法
“對(duì)于很多的嵌入式系統(tǒng),其代碼很多都存儲(chǔ)在nor flash中,運(yùn)行也是直接在flash中運(yùn)行.我最近了解到我新公司的軟件中的一段代碼當(dāng)時(shí)為了提高運(yùn)行速度被加載到ram中運(yùn)行.當(dāng)時(shí)他們是花了很多時(shí)間來(lái)解決這個(gè)問(wèn)題的.
我仔細(xì)研究了一下鏈接腳本,用的是gnu的Linux的交叉工具鏈.地址分配是寫(xiě)在一個(gè)ld腳本中的.
他們是這樣實(shí)現(xiàn)的:
1,將你需要在ram中運(yùn)行的代碼寫(xiě)在單獨(dú)的一個(gè)c文件中,然后在腳本中設(shè)置其運(yùn)行地址與存放地址分開(kāi).設(shè)置好必要的代碼起始和結(jié)束的標(biāo)志變量.
2,在代碼中將存放地址處的代碼拷貝到運(yùn)行地址中.
這段代碼倒是沒(méi)什么問(wèn)題,只是我有個(gè)更簡(jiǎn)單的辦法:
還記得全局變量是怎么初始化的嗎? .data段是一個(gè)自動(dòng)初始化的段(內(nèi)核代碼處理),我只需要將這個(gè)c文件產(chǎn)生的代碼放置在.data段中,這段代碼就可以被加載到ram運(yùn)行了.我測(cè)試了一下運(yùn)行良好.
馮.諾依曼體系與哈佛體系的區(qū)別
二者的區(qū)別就是程序空間和數(shù)據(jù)空間是否是一體的。 早期的微處理器大多采用馮諾依曼結(jié)構(gòu),典型代表是Intel公司的X86微處理器。取指令和取操作數(shù)都在同一總線(xiàn)上,通過(guò)分時(shí)復(fù)用的方式進(jìn)行的。缺點(diǎn)是在高速運(yùn)行時(shí),不能達(dá)到同時(shí)取指令和取操作數(shù),從而形成了傳輸過(guò)程的瓶頸。
哈佛總線(xiàn)技術(shù)應(yīng)用是以DSP和ARM為代表的。采用哈佛總線(xiàn)體系結(jié)構(gòu)的芯片內(nèi)部程序空間和數(shù)據(jù)空間是分開(kāi)的,這就允許同時(shí)取指令和取操作數(shù),從而大大提高了運(yùn)算能力。
例如STM320LF240x系列DSP是增強(qiáng)型的哈佛結(jié)構(gòu)通過(guò)三組并行的總線(xiàn)訪(fǎng)問(wèn)多個(gè)存儲(chǔ)空間。它們分別是:程序地址總線(xiàn)(PAB),數(shù)據(jù)地址讀總線(xiàn)(DRAB)和數(shù)據(jù)地址寫(xiě)總線(xiàn)(DWRB)。
stm32內(nèi)部是nor flash,直接執(zhí)行代碼。
1. 馮諾依曼結(jié)構(gòu)和哈佛結(jié)構(gòu)
PC(x86)采用的是馮諾依曼結(jié)構(gòu),運(yùn)行的時(shí)候即數(shù)據(jù)和程序都放在同一個(gè)存儲(chǔ)器(ram)里,共用一條存儲(chǔ)總線(xiàn)。具體 :當(dāng)PC沒(méi)電的時(shí)候,程序和數(shù)據(jù)存儲(chǔ)在硬盤(pán)里,當(dāng)pc上電的時(shí)候,在硬盤(pán)里運(yùn)行的一段小程序把全部程序從硬盤(pán)搬運(yùn)到ram中,然后程序開(kāi)始在ram中運(yùn)行;
而嵌入式系統(tǒng)(arm,dsp)采用的哈佛結(jié)構(gòu),運(yùn)行的時(shí)候程序存儲(chǔ)在flash中,數(shù)據(jù)存儲(chǔ)在ram中,所以cpu從flash中取指令,到ram中取數(shù)據(jù),指令總線(xiàn)和數(shù)據(jù)總線(xiàn)也是分開(kāi)的;
2者之所以采用不同的結(jié)構(gòu),主要因?yàn)镻C的ram空間足夠,而嵌入式的ram太小;
以下以stm32來(lái)說(shuō)明:
(1)cpu根據(jù)boot0和boot1的硬件引腳決定從flash還是ram中啟動(dòng),默認(rèn)是從flash中啟動(dòng);啟動(dòng)之后會(huì)搬運(yùn)rw-data 到ram,但是不會(huì)搬運(yùn)code;
(2)如果采用ram中運(yùn)行,一般只能用作調(diào)試模式,因?yàn)榈綦姵绦蚓蛠G失了;
(3)從系統(tǒng)啟動(dòng)其實(shí)就是isp,是固化在rom中的一段代碼;
參考: 3中啟動(dòng)方式的區(qū)別;
參考: ?url=ilgM8Oky4ogqfmNX9f-nLN3-a7gpZmSnarJjXtrlhK3UgnSn8jQRyY9nJ-pUK4REqkbow185fFrVk8WU7KVfTiPlttW3bOfOeLn8HI3FkKC
在ram中調(diào)試的設(shè)置方法;(主要是把ram的一段設(shè)置為rom來(lái)用,注意程序的大小要小于ram)
至于linux中從flash搬運(yùn)到ram中之后,ram的link地址怎么從flash改變,每個(gè)函數(shù)的地址有時(shí)怎樣在ram中尋址的,這是另外一個(gè)問(wèn)題,需要學(xué)習(xí)和研究,
可以度娘 “stm32內(nèi)存管理” 或者 “c語(yǔ)言?xún)?nèi)存分區(qū)”
評(píng)論
查看更多