This article was last updated on <span id="expire-date"></span> days ago, the information described in the article may be outdated.
最近做海雾的预报比较无聊,总得找个东西打发时间,于是翻出了大概两年前嫖的别人的板子。当时他们的创业园办公室要被收回了,于是我就去捡垃圾,看看有什么好东西。然后就搞到了这块STM32F103VET6
野火指南者板子,上面还有一块屏幕,挺香的。
翻了一下野火官方的教学视频,发现是用的Keil开发的,但是我的Arch没法运行Keil,所以又花了两天时间弄清楚如何在Arch上开发,编译,烧录STM32的程序。
安装软件
arm-none-eabi-gcc
:编译器cmake
:编译程序VS Code
:写代码OpenOCD
:烧录程序stm32cubemx
:生成板子的启动脚本、链接脚本,初始化项目,提供HAL库文件
以上软件除了stm32cubemx
需要从AUR安装,其他的都可以直接用pacman安装。(VS Code
在arch4edu中可以找到)
设置udev
使用USB将板子连接到电脑上以后,在/dev
下并不会出现对应的设备符号,我们需要手动设置udev规则。
首先运行以下命令让udev监控usb的更改
1 | udevadm monitor |
然后插上调试器的USB线,这个时候会出现许多日志
然后随便复制一个比较长的路径,例如/devices/pci0000:00/0000:00:14.0/usb1/1-11/1-11.1/1-11.1:1.1
,然后运行下面的命令查看对应设备的信息,udev会一并把父设备也列出来。
1 | sudo udevadm info -a --path=/sys/devices/pci0000:00/0000:00:14.0/usb1/1-11/1-11.1/1-11.1:1.1 |
将
/devices/xxxx
路径添加到/sys
后面
在输出的信息中寻找到含有"KeilSoftware"
字样对应的设备,这个设备就是调试器。记录下设备的路径/devices/pci0000:00/0000:00:14.0/usb1/1-11/1-11.1
重新运行命令查看该设备的信息,并记录下KERNEL
,SUBSYSTEM
,ATTR{idProduct}
,ATTR{idVendor}
1 | sudo udevadm info -a --path=/sys/devices/pci0000:00/0000:00:14.0/usb1/1-11/1-11.1 |
然后我们就可以编写udev的规则了。
1 | sudo vim /etc/udev/rules.d/stm32f103vet6.rules |
1 | KERNEL=="1-11.1",SUBSYSTEMS=="usb",ATTRS{idVendor}=="c251",ATTRS{idProduct}=="f001",MODE:="0777",SYMLINK+="STM32F103VET6" |
其中SUBSYSTEMS
对应SUBSYSTEM
的值,ATTRS{idVendor}
对应ATTR{idVendor}
的值,ATTRS{idProduct}
对应ATTR{idProduct}
的值。MODE
是设备的权限,设为0777
则普通用户即可访问。SYMLINK
是出现在/dev
中的设备的名称,这里我设置为STM32F103VET6
,方便识别。
将规则保存,然后拔出调试器的USB线重新插入,这个时候就应该可以在/dev
下找到对应的设备了。
初始化项目
首先我们需要使用stm32cubemx
这个程序初始化项目,它给给我们准备所需要的HAL库文件,启动文件,链接文件,CMSIS-DAP头文件等。
打开stm32cudemx
,首先你需要登陆一下,否则是无法下载文件的。
然后点击新建项目。首先输入自己板子的型号,然后双击选择对应的板子
设置时钟源
我用的这个板子推荐频率是72MHz。为了能够之后不再设置,所以预先在stm32cubemx
里面设置一下,后面就不用手动再设置时钟了。
点击System Core -> RCC
,High Speed Clock (HSE)
选择Crystal/Ceramic Resonator
,然后在Clock Configuration
页面设置时钟源、分频和倍频。
设置GPIO引脚
如果使用按键、LED灯的话,是需要初始化对应的GPIO引脚的。可以选择在stm32cubemx
中一并预先设置好,或者生成代码以后自己再设置,反正都差不多。这里不再多说。
项目设置
然后在Project Manager
里面设置项目的名称之类的。Toolchain / IDE
可以选Makefile
,后面可以根据Makefile
编写CMake
的规则。
Code Generator
这里可以选仅复制必要的库文件,这样库文件量会少很多。
其他的默认就可以,然后点击GENERATE CODE
生成代码。生成完了以后就可以把stm32cubemx
关掉了。
调整项目结构
打开项目所在目录,默认的目录结构我不太喜欢,所以自己调整了一下。
默认的文件结构如下
更改后的结构(其实改得也不多)
编写CMakeLists.txt
因为我想用cmake来帮助编译,所以需要编写一个CMakeLists.txt文件。这里我就直接贴内容了。只需要将46和53行那里设置源文件和头文件的路径,以及39行设置宏定义来选择板子型号,15行MCU型号的设置修改一下应该就可以用于其他型号的板子了。
1 | cmake_minimum_required(VERSION 3.20) |
烧录
中间编写代码的过程我就不做介绍了。假设你写好了一个流水灯的程序,并且已经编译得到了elf
文件,那么下一步我们需要将其烧录进单片机中。我们使用OpenOCD
进行烧录,命令如下
1 | openocd -f /usr/share/openocd/scripts/interface/cmsis-dap.cfg -c "transport select swd" -f Drivers/openocdcfg/stm32f1x.cfg -c "init" -c "reset halt" -c "sleep 100" -c "wait_halt 2" -c "flash write_image erase build/STM32LED.elf" -c "sleep 100" -c "reset run" -c shutdown |
其中
-f /usr/share/openocd/scripts/interface/cmsis-dap.cfg
:由于我用的调试器使用CMSIS-DAP标准,所以配置文件选择cmsis-dap.cfg
-c "transport select swd"
:使用SWD模式进行数据传输-f Drivers/openocdcfg/stm32f1x.cfg
:使用stm32f1x
类型芯片的配置文件。此文件是我从/usr/share/openocd/scripts/target
下复制过来的-c "init"
:初始化-c "reset halt"
:执行硬件复位,将所有已定义的目标重置,并立即停止目标的运行-c "sleep 100"
:OpenOCD
在状态恢复之前等待至少100毫秒-c "wait_halt 2"
:OpenOCD
等待目标停止的时间为2毫秒-c "flash write_image erase build/STM32LED.elf"
:擦出flash扇区并将build/STM32LED.elf
文件烧录到其中-c "reset run"
:执行硬件复位,将所有已定义的目标重置,并开始目标的运行-c shutdown
:关闭OpenOCD
可以将以上的命令写进一个shell脚本中,方便后续重复运行。然后我发现烧录的时候,烧录bin
文件是有问题的,烧录不进去,但是烧录elf
文件就是正常的,这个问题比较奇怪,还没有找到原因。
Author: Syize
Permalink: https://blog.syize.cn/2023/11/08/linux-stm32-development/
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Syizeのblog!
Comments