( https://goo.gl/W4cwGn )會選擇 c++ 來開發 scheme, 最主要是因為 c++ 的標準程式
庫有很多好用的 class: string, vector, map, list ... 不用為了這些基本的東西傷腦
筋; 但這次要開發的是 - 在作業系統之前的 scheme (開發平台是 stm32f4discovery),
這些好東西通通派不上用場, 沒有 malloc/new, 又怎麼能用這些東西呢! 甚至連
global object 都不能用, 所以幾乎和使用 c 一樣, 不過還是能用上點 c++ 的特性。
原本程式中用到 list, vector, map 的部份, 通通要改, 全部改用 array, 不夠彈性,
但容易實作, 至於 input/output function, 需改用 uart 這部份的程式碼, 所以直接把
之前搞定的 uart 程式碼複製一份過來修改。
getline 我得換成 getchar uart 的版本, cout 也要換成 myprint uart 的版本, 這之
前都做過了, 把以前的努力都集合起來就可以, scanner 的作法則改為一次讀一個 byte
來轉成 token, s-express 不複雜, 但我覺得還是不容易, 沒想到花點時間竟然搞定, 感
謝周自制本言 ( http://goo.gl/X8U0CW )的 scanner 這節提供的知識。
再來是 malloc Cell* 的部份, 由於在重寫 struct Cell 時, 我就考慮到在
stm32f4discovery 開發板上執行, 也就是沒有 os 的環境, 所以才使用了 array pool
來得到一個 Cell 的記憶體。雖然沒有彈性, 但能簡化問題, 再搭配一些人工手法, 可以
減低 pool 可能會不夠用的問題。
我先在 qemu stm32 p103 emulator 上測試, 等成功了再上到 stm32f4discovery, 減少
flash 讀寫次數。也的確有必要, 光在模擬器上就測試了無數次, 減少了多次的 flash
讀寫。
在製作 p103 emulator 的版本階段, 出了一個 link 問題:
[email protected]:descent/stm32_p103_demos.git
stm32_p103_demos/demos/uart_echo
git commit: 6b2df2c6e62f3c48a6c6dc20c76367124c1ca447
bss_to_big
1
/home/descent/arm-cs-tools/lib/gcc/arm-none-eabi/4.7.3/../../../../arm-none-eabi/bin/ld:
mymain.elf section `.bss' will not fit in region `RAM'
2
/home/descent/arm-cs-tools/lib/gcc/arm-none-eabi/4.7.3/../../../../arm-none-eabi/bin/ld:
region `RAM' overflowed by 34085848 bytes
3 collect2: error: ld returned 1 exit status
我以為我已經很了解 link 的問題了, 這應該難不倒我, 就是哪個 section 太大, 整個
記憶體空間不足嘛! 嚇不了我的。但隨著時間的過去, 我還是無法處理這問題, 亂
google 找問題, 我 - 開始緊張了, 原來我還有沒搞懂的東西。
當然最後還是搞定了, 原因是: bss 竟然需要 34M 的記憶體空間, 嚇壞我了, p103 只有
20K ram, 把 main.ld 的 RAM 從 20K 改成 48M 就可以編過, 但想也知道, 放入
flash 執行, 一定掛掉。
main.ld
MEMORY
{
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 128K
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 20K -> 48M
}
...
...
我當然是不會用這麼蠢的改法。程式中用到相當多的 global variable (global
variable 不一定佔據 bss, 得找對才行), 來把他們減少, shorten_bss L32 的效果最好
,
/bin/ld: region `RAM' overflowed by 877288 bytes
collect2: error: ld returned 1 exit status
從 34M 降到 877K, 效果不錯, 可是還不夠 ...
shorten_bss
1 diff