rust-hal库嵌入式开发

linux下用rust优雅地开发stm32

用rust开发嵌入式的特点

优势:

  • ​ 社区驱动
  • ​ 高性能高效率
  • ​ 跨平台

劣势:

  • ​ rust难学
  • ​ 文档全英文
  • ​ 国内用rust开发嵌入式的人少,问题需要自己解决

硬件需求

  • 最起码需要有st-linkv2+的下载器
  • 一块stm32f1xx的最小系统开发板

搭建开发stm32开发环境

linux下(我用的Deepin 20.7):

rust工具链

下载rust 上rust语言官网,我就不多说了

添加编译目标

$rustup target add thumbv7m-none-eabi

openocd

类似一个烧写代码的开源软件

$sudo apt install openocd

arm gdb

代码调试器

Ubuntu 18.04/Debian stretch 或更高的版本.

$sudo apt install gdb-multiarch

其他版本的linux,下载gdb-arm-none-eabi

cargo-binutils

检查工具集,包括objdump, nm 和size

$cargo install cargo-binutils
$rustup component add llvm-tools-preview

基本流程

创建一个工程

$mkdir stm32f103
$cd stm32f103
$cargo init

工程中有 build.rs ,Cargo.toml,src ,没有其他的文件或者文件夹,也没有隐藏文件。

之后我们要添加一些东西在这个项目中。

在Cargo.toml中添加依赖

[dependencies]                     
embedded-hal = "0.2.3"             
nb = "0.1.2"                       
cortex-m = "0.6.2"                 
cortex-m-rt = "0.7.1"                 
panic-halt = "0.2.0"               
cortex-m-semihosting = "0.5.0"     
[dependencies.stm32f1xx-hal]       
version = "0.9.0"                  
features = ["stm32f100", "rt"]     
                              

添加memory.x文件在工程中

 MEMORY                                                                           
 {
 	FLASH : ORIGIN = 0x08000000, LENGTH = 64K
 	RAM : ORIGIN = 0x20000000, LENGTH = 20K
 }

查找芯片手册,将flash和ram映射的地址开头和长度添加到上面,如果你和我一样使用的是stm32f103的芯片可以不用改。

创建cargo配置.cargo/config.toml

[target.thumbv7m-none-eabi]     
rustflags = [
  # 如果你的闪存或ram地址没有与memory.x中的0x10000对齐,就需要这样做
  # 见 https://github.com/rust-embedded/cortex-m-quickstart/pull/95
  #"-C", "link-arg=--nmagic",
 
  # LLD(随Rust工具链一起提供)被用作默认链接器
  "-C", "link-arg=-Tlink.x",
 
  # 如果你遇到LLD的问题,通过注释到GNU链接器这行
  # "-C", "linker=arm-none-eabi-ld",
 
  #如果你需要链接到C工具链提供的预编译C库
   #使用GCC作为链接器,注释掉上面的两行,然后
   #取消下面三行的注释
  # "-C", "linker=arm-none-eabi-gcc",
  # "-C", "link-arg=-Wl,-Tlink.x",
  # "-C", "link-arg=-nostartfiles",
]

[build]    
target = "thumbv7m-none-eabi" 

修改源代码 main.rs

#![deny(unsafe_code)]                                                                                                              #![no_main]                                           
#![no_std]                                            
use panic_halt as _;                                  
use cortex_m_rt::entry;    
use stm32f1xx_hal::{pac, prelude::*};    
       
#[entry]    
fn main() -> ! {    
      let p = pac::Peripherals::take().unwrap();                                                                                 
      let mut gpioc = p.GPIOC.split();                                                                                           
      gpioc.pc13.into_push_pull_output(&mut gpioc.crh).set_low();                                                                
      loop {}                                                                                                                    
  }                                                                                                                              

这是文档给出点亮led灯的代码。

硬件中,将led灯正极连到vcc(3.3v)负极连接到pc13这个引脚上。

构建代码

$cargo build

产生的可执行代码在当前目录下target/thumbv7m-none-eabi/debug/stm32f103

注意这只是开发版本,如果你想要更小更快的二进制文件,配置你的profile.release

烧写代码

1.打开openocd
$sudo openocd -f interface/stlink-v2.cfg -f target/stm32f1x.cfg

stlink-vX X是你下载器的版本号

出现

Info : stm32f1x.cpu: hardware has 6 breakpoints, 4 watchpoints

就是成功了

2.打开gdb

打开一个新的终端并进入项目中

$gdb-multiarch -q target/thumbv7m-none-eabi/debug/stm32f103

进入gdb的交互模式后输入

$(gdb) target remote:3333

连接openocd

用gdb烧录

$(gdb) load

烧写的过程就完成了

简化

是不是觉得每次写openocd命令和gdb的命令过于繁琐,我们可以用一些方法简化它。

1.不用写sudo(避免每次用root执行openocd)

创造文件/etc/udev/rules.d/70-st-link.rules内容如下:

# STM32F3DISCOVERY rev A/B - ST-LINK/V2
ATTRS{idVendor}=="0483", ATTRS{idProduct}=="3748", TAG+="uaccess"

# STM32F3DISCOVERY rev C+ - ST-LINK/V2-1
ATTRS{idVendor}=="0483", ATTRS{idProduct}=="374b", TAG+="uaccess"

然后用以下命令重新加载所有udev规则:

$sudo udevadm control --reload-rules

将开发板连接在电脑上

$lsusb

出现

(..) 

Bus 001 Device 018: ID 0483:374b STMicroelectronics ST-LINK/V2.1 

(..)

即可 ,2.1或者2都是你的下载器决定

这样你就可以不用写sudo

$openocd -f interface/stlink-v2.cfg -f target/stm32f1x.cfg

2.简化gdb

$gdb-multiarch -q target/thumbv7m-none-eabi/debug/stm32f103

每次修改代码烧录调试,要打上面的代码和gdb命令,实在是太累了!

这就要说rust工具链的优点了。

打开.cargo/config
[target.thumbv7m-none-eabi]                                                                                                              
rustflags = [    
  "-C", "link-arg=-Tlink.x",    
]    
runner = "gdb-multiarch -q target/thumbv7m-none-eabi/debug/stm32f103 -x gdb.cfg"    #新添加一行runner
[build]    
target = "thumbv7m-none-eabi"    

其中gdb命令脚本

gdb.cfg
target remote :3333                                                                                                                      
     
monitor arm semihosting enable    
     
# # send captured ITM to the file itm.fifo    
# # (the microcontroller SWO pin must be connected to the programmer SWO pin)    
# # 8000000 must match the core clock frequency    
# monitor tpiu config internal itm.fifo uart off 8000000    
     
# # OR: make the microcontroller SWO pin output compatible with UART (8N1)    
# # 2000000 is the frequency of the SWO pin    
# monitor tpiu config external uart off 8000000 2000000    
     
# # enable ITM port 0    
# monitor itm port 0 on    
     
load    
quit    
       

以后运行可以直接执行

$cargo run 

将二进制文件发送到openocd再烧录到开发板中

检查

主要检查的就是rust产生二进制体积大小是否超过你的mcu flash的容量

$cargo size --bin stm32f103 --release -- -A

查看release版本的二进制大小

app  :
section             size        addr
.vector_table       1024         0x0
.text                 92       0x400
.rodata                0       0x45c
.data                  0  0x20000000
.bss                   0  0x20000000
.debug_str          2958         0x0
.debug_loc            19         0x0
.debug_abbrev        567         0x0
.debug_info         4929         0x0
.debug_ranges         40         0x0
.debug_macinfo         1         0x0
.debug_pubnames     2035         0x0
.debug_pubtypes     1892         0x0
.ARM.attributes       46         0x0
.debug_frame         100         0x0
.debug_line          867         0x0
Total              14570

优化

在Cargo.toml中,新加官方推荐的release版本优化参数

[profile.release]
codegen-units = 1 # better optimizations
debug = true # symbols are nice and they don't increase the size on Flash
lto = true # better optimizations

更多资料

  • 关于stm32的更多例子https://github.com/stm32-rs/stm32f1xx-hal/tree/master/examples,实打实的复制粘贴改改就行

  • 官方的第二本嵌入式书embedded book 我有翻译https://blog.csdn.net/qq_37813963/article/details/126209924?spm=1001.2014.3001.5502,其中有关于调试信息,中断异常等更具体的内容

  • 官方第三本Embedonomicon 我看了大概是一些优化

  • 其他的书都是给芯片厂商看的,有兴趣有能力的可以去学一下,给社区贡献hal库

  • 更多的嵌入式系统开发库https://github.com/rust-embedded/awesome-embedded-rust#driver-crates

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值