[分享] 打造 c++ 標準程式庫 for stm32f407

作者: descent (「雄辯是銀,沉默是金」)   2016-02-07 22:50:56
接續的是 simple c++ 標準程式庫。我從來沒想過我會去寫標準程式庫, 這是無心插柳之
作。
標準程式庫是一個演算法和系統知識的結合, 和之前偏重在系統知識的程式不同, 比較偏
軟體, 我的演算法和資料結構能力太弱, 順道練習不是壞事。
不知道你有沒有和我一樣的感覺, 教科書上的演算法資料結構, 似乎在平凡人的工作上功
效不大, 總是有基本程式庫打造好這些, 我們只要去用就好了, 這也造成我們很難去練習
這樣的程式, 畢竟有了 std::list, 有誰能忍住誘惑不去用呢? 你說用 c 的怎麼辦, 有
發現在這樣環境下的工程師大部份都用 array 嗎? 很少用上 list, map 這些資料結構。
simple os 一開始也都是用 array, simple scheme 也是。
現在我迷上 bare-metal 程式, 剛好有個機會來練習這些基本功, 不是壞事, 只是能在學
生時代就練習到是比較好的。
在寫 simple os 時, 就已經寫了 (抄了) 不少相對應的 c function, 而在完成 simple
scheme bare-metal 的版本時, 又多了一些資料結構, 再來實作 malloc 之後, 我終於有
了動態配置記憶體的能力, 可以寫 c++ 的容器 (list, vector, map ...), 好用不少,
再加上實作出 exception handle, 記憶體的管理方便多了, 又在回頭改善了 c++ 容器,
讓她更像標準程式庫的行為。
這是一個累積的成果, 把之前的努力集合起來, 再加上一些程式碼, 就是 c++ 標準程式
庫了。成果在這裡:
https://github.com/descent/simple_stdcpplib ( https://goo.gl/K5Khpe )
目前支援 3 個平台, p103 模擬器, stm32f4discovery board, raspberry pi2 (無法藉
由 uart 輸入), 所以也提供了 3 個 linker script。
要移植這個 library 有兩部份:
輸出/輸入 - 在這三個平台都是 uart
c runtime - 如何從組合語言切換到 c/c++
c runtime 每個硬體平台都不同, 這便是從組合語言到 c 這段所需要最辛苦的過程, 從
這裡開始就可以擺脫組合語言, 用 c 了。當然如果你喜歡用組合語言來開發程式, 就沒
有這個需求。
在 p103/stm32f407 要做:
bss init
data section init
rpi2 要做:
bss init
stack register 的設定
x86 要做:
bss init
stack register 的設定
使用保護模式的 Flat memory model 還要把 %ss, %ds, %cs 設到同一個 selector
c runtime 除了和硬體相關之外還可能和你使用的 c compiler 有相關性, 我只有研究
gcc 這個 c compiler。
而 c++ runtime 則是 c runtime 做的事情, c++ 都要做, 而 c++ 有很多特性, 有些要
在 c++ runtime 支援, ex:
global object
static object
rtti
exception handle
Pure virtual functions
http://wiki.osdev.org/C%2b%2b#Pure_virtual_functions
未知
目前只支援 global object, 本來不想做的, 因為覺得過於麻煩 (這個可得從 linker
script 開始著手) 也怕整個 code 太大, 不過 cout 是 global object, 就做吧! 反正
c++ 就是大。
feature list:
c runtime
c++ runtime
global object ctor/dtor
exception handle (implement by setjmp/longjmp)
printf (support float)
malloc/free
new/delete
vector
string
map
list
想試試的朋友可以從 stm32 p103 模擬器開始:
https://github.com/beckus/qemu_stm32.git ( https://goo.gl/5Sqynm )
編譯出支援的模擬器之後, 再編譯本 library, 會有一個 mymain.bin, 執行
typescript L2 的 command, ctrl-A+X 離開 qemu。
typescript
1 Script started on Tue 12 Jan 2016 09:38:47 AM CST
2 descent@debian64: ~/git/qemu_stm32/arm-softmmu/qemu-system-arm -M
stm32-p103 -kernel mymain.bin -nographic
3
4 (process:25512): GLib-WARNING **:
/build/glib2.0-VKSJTv/glib2.0-2.46.1/./glib/gmem.c:482: custom memory
allocation vtable not supported
5 STM32_UART: UART1 clock is set to 0 Hz.
6 STM32_UART: UART1 BRR set to 0.
7 STM32_UART: UART1 Baud is set to 0 bits per sec.
8 STM32_UART: UART2 clock is set to 0 Hz.
9 STM32_UART: UART2 BRR set to 0.
10 STM32_UART: UART2 Baud is set to 0 bits per sec.
11 STM32_UART: UART3 clock is set to 0 Hz.
12 STM32_UART: UART3 BRR set to 0.
13 STM32_UART: UART3 Baud is set to 0 bits per sec.
14 STM32_UART: UART4 clock is set to 0 Hz.
15 STM32_UART: UART4 BRR set to 0.
16 STM32_UART: UART4 Baud is set to 0 bits per sec.
17 STM32_UART: UART5 clock is set to 0 Hz.
18 STM32_UART: UART5 BRR set to 0.
19 STM32_UART: UART5 Baud is set to 0 bits per sec.
20 STM32_UART: UART5 clock is set to 0 Hz.
21 STM32_UART: UART5 BRR set to 0.
22 STM32_UART: UART5 Baud is set to 0 bits per sec.
23 STM32_UART: UART4 clock is set to 0 Hz.
24 STM32_UART: UART4 BRR set to 0.
25 STM32_UART: UART4 Baud is set to 0 bits per sec.
26 STM32_UART: UART3 clock is set to 0 Hz.
27 STM32_UART: UART3 BRR set to 0.
28 STM32_UART: UART3 Baud is set to 0 bits per sec.
29 STM32_UART: UART2 clock is set to 0 Hz.
30 STM32_UART: UART2 BRR set to 0.
31 STM32_UART: UART2 Baud is set to 0 bits per sec.
32 STM32_UART: UART1 clock is set to 0 Hz.
33 STM32_UART: UART1 BRR set to 0.
34 STM32_UART: UART1 Baud is set to 0 bits per sec.
35 LED Off
36 CLKTREE: HSI Output Change (SrcClk:None InFreq:8000000 OutFreq:8000000
Mul:1 Div:1 Enabled:1)
37 CLKTREE: HSI/2 Output Change (SrcClk:HSI InFreq:8000000 OutFreq:4000000
Mul:1 Div:2 Enabled:1)
38 CLKTREE: SYSCLK Output Change (SrcClk:HSI InFreq:8000000 OutFreq:8000000
Mul:1 Div:1 Enabled:1)
39 CLKTREE: HCLK Output Change (SrcClk:SYSCLK InFreq:8000000 OutFreq:8000000
Mul:1 Div:1 Enabled:1)
40 STM32_RCC: Cortex SYSTICK frequency set to 8000000 Hz (scale set to 125).
41 STM32_RCC: Cortex SYSTICK ext ref frequency set to 1000000 Hz (scale set
to 1000).
42 CLKTREE: PCLK1 Output Change (SrcClk:HCLK InFreq:8000000 OutFreq:8000000
Mul:1 Div:1 Enabled:1)
43 CLKTREE: PCLK2 Output Change (SrcClk:HCLK InFreq:8000000 OutFreq:8000000
Mul:1 Div:1 Enabled:1)
44 CLKTREE: GPIOA Output Change (SrcClk:PCLK2 InFreq:8000000 OutFreq:8000000
Mul:1 Div:1 Enabled:1)
45 CLKTREE: AFIO Output Change (SrcClk:PCLK2 InFreq:8000000 OutFreq:8000000
Mul:1 Div:1 Enabled:1)
46 CLKTREE: UART2 Output Change (SrcClk:PCLK1 InFreq:8000000 OutFreq:8000000
Mul:1 Div:1 Enabled:1)
47 STM32_UART: UART2 clock is set to 8000000 Hz.
48 STM32_UART: UART2 BRR set to 0.
49 STM32_UART: UART2 Baud is set to 0 bits per sec.
50 STM32_UART: UART2 clock is set to 8000000 Hz.
51 STM32_UART: UART2 BRR set to 833.
52 STM32_UART: UART2 Baud is set to 9603 bits per sec.
53 i am cout ctor: 0
54
作者: cebelas (DD_cebelas)   2016-02-08 00:33:00
作者: LPH66 (-6.2598534e+18f)   2016-02-08 01:10:00
作者: fr3ak (fr3@K)   2016-02-08 01:49:00
推有心!
作者: Hurricaneger (褲襪脫落大尉)   2016-02-08 10:40:00
只能跪了
作者: ggBird (ggBird)   2016-02-08 20:17:00
作者: trylovetom (閒閒的猛男)   2016-02-08 21:29:00
有神快拜
作者: winken2004 (新竹肥宅)   2016-02-08 22:29:00
作者: ray2501 (貓是一隻貓)   2016-02-09 17:42:00
作者: cobrasgo (人魚線變成鮪魚線,超帥)   2016-02-09 20:57:00
如果是只想在stm32f系列上跑c++的話,mbed os也是個選項目前已知401/411/426都可以動407應該只要做部份修改
作者: damody (天亮damody)   2016-02-11 07:51:00
讚讚讚
作者: yoco (眠月)   2016-02-11 13:04:00
孝心感動天 qq
作者: BlazarArc (Midnight Sun)   2016-02-15 11:00:00

Links booklink

Contact Us: admin [ a t ] ucptt.com