Rust的高性能、可靠性和生产力使其适用于嵌入式系统。在过去的几年里,Rust在程序员中获得了狂热的追随者。技术潮流来来去去,因此很难将对新技术的兴奋与其优点的兴奋区分开来,但我认为Rust是一种设计精良的语言。它的目标是帮助开发人员构建可靠、高效的软件,它从一开始就是为此目的而设计的。您可能听说过Rust的一些关键特性,在这篇文章中,我将证明这些正是Rust也适合嵌入式系统的原因。例如:高性能:速度快且内存效率高可靠性:消除编译期间的内存错误生产力:出色的文档、友好的编译器、有用的错误消息和一流的工具。它有一个集成的包管理器和构建工具、智能多编辑器支持自动完成和类型检查、自动格式化等。为什么使用Rust进行嵌入式开发?Rust被设计为安全和高性能。嵌入式软件问题主要是内存问题。在某种程度上,Rust是一种面向编译器的语言,因此您可以确保在编译时安全地使用内存。以下是使用Rust在嵌入式设备上进行开发的一些好处:强大的静态分析灵活的内存无畏的并发性互操作性可移植性社区驱动在本文中,我使用开源的RT-Thread操作系统来演示如何使用Rust进行嵌入式开发。如何从C调用Rust从C代码调用Rust代码时,必须将Rust源代码打包为静态库文件。C代码在编译的时候,是链接进来的。用Rust创建静态库的过程有两个步骤:1.在Clion中使用cargoinit--librust_to_c来构建一个lib库。将以下代码添加到lib.rs。下面的函数计算两个i32类型值的和并返回结果:#![no_std]usecore::panic::PanicInfo;#[no_mangle]pubextern"C"fnsum(a:i32,b:i32)->i32{a+b}#[panic_handler]fnpanic(_info:&PanicInfo)->!{loop{}}2.将以下代码添加到您的Cargo.toml文件中,以告诉Rustc生成什么类型??的库:[lib]name="sum"crate-type=["staticlib"]path="src/lib.rs"交叉编译你可以为你的目标平台交叉编译。假设你的嵌入式系统基于Arm,步骤很简单:$rustuptargetaddarmv7a-none-eabi生成静态库文件:$cargobuild--target=armv7a-none-eabi--release--verboseFreshrust_to_cv0.1.0在0.01秒内完成发布[优化]目标生成头文件您还需要头文件:1.安装cbindgen。cbindgen工具将从Rust库生成一个C或C++11头文件:$cargoinstall--forcecbindgen2,在你的项目文件夹中创建一个新的cbindgen.toml文件。3.生成一个头文件:$cbindgen--configcbindgen.toml--craterust_to_c--outputsum.h调用Rust库文件现在你可以调用你的Rust库了。1.将生成的sum.h和sum.a文件放在rt-thread/bsp/qemu-vexpress-a9/applications目录下。2、修改SConscript文件,添加静态库:frombuildingimport*cwd=GetCurrentDir()src=Glob('*.c')+Glob('*.cpp')CPPPATH=[cwd]LIBS=["libsum.a"]LIBPATH=[GetCurrentDir()]group=DefineGroup('Applications',src,depend=[''],CPPPATH=CPPPATH,LIBS=LIBS,LIBPATH=LIBPATH)Return('group')3.在main函数调用sum函数,获取返回值,并将值printf:#include#include#include#includeh"intmain(void){int32_ttmp;tmp=sum(1,2);printf("调用rustsum(1,2)=%d\n",tmp);返回0;}4.在RT-ThreadEnv环境下,使用scons编译工程,运行:$scons-j6scons:ReadingSConscriptfiles...scons:donereadingSConscriptfiles。scons:构建目标...[...]scons:完成构建目标。$qemu.sh\|/-RT-线程操作系统/|\4.0.4构建20212006年7月28日-2021年版权归rt-threadteamlwIP-2.1.2已初始化![。..]callrustsum(1,2)=3加减乘除你可以在Rust中实现一些复杂的数学运算在lib.rs文件中,使用Rust语言实现加减乘除:#![no_std]usecore::panic::PanicInfo;#[no_mangle]pubextern"C"fnadd(a:i32,b:i32)->i32{a+b}#[no_mangle]pubextern"C"fnsubtract(a:i32,b:i32)->i32{a-b}#[no_mangle]pubextern"C"fnmultiply(a:i32,b:i32)->i32{a*b}#[no_mangle]pubextern"C"fndivide(a:i32,b:i32)->i32{a/b}#[panic_handler]fnpanic(_info:&PanicInfo)->!{loop{}}构建你的库文件和头文件并将它们放在应用程序目录中。使用scons编译。如果在链接过程中出现错误,请在官方Github页面中查找解决方案。修改rtconfig.py文件,添加链接参数--allow-multiple-definition:DEVICE='-march=armv7-a-marm-msoft-float'CFLAGS=DEVICE+'-Wall'AFLAGS='-c'+设备+'-xassembler-with-cpp-D__ASSEMBLY__-I.'LINK_SCRIPT='link.lds'LFLAGS=DEVICE+'-nostartfiles-Wl,--gc-sections,-Map=rtthread.map,-cref,-u,system_vectors,--allow-multiple-definition'+\'-T%s'%LINK_SCRIPTCPATH=''LPATH=''编译并运行QEMU以查看您的工作。从Rust调用CRust可以从C代码调用,但是如何从Rust代码调用C?下面是在Rust代码中调用rt_kprintfC函数的示例。首先,修改lib.rs文件://Theimportedrt-threadfunctionslistextern"C"{pubfnrt_kprintf(format:*constu8,...);}#[no_mangle]pubextern"C"fnadd(a:i32,b:i32)->i32{unsafe{rt_kprintf(b"thisisfromrust\n"as*constu8);}a+b}接下来,生成库文件:$cargobuild--target=armv7a-none-eabi--release--verboseCompilingrust_to_cv0.1.0Running`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=aFinishedrelease[optimized]target(s)in0.11s现在,要运行代码,将Rust生成的库文件复制到应用程序目录中,然后重建:$scons-j6scons:ReadingSConscriptfiles...scons:读完SConscript文件。[...]scons:构建目标...scons:完成构建目标。再次运行QEMU并在嵌入的图像中查看结果。您可以拥有一切在嵌入式开发中使用Rust,您可以在不牺牲灵活性或稳定性的情况下获得Rust的所有功能。今天就在您的嵌入式系统上试试Rust。有关嵌入Rust(和RT-Thread本身)过程的更多信息,请查看RT-Thread项目的YouTube频道。请记住,嵌入式也可以是开放的。