問題1:FLASH中的代碼是如何得到運(yùn)行的呢?比如PC指針是在哪里由誰設(shè)置的?
以ARM為例:
ARM-cortex-M3/4的單片機(jī)(比如STM32 等):該類單片機(jī)的代碼在nor flash中,cortex內(nèi)核可以直接運(yùn)行,不需要將代碼加載到ram中運(yùn)行。
ARM-cortex-A系列的SOC(比如Exynos4412):該類SOC更加復(fù)雜,通常有內(nèi)存管理單元(MMU),代碼存儲在nand flash中,程序運(yùn)行時,需要先將代碼加載到ram中運(yùn)行,該類SOC的啟動環(huán)節(jié)包含了加載程序。就像Windows操作系統(tǒng)存儲在硬盤中,開機(jī)的時候,操作系統(tǒng)的代碼會加載到內(nèi)存條(RAM)中。
PC指針:無論什么單片機(jī)或者SOC,都有一個PC寄存器,這個寄存器保存了下一條待取指令的地址。正常情況下自動加“4”,遇到分支跳轉(zhuǎn)的時候,由跳轉(zhuǎn)指令設(shè)置值。那么指針是什么?指針是一個變量的地址,在含有操作系統(tǒng)(比如Linux、Windows)即硬件層面含有內(nèi)存管理單元(MMU)的情況下,指針是虛擬地址,不含操作系統(tǒng)的情況下,是物理地址,虛擬地址和物理地址經(jīng)過MMU轉(zhuǎn)換。
問題2:這些代碼需要搬到RAM中才能運(yùn)行嗎?不這樣做會有什么不妥嗎?
上文講了,大部分單片機(jī)的代碼直接在nor flash中運(yùn)行,少部分需要加載到ram中。nor flash可以直接尋址一個字節(jié),可以找到一個指令的具體地址,因此可以直接運(yùn)行。nand flash 的存儲單元是塊,不能對指令直接尋址,因此不能直接運(yùn)行其中的代碼。因此保存在nand flash中的程序不加載到ram中運(yùn)行不了。即你的硬盤中的Windows不加載到內(nèi)存條中,運(yùn)行不起來。
問題3:如果需要搬到RAM,那是片內(nèi)還是片外有什么區(qū)別嗎?
片內(nèi)片外都可以,具體看是那款SOC或CPU了。
問題4:如果用戶存在FLASH的實(shí)際代碼大小(比如1MB),超過了RAM的可用空間(比如512KB),那這個搬移過程是啥樣的?
現(xiàn)在實(shí)際情況很少遇到這種情況,當(dāng)然可能會有RAM很小的系統(tǒng),可以分時分段的使用,即程序運(yùn)行一段,加載一段,運(yùn)行完,加載下一段。很不建議這樣玩,現(xiàn)在的RAM很大了,你的實(shí)際代碼達(dá)到1MB的時候,你的內(nèi)存可能都有1G,2G了。比如Linux操作系統(tǒng)編譯完后,實(shí)際上只有幾MB,實(shí)際的Linux系統(tǒng)會有幾個G 的內(nèi)存可用。
問題5:片外擴(kuò)展的FLASH和SRAM與片內(nèi)的想比,除了空間大小有差別,性能速度上會有怎樣的差異呢?
具體要看SOC的總線設(shè)計。一般來說片外的性能弱一點(diǎn)。
能不能在Flash中直接運(yùn)行程序代碼,取決于Flash的訪問特性。
Flash存儲器是按塊組織的,在使用時也傾向于按塊訪問才更加高效。Flash類似于ROM一類的存儲器,但它其實(shí)是可讀可寫的,不同于同樣可讀可寫的RAM,它在寫入數(shù)據(jù)時需要先將你所寫位置所屬的塊擦除,不管你是不是只寫幾個字節(jié),所以如果要改寫Flash中的數(shù)據(jù),總是會先將數(shù)據(jù)所屬的塊緩存到內(nèi)存中,然后再在內(nèi)存中改寫好數(shù)據(jù)后又重新將塊寫回,這樣就不會丟失數(shù)據(jù),但是花銷太大。讀的時候,往往也是先定位塊的位置,然后在塊中順序讀取,在不同塊中間斷讀取數(shù)據(jù)是非常低效的,所以按塊讀按塊寫是Flash的一大特點(diǎn),它不能夠隨意的對存儲區(qū)域?qū)ぶ罚湫偷娜鏝AND Flash。
不過有一類Flash存儲器在讀取數(shù)據(jù)時可以做到任意的尋址而不會有太大的花銷,它的讀操作是接近于RAM的,而寫操作依然延續(xù)了按塊擦除然后再按塊寫的特點(diǎn),典型的如NOR Flash。
所以正因?yàn)檫@樣的特性,F(xiàn)lash通常用于存儲不需要頻繁改動的掉電不能丟失的數(shù)據(jù)。
介紹完背景知識,回到問題:
首先要清楚的是,CPU需要在存儲器中讀取指令,指令地址由PC寄存器給出,每執(zhí)行完一條指令PC會自動的指向下一條指令,如果指令的長度不等會使得給出的地址不總是有一致的對齊,其次程序運(yùn)行總會伴隨跳轉(zhuǎn),這使得指令的尋址更具有隨意性,所以說要直接在某種存儲器中執(zhí)行程序,至少讀取數(shù)據(jù)時要能夠任意尋址,而NOR Flash是剛好能滿足要求的,市面上常見的MCU內(nèi)置的Flash就是這種類型,所以能夠直接在上面運(yùn)行存儲的程序,而不需要加載到RAM中。其他不具備這種訪問特性的存儲器是不能直接在上面執(zhí)行程序的,必須轉(zhuǎn)移到滿足這種特性的存儲器當(dāng)中執(zhí)行,比如加載到RAM。
1、FLASH中的代碼是如何得到運(yùn)行的呢?比如PC指針是在哪里由誰設(shè)置的?
采用cortex- m內(nèi)核的MCU會根據(jù)外部啟動配置引腳的電平,將啟動存儲器映射到0x00000000地址,如果是在Flash啟動,在內(nèi)部Flash的起始位置會存儲一張異常中斷向量表,表中的第一項和第二項存儲了初始的棧地址和復(fù)位向量,這張表的位置是可配置的,而復(fù)位后的位置正是在0x00000000地址。硬件上電復(fù)位后,SP,PC寄存器會自動依次設(shè)置為表中的前兩項,然后根據(jù)PC設(shè)置的初始值開始執(zhí)行代碼,所以說PC的值是在復(fù)位時是自動設(shè)置的。
2、這些代碼需要搬到RAM中才能運(yùn)行嗎?不這樣做會有什么不妥嗎?
正如前面敘述的,并不必要。在RAM中執(zhí)行可能會得到更好的執(zhí)行性能,但是對于MCU內(nèi)部的Nor Flash來說是沒有必要的。有一點(diǎn)要提及的是,程序一般會由代碼段txt,只讀數(shù)據(jù)段rodata,初始化數(shù)據(jù)段data和未初始化數(shù)據(jù)段bss(并無數(shù)據(jù))組成,只讀數(shù)據(jù)段因?yàn)楹痛a段一樣不需要改動,所以可以留在Flash當(dāng)中 ,但是需要將也存儲在Flash中的data段加載到RAM中以及空出空間給bss。這是運(yùn)行環(huán)境的初始化,是有搬運(yùn)的,只是搬運(yùn)的不是代碼,這發(fā)生在進(jìn)入main函數(shù)之前。
3、如果需要搬到RAM,那是片內(nèi)還是片外有什么區(qū)別嗎?
在片內(nèi)的RAM性能會更好,但是容量一般不能做的太大。
4、如果用戶存在FLASH的實(shí)際代碼大?。ū热?MB),超過了RAM的可用空間(比如512KB),那這個搬移過程是啥樣的?
是可以分階段加載執(zhí)行的,但是對程序的組織會變得復(fù)雜,運(yùn)行變得低效,如果出現(xiàn)了這種情況應(yīng)該考慮更換硬件配置或者對程序優(yōu)化裁剪。
5、片外擴(kuò)展的FLASH和SRAM與片內(nèi)的想比,除了空間大小有差別,性能速度上會有怎樣的差異呢?
這取決于存儲器的時鐘速率和訪問延遲,集成在內(nèi)部的存儲器性能一般是能比片外的更好的,所以要使程序有更高的運(yùn)行性能應(yīng)該優(yōu)先使用內(nèi)部存儲器。低端MCU由于運(yùn)行速率低,內(nèi)部和外部不會有太大的區(qū)別。
可以從以下三個方面可以回答這個問題:
1、計算機(jī)組成原理
馮諾依曼模型
計算機(jī)專業(yè)的同學(xué)對這張圖一定不陌生,這是最經(jīng)典的計算機(jī)模型,現(xiàn)在所有的計算機(jī)設(shè)備(當(dāng)然也包括嵌入式)都沒有跳出這個模型。里面的五項可以分為三部分:(1)CU和ALU是CPU(2)Memory是內(nèi)存設(shè)備(理想的內(nèi)存設(shè)備)(3)Input和Output是各種外設(shè)設(shè)備(鍵盤、鼠標(biāo)、顯示器······)。
我們這里關(guān)注的點(diǎn)是內(nèi)存設(shè)備。馮諾依曼模型中將Memory想象成理想內(nèi)存設(shè)備。所謂理想內(nèi)存設(shè)備就是可讀可寫、非易失、隨機(jī)讀寫。對于理論模型來說,簡介易懂是關(guān)鍵。但是在現(xiàn)實(shí)中卻沒有這么理想,受限于成本,不同的存儲器只能滿足部分指標(biāo),這就是接下來要說的主流存儲器。
2、主流存儲器的特點(diǎn)
現(xiàn)在的存儲器可以大致分為兩類:RAM和ROM。關(guān)于這兩類存儲器的具體定義和發(fā)展歷程已經(jīng)有很多總結(jié),這里就不再贅述,只從我個人的角度談一下對這兩類存儲器的理解。
(1)RAM,具體可以分為SRAM和DRAM
共同特點(diǎn)(RAM的根本特點(diǎn)):可讀可寫、隨機(jī)讀寫
區(qū)別:SRAM上電即可用,DRAM需要初始化后才能使用,并且SRAM單位成本高于DRAM。
(2)ROM,具體可分為硬盤、Flash(NOR Flash和NAND Flash)
共同特點(diǎn):非易失
區(qū)別:硬盤和NAND Flash都是整塊讀寫、NOR Flash可以隨機(jī)讀,但是需要整塊寫。
NOR Flash非易失、隨機(jī)讀的特性讓它可以作為系統(tǒng)的啟動介質(zhì)。
3、CPU與存儲器之間的速度差異是現(xiàn)在制約計算機(jī)性能的主要原因。
4、具體到上面5個問題
(1)具體要看是什么Flash,如果是NOR Flash,那么系統(tǒng)可以直接訪問執(zhí)行。如果是NAND Flash,則需要將代碼加載到RAM中再運(yùn)行。PC寄存器在CPU中,在CPU上電時由硬件設(shè)置一個特定的值(例如:ARM Cortex-M3的PC寄存器上電默認(rèn)是0x4)。
(2)和第一問一樣,需不需要搬移代碼要看Flash類型。
(3)如果是相同類型的RAM,片內(nèi)和片外沒有區(qū)別。如果RAM類型不同,就需要具體情況具體分析。
(4)這里假設(shè)Flash是1MB,RAM是512KB,猜測應(yīng)該是NOR Flash和SRAM(例如STM32),則代碼不需要搬移。如果是NAND Flash,一般會和DRAM搭配,容量會大很多,應(yīng)該假設(shè)不成立。
編輯:黃飛
?
評論