( 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