Rust嵌入stm32的C工程
Rust具有良好的C语言互操作性,A little Rust with your C中介绍了如何将Rust代码嵌入C工程中。
简言之你需要将Rust的类型转为C的类型,然后生成库和头文件,在C工程中引入使用。
但是在单片机中需要静态编译于是需要
crate-type = ["staticlib"]
这里使用cargo命令创建一个简单的lib
cargo new lib_demo --lib
cd lib_demo
然后在Cargo.toml中添加
[lib]
name = "lib_demo"
crate-type = ["staticlib"]
添加一个简单的加减乘除运算
#![allow(unused)] #![no_std] fn main() { /// 加法运算 /// 提供panic处理函数,在no_std环境下 #[panic_handler] fn panic(_info: &core::panic::PanicInfo) -> ! { loop {} } #[no_mangle] pub extern "C" fn add(a: i32, b: i32) -> i32 { a + b } /// 减法运算 #[no_mangle] pub extern "C" fn subtract(a: i32, b: i32) -> i32 { a - b } /// 乘法运算 #[no_mangle] pub extern "C" fn multiply(a: i32, b: i32) -> i32 { a * b } /// 除法运算(返回安全的结果,除以零时返回预设的安全结果0) #[no_mangle] pub extern "C" fn divide(a: i32, b: i32) -> i32 { if b == 0 { 0 // 防止除以零错误 } else { a / b } } /// 浮点数除法 #[no_mangle] pub extern "C" fn divide_float(a: f64, b: f64) -> f64 { if b == 0.0 { 0.0 // 防止除以零错误 } else { a / b } } }
然后编写一个调用的头文件
#ifndef LIB_DEMO_H
#define LIB_DEMO_H
#ifdef __cplusplus
extern "C" {
#endif
// 整数运算
int add(int a, int b);
int subtract(int a, int b);
int multiply(int a, int b);
int divide(int a, int b);
// 浮点运算
double divide_float(double a, double b);
#ifdef __cplusplus
}
#endif
#endif // LIB_DEMO_H
至此就可以用c语言调用写的库了,推荐补充阅读ffi
STM32CubeIDE中嵌入
stm32CubeIDE是st官方提供的开发环境,这里以cubeide的工程为例来介绍 STM32CubeIDE的入门可以参考STM32CubeIDE快速入门指南
我们首先打开cubeide,选择新建一个工程
输入我们使用的芯片stm32g8u6并选择
输入工程名称并点击finish即可完成创建
这个简单示例我们用USART输出结果所以只用初始化USART2
左侧选择USART2将mode配置为Asynchronous模式,即可自动配置引脚
然后CTRL+S保存,CubeIDE会自动生成代码
main.c中添加以下代码用以支持printf
#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif
PUTCHAR_PROTOTYPE
{
HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1,HAL_MAX_DELAY);
return ch;
}
Project/Properties/C/C++ Build/Settings/Tool Settings中添加浮点数printf支持
至此一个stm32C的模板完成,添加lib_demo库 首先编译lib_demo
cargo build --release --target thumbv6m-none-eabi
找到lib_demo.a文件,将他和lib_demo.h文件添加到STM32CubeIDE工程的Src和Inc目录下
在CUBEIDE中右键刷新即可看到添加的文件
最后需要在工程中添加这个库
在Project/Properties中选择并添加库
在main.c中添加
#include "lib_demo.h"
...
int main(void)
{
...
/* USER CODE BEGIN 2 */
int a = 10, b = 5;
printf("整数运算:\n");
printf("%d + %d = %d\n", a, b, add(a, b));
printf("%d - %d = %d\n", a, b, subtract(a, b));
printf("%d * %d = %d\n", a, b, multiply(a, b));
printf("%d / %d = %d\n", a, b, divide(a, b));
// 测试除以零
printf("%d / %d = %d (除以零保护)\n", a, 0, divide(a, 0));
// 测试浮点除法
double x = 10.5, y = 2.5;
printf("\n浮点运算:\n");
printf("%.2f / %.2f = %.2f\n", x, y, divide_float(x, y));
printf("%.2f / %.2f = %.2f (除以零保护)\n", x, 0.0, divide_float(x, 0.0));
/* USER CODE END 2 */
...
}
点击调试并运行即可在串口助手中看到输出
至此完成了在stm32C语言工程中嵌入Rust库
小结
这里只是用一个最简单的例子举例,实际应用中可以将复杂且需要安全性保证的逻辑用Rust实现,然后嵌入到C工程中。 比如一些协议编解码,计算等等