天天看點

STM32的燒錄和Hex/bin燒錄檔案解析、燒錄檔案是被如何存儲到MCU中的?

什麼是hex檔案

以*.hex為字尾的檔案我們稱之為HEX檔案。hex是intel規定的标準,hex的全稱是Intel HEX,此類檔案通常用于傳輸将被存于ROM或EEPROM中的程式和資料。是由一行行符合Intel HEX檔案格式的文本所構成的ASCII文本檔案。

HEX的英語原始意思是16進制。這種檔案格式主要用于儲存單片機固件。

整個檔案以行為機關,每行以冒号開頭,内容全部為16進制碼,2個ASCII碼字元表示1個Hex位元組

下面轉自文章,如有侵權請聯系作者删除

https://blog.csdn.net/little_grapes/article/details/128497777

hex檔案格式

先上圖:這是我用Notepad++ 直接打開的一個32bit的單片機編譯器編譯的一個hex檔案(中間省略了部分):

STM32的燒錄和Hex/bin燒錄檔案解析、燒錄檔案是被如何存儲到MCU中的?

我們解釋一下檔案的内容:

a)hex檔案内部是以文本格式來存儲内容的,每行以冒号(:)起始,後面每兩個字母是一個8bit的16進制數;

b)每行的格式:BBAAAATTD……DCC;

BB表示本行資料的長度;AAAA表示本行資料存儲的位址;TT表示資料類型;DD的長度可長可短,是實際的資料;CC是校驗和;

我們以第一行為例:020000040800F2

02是資料長度,也就是後面的實際資料“0800”的長度,2位元組;

0000表示位址0;

04是資料類型,後面在詳細解釋;

0800是實際的資料;

F2是校驗和,計算方法是,本行所有位元組累加和(累加和隻用低8位)取反再加1,即計算過程為0xF2=0x01 + not(0x02+0x04+0x08);

c)這裡需要補充說明的是TT表示的資料類型

資料類型一共有6種形式:

'00’資料記錄:用來記錄資料,HEX檔案的大部分記錄都是資料記錄;

'01’檔案結束記錄:用來辨別檔案結束,放在檔案的最後,辨別HEX檔案的結尾;

'02’擴充段位址記錄:用來辨別擴充段位址的記錄;

'03’開始段位址記錄:開始段位址記錄;

'04’擴充線性位址記錄:用來辨別擴充線性位址的記錄;

'05’開始線性位址記錄:開始線性位址記錄;

這裡仍然舉幾個例子說明,第一行:020000040800F2的資料類型是04,即擴充線性位址記錄,表示的是這樣一行的内容是位址的高位,也即DD區域表示位址高位為0x0800;當位址長度超過16bit時,就需要擴充線性位址記錄來聲明高位位址;

第二行10000000000400200900000800F009F800F01CF8C6,資料類型是00,也就是資料記錄,那麼它的DD區域就是資料;同時,它的位址區域是0000,那麼就表示,這一行的資料應該存在0000位址中;再結合上一行的擴充線性位址記錄,它實際存儲的位址應該是0x08000000。熟悉stm32單片機的朋友可能清楚,flash起始位址就是0x08000000:

STM32的燒錄和Hex/bin燒錄檔案解析、燒錄檔案是被如何存儲到MCU中的?

第三行1000100000F026F800F01EF800F022F8F6E703B52D,格式與第二行一樣,但是位址不同,表示這一行的資料存在0x08000010位址中;我們發現這兩位址相隔0x10,剛好是第一行的資料内容實際長度。

倒數第三行,格式與第二、三行也是一樣的,隻是長度不足0x10,隻有0x08,這是已經到了實際内容的末尾。

Hex檔案内大部分都是這種資料記錄。

d)最後兩行

:0400000508000009E6

:00000001FF

我們先解釋末尾一行,:00000001FF,這行是表示檔案結尾,所有的hex檔案最後一行都可以是這個。

倒數第二行,資料類型是05,開始線性位址記錄,其實它表示的是一個函數入口位址,但是這個函數位址并不會影響實際燒寫到flash中的内容,我們可以不管它,MDK官方的解釋是大多數情況下可以忽略它:

The Start Linear Address specifies the address of the __main (pre-main) function but not the address of the startup code which usually calls __main after calling SystemInit(). An odd linear start address specifies that __main is compiled for the Thumb instruction set.

The Start Linear Address Record can appear anywhere in hex file. In most cases this record can be ignored because it does not contain information which is needed to program flash memory.

到這裡,hex檔案中常見的一些格式就介紹完了,如果需要研究更深入,可以通過http://www.keil.com/support/docs/1584/

找到keil官方的解析(這個連結好像已經404了,可以在文末關注公衆号找到儲存的原文檔)。

我們在做有IAP功能的項目時,有時需要把boot和app兩段代碼合并以後燒寫,這樣可以大大簡化操作步驟,此時,可以把兩個hex檔案手動合并。

操作方法是,把其中一個hex檔案最後的兩行(開始線性位址記錄、檔案結束記錄)删除:

STM32的燒錄和Hex/bin燒錄檔案解析、燒錄檔案是被如何存儲到MCU中的?

再把另一個hex檔案的所有内容都複制粘貼到其後,就可以了。

但是要注意,兩個檔案的位址區不能有重疊!

2)bin檔案格式

相比hex檔案,bin檔案格式就簡單得多了,它直接就是儲存的需要燒寫的目标檔案内容,是沒有任何附加格式的原始二進制檔案。

我們把上一個工程設定為輸出bin檔案:

STM32的燒錄和Hex/bin燒錄檔案解析、燒錄檔案是被如何存儲到MCU中的?

再編譯輸出,可以同時輸出bin格式的目标檔案。

使用十六進制檔案編輯器打開,可以看到如下内容:

STM32的燒錄和Hex/bin燒錄檔案解析、燒錄檔案是被如何存儲到MCU中的?

對比之前的hex檔案格式,發現這些内容正好對應了hex檔案中所有“資料記錄”行中的實際資料内容。沒有位址、校驗、檔案結尾等等一些附加内容。

3.hex檔案和bin檔案有什麼不同

從幾個方面來看待它們的不同。

1、格式的不同

HEX檔案格式,看文章前一節已經詳細講解了。

BIN檔案格式,對二進制檔案而言,其實沒有”格式”。檔案隻是包括了純粹的二進制資料。

Bin檔案是MCU固件燒寫的最終形式,也就是說晶片ROM中燒寫的内容完全就是Bin檔案的内容。

2、使用的不同

HEX檔案是包括位址資訊的,而BIN檔案格式隻包括了資料本身。在燒寫或下載下傳HEX檔案的時候,一般都不需要使用者指定位址,因為HEX檔案内部的資訊已經包括了位址。而燒寫BIN檔案的時候,使用者是一定需要指定燒錄的起始位址資訊的。

3、HEX檔案和BIN檔案大小的差別

HEX檔案是用ASCII來表示二進制的數值。例如一般8BIT的二進制數值0x3F,用ASCII來表示就需要分别表示字元’3’和字元’F’,每個字元需要一個BYTE,是以對比同一個工程編譯出來的HEX檔案和BIN檔案,HEX檔案至少是BIN檔案大小的兩倍以上。

STM32的燒錄和Hex/bin燒錄檔案解析、燒錄檔案是被如何存儲到MCU中的?
STM32的燒錄和Hex/bin燒錄檔案解析、燒錄檔案是被如何存儲到MCU中的?

上面兩張圖分别以文本形式檢視一個hex檔案,以及使用十六進制形式檢視該hex檔案,可以更明顯得看出:

hex檔案是以ASCII碼形式儲存下來的。比如0x3a對應字元’:',0x30 0x32 0x30 0x30 對應字元0200,并且每行的末尾用了0D 0A進行回車換行。

對一個BIN檔案而言,你檢視檔案的大小就可以知道檔案包括的資料的實際大小。而對HEX檔案而言,你看到的檔案大小并不是實際的資料的大小。一是因為HEX檔案是用ASCII來表示資料,二是因為HEX檔案本身還包括别的附加資訊。

4、hex檔案和bin檔案的對比和轉換

通過前述的解釋,我們了解了,bin檔案隻有最原始的程式資料,它與儲存在單片機flash中的原始值是一樣的;hex檔案中,則除了程式資料外,還包含了位址、校驗等等一些資訊。

是以,一般在自己設計IAP程式時,直接傳輸bin檔案可以簡化bootloader軟體的設計,減少一些處理過程,縮小boot程式的體積,但是要注意需要事先規定寫入的位址;而通過上位機軟體和下載下傳器燒寫時,使用hex檔案,可以簡化操作、增加可靠性。

一般軟體IDE都可以生成hex檔案,有的也能生成bin檔案,如上文中提到的keil;st公司出品的STM32CubeProgrammer也可以将hex轉bin。

如果軟體沒有這個功能,我們也不用重複造輪子,有很多前輩大佬已經做了轉換工具,我們可以使用現成的。

我試用了多種,選了比較好用的一種hex轉bin檔案工具推薦給大家:

STM32的燒錄和Hex/bin燒錄檔案解析、燒錄檔案是被如何存儲到MCU中的?

這個軟體由“不鹹不要錢”大佬編寫,該大佬的軟體開源位址:GitHub - mian2018/CSharp_Hex2Bin: 嵌入式 hex轉bin

下面轉自文章,如有侵權請聯系作者删除https://blog.csdn.net/he__yuan/article/details/78036073

hex檔案大小與STM32中晶片flash大小的關系

之前一直以為STM32flash空間大小和hex檔案

相關,以為hex檔案大小超過flas大小後程式就會

出問題但是我發現hex檔案大于flash也可以正常

下載下傳,有的程式也可以正常運作,有的不可以,所

以經過總結如下:

1、flhex檔案其實是個格式規範的文本檔案。程式代碼大小與hex檔案大小沒有絕對的關聯性,因為我們在用序列槽下載下傳程式時一般都是用的hex檔案下載下傳,,是以大家會以為hex檔案大小和flash大小息息相關,hex檔案大小超過了flash大小就會出問題,我也以為是這樣,直到最近我發現有hex檔案大于flash的大小但是依然可以寫進去,因為真正燒寫進去的是二進制檔案,在hex檔案中包含了bin檔案的資訊

2、hex檔案大小和bin檔案大小沒有決定性關系hex檔案内容很多,其中就包含了bin檔案二進制的内容,所有很多軟體都能直接把hex檔案轉化成bin檔案,燒寫進flash的檔案不是hex而是一堆bin檔案

3、flash大小和bin檔案大小息息相關

bin檔案就是完全的程式檔案,裡面包含了所有的程式

内容,bin檔案燒寫進flash就可以執行,可以用STlink進入仿真檢視相關的flash,就是bin檔案内容

燒錄程式本質

把單片機當做一個存儲器,每一條程式指令都對應一個唯一的存儲位址,把這些指令以位元組為機關一條條存儲到指定的存儲位址中,這就是燒錄程式的本質。對于STC89C52RC單片機,在下載下傳程式時需要上位機軟體和一根USB轉序列槽線。上位機軟體負責把.hex格式的機器碼檔案打開,機器碼檔案裡面記錄着每條程式指令所對應的位址資訊,下載下傳過程時,上位機軟體根據.hex檔案記錄的指令内容和對應的位址資訊,經過USB轉序列槽線,跟單片機的預置系統程式進行序列槽通訊,進而把.hex記錄的資訊傳輸到單片機内部的flash存儲器中,實作了程式的燒錄下載下傳。

STM32的燒錄

  1. 用IDE工具燒錄

可以配置IAR或Keil,用IDE下載下傳。硬體工具需要使用ST-Link(分為SWD或Jtag方式,SWD連線少,比較常用于調試)或J-Link連接配接到闆子的相應引腳(詳見Jtag引腳定義)。需要注意的是ST-Link燒錄盒分為隔離和非隔離,如果闆子必須斷電燒錄,那麼用非隔離的燒錄(這個時候燒錄器也會帶電讓STM32運作,某些DSP需要單獨供電),如果闆子需要上電燒錄或線上調試,一般使用帶隔離的ST-Link或JLink。

2. 用ST-LINK Utility工具燒錄

下載下傳HEX檔案,設定好位址後,可以下載下傳app(如果是STM32,那麼起始位址一般是0x0800xxxx)和bootloader(如果是STM32,那麼起始位址一般是0x08000000)。這個工具大概作用總結如下:

  • 擦除flash相應區域
  • 根據位址設定,可以分别燒錄app或bootloader到flash,如果app和bootloader合成為一個hex,那麼可以把位址設定為0x08000000,一次燒錄app和bootloader到flash的兩個區域。
  • 可以作為量産PCBA闆的燒錄工具
  • 如果闆子上STM32的flash沒有被添加保護,可以用它讀出flash裡面的所有資料,然後生成一個hex檔案。
  • 可以讀取STM32晶片的型号、ID、版本等資訊
  • 此軟體包含了ST-Link驅動,安裝了它,像Keil 或IAR線上調試下載下傳等就不需要額外安裝驅動了。

    3、 線上更新

    這種方式隻能更新app,不能更新bootloader,具體方法是在程式運作的時候,如果線上更新被觸發,那麼把一個變量設定為燒錄模式(這個變量存放于ram某個位置,一般比較末尾的位置,并在代碼中使用相應關鍵字限定次變量在記憶體中不會被設定為0,即使STM32被複位)。然後不喂狗,讓STM32複位進入bootloder,在bootloader代碼中讀取上面描述的ram位址的變量,決定進入燒錄模式還是調到app入口位址處運作app程式。

    下面轉自文章,如有侵權請聯系作者删除,原文連結:https://blog.csdn.net/ZHOU_YONG915/article/details/122842967

單片機程式燒錄

單片機程式下載下傳方式

由于單片機發展到今天已經非常成熟了,如果我們想要了解程式下載下傳這個一直都有讨論的命題,我覺得可以從其曆史發展來看。

1 程式設計器程式設計

  首先需要明确的是,單片機程式下載下傳的本質就是将由0和1組成的hex檔案寫入到掉電資料不會消失的EEPROM(Electrically Erasable Programmable Read Only Memory,電可擦除可程式設計隻讀存儲器)中。 最早使用的燒錄程式的方式是使用單獨的程式設計器,據說價格比較昂貴,而且每次程式設計時都需要把可程式設計晶片取下來放在程式設計器上,然後再寫入程式。【似乎知道為什麼現在普遍使用的51單片機最小系統闆是用一個夾緊的綠色底座而不是接觸更好的雙列直插的晶片插座,估計就是曆史遺留問題】

這裡的程式設計器是電擦除的,據說更早還有紫外線擦除的,應該是比對EPROM。

顯然,這種燒錄程式的方式一個是價格昂貴,意味着你每開發一款晶片,都需要先買一個可能比單片機還貴的程式設計器;另一方面就是這種程式設計方式意味着你每改動一次程式都需要拆裝一次,不僅麻煩還會對電路闆造成損傷,而且如果是成型的産品需要更新程式,還需要返廠或者讓技術人員到現場解決,非常不便。于是後來就有了ISP。

2 ISP (In System Programming, 系統線上程式設計)

  所謂ISP,即In System Programming,有些人翻譯成“在系統中程式設計”,确實也有道理,因為原來的程式設計方式需要将晶片取下,即離開系統,而ISP不需要程式設計器即可完成程式燒錄,此時單片機晶片可以焊在電路闆上,調試完即是成品。但我比較喜歡另一種解釋,那就是用程式設計器程式設計屬于離線程式設計,而ISP屬于線上程式設計,這個“線”大概就是指系統,到底有沒有離開系統。是以個人覺得這個翻譯成系統線上程式設計最為合适。

  ISP基本是目前單片機燒錄程式的主要方式。它的實作方式就是通過電腦端的上位機軟體,通過某種資料傳輸協定,将程式編譯産生的二進制檔案燒錄到單片機的EEPROM中。一般電路闆上還需要添加少量的外圍電路輔助程式的燒錄。是以調試單片機程式時,隻需要将相關的接口留出即可,而不需要來回取下晶片。

  其中,因為對燒錄速度和品質的要求,人們在 “某種資料傳輸協定” 上不斷更新,是以也就有了各種不同的燒錄方式。如STC的51單片機基于的就是序列槽協定,即程式通過序列槽寫入到FLASH(EEPROM的一種)中;Atmel的AT89S51,AT89S52等系列單片機基于SPI協定将程式寫入到FLASH中;STM32系列的晶片采用ST-Link和J-Link等裝置來下載下傳程式,其基于的協定為SWD和JTAG,當然,STM32也可以基于序列槽協定下載下傳程式;Arduino單片機可以通過序列槽協定下載下傳程式,也可以通過SPI協定下載下傳(算是AVR單片機一個獨有的特點吧)。

  但是雖然大家都是ISP,但各自還是有差別的。

  其中最為特殊的莫過于序列槽協定,因為其他的各種協定都是借助外界裝置(如ST-Link、USBasp)來直接操作單片機的FLASH,而通過序列槽下載下傳程式時,雖然也需要使用外部裝置(一般是一個USB轉TTL子產品),但是其本質還是靠晶片内部已固化的一段程式來寫入FALSH。

這也就是為什麼網上很多資料都把序列槽下載下傳稱之為ISP,而基于其他協定下載下傳的都不叫ISP。

另外,對于某些單片機,支援ISP模式燒寫程式的協定可能不止序列槽協定,或者說不止一個通訊接口。如STM32F4支援多個序列槽寫入和CAN協定【參考連結第二個】

用來寫入FLASH的這部分程式是晶片出廠就已經固化到晶片當中的,稱為引導程式,也叫自舉程式(自己能舉起自己嘛),英文名叫BootLoader。這部分程式是對使用者保密的,也就是說使用者無法知道這段程式到底是怎麼寫入FLASH的,隻知道它能這麼做。

  是以,為實作這種功能,晶片内部ROM就可以分為兩部分,一部分是系統存儲區 (System Flash),一般在低位址,用來存放引導程式;另一部分是使用者存儲區(User Flash),有些也稱為應用程式區(Application Flash),一般在高位址,用來存放使用者編寫的程式(主要執行的部分)。其示意圖如下所示。

STM32的燒錄和Hex/bin燒錄檔案解析、燒錄檔案是被如何存儲到MCU中的?

以STM32為例,由于它既支援SWD,JTAG這種直接操作FLASH的協定,也支援基于序列槽協定利用引導程式寫入FLASH,是以它需要支援多種啟動模式。如下圖所示。

STM32的燒錄和Hex/bin燒錄檔案解析、燒錄檔案是被如何存儲到MCU中的?

這裡的“主閃存存儲器”即上面提到的使用者存儲區,用來存放使用者編寫的程式。

  是以,顯而易見,如果手邊有ST-Link或J-Link,就可以考慮從使用者存儲區開始運作,這樣上位機就直接将資料寫入到使用者存儲區的FLASH中;如果要采用序列槽下載下傳,就需要從系統存儲區開始啟動,當晶片在這個部分開始執行程式時,會不斷檢測序列槽是否有寫入FLASH的指令,如果沒有,則開始執行後面的使用者程式,如果有,則開始寫入使用者存儲區的FLASH。

但是,一般序列槽下載下傳要更慢,而且ST-Link或J-Link除了下載下傳程式外,還支援硬體仿真,這也就是為什麼用序列槽下載下傳的比較少。

為了更好地了解這個過程,下面以STC單片機為例來展示這個過程。【圖檔來自官網手冊】

STM32的燒錄和Hex/bin燒錄檔案解析、燒錄檔案是被如何存儲到MCU中的?

這裡值得注意的是,STC單片機對于從系統存儲區啟動有一個特别的要求,那就是冷啟動,即單片機徹底沒電(給2-3V供電也不行)。這個時候上電單片機才會執行ISP程式(一般按下RST單片機不會執行ISP程式,隻是從頭開始執行使用者程式),檢測是否有燒入程式的需求。

還有一種單獨給STC單片機燒錄的裝置,不用冷啟動就能燒錄程式,我隻知道它大概是通過軟體複位到系統存儲區去執行ISP程式(這個功能STC已提供,而且應該是獨有的),但具體原理還不太明白。(為什麼那個下載下傳器能在晶片運作過程中修改晶片内部寄存器的數值呢?)

3 IAP (In Application Programming,應用線上程式設計)

說了這麼多ISP,感覺基本夠用了,為什麼還會有IAP呢?這個主要是用于一些特殊的情況,比如一個産品内程式的遠端更新。

  和上面的ISP一樣,IAP也有翻譯成“在應用中程式設計”,這個也有其合理性,但是個人感覺“應用線上程式設計”會更形象點,這個“線”就不是指系統了,而是指晶片正在執行應用程式,在這個過程中實作程式的自我更新,此即IAP的原理。也正是這種特殊操作,能夠實作對一個已開發的産品進行遠端的程式更新。

  咋一看似乎感覺IAP和ISP差不多? 确實如此。因為ISP也是支援程式正在運作時執行程式燒錄的指令的(STM32的序列槽下載下傳和STC單片機的熱啟動),其原理和上面提到是一樣的,那就是内部有相關的寄存器能夠進行複位操作使得程式從ISP區開始執行,然後檢測是否有燒錄的操作。這樣看來似乎IAP也差不多是這個需求,但是前面也提到,一般晶片出廠的時候,ISP程式是已固化到晶片當中的,關鍵它還是對使用者保密的,是以對于使用這個晶片開發産品的開發者來說,是不知道這個晶片到底是怎麼将程式燒錄到使用者FLASH中的,是以就不能通過ISP來實作需要的功能,而需要根據晶片提供的一些函數自定義一套協定和規範來寫入FLASH進而實作IAP,是以,就還需要一塊類似于存放ISP程式的區域的存放IAP程式的區域,如下圖所示。【圖檔來自參考連結的第二個】

STM32的燒錄和Hex/bin燒錄檔案解析、燒錄檔案是被如何存儲到MCU中的?

從上圖可知,ISP程式引導加載IAP程式,IAP程式引導加載應用程式。在開發者開發産品時,IAP程式必須通過SWD、JTAG或者ISP(序列槽or其他協定)燒錄,第二部分應用程式可以在第一部分燒錄時一起燒錄,也可以通過IAP程式燒錄。

  那在程式運作過程中,也就是正在執行應用程式時,是怎麼跳轉到IAP程式部分執行的呢?STM32中是采用中斷的方式。一般中斷向量都是存放在低位址,而IAP恰好在低位址段,是以IAP程式就相當于是一個中斷服務程式,當相關中斷被觸發時,晶片就開始執行IAP程式,來進行自我更新。是以,在第二部分代碼開始執行時,首先需要把CPU的中斷向量表映像到自己的向量表,然後再執行其他的操作。

  如果IAP程式被破壞,産品必須返廠才能重新燒寫程式,這是很麻煩并且非常耗費時間和金錢的。針對這樣的需求,STM32在對Flash區域實行讀保護的同時,自動地對使用者Flash區的開始4頁設定為寫保護,這樣可以有效地保證IAP程式(第一部分代碼)區域不會被意外地破壞。

其他名詞的解釋

1 ICP

  ICP全稱是In Circuit Programming,即在電路中程式設計,這個我感覺應該是和ISP是一個意思,因為晶片所在的系統不就是電路系統嗎?不需要離開電路就能對晶片進行程式設計,感覺和ISP是一個意思,有些型号的晶片之是以區分這兩者估計是使用的協定不同。

2 ICSP

  ICSP全稱是In Circuit Serial Programming,這個一般的翻譯是線上串行程式設計,這個主要是出現在Arduino中,上面有六個引腳,也可能用來下載下傳程式。其實這個算是AVR單片機的一個特性,其本質是通過SPI協定來寫入程式,和AT89S52的燒錄方式差不多(雖然一個是10引腳,一個是6引腳)。

  但是值得一提的是,Arduino如果采用ICSP的方式燒錄程式,那麼它還是會從FLASH的起始位址開始燒錄,也就是說會覆寫掉低位址段的引導程式!!! 這一點個人感覺很不合理。是以,如果要轉為使用序列槽下載下傳,需要在IDE中再次燒錄引導程式。如下圖所示。

STM32的燒錄和Hex/bin燒錄檔案解析、燒錄檔案是被如何存儲到MCU中的?

在描述單片機程式時,需要區分“運作時”和“非運作時”

原文連結:https://blog.csdn.net/qq_28877125/article/details/108662427

非運作時的單片機程式在ROM内的分布

非運作時的單片機程式在ROM内的分布

下圖就是通過單片機下載下傳工具燒錄到單片機Flash裡面去之後的Flash空間區域分布圖:

STM32的燒錄和Hex/bin燒錄檔案解析、燒錄檔案是被如何存儲到MCU中的?

其中:

Code:為程式代碼部分

Ro-data: 表示程式定義的常量(const修飾的常量、#define 宏定義等);

Rw-data: 表示已初始化的全局變量

Zi-data: 表示未初始化的全局變量(Zi-data可以表示RAM未上電時整個區域的狀态,或者上電初始化之後未被使用的區域,上表僅僅描述的是ROM區域的空間分布)

而棧區(stack)、堆區(heap)、全局區(靜态區)(static)、文字常量區和程式代碼區和上面所介紹的Code、Ro-data等的關系。

1、棧區(stack):由編譯器自動配置設定釋放 ,存放函數的參數值,局部變量的值等。其操作方式類似于資料結構中的棧。 這些值是可讀寫的,那麼stack應該被包含在RW-data(讀寫資料存儲區),也就是單片機的sram中。

2、堆區(heap):一般由程式員配置設定釋放, 若程式員不釋放,程式結束時可能由OS回收 。可以了解,這些也是被包含在單片機的sram中的。

3、全局區(靜态區)(static):全局變量和靜态變量的存儲是放在一塊的,初始化的全局變量和靜态變量在一塊區域, 未初始化的全局變量和未初始化的靜态變量在相鄰的另一塊區域,程式結束後由系統釋放。這些資料也是可讀可寫的,和stack、heap一樣,被包含在RAM中。

4、文字常量區:常量字元串就是放在這裡的。這些資料是隻讀的,配置設定在Ro-data(隻讀資料存儲區),則被包含在flash中。

5、程式代碼區:存放函數體的二進制代碼,可以想象也是被包含在flash,因為對于MCU來說,當其重新上電,代碼還會繼續運作,并不會消失,是以存儲在flash中。

下圖是初始化之前的ROM和RAM中的資料分布:

1、未初始化之前的RAM裡面所有區域都是随機的值即:Zi-data

STM32的燒錄和Hex/bin燒錄檔案解析、燒錄檔案是被如何存儲到MCU中的?

運作時的單片機程式在RAM内的分布

下圖是初始化之後的ROM和RAM中的資料分布:

1、初始化的時候會由Boot程式(進入main函數之前)拷貝Flash裡面的Rw-data區域到RAM

STM32的燒錄和Hex/bin燒錄檔案解析、燒錄檔案是被如何存儲到MCU中的?

下圖是初始化之後正常運作時,單片機内ROM和RAM區域分布圖:

上電初始化之後Flash的Rw-data就不會再使用了,除非重新上電、複位了boot才會重新從ROM(Flash)中拷貝Rw-data區域到RAM中去。

運作時,根據上一節對哈佛模型的描述(51核心、Cortex-M3、Cortex-M4是哈佛模型),程式存儲區對應ROM(Flash)資料存儲區對應RAM,如此這般兩個區域就是實體上的分開的–經典的哈佛模型。

STM32的燒錄和Hex/bin燒錄檔案解析、燒錄檔案是被如何存儲到MCU中的?

燒錄檔案是被如何存儲到MCU中的?

STM32的燒錄和Hex/bin燒錄檔案解析、燒錄檔案是被如何存儲到MCU中的?

哈哈我就不轉載了,放個連結

https://www.dianyuan.com/eestar/article-3676.html

繼續閱讀