像 STM32MP157-DK 这类跑Linux的板子,如果是将系统写到SD卡、Flash芯片上面,然后等待Linux启动后登陆上去操作的话,就和玩PC上的Linux相似了,只是多了很多可以通过程序直接访问的硬件。相对于通常MCU开发,STM32MP1 Linux下面程序的编写软件自由度就比较大了,至少是RAM管够;对硬件的访问则需要和操作系统(Linux)打交道,而不是直接访问寄存器。
不过这些且先放到后面。我第一次上手ARM Cortex-A系列处理器,是打算当成单片机来玩的。按照评测计划,需要实现 STM32MP157 的“裸机”编程,那么就得有办法把一段程序放进去让MPU运行。一种办法是把程序写到SD卡的启动代码中,也就是上电后从SD卡读取的第一段程序(相当于玩PC时编写MBR中的启动程序);另一种办法是使用调试器,就像MCU那样直接修改内存的内容和寄存器的值。
STM32MP157A-DK 上面带了个 ST-Link v2. 官方介绍主要提的是用它的虚拟串口连接到 MP157, 实现Linux终端、ROM boot等用到UART的功能。但显然 ST-Link 主要用途是调试,STM32MP157 的 SWDIO, SWCLK 信号已连到 ST-Link 上了。根据芯片手册可以确定,Cortex-A7 的核也是能用 SWD 方式调试的。
起初我用下载MCU的工具 ST-Link_CLI 来试一下 SWD 连接,结果是 "No target connected" " Unable to connect to ST-LINK" . 我想可能是和 MPU 的通信和以往的 STM32 不同的缘故。官方介绍也没有提到过 STM32MP1 专用的 ST-Link Utility 软件。
那么这个 ST-Link 怎样才能用上?网上得来的线索是用 OpenOCD:
其一,在 wiki.st.com/stm32mpu/wiki/STM32MP15_OpenSTLinux_release_note 页提到了 openocd-stm32mp
其二,在 docs.zephyrproject.org/latest/boards/arm/96b_avenger96/doc/index.html 提到用 stm32mp1 developer package 里的 openocd 调试
其三,在 sysprogs.com/VisualKernel/tutorials/stm32mp1/ 这里讲解调试 Linux 内核模块,用到专用的 openocd 工具
这里有一个Github页的链接,可以下载一个编译好的 windows 版本 openocd. 然而因为网络原因我总不能成功下载。
其四,ST社区上的回答 community.st.com/s/question/0D50X0000CAtzDH/can-i-debug-cortexa7-cores-on-stm32mp157 关于 Can I debug Cortex-A7 cores on STM32MP157? 问题
ST的人员的回答肯定了用板子上的 ST-Link 是可以调试 A7 核的,软件就是 OpenOCD + GDB.
以往调试 STM32 MCU 的 OpenOCD 是不支持 STM32MP157 的,试一下便知道了,至少是缺少了配置文件。那么把配置文件复制过来呢?我搜索到了ST在github上提供的专用 OpenOCD (修改过的版本,支持STM32MP1) github.com/STMicroelectronics/device-stm-openocd 可以 git clone 下到本地。其中有一个编译好的 linux 程序,带上其它脚本文件,源码目录没有 openocd 原版代码,主要是patch. 我试图把其中的配置文件复制出来,用windows下的 openocd 试一下,结果是有错误,似乎脚本文件在 openocd 不同版本间也不兼容。至于编译好的那个 openocd, 在我单位电脑上试了 Glibc 版本不兼容不能运行。我自己的PC Linux因为是32位,也无法拿来测试。
官方的 SDK 也是 x86_64 版本的,所以自己用的PC上Linux 也是无法运行。我要么是编译 x86_64 的一套 GLibc runtime库,以支持官方 SDK 中的程序,要么就是在现有系统上编译 OpenOCD 和 GDB、以及 ARM GCC toolchain. 都得有折腾的。我的决定是后者。
OpenOCD 的正式发布版本最后一个是 0.10.0, 编译起来难度不大。特殊的库就只需要 libusb 1.x 或 0.x 版本,而 libusb 有 libudev 就可以编译了还好办。我自己玩 STM32 因为老用 windows 开发,Linux的工具没怎么准备,没有的就都从头来了。
把 OpenOCD 编译成功,确认能用它访问 st-link 调试一个 MCU 以后,我再打算把 STM32MP1 的 patch 弄进去(从上面ST)。结果呢,居然有很多 patch 失败。后来我明白,OpenOCD 除了正式发布的版本,开发中的版本一直在改动(命令也在变化,并不是和旧的兼容),所以现在这个需求用 0.10.0 版本改还不行。
于是我又从 OpenOCD mirror站上下载了一个很新的 snapshot 版本,解开再试图 patch, 居然也是很多失败的。想来这个也难免,我对版本管理又不熟悉,去分析要怎么patch不现实——太折腾了就不如换条路了。
ST社区还有一个问答里面讲了:"
I'm upstreaming the support for STM32MP1 in mainline OpenOCD.
Today there is a conflict between some other patches waiting to be merged and the ST code to handle ST-Link in the way required by STM32MP1. This conflict prevents merging STM32MP1 code.
I hope this will get solved soon." 就是说ST这个patch和其它的 (不断地有新的patch) 存在冲突。所以我下的最新 snapshot 不能用来改成 STM32MP1 专用版。那么怎么知道 ST 用的是哪个原始版本?
幸运地我找着了,在 github.com/STMicroelectronics/meta-st-stm32mp/blob/thud/recipes-devtools/openocd/openocd-stm32mp_0.10.0.bb 描述里面其实暗藏了:
根据这串字符去 OpenOCD git mirror上找,就能下载了。然后应用 ST 的 patch, 完美!
不过这个 git 的 openocd 要 autoconfig 一下才可以得到 configure 程序。先要执行其中的 bootstrap 脚本。因为我的 Linux 上 autoconf, automake, m4 几个软件的版本都太老,又重新编译升级了一下,这都是小插曲。在编译这个新版本 openocd 时又遇到一些小问题,我自己手工修补搞定。
make install 之后,连上开发板子试一把:
这说明 OpenOCD 已经识别到了两个 Cortex-A CPU核。第一步迈出终于成功了。
这段时间通过对 ARM 文档的阅读我了解到 Cortex-A7 和 Cortex-M0/4 的差别还是很大的。现在终于可以使用调试工具了,对观察 CPU 的状态将有大的帮助。OpenOCD 自带的内存访问、反汇编功能也可以试。
比如打断 CPU 的执行,查看一下现在运行的代码在哪里:
[fox@ULFS]~$ telnet localhost 4444
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Open On-Chip Debugger
> halt
stm32mp15x.cpu0 rev 5, partnum c07, arch f, variant 0, implementor 41
stm32mp15x.cpu0 cluster 0 core 0 multi core
stm32mp15x.cpu1 rev 5, partnum c07, arch f, variant 0, implementor 41
stm32mp15x.cpu1 cluster 0 core 1 multi core
target halted in ARM state due to debug-request, current mode: Supervisor
cpsr: 0x60030093 pc: 0xc011b368
MMU: enabled, D-Cache: enabled, I-Cache: enabled
target halted in ARM state due to debug-request, current mode: Supervisor
cpsr: 0x200b0193 pc: 0xc015db00
MMU: enabled, D-Cache: enabled, I-Cache: enabled
> reg pc
pc (/32): 0xC015DB00
> arm disassemble 0xC015DB00 20
0xc015db00 0xe58d3038 STR r3, [r13, #0x38]
0xc015db04 0x0a000031 BEQ 0xc015dbd0
0xc015db08 0xe1a0300d MOV r3, r13
0xc015db0c 0xe3c32d7f BIC r2, r3, #0x1fc0
0xc015db10 0xe3c2203f BIC r2, r2, #0x3f
0xc015db14 0xe3031d00 MOVW r1, #0x3d00
0xc015db18 0xe34c1100 MOVT r1, #0xc100
0xc015db1c 0xe592300c LDR r3, [r2, #0xc]
0xc015db20 0xe5910000 LDR r0, [r1]
0xc015db24 0xe593c020 LDR r12, [r3, #0x20]
0xc015db28 0xe2600064 RSB r0, r0, #0x64
0xc015db2c 0xe170000c CMN r0, r12
0xc015db30 0x4a000063 BMI 0xc015dcc4
0xc015db34 0xe5931024 LDR r1, [r3, #0x24]
0xc015db38 0xe15b0001 CMP r11, r1
0xc015db3c 0x0a000005 BEQ 0xc015db58
0xc015db40 0xe583b024 STR r11, [r3, #0x24]
0xc015db44 0xe592100c LDR r1, [r2, #0xc]
0xc015db48 0xe591301c LDR r3, [r1, #0x1c]
0xc015db4c 0xe2833001 ADD r3, r3, #0x1
此内容由EEWORLD论坛网友cruelfox原创,如需转载或用于商业用途需征得作者同意并注明出处