STM32 記憶體分布探究

來源:互聯網
上載者:User

STM32 記憶體分布探究

2016-2-2

        本人在運行ucos時遇到一個非常奇怪的問題,運行一段時間後就會莫名進入hardfault函數,導致系統死機。後來根據對堆棧調試,發現每次調用的函數都不一樣,甚是費解。通過map檔案最後得出結論,原來在系統初始化的時候在flash裡面讀出了系統配置參數,在系統運行過程中會寫flash,而flash定義的地址與程式碼儲存的位置發生了重疊,一寫資料就擦掉了一些函數,當調用到這些函數的時候就會發生未知指令的錯誤。把這個參數儲存地址定義的分開些就會解決這個問題。可是,開始這個地址寫好了,隨著程式碼不斷增多,消耗的片上flash也會增大,是個動態增長的過程,不注意很有可能發生衝突。所以在項目開發過程中定期檢查定義的參數儲存地址,或者乾脆把參數儲存地址定義在程式地址之前。

        今天詳細瞭解一下編譯後的STM32工程,堆棧記憶體分布情況,有助於對堆棧大小分配的理解。開啟一個基於STM32f103RET6的工程,具有512KB 內建flash,以及64KB SRAM,通過map檔案可以看出:

名稱

位置

地址

備忘

RESET 複位向量

Flash

0x08000000

上電執行的第一條代碼

庫函數程式碼片段

Flash

0x08000144

在程式中調用的庫函數,例如字串處理函數、記憶體配置函數等

使用者自訂函數程式碼片段

Flash

0x08001110

工程模板函數庫、使用者自訂函數編譯後的代碼,以函數名首字母排序

.constdata

Flash

0x0800d07c-0x0800d680

使用者定義的常量

剩餘空間

Flash

 

 

 

名稱

位置

地址

備忘

.data

SRAM

0x20000000

資料區段,以及初始化的全域變數

.bss

SRAM

0x20000268

未初始化的全域變數

HEAP(堆)

 

SRAM

0x200033e8

開機檔案定義的堆空間開始,程式調用malloc自由分配的記憶體在堆上

STACK(棧)

SRAM

0x200073e8

開機檔案定義的棧空間開始,各個函數中的局部變數空間分配到棧上

剩餘空間

SRAM

 

 

 

        例如在這個工程中,flash自訂參數儲存地址,不要定義在 0x0800d680之前。

        另外,還可以看出在SRAM裡,分配儲存的是全域變數區,未初始設定變數區,堆以及棧。要注意的是,如果堆和棧定義的過小,程式預設定義都不大,一旦使用了一個較大的局部變數,有可能造成棧空間溢出,覆蓋掉堆空間甚至上面的全域變數區,造成系統出錯的問題。例如在做IAP的過程中,每當向flash寫入512個位元組時,由於大容量STM32片上flash塊大小為2K,寫之前要先讀出,調用寫函數的時候就自動建立一個2K大小的局部變數,由於棧是向上增長的,自然會覆蓋堆以及全域變數區,造成未知的錯誤。根據片上SRAM的資源,將堆和棧適當調大一些為好,比如各設定為4K大小。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.