Author: liukang
What is Rust
Rust is a language that empowers everyone to build reliable and efficient software.
-
High performance: blazingly fast and extremely memory efficient
-
Reliability: Various memory errors can be eliminated at compile time
-
Productivity: excellent documentation, friendly compiler, and clear error messages
Why use Rust for embedded development?
Rust's design philosophy: both safety and high performance. Rust's design philosophy is exactly what embedded development requires.
Most of the problems that occur during the operation of embedded software are caused by memory. Rust can be said to be a compiler-oriented language. During compilation, it can ensure that you use memory safely.
At present, the mainstream development language for embedded systems is still C, and we cannot re-implement the underlying logic with Rust right away. However, we can embed Rust in C code.
Calling Rust from C
To call Rust code from C code, we need to package the Rust source code into a static library file and link it in when compiling the C code.
Create lib library
1. Use Build lib in Clion cargo init --lib rust_to_c . Add the following code to lib.rs to calculate the sum of two integers using Rust language:
1#![no_std]
2usecore::panic::PanicInfo;
3
4#[no_mangle]
5pubextern"C"fnsum(a:i32,b:i32)->i32{
6a+b
7}
8
9#[panic_handler]
10fnpanic(_info:&PanicInfo)->!{
11loop{}
12}
Add the following code in the Cargo.toml file to generate a static library file:
1[lib]
2name="sum"
3crate-type=["staticlib"]
4path="src/lib.rs"
Cross-compiling
1. Install armv7 target:
1rustuptargetaddarmv7a-none-eabi
2. Generate static library files:
1PSC:\Users\LiuKang\Desktop\RUST\rust_to_c>cargobuild--target=armv7a-none-eabi--release--verbose
2Freshrust_to_cv0.1.0(C:\Users\LiuKang\Desktop\RUST\rust_to_c)
3Finishedrelease[optimized]target(s)in0.01s
Generate header file
1. Install cbindgen](https://github.com/eqrion/cbindgen)), cbindgen generates C/C++ 11 header files from the rust library:
1cargoinstall--forcecbindgen
2. Create a new file in the project folder cbindgen.toml :
3. Generate header file:
1cbindgen--configcbindgen.toml--craterust_to_c--outputsum.h
Calling Rust library files
1. Put the generated sum.h files into the directorysum.a rt-thread\bsp\qemu-vexpress-a9\applications
2. Modify the SConscript file and add a static library:
1frombuildingimport*
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. Call the sum function in the main function and get the return value
1#include<stdint.h>
2#include<stdio.h>
3#include<stdlib.h>
4#include<rtthread.h>
5#include"sum.h"
6
7intmain(void)
8{
9int32_ttmp;
10
11tmp=sum(1,2);
12printf("callrustsum(1,2)=%d\n",tmp);
13
14return0;
15}
4. In the env environment, use scons to compile the project:
1LiuKang@DESKTOP-538H6DED:\repo\github\rt-thread\bsp\qemu-vexpress-a9
2$scons-j6
3scons:ReadingSConscriptfiles...
4scons:donereadingSConscriptfiles.
5
6scons:warning:youdonotseemtohavethepywin32extensionsinstalled;
7parallel(-j)buildsmaynotworkreliablywithopenPythonfiles.
8File"D:\software\env_released_1.2.0\env\tools\Python27\Scripts\scons.py",line204,in<module>
9scons:Buildingtargets...
10scons:buildingassociatedVariantDirtargets:build
11LINKrtthread.elf
12arm-none-eabi-objcopy-Obinaryrtthread.elfrtthread.bin
13arm-none-eabi-sizertthread.elf
14textdatabssdechexfilename
15628220214886700717068af10crtthread.elf
16scons:donebuildingtargets.
17
18LiuKang@DESKTOP-538H6DED:\repo\github\rt-thread\bsp\qemu-vexpress-a9
19$qemu.bat
20WARNING:Imageformatwasnotspecifiedfor'sd.bin'andprobingguessedraw.
21Automaticallydetectingtheformatisdangerousforrawimages,writeoperationsonblock0willberestricted.
22Specifythe'raw'formatexplicitlytoremovetherestrictions.
23
24\|/
25-RT-ThreadOperatingSystem
26/|\4.0.4buildJul282021
272006-2021Copyrightbyrt-threadteam
28lwIP-2.1.2initialized!
29[I/sal.skt]SocketAbstractionLayerinitializesuccess.
30[I/SDIO]SDcardcapacity65536KB.
31[I/SDIO]switchingcardtohighspeedfailed!
32callrustsum(1,2)=3
33msh/>
Addition, subtraction, multiplication and division
1. In the lib.rs file, use the rust language to implement addition, subtraction, multiplication and division operations:
1#![no_std]
2usecore::panic::PanicInfo;
3
4
5#[no_mangle]
6pubextern"C"fnadd(a:i32,b:i32)->i32{
7a+b
8}
9
10#[no_mangle]
11pubextern"C"fnsubtract(a:i32,b:i32)->i32{
12a-b
13}
14
15#[no_mangle]
16pubextern"C"fnmultiply(a:i32,b:i32)->i32{
17a*b
18}
19
20#[no_mangle]
21pubextern"C"fndivide(a:i32,b:i32)->i32{
22a/b
23}
24
25#[panic_handler]
26fnpanic(_info:&PanicInfo)->!{
27loop{}
28}
2. Generate library files and header files and place them in the application directory
3. Use scons to compile, and an error occurs when linking. The solution is found in the issues of the rust github repository (https://github.com/rust-lang/compiler-builtins/issues/353):
1LINKrtthread.elf
2d:/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):Infunction`__aeabi_ul2d':
3(.text+0x304):multipledefinitionof`__aeabi_ul2d'
4applications\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:firstdefinedhere
5collect2.exe:error:ldreturned1exitstatus
6scons:***[rtthread.elf]Error1
7scons:buildingterminatedbecauseoferrors.
4. Modify rtconfig.py the file and add link parameters --allow-multiple-definition :
1DEVICE='-march=armv7-a-marm-msoft-float'
2CFLAGS=DEVICE+'-Wall'
3AFLAGS='-c'+DEVICE+'-xassembler-with-cpp-D__ASSEMBLY__-I.'
4LINK_SCRIPT='link.lds'
5LFLAGS=DEVICE+'-nostartfiles-Wl,--gc-sections,-Map=rtthread.map,-cref,-u,system_vectors,--allow-multiple-definition'+\
6'-T%s'%LINK_SCRIPT
7
8CPATH=''
9LPATH=''
5. Compile and run qemu:
1LiuKang@DESKTOP-538H6DED:\repo\github\rt-thread\bsp\qemu-vexpress-a9
2$scons-j6
3scons:ReadingSConscriptfiles...
4scons:donereadingSConscriptfiles.
5
6scons:warning:youdonotseemtohavethepywin32extensionsinstalled;
7parallel(-j)buildsmaynotworkreliablywithopenPythonfiles.
8File"D:\software\env_released_1.2.0\env\tools\Python27\Scripts\scons.py",line204,in<module>
9scons:Buildingtargets...
10scons:buildingassociatedVariantDirtargets:build
11LINKrtthread.elf
12arm-none-eabi-objcopy-Obinaryrtthread.elfrtthread.bin
13arm-none-eabi-sizertthread.elf
14textdatabssdechexfilename
15628756214886700717604af324rtthread.elf
16scons:donebuildingtargets.
17
18LiuKang@DESKTOP-538H6DED:\repo\github\rt-thread\bsp\qemu-vexpress-a9
19$qemu.bat
20WARNING:Imageformatwasnotspecifiedfor'sd.bin'andprobingguessedraw.
21Automaticallydetectingtheformatisdangerousforrawimages,writeoperationsonblock0willberestricted.
22Specifythe'raw'formatexplicitlytoremovetherestrictions.
23
24\|/
25-RT-ThreadOperatingSystem
26/|\4.0.4buildJul282021
272006-2021Copyrightbyrt-threadteam
28lwIP-2.1.2initialized!
29[I/sal.skt]SocketAbstractionLayerinitializesuccess.
30[I/SDIO]SDcardcapacity65536KB.
31[I/SDIO]switchingcardtohighspeedfailed!
32callrustsum(1,2)=3
33callrustsubtract(2,1)=1
34callrustmultiply(2,2)=4
35callrustdivide(4,2)=2
Calling C from Rust
Since we can call Rust from C code, we can also call C code from Rust. We call the rt_kprintf function in Rust code:
Modify the lib.rs file
1//导入的rt-thread函数列表
2extern"C"{
3pubfnrt_kprintf(format:*constu8,...);
4}
5
6#[no_mangle]
7pubextern"C"fnadd(a:i32,b:i32)->i32{
8unsafe{
9rt_kprintf(b"thisisfromrust\n\0"as*constu8);
10}
11a+b
12}
Generate library files
1cargobuild--target=armv7a-none-eabi--release--verbose
2Compilingrust_to_cv0.1.0(C:\Users\LiuKang\Desktop\RUST\rust_to_c)
3Running`rustc--crate-namesum--edition=2018src/lib.rs--error-format=json--json=diagnostic-rendered-ansi--crate-typestaticlib--emit=dep-info,link-Copt-level=3-Cembed-bitcode=no-Cmetadata=a
40723fa112c78339-Cextra-filename=-a0723fa112c78339--out-dirC:\Users\LiuKang\Desktop\RUST\rust_to_c\target\armv7a-none-eabi\release\deps--targetarmv7a-none-eabi-Ldependency=C:\Users\LiuKang\Desktop\RUS
5T\rust_to_c\target\armv7a-none-eabi\release\deps-Ldependency=C:\Users\LiuKang\Desktop\RUST\rust_to_c\target\release\deps`
6Finishedrelease[optimized]target(s)in0.11s
run
Copy the library files generated by rust to the application directory.
1LiuKang@DESKTOP-538H6DED:\repo\github\rt-thread\bsp\qemu-vexpress-a9
2$scons-j6
3scons:ReadingSConscriptfiles...
4scons:donereadingSConscriptfiles.
5scons:warning:youdonotseemtohavethepywin32extensionsinstalled;
6parallel(-j)buildsmaynotworkreliablywithopenPythonfiles.
7File"D:\software\env_released_1.2.0\env\tools\Python27\Scripts\scons.py",line204,in<module>
8scons:Buildingtargets...
9scons:buildingassociatedVariantDirtargets:build
10LINKrtthread.elf
11arm-none-eabi-objcopy-Obinaryrtthread.elfrtthread.bin
12arm-none-eabi-sizertthread.elf
13textdatabssdechexfilename
14628812214890796721756b035crtthread.elf
15scons:donebuildingtargets.
16
17LiuKang@DESKTOP-538H6DED:\repo\github\rt-thread\bsp\qemu-vexpress-a9
18$qemu.bat
19WARNING:Imageformatwasnotspecifiedfor'sd.bin'andprobingguessedraw.
20Automaticallydetectingtheformatisdangerousforrawimages,writeoperationsonblock0willberestricted.
21Specifythe'raw'formatexplicitlytoremovetherestrictions.
22
23\|/
24-RT-ThreadOperatingSystem
25/|\4.0.4buildJul282021
262006-2021Copyrightbyrt-threadteam
27lwIP-2.1.2initialized!
28[I/sal.skt]SocketAbstractionLayerinitializesuccess.
29[I/SDIO]SDcardcapacity65536KB.
30[I/SDIO]switchingcardtohighspeedfailed!
31thisisfromrust
32callrustsum(1,2)=3
33callrustsubtract(2,1)=1
34callrustmultiply(2,2)=4
35callrustdivide(4,2)=2
36msh/>
|