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