rust 是什么 rust 是一门赋予每个人构建可靠且高效软件能力的语言。
高性能:速度惊人且内存利用率极高
可靠性:在编译期就能消除各种内存错误
生产力:出色的文档,友好的编译器和清晰的错误提示信息
为什么要用 rust 进行嵌入式开发 rust 的设计理念:既要安全,也要高性能。rust 的设计理念完全是嵌入式开发所需要的。
嵌入式软件在运行过程中出现问题,大部分是由于内存引起的。rust 语言可以说是一门面向编译器的语言。在编译期间,就能够确保你安全地使用内存。
目前,嵌入式的主流开发语言还是 c 语言,不能上来就把底层的逻辑用 rust 重新实现一遍。但是可以在 c 代码中嵌入 rust 语言。
c 调用 rust 在 c 代码中调用 rust 代码,需要我们将 rust 源代码打包为静态库文件。在 c 代码编译时,链接进去。
创建 lib 库 1、在 clion 中使用 cargo init --lib rust_to_c 建立 lib 库。添加以下代码到 lib.rs 中,使用 rust 语言计算两个整数的和:
1#![no_std] 2use core::panicinfo; 3 4#[no_mangle] 5pub extern c fn sum(a: i32, b: i32) -> i32 { 6 a + b 7} 8 9#[panic_handler]10fn panic(_info:&panicinfo) -> !{11 loop{}12}
在 cargo.toml 文件中添加以下代码,生成静态库文件:
1[lib]2name = sum3crate-type = [staticlib]4path = src/lib.rs
交叉编译 1、安装 armv7 target:
1rustup target add armv7a-none-eabi
2、生成静态库文件:
1ps c:usersliukangdesktoprustust_to_c> cargo build --target=armv7a-none-eabi --release --verbose2 fresh rust_to_c v0.1.0 (c:usersliukangdesktoprustust_to_c)3 finished release [optimized] target(s) in 0.01s
生成头文件 1、安装 cbindgen](https://github.com/eqrion/cbindgen)), cbindgen 从 rust 库生成 c/c++ 11 头文件:
1cargo install --force cbindgen 2、在项目文件夹下新建文件 cbindgen.toml 文件:
3、生成头文件:
1cbindgen --config cbindgen.toml --crate rust_to_c --output sum.h
调用 rust 库文件 1、将生成的sum.h 以及 sum.a 文件放入 rt-threadspqemu-vexpress-a9applications 目录下
2、修改 sconscript 文件,添加静态库:
1from building import * 2 3cwd = getcurrentdir() 4src = glob('*.c') + glob('*.cpp') 5cpppath = [cwd] 6 7libs = [libsum.a] 8libpath = [getcurrentdir()] 910group = definegroup('applications', src, depend = [''], cpppath = cpppath, libs = libs, libpath = libpath)1112return('group')
3、在 main 函数中调用 sum 函数, 并获取返回值
1#include 2#include 3#include 4#include 5#include sum.h 6 7int main(void) 8{ 9 int32_t tmp;1011 tmp = sum(1, 2);12 printf(call rust sum(1, 2) = %d, tmp);1314 return 0;15}
4、在 env 环境下,使用 scons 编译工程:
1 liukang@desktop-538h6de d:epogithubt-threadspqemu-vexpress-a9 2 $ scons -j6 3 scons: reading sconscript files ... 4 scons: done reading sconscript files. 5 6 scons: warning: you do not seem to have the pywin32 extensions installed; 7 parallel (-j) builds may not work reliably with open python files. 8 file d:softwareenv_released_1.2.0env oolspython27scriptsscons.py, line 204, in 9 scons: building targets ...10 scons: building associated variantdir targets: build11 link rtthread.elf12 arm-none-eabi-objcopy -o binary rtthread.elf rtthread.bin13 arm-none-eabi-size rtthread.elf14 text data bss dec hex filename15628220 2148 86700 717068 af10c rtthread.elf16 scons: done building targets.1718 liukang@desktop-538h6de d:epogithubt-threadspqemu-vexpress-a919 $ qemu.bat20 warning: image format was not specified for 'sd.bin' and probing guessed raw.21automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.22specify the 'raw' format explicitly to remove the restrictions.2324 | /25 - rt - thread operating system26/ | 4.0.4 build jul 28 2021272006 - 2021 copyright by rt-thread team28 lwip-2.1.2 initialized!29 [i/sal.skt] socket abstraction layer initialize success.30 [i/sdio] sd card capacity 65536 kb.31 [i/sdio] switching card to high speed failed!32 call rust sum(1, 2) = 333 msh />
加减乘除 1、在 lib.rs 文件中,使用 rust 语言实现加减乘除运算:
1 #![no_std] 2 use core::panicinfo; 3 4 5 #[no_mangle] 6 pub extern c fn add(a: i32, b: i32) -> i32 { 7 a + b 8 } 910 #[no_mangle]11 pub extern c fn subtract(a: i32, b: i32) -> i32 {12 a - b13 }1415 #[no_mangle]16 pub extern c fn multiply(a: i32, b: i32) -> i32 {17 a * b18 }1920 #[no_mangle]21 pub extern c fn divide(a: i32, b: i32) -> i32 {22 a / b23 }2425 #[panic_handler]26 fn panic(_info:&panicinfo) -> !{27 loop{}28 }
2、生成库文件和头文件并放在 application 目录下
3、使用 scons 编译,链接时报错,在 rust github 仓库的 issues 中找到了 解决办法(https://github.com/rust-lang/compiler-builtins/issues/353) :
1 link rtthread.elf2 d:/software/env_released_1.2.0/env/tools/gnu_gcc/arm_gcc/mingw/bin/../lib/gcc/arm-none-eabi/5.4.1/armv7-ar/thumblibgcc.a(_arm_addsubdf3.o): in function `__aeabi_ul2d':3 (.text+0x304): multiple definition of `__aeabi_ul2d'4 applicationslibsum.a(compiler_builtins-9b744f6fddf5e719.compiler_builtins.20m0qzjq-cgu.117.rcgu.o):/cargo/registry/src/github.com-1ecc6299db9ec823/compiler_builtins-0.1.35/src/float/conv.rs:143: first defined here5 collect2.exe: error: ld returned 1 exit status6 scons: *** [rtthread.elf] error 17 scons: building terminated because of errors.
4、修改 rtconfig.py 文件, 添加链接参数 --allow-multiple-definition:
1 device = ' -march=armv7-a -marm -msoft-float'2 cflags = device + ' -wall'3 aflags = ' -c' + device + ' -x assembler-with-cpp -d__assembly__ -i.'4 link_script = 'link.lds'5 lflags = device + ' -nostartfiles -wl,--gc-sections,-map=rtthread.map,-cref,-u,system_vectors,--allow-multiple-definition'+6 ' -t %s' % link_script78 cpath = ''9 lpath = ''
5、编译并运行 qemu:
1 liukang@desktop-538h6de d:epogithubt-threadspqemu-vexpress-a9 2 $ scons -j6 3 scons: reading sconscript files ... 4 scons: done reading sconscript files. 5 6 scons: warning: you do not seem to have the pywin32 extensions installed; 7 parallel (-j) builds may not work reliably with open python files. 8 file d:softwareenv_released_1.2.0env oolspython27scriptsscons.py, line 204, in 9 scons: building targets ...10 scons: building associated variantdir targets: build11 link rtthread.elf12 arm-none-eabi-objcopy -o binary rtthread.elf rtthread.bin13 arm-none-eabi-size rtthread.elf14 text data bss dec hex filename15628756 2148 86700 717604 af324 rtthread.elf16 scons: done building targets.1718 liukang@desktop-538h6de d:epogithubt-threadspqemu-vexpress-a919 $ qemu.bat20 warning: image format was not specified for 'sd.bin' and probing guessed raw.21 automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.22 specify the 'raw' format explicitly to remove the restrictions.2324 | /25 - rt - thread operating system26/ | 4.0.4 build jul 28 2021272006 - 2021 copyright by rt-thread team28 lwip-2.1.2 initialized!29 [i/sal.skt] socket abstraction layer initialize success.30 [i/sdio] sd card capacity 65536 kb.31 [i/sdio] switching card to high speed failed!32 call rust sum(1, 2) = 333 call rust subtract(2, 1) = 134 call rust multiply(2, 2) = 435 call rust divide(4, 2) = 2
rust 调用 c
可以 在 c 代码中调用 rust,那么在 rust 中也可以调用 c 代码。我们在 rust 代码中调用 rt_kprintf 函数:
修改 lib.rs 文件 1 // 导入的 rt-thread 函数列表 2 extern c { 3 pub fn rt_kprintf(format: *const u8, ...); 4 } 5 6 #[no_mangle] 7 pub extern c fn add(a: i32, b: i32) -> i32 { 8 unsafe { 9 rt_kprintf(bthis is from rust as *const u8);10 }11 a + b12 }
生成库文件 1 cargo build --target=armv7a-none-eabi --release --verbose2 compiling rust_to_c v0.1.0 (c:usersliukangdesktoprustust_to_c)3 running `rustc --crate-name sum --edition=2018 src/lib.rs --error-format=json --json=diagnostic-rendered-ansi --crate-type staticlib --emit=dep-info,link -c opt-level=3 -c embed-bitcode=no -c metadata=a4 0723fa112c78339 -c extra-filename=-a0723fa112c78339 --out-dir c:usersliukangdesktoprustust_to_c argetarmv7a-none-eabieleasedeps --target armv7a-none-eabi -l dependency=c:usersliukangdesktoprus5 tust_to_c argetarmv7a-none-eabieleasedeps -l dependency=c:usersliukangdesktoprustust_to_c argeteleasedeps`6 finished release [optimized] target(s) in 0.11s
运行 复制 rust 生成的库文件到 application 目录下。
1 liukang@desktop-538h6de d:epogithubt-threadspqemu-vexpress-a9 2 $ scons -j6 3 scons: reading sconscript files ... 4 scons: done reading sconscript files. 5 scons: warning: you do not seem to have the pywin32 extensions installed; 6 parallel (-j) builds may not work reliably with open python files. 7 file d:softwareenv_released_1.2.0env oolspython27scriptsscons.py, line 204, in 8 scons: building targets ... 9 scons: building associated variantdir targets: build 10 link rtthread.elf 11 arm-none-eabi-objcopy -o binary rtthread.elf rtthread.bin 12 arm-none-eabi-size rtthread.elf 13 text data bss dec hex filename 14 628812 2148 90796 721756 b035c rtthread.elf 15 scons: done building targets. 1617 liukang@desktop-538h6de d:epogithubt-threadspqemu-vexpress-a9 18 $ qemu.bat 19 warning: image format was not specified for 'sd.bin' and probing guessed raw. 20 automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted. 21 specify the 'raw' format explicitly to remove the restrictions. 2223 | / 24 - rt - thread operating system 25 / | 4.0.4 build jul 28 2021 26 2006 - 2021 copyright by rt-thread team 27 lwip-2.1.2 initialized! 28 [i/sal.skt] socket abstraction layer initialize success. 29 [i/sdio] sd card capacity 65536 kb. 30 [i/sdio] switching card to high speed failed! 31 this is from rust 32 call rust sum(1, 2) = 3 33 call rust subtract(2, 1) = 1 34 call rust multiply(2, 2) = 4 35 call rust divide(4, 2) = 2 36 msh />
来源:
https://club.rt-thread.org/ask/article/2944.html
全志A523八核Cortex-A55处理器规格参数
爱立信亮相中国移动研究院无线通算融合共生技术论坛
科学家开发可提高3D感知能力的模型,实现四足机器人自由行走
ADI实验室电路:16位、100kSPS逐次逼近型ADC系统
如何在vivado创建新工程上使用IP集成器创建块设计
为什么要用Rust进行嵌入式开发
不间断电源怎么使用
荣耀V20评测 称得上是科技标杆
长虹电视机通病[2]
小米6与荣耀v9怎样选择?小米6评测:小米6与荣耀v9对比评测
搭建PCB产业采购直通车,CS Show 2016深圳展8月30日盛大开幕
要想安全吸氧就要选对制氧机!如何选购家用制氧机?
中国将加强新能源汽车的安全排查
I2C总线的工作原理和应用
二手iPhone市场崛起 且看最全的二手iPhone验机指南
U5251-001005-300PG压力传感器的功率和信号
熔喷无纺布瑕疵在线检测系统介绍
半导体巨头聚焦汽车电子市场,IC设计忙翻天
玩转“多∙智∙享”炫酷生活 就在三星电视全新Tizen系统
物联网是什么?低功耗技术ZETA有哪些优势?