Rust语言被认为是21世纪应用广泛的编程语言之一。Rust之所以受到广泛认可,其中一个原因是它可以运行在多样的目标上,包括桌面和服务器设备,以及资源有限的嵌入式设备。
Rust 是什么
Rust是一门赋予每个人构建可靠且高效软件能力的语言。
-
高性能:具有惊人的速度和极高的内存利用率 -
可靠性:能够在编译期消除各种内存错误 -
生产力:提供出色的文档、友好的编译器和清晰的错误提示
为什么要使用Rust进行嵌入式开发
Rust的设计理念是同时追求安全性和高性能。这完全符合嵌入式开发的需求。
嵌入式软件在运行过程中往往会出现与内存相关的问题。Rust语言可以被看作是一门面向编译器的语言,在编译期间就能够确保安全地使用内存。
目前,C语言仍然是嵌入式开发的主流语言,不可能直接使用Rust来重新实现底层逻辑。但是,可以在C代码中嵌入Rust语言的代码,以获得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::panic::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 = "sum"
3crate-type = ["staticlib"]
4path = "src/lib.rs"
交叉编译
1、安装 armv7 target:
1rustup target add armv7a-none-eabi
2、生成静态库文件:
1PS C:\Users\LiuKang\Desktop\RUST\rust_to_c> cargo build --target=armv7a-none-eabi --release --verbose
2 Fresh rust_to_c v0.1.0 (C:\Users\LiuKang\Desktop\RUST\rust_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-thread\bsp\qemu-vexpress-a9\applications
目录下
2、修改 SConscript 文件,添加静态库:
1from building import *
2
3cwd = GetCurrentDir()
4src = Glob('*.c') + Glob('*.cpp')
5CPPPATH = [cwd]
6
7LIBS = ["libsum.a"]
8LIBPATH = [GetCurrentDir()]
9
10group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH, LIBS = LIBS, LIBPATH = LIBPATH)
11
12Return('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;
10
11 tmp = sum(1, 2);
12 printf("call rust sum(1, 2) = %d\n", tmp);
13
14 return 0;
15}
4、在 env 环境下,使用 scons 编译工程:
1 LiuKang@DESKTOP-538H6DE D:\repo\github\rt-thread\bsp\qemu-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:\software\env_released_1.2.0\env\tools\Python27\Scripts\scons.py", line 204, in
9 scons: Building targets ...
10 scons: building associated VariantDir targets: build
11 LINK rtthread.elf
12 arm-none-eabi-objcopy -O binary rtthread.elf rtthread.bin
13 arm-none-eabi-size rtthread.elf
14 text data bss dec hex filename
15628220 2148 86700 717068 af10c rtthread.elf
16 scons: done building targets.
17
18 LiuKang@DESKTOP-538H6DE D:\repo\github\rt-thread\bsp\qemu-vexpress-a9
19 $ qemu.bat
20 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.
23
24\ | /
25 - RT - Thread Operating System
26/ | \ 4.0.4 build Jul 28 2021
272006 - 2021 Copyright by rt-thread team
28 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) = 3
33 msh />
加减乘除
1、在 lib.rs 文件中,使用 rust 语言实现加减乘除运算:
1 #![no_std]
2 use core::panic::PanicInfo;
3
4
5 #[no_mangle]
6 pub extern "C" fn add(a: i32, b: i32) -> i32 {
7 a + b
8 }
9
10 #[no_mangle]
11 pub extern "C" fn subtract(a: i32, b: i32) -> i32 {
12 a - b
13 }
14
15 #[no_mangle]
16 pub extern "C" fn multiply(a: i32, b: i32) -> i32 {
17 a * b
18 }
19
20 #[no_mangle]
21 pub extern "C" fn divide(a: i32, b: i32) -> i32 {
22 a / b
23 }
24
25 #[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.elf
2 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/thumb\libgcc.a(_arm_addsubdf3.o): In function `__aeabi_ul2d':
3 (.text+0x304): multiple definition of `__aeabi_ul2d'
4 applications\libsum.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 here
5 collect2.exe: error: ld returned 1 exit status
6 scons: *** [rtthread.elf] Error 1
7 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_SCRIPT
7
8 CPATH = ''
9 LPATH = ''
5、编译并运行 qemu:
1 LiuKang@DESKTOP-538H6DE D:\repo\github\rt-thread\bsp\qemu-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:\software\env_released_1.2.0\env\tools\Python27\Scripts\scons.py", line 204, in
9 scons: Building targets ...
10 scons: building associated VariantDir targets: build
11 LINK rtthread.elf
12 arm-none-eabi-objcopy -O binary rtthread.elf rtthread.bin
13 arm-none-eabi-size rtthread.elf
14 text data bss dec hex filename
15628756 2148 86700 717604 af324 rtthread.elf
16 scons: done building targets.
17
18 LiuKang@DESKTOP-538H6DE D:\repo\github\rt-thread\bsp\qemu-vexpress-a9
19 $ qemu.bat
20 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.
23
24\ | /
25 - RT - Thread Operating System
26/ | \ 4.0.4 build Jul 28 2021
272006 - 2021 Copyright by rt-thread team
28 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) = 3
33 call rust subtract(2, 1) = 1
34 call rust multiply(2, 2) = 4
35 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(b"this is from rust\n\0" as *const u8);
10 }
11 a + b
12 }
生成库文件
1 cargo build --target=armv7a-none-eabi --release --verbose
2 Compiling rust_to_c v0.1.0 (C:\Users\LiuKang\Desktop\RUST\rust_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=a
4 0723fa112c78339 -C extra-filename=-a0723fa112c78339 --out-dir C:\Users\LiuKang\Desktop\RUST\rust_to_c\target\armv7a-none-eabi\release\deps --target armv7a-none-eabi -L dependency=C:\Users\LiuKang\Desktop\RUS
5 T\rust_to_c\target\armv7a-none-eabi\release\deps -L dependency=C:\Users\LiuKang\Desktop\RUST\rust_to_c\target\release\deps`
6 Finished release [optimized] target(s) in 0.11s
运行
复制 rust 生成的库文件到 application 目录下。
1 LiuKang@DESKTOP-538H6DE D:\repo\github\rt-thread\bsp\qemu-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:\software\env_released_1.2.0\env\tools\Python27\Scripts\scons.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.
16
17 LiuKang@DESKTOP-538H6DE D:\repo\github\rt-thread\bsp\qemu-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.
22
23 \ | /
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 />
以上就是良许教程网为各位朋友分享的Linu系统相关内容。想要了解更多Linux相关知识记得关注公众号“良许Linux”,或扫描下方二维码进行关注,更多干货等着你 !