作者:RT-Thread社区团队 liukang 原文链接: https://club./ask/article/2944.html 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::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 <stdint.h> 2#include <stdio.h> 3#include <stdlib.h> 4#include <rtthread.h> 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 <module> 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 <module> 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 <module> 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 />
|