0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

为什么要用Rust进行嵌入式开发

strongerHuang 来源:RTThread 作者:liukang 2021-11-06 10:04 次阅读

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]
 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 文件中添加以下代码,生成静态库文件:

1[lib]
2name="sum"
3crate-type=["staticlib"]
4path="src/lib.rs"

交叉编译

1、安装 armv7 target:

1rustuptargetaddarmv7a-none-eabi

2、生成静态库文件:

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、在项目文件夹下新建文件cbindgen.toml文件:

3、生成头文件:

1cbindgen--configcbindgen.toml--craterust_to_c--outputsum.h

调用 Rust 库文件

1、将生成的sum.h以及sum.a文件放入rt-threadspqemu-vexpress-a9applications目录下

2、修改 SConscript 文件,添加静态库:

 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 函数中调用 sum 函数, 并获取返回值

 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 环境下,使用 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 语言实现加减乘除运算:

 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 编译,链接时报错,在 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文件, 添加链接参数--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、编译并运行 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 调用 C

可以 在 C 代码中调用 Rust,那么在 Rust 中也可以调用 C 代码。我们在 Rust 代码中调用 rt_kprintf 函数:

修改 lib.rs 文件

 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
"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

运行

复制 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

责任编辑:haq
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 嵌入式
    +关注

    关注

    5068

    文章

    19013

    浏览量

    303128
  • Rust
    +关注

    关注

    1

    文章

    228

    浏览量

    6568

原文标题:手把手教你用 Rust 开发嵌入式

文章出处:【微信号:strongerHuang,微信公众号:strongerHuang】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    一文了解嵌入式软件开发的对象

    以前应用场景很单一,嵌入式开发可能谈不上面向对象开发。但现在,做嵌入式开发,没有面向对象开发,你就有点落伍了。 本文结合个人经验和周立功《抽象接口技术和组件
    的头像 发表于 11-15 10:31 235次阅读
    一文了解<b class='flag-5'>嵌入式</b>软件<b class='flag-5'>开发</b>的对象

    零基础嵌入式开发学习路线

    嵌入式开发”没有接触过的同学可能会不明觉厉,但是只要你了解了,感兴趣并且有一个正确的学习路线的话,零基础也能入门。给大家介绍一个简单易懂的学习路线,让你能够从零开始学习嵌入式开发。 第一步:掌握
    发表于 10-25 15:55

    嵌入式开发常见问题排查

    嵌入式开发问题排查很多人认为嵌入式开发很难,主要是因为在这个过程中常常会遇到各式各样的问题。这些问题的复杂性和多样性使得许多人感到困惑和无所适从。然而,如果将这些问题逐一拆解,实际上大部分都可以
    的头像 发表于 09-22 08:04 263次阅读
    <b class='flag-5'>嵌入式开发</b>常见问题排查

    聚焦嵌入式开发中的合规性工具、项目管理工具、版本迭代工具应用

    日前,龙智携嵌入式开发及管理解决方案亮相2024上海国际嵌入式展(embedded world China 2024)。展会期间,我们对话了多位龙智资深DevSecOps顾问及技术支持专家
    的头像 发表于 07-29 15:15 470次阅读

    嵌入式开发前景怎么样?

    嵌入式开发前景非常广阔,这主要得益于物联网、人工智能、大数据等技术的快速发展,以及嵌入式系统在各个领域的广泛应用。以下是对嵌入式开发前景的详细分析
    的头像 发表于 07-10 09:00 2490次阅读
    <b class='flag-5'>嵌入式开发</b>前景怎么样?

    嵌入式开发者的未来

    嵌入式系统的就业方向非常广泛,涵盖了许多不同的行业和领域。以下是一些常见的嵌入式系统就业方向:消费电子产品:这包括智能手机、平板电脑、智能电视、智能家居设备等。嵌入式系统工程师可以参与设计、
    的头像 发表于 06-23 08:10 327次阅读
    <b class='flag-5'>嵌入式开发</b>者的未来

    嵌入式开发就业前景怎么样?

    和医疗器械使用经验。 3)工业控制 工业控制是指通过各种控制设备和系统,对工业生产过程进行监测、控制和优化。随着工业自动化和智能化的发展,工业控制领域对嵌入式开发的需求也在不断增加。在工业控制领域
    发表于 06-07 14:51

    ARM Cortex-A53嵌入式开发平台Android手册

    电子发烧友网站提供《ARM Cortex-A53嵌入式开发平台Android手册.pdf》资料免费下载
    发表于 04-28 15:10 0次下载

    fpga是嵌入式开发

    FPGA(现场可编程门阵列)与嵌入式开发之间确实存在一定的关联,但它们在本质上是两个不同的领域。
    的头像 发表于 03-15 14:18 977次阅读

    基于Rust嵌入式符合ACID的键值数据库

    surrealkv -- 基于 Rust 的 low level、版本化、嵌入式、符合 ACID 的键值数据库
    的头像 发表于 12-28 11:29 857次阅读

    嵌入式开发常见的C语言技巧与方法分享

    嵌入式开发中,常常要操作寄存器,对寄存器进行写入,读出等等操作。每个寄存器都有自己固有的地址,通过C语言访问这些地址就变得尤为重要。
    的头像 发表于 12-26 09:55 1055次阅读

    嵌入式开发学习的十三法则分享

    嵌入式开发学习是一个不断积累和总结的过程,来自一个嵌入式开发高级工程师为我们总结的关于嵌入式开发学习的十三法则,大家不妨参考一下: 一、冗余度法则 在嵌入式系统具有足够的冗余度
    发表于 12-21 06:32

    嵌入式开发中的交叉编译详解

    嵌入式开发中,经常会遇到目标平台资源贫乏,无法运行需要的编译器。亦或是目标平台上不允许或不能够安装需要的编译器。这时候就需要使用交叉编译了。
    的头像 发表于 12-01 13:24 1148次阅读
    <b class='flag-5'>嵌入式开发</b>中的交叉编译详解

    嵌入式开发为什么需要输出调试信息?

    嵌入式开发为什么需要输出调试信息? 因为输出调试信息是嵌入式开发中一项非常重要的实践,它有助于保证软件的可靠性、稳定性和性能,也是故障排查的关键工具之一。 嵌入式开发输出调试信息主要有以下
    发表于 11-28 16:46

    嵌入式开发测试秘诀

    。 多年前,一位工程师为了对嵌入式拥有更深层次理解的追求,曾发出这样的疑问:“我怎么才能知道并懂得我的系统到底在干些什么呢?”。同时代的嵌入式开发人员问得最多的问题大都围绕“我怎么才能使程序跑得更快”、“什么编译器最
    的头像 发表于 11-24 16:18 507次阅读