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