- 本次採用的os是freertos,基於stm32f407zgt6
- 移植過程及代碼
代碼分析
startup_stm32f407xx.s
Reset_Handler
初始化棧
從flash 上 加載data 段入sram
清bss段
SystemInit
__libc_init_array
main
$ nm build/startup_stm32f407xx.o |grep " U "
U _ebss
U _edata
U _estack
U __libc_init_array
U main
U _sbss
U _sdata
U _sidata
U SystemInit
main
xTaskCreate(start_task)
vTaskStartScheduler
start_task
taskENTER_CRITICAL
task1_task
task2_task
taskEXIT_CRITICAL
task1_task
while(1)
task2_task
while(1)
-------------
1. 首先創建了一個任務A
2. 然後開始調度
3. A開始執行
4. A創建了兩個任務B C ,並刪除了任務A
5. B 開始執行
6. B結束執行,C 開始執行
7. C結束執行,B 開始執行
8. B結束執行,C 開始執行
9. ...
分析到 6 應該能分析完所有系統做的內存相關的動作.這裏麪包括了所有狀態下的調度.
3中的 A 開始執行
5中的 B 開始執行
6中的 C 開始執行
從其他角度分析
os管理內存的話
1. 爲 os 提供 api 和 內存空間
1. os的正常運行需要內存
1.1 os的 各個段
.code
.data
.ro-data
.bss
.stack
.heap
1.2 調度器
1.3 消息隊列
1.4 定時器
2. 爲 user space 提供 api和內存空間
1. os 需要維護應用程序的狀態(TCB和STACK)
2.1 爲了提供應用程序需要的各個段做了什麼
用戶使用內存的話
1. 使用 os 提供的malloc 函數 操作 os 提供給應用程序的空間.
1.1 應用程序的各個段在哪裏
1.2 應用程序什麼時候用了哪個段
運行的時候
.code 從 flash 加載,通過TCB中的PC控制
.ro-data 直接在.code中,通過.code索引
.data 在 ram ,通過 .code 索引
.bss 在 ram ,通過.code 索引
.stack 在 ram ,通過TCB中的SP索引
.heap 在 ram ,通過malloc索引
不運行的時候
.code 對應的PC放在了 TCB 中,其他進程不能訪問該進程TCB,也就訪問不了該進程的.code
.ro-data 在 .code中
.data .bss 在ram中,其他進程沒有 索引(索引在.code中)
.stack 對應的SP被放在了TCB中,其他進程不能訪問該進程TCB,也就訪問不了該進程的.stack
.heap 在 ram 中,已經被malloc過,未被free,其他進程不能malloc到該進程的.heap
------------------------------
按照stm32 freertos來說
系統的.code(調度器) .ro-data .data .bss .heap 和 應用程序的.code(功能函數) .ro-data .data .bss .heap 是在一塊的
系統的.stack 和 應用程序的.stack 是分離的.
且 .code .ro-data 在flash上
.data .bss .heap .stack 在內存裏
另外內存裏還有每個進程的TCB
所以整體來說,大小的話
初始化的時候 .data .bss 是初始化好的,佔用的內存可以通過map來查看
另外只要知道 .heap(可以通過配置來查看) .stack(可以通過配置來查看) TCB(可以通過配置來查看) 佔用多少內存就可以了
整體來說,佈局的話
flash
.code .ro-data
ram
.data .bss .heap TCB(應用程序)
.stack(內核) .stack(應用程序1) .stack(應用程序2) ...
---------------------------和裸機內存的佈局有什麼不同
1.大體相同(都是 .code .ro-data .data .bss .heap .stack)
2.只不過.heap被內核用了一部分(用於TCB的管理)
3.stack被分成了很多份(內核一份(內核的stack在.stack),每個應用程序一份(用戶的stack在.heap))
參考資料