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