当前位置:   article > 正文

Rust+STM32+VSCode开发调试环境搭建_rust stm32

rust stm32

准备工作:

  1. 一个安装好的VSCode

  2. arm-gnu-toolchain工具链。注意:部分版本工具链的GDB无法直接启动,需要本地编译。测试中发现的情况:11.3的GDB可以启动。11.2无法正常启动。双击bin目录下arm-none-eabi-gdb.exe,确保可以运行。可以用11.2的GBD复制到11.2中。(仅测试这两个版本)在这里插入图片描述

  3. 安装Rust(不再赘述),安装Rust的arm编译工具

rustup target add thumbv7m-none-eabi
  • 1
  1. Windows的OpenOCD二进制包

创建工程并编译:

1:创建Rust工程

cargo new stm32Rust。这里stm32Rust是我的工程名

2:VSCode打开新建工程文件夹

此时显示如下: 在这里插入图片描述

3:Cargo.toml中添加依赖项

在这里插入图片描述
注意:目前依赖包还没有到达稳定版本。可按自己需求更换版本。
完整Cargo.toml文件:

[package]
name = "stm32_rust"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[profile.dev]
opt-level = 0 # debug

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[profile.release]
opt-level = 'z' # turn on maximum optimizations. We only have 64kB
lto = true      # Link-time-optimizations for further size reduction

[dependencies]
cortex-m = "^0.7.6"      # Access to the generic ARM peripherals
cortex-m-rt = "^0.7.1"  # Startup code for the ARM Core
embedded-hal = "^0.2.4"  # Access to generic embedded functions (`set_high`)
panic-halt = "^0.2.0"    # Panic handler

# Access to the stm32f103 HAL.
[dependencies.stm32f1xx-hal]
# Bluepill contains a 64kB flash variant which is called "medium density"
features = ["stm32f103", "rt", "medium"]
version = "^0.9.0"
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

4:创建memory.x文件

MEMORY
{
/* NOTE 1 K = 1 KiBi = 1024 bytes */
FLASH : ORIGIN = 0x08000000, LENGTH = 128K//修改为芯片大小
RAM : ORIGIN = 0x20000000, LENGTH = 20K//修改为芯片大小
}

5:新建.cargo文件夹

创建config文件,如图:
在这里插入图片描述

config文件内容如下:

# .cargo/config
[build]
target = "thumbv7m-none-eabi"

[target.'cfg(all(target_arch = "arm", target_os = "none"))']
runner = 'E:\\Program\\arm-none-eabi\\gcc-arm-11.2-2022.02-mingw-w64-i686-arm-none-eabi\\bin\\arm-none-eabi-gdb.exe -q -x debug.gdb'

[target.thumbv7m-none-eabi]
rustflags = [
    "-C", "linker=E:\\Program\\arm-none-eabi\\gcc-arm-11.2-2022.02-mingw-w64-i686-arm-none-eabi\\bin\\arm-none-eabi-gcc.exe",
    "-C", "link-arg=-Wl,-Tlink.x",
    "-C", "link-arg=-nostartfiles",
]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

runner与linker按实际路径修改配置。

6:改造一个最小main文件

#![no_std]
#![no_main]

use cortex_m_rt::entry; // The runtime
use stm32f1xx_hal::{
}; // STM32F1 specific functions
#[allow(unused_imports)]
use panic_halt;
#[entry]
fn main() -> ! {
    //println!("Hello, world!");
    loop {
        
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

use stm32f1xx_hal:我是用的stm32f103

7:测试

终端运行cargo build
在这里插入图片描述

此时应当会出现如下样式:
在这里插入图片描述

应当会出现target目录,目录下有thumbv7m-none-eabi/debug/stm32_rust文件,是我们编译生成的目标文件。
说明我们编译已经通过,配置完成。接下来配置debug。

Debug调试配置:

1:VSCode安装插件Cortex-Debug

在这里插入图片描述

(我这里安装的1.6.0版本。可能版本升级对OpenOCD以及ST-Link的版本会有要求)

2:配置Debug运行参数

点击小齿轮,进入配置。
在这里插入图片描述

点击“在setting.json中编辑”,配置交叉编译工具链,添加四个配置:

"cortex-debug.gdbPath": "E:\\Program\\arm-none-eabi\\gcc-arm-11.2-2022.02-mingw-w64-i686-arm-none-eabi\\bin\\arm-none-eabi-gdb.exe",   
"cortex-debug.armToolchainPath": "E:\\Program\\RT-ThreadStudio\\repo\\Extract\\ToolChain_Support_Packages\\ARM\\GNU_Tools_for_ARM_Embedded_Processors\\10.2.1\\bin",
"cortex-debug.openocdPath": "E:\\Program\\arm-none-eabi\\OpenOCD-20211118-0.11.0\\bin\\openocd.exe",
  • 1
  • 2
  • 3

注意:请按自己的路径调整:gdb所在位置,工具链所在位置,openecd所在位置。

3:新建debug.gdb文件。

本文件用于gdb与openocd的连接命令:

target remote :3333

set backtrace limit 32

monitor reset halt

load
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

4:创建launch.json文件:
在这里插入图片描述

选择Cortex Debug
在这里插入图片描述

修改如下内容:
“servertype”: “jlink"改为"servertype”: “jlink”
“executable”: “./bin/executable.elf"改为"executable”: “./target/thumbv7m-none-eabi/debug/stm32_rust”
增加:

"device": "STM32F103RB",// 芯片型号
"showDevDebugOutput":"raw",
"configFiles": [
	"E:/Program/arm-none-eabi/OpenOCD-20211118-0.11.0/share/openocd/scripts/interface/stlink-v2.cfg",           // 调试器
	"E:/Program/arm-none-eabi/OpenOCD-20211118-0.11.0/share/openocd/scripts/target/stm32f1x.cfg",         // 芯片型号
]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

完整launch.json文件如下:

{
    // 使用 IntelliSense 了解相关属性。 
    // 悬停以查看现有属性的描述。
    // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Cortex Debug",
            "cwd": "${workspaceFolder}",
            "executable": "./target/thumbv7m-none-eabi/debug/stm32_rust",
            "request": "launch",
            "type": "cortex-debug",
            "runToEntryPoint": "main",
            "servertype": "openocd",
            "device": "STM32F103RB",
                "showDevDebugOutput":"raw",
                "configFiles": [
                    "E:/Program/arm-none-eabi/OpenOCD-20211118-0.11.0/share/openocd/scripts/interface/stlink-v2.cfg",           // 调试器
                    "E:/Program/arm-none-eabi/OpenOCD-20211118-0.11.0/share/openocd/scripts/target/stm32f1x.cfg",         // 芯片型号
                ]
        }
    ]
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

5:测试断点debug:
在main函数中设置一个断点,点击Cortex Debug的三角按钮运行,进入调试,命中断点。本次配置成功。
在这里插入图片描述

之后,开始写Rust代码吧!

示例代码:

// src/main.rs

#![no_std]
#![no_main]

use cortex_m_rt::entry; // The runtime
//use embedded_hal::digital::v2::OutputPin; // the `set_high/low`function
use stm32f1xx_hal::{
    pac, 
    prelude::*,
    serial::{self, Serial},
}; // STM32F1 specific functions

//use stm32f1xx_hal::{delay::Delay, pac, prelude::*}; // STM32F1 specific functions
#[allow(unused_imports)]
use panic_halt; // When a panic occurs, stop the microcontroller
#[entry]
fn main() -> ! {
    let dp = pac::Peripherals::take().unwrap();
    let cp = cortex_m::Peripherals::take().unwrap();
    let rcc = dp.RCC.constrain();
    let mut gpioc = dp.GPIOC.split();
    let mut led0 = gpioc.pc0.into_push_pull_output(&mut gpioc.crl);
    let mut led1 = gpioc.pc1.into_push_pull_output(&mut gpioc.crl);
    let mut led2 = gpioc.pc2.into_push_pull_output(&mut gpioc.crl);
    let mut led3 = gpioc.pc3.into_push_pull_output(&mut gpioc.crl);
    let mut led4 = gpioc.pc4.into_push_pull_output(&mut gpioc.crl);
    let mut led5 = gpioc.pc5.into_push_pull_output(&mut gpioc.crl);
    
    let mut flash = dp.FLASH.constrain();
    let cfgr = rcc.cfgr.use_hse(12.MHz()).sysclk(72.MHz());
    let clocks = cfgr.freeze(&mut flash.acr); 

    let mut afio = dp.AFIO.constrain();
    let mut gpioa = dp.GPIOA.split();
    let tx = gpioa.pa9.into_alternate_push_pull(&mut gpioa.crh);
    let rx = gpioa.pa10;
    let mut serial = Serial::usart1(
        dp.USART1,
        (tx, rx),
        &mut afio.mapr,
        serial::Config::default()
            .baudrate(115200.bps())
            .stopbits(serial::StopBits::STOP1)
            .wordlength_8bits()
            .parity_none(),
        clocks,
    );

    let mut delay = cp.SYST.delay(&clocks);
    let mut i = 0u8;
    loop {
        serial.write(b'U').ok();  
        led0.set_high();
        led1.set_high();
        led2.set_high();
        led3.set_high();
        led4.set_high();
        led5.set_high();
        if i == 0{
            led0.set_low();
            i += 1;
        }
        else if i == 1{
            led1.set_low();
            i += 1;
        }
        else if i == 2{
            led2.set_low();
            i += 1;
        }
        else if i == 3{
            led3.set_low();
            i += 1;
        }
        else if i == 4{
            led4.set_low();
            i += 1;
        }
        else if i == 5{
            led5.set_low();
            i = 0;
        }
        else{
            i=0;
        }
        delay.delay_ms(500_u16); 
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89

演示了一个跑马灯,以及串口发数据。
rcc.cfgr.use_hse(12.MHz()).sysclk(72.MHz())设置中,12.MHz()是晶振频率。72.MHz()是希望的倍频之后的频率。API后台会计算倍频倍率和设置参数。一般8M或12M的晶振都可以设置为72MHz。
串口波特率115200。

本文工具及代码下载:
https://download.csdn.net/download/lossage/86881018

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Li_阴宅/article/detail/958570
推荐阅读
相关标签
  

闽ICP备14008679号