631|5

280

帖子

0

TA的资源

一粒金砂(高级)

《Rust实战》3.利用Rust来编写STM32的LED控制代码 [复制链接]

本帖最后由 yangjiaxu 于 2024-7-3 14:31 编辑
大家好,上一篇说道搭建rust的开发环境在Windows上,并且使用vscode来作为辅助开发,《Rust实战》2.环境测试与vscode的环境搭建与应用 https://bbs.eeworld.com.cn/thread-1281652-1-1.html其实那篇还是比较简单的,我当时申请是想利用rust语言来开发STM32,当时想的是rust的优势是内存方面的管理,恰好当时遇到个问题就是关于内存方面的,所以就心血来潮的想利用rust语言试试,说归说,接下来就将rust应用在STM32上。
大家都知道STM32F103属于arm内核,因此需要让rust来支持arm才行,因此,需要安装,
rustup target install thumbv7m-none-eabi

rustup target install thumbv7m-none-eabi 是 Rust 工具链管理器 rustup 的一个命令,用于安装特定的目标(target)。这个目标 thumbv7m-none-eabi 是针对 ARM Cortex-M 系列处理器的,特别是那些支持 Thumb-2 指令集的处理器。

具体来说:
thumbv7m 表示目标架构是 Thumb-2 指令集的 ARMv7-M 架构。
none 表示没有操作系统(bare-metal)。
eabi 表示嵌入式应用程序二进制接口(Embedded Application Binary Interface)。
安装这个目标后,你可以使用 Rust 编译器 rustc 或构建工具 cargo 来编译代码,生成可以在 ARM Cortex-M 系列处理器上运行的二进制文件。这对于开发嵌入式系统、微控制器项目非常有用。
安装完之后需要创建一个工程,可以使用命令行的方式进行创建,如下图所示:
142412nlk480jklqxjz69j.jpg
创建成功之后,需要修改Cargo.toml,这个主要修改的目的是添加一些依赖项,说实话我是不会添加这些,所以本着拿来主义就好。
[dependencies]
embedded-hal = "0.2.7"
nb = "1"
cortex-m = "0.7.6"
cortex-m-rt = "0.7.1"
# Panic behaviour, see https://crates.io/keywords/panic-impl for alternatives
panic-halt = "0.2.0"
[dependencies.stm32f1xx-hal]
version = "0.10.0"
features = ["rt", "stm32f103", "medium"]
接下来需要创建.cargo/config and memory.x,主要是配置编译链和目标芯片的存储方面的信息。
接下来就可以进行程序编写了,在上文创建好的main.rs中,将以下代码复制进去:
//! Blinks an LED
//!
//! This assumes that a LED is connected to pc13 as is the case on the blue pill board.
//!
//! Note: Without additional hardware, PC13 should not be used to drive an LED, see page 5.1.2 of
//! the reference manual for an explanation. This is not an issue on the blue pill.
#![deny(unsafe_code)]
#![no_std]
#![no_main]
use panic_halt as _;
use nb::block;
use cortex_m_rt::entry;
use stm32f1::stm32f103::gpioa;
use stm32f1xx_hal::{pac, prelude::*, timer::Timer};
#[entry]
fn main() -> ! {
// Get access to the core peripherals from the cortex-m crate
let cp = cortex_m::Peripherals::take().unwrap();
// Get access to the device specific peripherals from the peripheral access crate
let dp = pac::Peripherals::take().unwrap();
// Take ownership over the raw flash and rcc devices and convert them into the corresponding
// HAL structs
let mut flash = dp.FLASH.constrain();
let rcc = dp.RCC.constrain();
// Freeze the configuration of all the clocks in the system and store the frozen frequencies in
// `clocks`
let clocks = rcc.cfgr.freeze(&mut flash.acr);
// Acquire the GPIOC peripheral
let mut gpioa = dp.GPIOA.split();
// Configure gpio C pin 13 as a push-pull output. The `crh` register is passed to the function
// in order to configure the port. For pins 0-7, crl should be passed instead.
let mut led = gpioa.pa8.into_push_pull_output(&mut gpioa.crh);
// Configure the syst timer to trigger an update every second
let mut timer = Timer::syst(cp.SYST, &clocks).counter_hz();
timer.start(1.Hz()).unwrap();
// Wait for the timer to trigger an update and change the state of the LED
loop {
block!(timer.wait()).unwrap();
led.set_high();
block!(timer.wait()).unwrap();
led.set_low();
}
}

 

这段代码是一个嵌入式 Rust 程序,用于在 STM32F1 微控制器上闪烁连接到 PA8 引脚的 LED。由于担心很多人可能会看不懂,逐行进行了代码解释,解释如下:
#![deny(unsafe_code)]:禁止使用 unsafe 代码。
#![no_std]:不使用标准库 std,而是使用嵌入式系统常用的 core 库。
#![no_main]:不使用标准的 main 函数入口,而是使用嵌入式系统常用的入口点。
use panic_halt as _;:导入 panic_halt 库,用于处理 panic 情况。
use nb::block;:导入 nb 库的 block 模块,用于阻塞等待操作。
use cortex_m_rt::entry;:导入 cortex_m_rt 库的 entry 宏,用于定义程序入口点。
use stm32f1xx_hal::{pac, prelude::*, timer::Timer};:导入 stm32f1xx_hal 库的相关模块。
#[entry]:定义程序的入口点。
fn main() -> !:定义一个无限循环的 main 函数。
let cp = cortex_m::Peripherals::take().unwrap();:获取 Cortex-M 内核的外设。
let dp = pac::Peripherals::take().unwrap();:获取 STM32F1 设备的外设。
let mut flash = dp.FLASH.constrain();:获取并约束 Flash 外设。
let rcc = dp.RCC.constrain();:获取并约束 RCC(复位和时钟控制)外设。
let clocks = rcc.cfgr.freeze(&mut flash.acr);:冻结时钟配置并获取时钟频率。
let mut gpioa = dp.GPIOA.split();:获取 GPIOA 外设。
let mut led = gpioc.pa8.into_push_pull_output(&mut gpioa.crh);:配置 PA8 引脚为推挽输出模式。
let mut timer = Timer::syst(cp.SYST, &clocks).counter_hz();:配置系统定时器。
timer.start(1.Hz()).unwrap();:启动定时器,设置定时器触发频率为 1 Hz。
loop { block!(timer.wait()).unwrap(); led.set_high(); block!(timer.wait()).unwrap(); led.set_low(); }:无限循环,等待定时器触发,切换 LED 状态。
这段代码通过配置 GPIO 和定时器,实现了在 STM32F1 微控制器上闪烁连接到 PA8 引脚的 LED。
当代码编辑好了之后,需要进行编译了
cargo build --features stm32f103 --example blinky

我是直接在例程的基础上进行的,所以当时名字没有修改,是blinky,在example文件夹下的blinky进行编译,编译好之后,会生成blinky文件,这个文件是不可执行文件,需要将其转换为bin可烧录的二进制文件,需要下面的命令:

rust-objcopy -O binary target/thumbv7m-none-eabi/debug/examples/blinky blinky.bin

这个命令具体来说是这样的:

rust-objcopy 是一个工具,通常是 llvm-objcopy 或 objcopy 的别名,用于处理对象文件(object files)。
-O binary 表示输出格式为二进制(binary)格式。
target/thumbv7m-none-eabi/debug/examples/blinky 是输入的 ELF 文件路径,这是 Rust 编译生成的可执行文件。
blinky.bin 是输出的二进制文件路径,这个文件可以直接烧录到目标硬件上。
这个命令的作用是将 Rust 编译生成的 ELF 文件 blinky 转换为二进制文件 blinky.bin,以便于将其烧录到 ARM Cortex-M 系列的微控制器中运行。
在嵌入式开发中,通常需要将编译生成的 ELF 文件转换为二进制文件,因为微控制器通常需要的是二进制格式的可执行文件,而不是 ELF 格式的文件。
当执行这个命令之后,就会生成一个bin文件
142412gjjvb372bbswwvkq.png
将该bin文件,地址是0x08000000,烧录到目标芯片即可。工作效果如下图所示。
142412y08fhoszzne8z11l.jpg
至此,利用rust进行编写LED控制代码来让STM32F103执行就完成了,这系列的操作流程有几个难点:
第一就是针对Cargo.toml的编辑,主要是有那些依赖项,添加什么内容是比较难摸索的,需要有参考才可以。
第二是创建.cargo/config and memory.x,这个说实话可以找个好用的例程直接复制过来,但是如果找不到例程就需要自己来写了,网上可以找到,比如memory.x
142412hl29ytmampmtbcap.png
接下来就是工具的问题,比如我第一次操作的时候,发现没安装rust-objcopy,导致找不到其命令,还有就是GCC编译链没安装,导致程序编译出错,不过通过对应的提示可以知道怎么操作,这个还算是简单一些。
最后就是针对GCC调试,这个我暂时还没实现,因为使用rust进行调试我还是不太习惯,而且调试感觉没有keil或者IAR这种单步调试来得直观。
总结:就是不是很建议使用rust开发STM32,哈哈,真的很麻烦,如果不熟悉的话,确实不是一个很适合的语言,不如C来的痛快,不过这两种语言和有优势,如果将rust用在网络/后台开发方面,应该更加方便和强大。
此帖出自编程基础论坛

最新回复

多谢指导,我感觉我还是先学好C先。   详情 回复 发表于 2024-7-4 11:21

回复
举报

6758

帖子

9

TA的资源

版主

我搞了几天没有搞定,然后就没有然后了。。。
此帖出自编程基础论坛

点评

哈哈哈 感觉很麻烦,尤其是配置环境的时候真的懵  详情 回复 发表于 2024-7-3 21:34

回复

280

帖子

0

TA的资源

一粒金砂(高级)

lugl4313820 发表于 2024-7-3 18:15 我搞了几天没有搞定,然后就没有然后了。。。

哈哈哈 感觉很麻烦,尤其是配置环境的时候真的懵

此帖出自编程基础论坛

点评

大佬什么时候带带我搞定开发环境呀。开发环境这临门一脚有点难呀。  详情 回复 发表于 2024-7-4 07:44

回复

6758

帖子

9

TA的资源

版主

yangjiaxu 发表于 2024-7-3 21:34 哈哈哈 感觉很麻烦,尤其是配置环境的时候真的懵

大佬什么时候带带我搞定开发环境呀。开发环境这临门一脚有点难呀。

此帖出自编程基础论坛

点评

这个环境倒是简单一些,就是先改变源,改成国内的源,不然需要等很久,这个网上讲安装rust的时候就有,其实就是改变环境变量,添加我们需要配置环境变量 RUSTUP_DIST_SERVER(默认指向 https://static.rus  详情 回复 发表于 2024-7-4 09:49

回复

280

帖子

0

TA的资源

一粒金砂(高级)

lugl4313820 发表于 2024-7-4 07:44 大佬什么时候带带我搞定开发环境呀。开发环境这临门一脚有点难呀。

这个环境倒是简单一些,就是先改变源,改成国内的源,不然需要等很久,这个网上讲安装rust的时候就有,其实就是改变环境变量,添加我们需要配置环境变量 RUSTUP_DIST_SERVER(默认指向 https://static.rust-lang.org)和 RUSTUP_UPDATE_ROOT (默认指向https://static.rust-lang.org/rustup),让其指向国内源,参考链接https://zhuanlan.zhihu.com/p/655386777。然后是安装一些必要的工具,举例说我用到文件转换rust-objcopy工具,自己安装一下就好了,命令是:cargo install rust-objcopy,跟Linux安装软件一样;最后就是找到一个靠谱且好用的rust的例程,因为刚开始cargo.toml这种都不会写的。不知道加哪个不加哪个。推荐看看这个例程,真的很全,https://github.com/stm32-rs/stm32f1xx-hal?tab=readme-ov-file 根据例程自己摸索如何搞嵌入式开发就好了。不过这种就是图一新鲜,我觉得rust做嵌入式开发还是不方便,还是按照作者的想法,做一些后端服务器之类的开发吧

此帖出自编程基础论坛

点评

多谢指导,我感觉我还是先学好C先。  详情 回复 发表于 2024-7-4 11:21

回复

6758

帖子

9

TA的资源

版主

yangjiaxu 发表于 2024-7-4 09:49 这个环境倒是简单一些,就是先改变源,改成国内的源,不然需要等很久,这个网上讲安装rust的时候就有, ...

多谢指导,我感觉我还是先学好C先。

此帖出自编程基础论坛

回复
您需要登录后才可以回帖 登录 | 注册

猜你喜欢
随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
推荐帖子
谁可以仔细讲一讲51单片机复位电路的工作原理 ?

谁可以仔细讲一讲51单片机复位电路的工作原理 ?

开关稳压电源(2007电子设计竞赛 E题)(内附论文和PCB图)

本帖最后由 paulhyde 于 2014-9-15 03:28 编辑 这是我去年作的,还请多多指教~!

MATLAB课件 初级篇

目 录 就算了,由于都是doc文档,压缩可以节省很多空间!第一次上传没有成功,所以来编辑一下啦1 下载回复,可以派送芯币 ...

飞思卡尔智能汽车比赛

本来是要参加明天的飞思卡尔智能汽车比赛的,前段时间被老师叫去帮他完成一些东西,就退出来了。下面是一些飞思卡尔的资料,或许 ...

【TI电池管理】BQ24610充电对比测试

先上图:243718243719 BQ24610是具有 5V–28V VCC 输入的独立同步开关模式锂离子或锂聚合物电池充电器,最大输入支持6串28 ...

窄带物联网(NB-IoT)发展历程标准特性

一、发展历程 物联网通信技术繁多,从传输距离上可划分成两类:第一类是短距离通信技术,例如ZigBee、Wi-Fi、Bluetooth等,典型 ...

TI DSP 28335编程实例

首先说明:开发环境Manjaro linux,内核5.0,滚动升级版本,随时都是最新,CCS也是最新的CCv 8 复制代码 1 #include "DSP2 ...

相位噪声基础及测试原理和方法 做频率源 (LO)

相位噪声指标对于当前的射频微波系统、移动通信系统、雷达系统等电子系统影响非常明显,将直接影响系统指标的优劣。该项指标对于 ...

颁奖:瓜分2000元新年开工红包!贸泽电子邀你元宵猜灯谜

贸泽表情包活动颁奖啦!可参与瓜分红包的openid名单详见下方列表。 特别注意: 将于3月21日下午直接通过微信向您发送红包 ...

【极海APM32F407 Tiny Board】开箱评测:THREADX & 串口

感谢极海和电子工程世界论坛提供的评测机会。 板子用电子物料盒包装,看上去很精致。本评估板引出了两个比较有特色的外设,一个 ...

关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表