基于之前对f1c200快速启动项目的研究,抽离出基本的在arm9处理器上最基本运行代码。
适配串口后同样能在f1c200上跑起来,供大家一起研究共同进步。
git地址: https://github.com/shaoxi2010/rust-arm9
项目目标
由于目前rust官方没有提供arm9的裸机环境支持,但是本身又不想放弃f1c200这个便宜又实在的平台。
这里就单纯的抛砖引玉作用了,吸引大家一起来研究下arm9的rust开发。
代码参考来源xboot,大佬真强。
使用rust与c开发的优缺点
1. cargo的存在使得rust不用在额外学习makefile等,简化项目管理统一编译
2. rust本身提供了很多基础实现,可以很方便的使用
3. rust提供的抽象可以很直观的理解代码含义,自身命名空间有效解决隔离问题
4. rust的抽象成本非常低,异常逻辑完善,debug起来很直观
5. rust的格式化字符串消耗较大,但灵活度高,在小内存比较难控制
6. rust的内联汇编与GCC内联汇编有些许的不一样,需要一定的学习成本
实现原理
核心思想与gcc编译内核一致,只要需要rust生成代码时,去除掉允许库相关依赖,程序严格
上来讲是可以允许在裸机环境。这时我们在采用arm-none-eabi-gcc的链接功能,将程序链接
成为一个完整环境即可,即可以同时将C与RUST一同编译链接实现。
在编写程序中遇到的问题
1. 首先裸机开发需要link.lds链接文件,需要将text,data,rodata(不链接没有字符串),bss段
2. 在start的启动汇编上需要设置sp地址否则会发现程序异常跑飞,qemu反复验证
3. 启动汇编需要清理bss段,否则static变量会出问题,qemu反复验证
4. rust内连汇编切记,会引起寄存器变化一定要使用inout实现,否则变量可能会被认为不变而不会对寄存器赋值直接跑飞,反汇编
5. 对于cpu操作应当详细参考arm手册,操作cp异常也可能会导致程序卡死,cache_flush卡死,qemu联调发现
6. rust的目标armv5te-unknown-linux-gnueabi目标会使用动态链接器,如Scrt1.o、libc,需要添加-no-pie和-no-stdlib避免链接
7. unwind在裸机环境并不支持,需要关闭栈回溯功能使用profile下panic = "abort"
8. __aeabi_unwind_cpp_pr0和eh_personality方法依赖于libgcc,也是栈回溯的一部分,空实现就行。
9. 关闭mmu并不会对数据进行flush操作,需要手动flush相关内容,不知道是不是ARM9特有
10. asm与gloabl_asm均会对{}进行解析处理,arm指令内带{}需要使用{{}}包装,或者使用raw模式,参见rust内联汇编文档
11. mmu的页彪需要对齐,否则会卡死在打开mmu上,qemu联调
程序运行与程序验证
1. 首先使用rustup target add armv5te-unknown-linux-gnueabi添加rust的arm9支持 (nightly)
2. 使用apt install arm-none-eabi-gcc安装arm工具链
3. 使用cargo build --release 生成二进制
4. 使用 arm-none-eabi-objcopy --binray target/armv5te-unknown-linux-gnueabi/release/rust-arm9 arm9生成裸机运行二进制
5. 下载目标机器
QEMU虚拟化运行和gdb联调
在实际环境下可能没有设备可以调试,使用QEMU虚拟机调试是很有效的办法。
QMUE 平台
1. 当前代码平台适配versatilepb即ARM Versatile/PB (ARM926EJ-S)
2. 使用qemu-system-arm -M versatilepb -serial stdio -display none -kernel target/armv5te-unknown-linux-gnueabi/release/rust-arm9运行
3. 即可看到hello world 输出
GDB联合调试
1. 添加QEMU调试参数-s -S运行即qemu-system-arm -s -S -M versatilepb -serial stdio -display none -kernel target/armv5te-unknown-linux-gnueabi/release/rust-arm9
2. 使用gdb-multiarch target/armv5te-unknown-linux-gnueabi/release/rust-arm9加载GDB
3. 进入gdb后使用target remote :1234,即可看到程序停在入口_start
4. 使用break等命令添加断点,或者反汇编等操作,一步步监视运行,调试程序bug
离线
目前网上能找到的用rust写的操作系统已经不少了。
离线
不看好rust在嵌入式方面的发展,特别是MCU方面。
杀鸡用牛刀的感觉,把rust留给互联网的码农吧,我们还有可爱的c和新式的zig
离线
要不来试试在RT-Thread中运行Rust吧,系统和驱动用RT-Thread的,部分应用是Rust的。
rust是语言不是开发包,目前的rust还比较初级没有什么商业应用。
离线
不看好rust在嵌入式方面的发展,特别是MCU方面。
杀鸡用牛刀的感觉,把rust留给互联网的码农吧,我们还有可爱的c和新式的zig
C语言已经有几十年历史了,很多语言特性都已经过时。
离线
可能再过几十年还是会有人用c做mcu开发,无他,mcu主要做控制用,开发人员又大多不是专业计算机学生,一门简单直白够底层的语言更容易满足需求。
mcu资源固定,项目又不会太庞大,清空c程序的bug成本不高,rust的特性在mcu领域加成不大,反而增加学习和编写成本。而且一个团队可能有一两个高手能搞定rust,但其他人搞不定的话怎么做项目呢。
实在对c不满意的可以看看zig,可能搞mcu开发的更喜欢呢。
当然像linux那么庞大复杂的软件就很应该用rust了。
最近编辑记录 jlau (2022-02-19 23:34:06)
离线
跟rust把内存管理规则置于语言层面不同,zig选择跟c一样让程序员自己自由管理内存,但又提供了便利的手段去调试内存错误。就是说跟用c一样,你也可以写出有内存bug的代码,但如果你想要高质量的代码,比用c容易。zig用工程上的改进达到内存安全。
当然zig也提供了其它语言特性,譬如rust的option和result在zig都有对应的实现。go的defer zig也支持。泛型也有。没有class但支持struct内置方法。不妨把zig看成是路子正确的c ++语言吧。
zig设计的时候就考虑到了裸机开发,交叉编译、无运行时依赖一开始就有,而且可以选择生成快速的二进制或生成更紧凑的二进制,拿来做mcu开发挺合适的。
快速编码,方便解bug,这是zig做的权衡(trade off)。不妨说rust是学术的,zig是工程的实用导向的。事实上rust内存管理方式确实来自于十多年前编程语言领域的学术研究。但对于习惯了直接操作硬件的mcu工程师,rust这不行那不行,这里要那样,这样束手束脚的开发过程确实很挫败,特别是代码量不大操作指针不多内存方面出bug概率不多的程序,你会怀疑自己是不是捡了芝麻丢了西瓜。所以我很建议你们想用rust的不妨也看看zig会不会更适合自己。
最近编辑记录 jlau (2022-02-22 05:06:37)
离线
我赞同linux用rust开发,因为linux里面很多复杂且庞大的模块,而且它很多开发者是计算机科班出身的,还有一个原因是linux应用最广的是服务器领域,这个领域的企业有足够的资金请到熟手的rust程序员,嵌入式的薪资多少大家应该很清楚了。
离线
给大佬递烟~
离线
手动管理内存的语言在实时性上面超越GC管理内存的语言,主要是把内存释放工作化整为零,分散在执行路径各处了。大家都是手动管理内存,在实时性这方面zig不会比rust差。
可靠性zig要靠静态分析动态分析多做测试等工程上的努力去提高,这些工作做c/c++的人都很熟悉了。当然zig在这些工作上还是比c/c++方便些,而且也在语言层面做了一些保障,譬如有空安全语法,带有测试语法,可选数组越界判断,提供可跟踪的内存分配器等等。相当于把一些c/c++提高代码质量的最佳实践都提供了,只要你对代码质量有要求,是可以通过这些工具和语法去达成的。
rust说的安全其实也不是万灵神药,内存泄露是可能的,数组越界也是可能的,除0出错这些也没法处理的。当然这些都算代码逻辑错误,我的意思是rust解决了一些问题,但还是有它解决不了需要程序员以及工程方法去保证的问题。我觉得不要神话rust,特别是不要在嵌入式领域神话rust。
是选择zig这种语法熟悉灵活,但工程工作多些的语言,还是选择rust这种语法束缚多,工程工作少些的语言,还是继续c/c++到底,很考验cto们的智慧了。
最近编辑记录 jlau (2022-03-01 17:46:01)
离线
前阵子看到一个测评,rust 的代码大小和运行速度都比 c 要好,吃了一惊。
zig 倒是第一次听说。
离线
底层用C,APP用Go/Java才是更好的选择
Rust对底层特性太多、徒增难度,,对APP没有GC需要自己管理内存,难学、难用
离线
年头跟各位讨论了rust和zig语言各自的特点和应用领域,特别是我们都关注的嵌入式领域。
现在快到年尾了,最近发现了一个网站,报道zig语言的发展和在不同领域的应用:https://zig.news
从这个网站看到国外已经有人认真的把zig用在MCU开发了,譬如这个新加坡人做的一些项目https://zig.news/lupyuen
另外,游戏开发、WASM也是两个较多人探索的方向。联想到前段时间一夜爆红的Bun.js,以及前段时间报道过的因为zig对c/c++兼容性太好,uber拿zig做c/c++交叉编译器的新闻。看来zig确实解决了一些c/c++开发人员的痛点,是一个可以跟进的编程语言。
至于rust,年底发布的linux 6.1就能用rust写内核代码了,我也要去学学了,不然饭碗不保。虽然要冲rust,但希望在不久的将来能看到zig写的rtos。附送两个有用链接:
https://microzig.tech
https://github.com/ZigEmbeddedGroup
离线
还有一个,用zig在risc-v mcu上做裸机开发:https://github.com/nmeum/zig-riscv-embedded
离线