Rust 是什么
Rust 是一門賦予每個(gè)人構(gòu)建可靠且高效軟件能力的語言。
-
高性能:速度驚人且內(nèi)存利用率極高
-
可靠性:在編譯期就能消除各種內(nèi)存錯(cuò)誤
-
生產(chǎn)力:出色的文檔,友好的編譯器和清晰的錯(cuò)誤提示信息
為什么要用 Rust 進(jìn)行嵌入式開發(fā)
Rust 的設(shè)計(jì)理念:既要安全,也要高性能。Rust 的設(shè)計(jì)理念完全是嵌入式開發(fā)所需要的。
嵌入式軟件在運(yùn)行過程中出現(xiàn)問題,大部分是由于內(nèi)存引起的。Rust 語言可以說是一門面向編譯器的語言。在編譯期間,就能夠確保你安全地使用內(nèi)存。
目前,嵌入式的主流開發(fā)語言還是 C 語言,不能上來就把底層的邏輯用 Rust 重新實(shí)現(xiàn)一遍。但是可以在 C 代碼中嵌入 Rust 語言。
C 調(diào)用 Rust
在 C 代碼中調(diào)用 Rust 代碼,需要我們將 Rust 源代碼打包為靜態(tài)庫文件。在 C 代碼編譯時(shí),鏈接進(jìn)去。
創(chuàng)建 lib 庫
1、在 Clion 中使用cargo init --lib rust_to_c
建立 lib 庫。添加以下代碼到 lib.rs 中,使用 Rust 語言計(jì)算兩個(gè)整數(shù)的和:
1#![no_std]
2usecore::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}
在 Cargo.toml 文件中添加以下代碼,生成靜態(tài)庫文件:
1[lib]
2name="sum"
3crate-type=["staticlib"]
4path="src/lib.rs"
交叉編譯
1、安裝 armv7 target:
1rustuptargetaddarmv7a-none-eabi
2、生成靜態(tài)庫文件:
1PSC:UsersLiuKangDesktopRUST
ust_to_c>cargobuild--target=armv7a-none-eabi--release--verbose
2Freshrust_to_cv0.1.0(C:UsersLiuKangDesktopRUST
ust_to_c)
3Finishedrelease[optimized]target(s)in0.01s
生成頭文件
1、安裝cbindgen](https://github.com/eqrion/cbindgen)),cbindgen從 rust 庫生成 C/C++ 11 頭文件:
1cargoinstall--forcecbindgen
2、在項(xiàng)目文件夾下新建文件cbindgen.toml
文件:
3、生成頭文件:
1cbindgen--configcbindgen.toml--craterust_to_c--outputsum.h
調(diào)用 Rust 庫文件
1、將生成的sum.h
以及sum.a
文件放入rt-threadspqemu-vexpress-a9applications
目錄下
2、修改 SConscript 文件,添加靜態(tài)庫:
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、在 main 函數(shù)中調(diào)用 sum 函數(shù), 并獲取返回值
1#include
2#include
3#include
4#include
5#include"sum.h"
6
7intmain(void)
8{
9int32_ttmp;
10
11tmp=sum(1,2);
12printf("callrustsum(1,2)=%d
",tmp);
13
14return0;
15}
4、在 env 環(huán)境下,使用 scons 編譯工程:
1LiuKang@DESKTOP-538H6DED:
epogithub
t-threadspqemu-vexpress-a9
2$scons-j6
3scons:ReadingSConscriptfiles...
4scons:donereadingSConscriptfiles.
5
6scons:warning:youdonotseemtohavethepywin32extensionsinstalled;
7parallel(-j)buildsmaynotworkreliablywithopenPythonfiles.
8File"D:softwareenv_released_1.2.0env oolsPython27Scriptsscons.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:
epogithub
t-threadspqemu-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/>
加減乘除
1、在 lib.rs 文件中,使用 rust 語言實(shí)現(xiàn)加減乘除運(yùn)算:
1#![no_std]
2usecore::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、生成庫文件和頭文件并放在 application 目錄下
3、使用 scons 編譯,鏈接時(shí)報(bào)錯(cuò),在 rust github 倉庫的 issues 中找到了解決辦法(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/thumblibgcc.a(_arm_addsubdf3.o):Infunction`__aeabi_ul2d':
3(.text+0x304):multipledefinitionof`__aeabi_ul2d'
4applicationslibsum.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、修改rtconfig.py
文件, 添加鏈接參數(shù)--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、編譯并運(yùn)行 qemu:
1LiuKang@DESKTOP-538H6DED:
epogithub
t-threadspqemu-vexpress-a9
2$scons-j6
3scons:ReadingSConscriptfiles...
4scons:donereadingSConscriptfiles.
5
6scons:warning:youdonotseemtohavethepywin32extensionsinstalled;
7parallel(-j)buildsmaynotworkreliablywithopenPythonfiles.
8File"D:softwareenv_released_1.2.0env oolsPython27Scriptsscons.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:
epogithub
t-threadspqemu-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
Rust 調(diào)用 C
可以 在 C 代碼中調(diào)用 Rust,那么在 Rust 中也可以調(diào)用 C 代碼。我們?cè)?Rust 代碼中調(diào)用 rt_kprintf 函數(shù):
修改 lib.rs 文件
1//導(dǎo)入的rt-thread函數(shù)列表
2extern"C"{
3pubfnrt_kprintf(format:*constu8,...);
4}
5
6#[no_mangle]
7pubextern"C"fnadd(a:i32,b:i32)->i32{
8unsafe{
9rt_kprintf(b"thisisfromrust
"as*constu8);
10}
11a+b
12}
生成庫文件
1cargobuild--target=armv7a-none-eabi--release--verbose
2Compilingrust_to_cv0.1.0(C:UsersLiuKangDesktopRUST
ust_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:UsersLiuKangDesktopRUST
ust_to_c argetarmv7a-none-eabi
eleasedeps--targetarmv7a-none-eabi-Ldependency=C:UsersLiuKangDesktopRUS
5T
ust_to_c argetarmv7a-none-eabi
eleasedeps-Ldependency=C:UsersLiuKangDesktopRUST
ust_to_c arget
eleasedeps`
6Finishedrelease[optimized]target(s)in0.11s
運(yùn)行
復(fù)制 rust 生成的庫文件到 application 目錄下。
1LiuKang@DESKTOP-538H6DED:
epogithub
t-threadspqemu-vexpress-a9
2$scons-j6
3scons:ReadingSConscriptfiles...
4scons:donereadingSConscriptfiles.
5scons:warning:youdonotseemtohavethepywin32extensionsinstalled;
6parallel(-j)buildsmaynotworkreliablywithopenPythonfiles.
7File"D:softwareenv_released_1.2.0env oolsPython27Scriptsscons.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:
epogithub
t-threadspqemu-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/>
來源:
https://club.rt-thread.org/ask/article/2944.html
-
嵌入式
+關(guān)注
關(guān)注
5082文章
19104瀏覽量
304807 -
Rust
+關(guān)注
關(guān)注
1文章
228瀏覽量
6601
原文標(biāo)題:手把手教你用 Rust 開發(fā)嵌入式
文章出處:【微信號(hào):strongerHuang,微信公眾號(hào):strongerHuang】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論