STM32在使用Clion平台开发时调试失败 SystemClock_Config 返回 HAL_ERROR

news/2025/1/5 14:35:59/文章来源:https://www.cnblogs.com/68786C/p/18649593

问题记录

在尝试使用Clion在STM32平台上开发调试时,需要通过OpenOCD结合ST-Link等调试器进行烧录和调试。但通过STM32CubeMX生成代码后,发现出现以下现象:

  1. 程序能够正常编译并下载到开发板上,且运行符合预期。
  2. 调试时GDB Server能够正常连接,可以正常查看函数调用栈。但却在SystemClock_Config函数配置参数时,调用的HAL_RCC_OscConfig等函数均返回为HAL_ERROR,而导致死循环在Error_Handler
    image
    image
  3. OpenOCD的重置reset选项配置的为初始化init。
    image

既然问题在正常下载时没有复现(排除硬件问题),且这段CubeMX生成代码比较成熟,出问题的可能不大。所以主要查看为什么调试会导致时钟配置有误。

根因分析

image

首先,STM32使用手册提到,PLL使能后,主PLL的配置参数不可更改。也就是说,重复配置PLL是不允许的。

OpenOCD 的启动流程(/usr/share/openocd/scripts/target/stm32f4x.cfg)入手分析。首先,ARM Cortex 内核限制 SWD 时钟频率不能超过内核频率的 1/6,而单片机上电后如果不做任何配置,时钟来源为 HSI 的 16MHz,这样 SWD 频率就最高是 2.666MHz。因此,如果不做时钟上的更改,OpenOCD 默认只能使用 2000kHz 的 adapter speed。

adapter speed 2000
adapter srst delay 100
if {[using_jtag]} {jtag_ntrst_delay 100
}
reset_config srst_nogate

由于选择的重置选项是reset-init,所以,下面这行配置脚本会执行。

而如果让 OpenOCD 启动调试,为了加快 SWD 时钟,OpenOCD 会把 MCU 里面的 PLL 打开并设置到 64MHz,然后将系统时钟来源切换为 PLL.
在复位时提高系统时钟(16MHz → 64MHz),以提升调试速度。

$_TARGETNAME configure -event reset-init {mww 0x40023804 0x08012008   ;# 配置 PLLmww 0x40023C00 0x00000102   ;# 设置 Flash 等待状态mmw 0x40023800 0x01000000 0 ;# 启用 PLLsleep 10mmw 0x40023808 0x00001000 0 ;# 配置总线分频mmw 0x40023808 0x00000002 0 ;# 切换到 PLL 时钟adapter speed 8000
}

那么,为什么会出现时钟不正常呢?我们分析 HAL 库设置系统时钟的流程。按照正常流程,HAL 库会启动 HSE,然后配置 PLL 参数,并将 PLL 时钟源设为 HSE,最后将系统时钟来源设置为 PLL。如果单片机上电后不做任何额外的时钟配置,这部分程序是可以正常工作的,单片机能够在正确的时钟上运行。

然而,巧合的是,启用调试器后,在运行用户代码前,系统时钟就处于已经配置 PLL 的状态。HAL 库如果检测到这种状态,则不会对 PLL 配置进行更改,只会检测现有的 PLL 配置与欲应用的配置是否相符,如果不相符,则返回 HAL_ERROR。

__weak HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef  *RCC_OscInitStruct) {... // 初始化 HSI,HSE 等,在此省略if ((RCC_OscInitStruct->PLL.PLLState) != RCC_PLL_NONE) {// 如果 PLL 当前不是系统时钟if (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_CFGR_SWS_PLL) {// 正常上电时,__HAL_RCC_GET_SYSCLK_SOURCE 应该返回 RCC_CFGR_SWS_HSI,从而进入这个分支... // 对 PLL 进行配置} else {// 如果启动调试器,__HAL_RCC_GET_SYSCLK_SOURCE 应该返回 RCC_CFGR_SWS_PLL,就会进入这个分支// 对 PLL 配置进行检查,如果与给定的配置不符,就返回 ERRORpll_config = RCC->PLLCFGR;if((READ_BIT(pll_config, RCC_PLLCFGR_PLLSRC) != RCC_OscInitStruct->PLL.PLLSource) ||(READ_BIT(pll_config, RCC_PLLCFGR_PLLM) != RCC_OscInitStruct->PLL.PLLM) ||(READ_BIT(pll_config, RCC_PLLCFGR_PLLN) != RCC_OscInitStruct->PLL.PLLN) ||(READ_BIT(pll_config, RCC_PLLCFGR_PLLP) != RCC_OscInitStruct->PLL.PLLP) ||(READ_BIT(pll_config, RCC_PLLCFGR_PLLQ) != RCC_OscInitStruct->PLL.PLLQ)){return HAL_ERROR;}}}
}

后面的情况也正如开头所讲,返回错误值,卡死在错误处理函数内。

解决方法

  1. 调整OpenOCD的重置选项至Run,关于重置选项的用途,请参考:https://openocd.org/doc/html/Reset-Configuration.html
  • run Let the target run
  • halt Immediately halt the target
  • init Immediately halt the target, and execute the reset-init script
  1. main函数的 USER CODE 1 段内加入以下代码
int main(void)
{/* USER CODE BEGIN 1 */__HAL_RCC_HSI_ENABLE(); // 启用 HSI__HAL_RCC_SYSCLK_CONFIG(RCC_SYSCLKSOURCE_HSI); // 切换系统时钟为 HSI/* USER CODE END 1 */HAL_Init();SystemClock_Config();// 进行其他初始化
}

参考文章

https://blog.vinkvin.com/post/96/
https://blog.t123yh.xyz:3/index.php/archives/922

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/863277.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

《刚刚问世》系列初窥篇-Java+Playwright自动化测试-9- 浏览器的相关操作 (详细教程)

1.简介 在自动化测试领域,元素定位是非常重要的一环。正确定位页面元素是测试用例能否成功执行的关键因素之一。playwright是一种自动化测试工具,它提供了丰富的元素定位方法,可以满足不同场景下的定位需求。前边宏哥已经通过不少的篇幅将playwright的元素定位的一些常用的基…

ModBus功能码异常和功能码错误代码

参考来源: https://www.cnblogs.com/hi-9527/p/16308588.htmlModbus功能码异常功能码错误码Modbus协议主要构成是地址码/标识码,功能码,寄存器地址,数据报文等内容。由于modbus协议是请求/应答通信协议,其其中功能码主要用于表述该数据报文执行的功能,当服务器对客户机进…

PACT: Parameterized Clipping Activation for Quantized Neural Networks

目录概主要内容Choi J., Wang Z., Venkataramani S., Chuang P. I., Srinivasan V. and Gopalakrishnan K. PACT: Parameterized clipping activation for quantized neural networks. 2018.概 本文提出对网络中的激活值进行裁剪以实现更低量化. 主要内容作者的思想很简单, 作者…

DeskHIL桌面级仿真测试平台

敏捷开发和持续集成持续发布逐渐成为汽车电子系统主流开发模式。在此大背景下,研发过程中研发与测试的结合越来越紧密。硬件在环仿真测试系统,一直是汽车电子研发过程中的重要基础测试工具,测试工具如何应对敏捷开发模式下测试工具快速集成、快速测试的要求?对行业来说是一…

jib打包镜像,docker-compose启动报错

问题描述jib打包推送到harbor后,启动找不到启动脚本文件 docker-test-1 | exec /entrypoint.sh: no such file or directory entrypoint 原docker-compose配置:test:image: "xxxxxxxxx"environment:- TZ=Asia/Shanghai- JAVA_OPTS=-Xms3g -Xmx4gprivileged: truepo…

鲲鹏服务器屏蔽告警的方法

描述:工程现场发现设备开启snmp v2c后会有不安全协议告警,且客户侧纳管平台会一直存在这个告警。解决:手动干预进行告警屏蔽ipmitool raw 0x30 0x90 0x58 0x01 0x00 0x06 0x00 0x49 0x00 0x00 0x1A 0x00 0x02已知故障码是0x1A000049,而上面标红部分是故障码0x49 0x00 0x00 …

谷歌为什么将在2025年主导人工智能

谷歌通往AI霸主地位的路径图片由谷歌Imagen 3生成2023年2月6日,谷歌首席执行官桑达尔皮查伊在巴黎登台,展示了谷歌的首款AI驱动聊天机器人Bard。 Bard出现了“幻觉”。 演示失败了,谷歌母公司Alphabet市值蒸发了1000亿美元。 在2023年的大部分时间里,谷歌似乎在人工智能创新…

window redis注册为服务

1.将redis安装目录添加到环境变量中 2.在redis安装目录执行如下命令: redis-server.exe --service-install redis.windows.conf --loglevel verbose 3.成功后,即可在服务列表中查看到该服务 抱怨有用的话还要努力干什么

linux 优化网卡队列

RSS(Receive-Side Scaling)网卡的多队列负载分流技术为了更好的利用多核系统。可以将网卡的数据流分配到多个rx queue,多个队列再分配到多个CPU核上,多个CPU并 行处理数据包,大大提升网络处理能力。但是有可能造成同一个网络会话被分配到多 个rx queue上,导致应用层处理会…

Nginx-WMware安装 c

CentOS-7-x86_64-Minimal-1810.iso镜像下载地址 通过网盘分享的文件:CentOS-7-x86_64-Minimal-1810.iso 链接: https://pan.baidu.com/s/1As2tckziAeVVF7sNJkZSlA?pwd=sky1 提取码: sky1 一、新建虚拟机二、选择 “典型”三、选择刚刚下载的 CentOS-7-x86_64-Minimal-1810的I…

读数据保护:工作负载的可恢复性24磁带和其他

磁带和其他1. 速度不匹配 1.1. 磁带机的速度曾经比备份数据的生成速度慢,而且那时磁带机的速度也比网络速度要慢 1.2. 备份行业就把磁带上的磁位排得比原来更加紧密 1.2.1. 磁位排得密,意味着磁带在不增加长度的情况下能够存储更多的数据 1.2.2. 磁位紧密,同时还意味着磁头在…

宝塔Linux专业版后台帝国CMS更新栏目出现404错误怎么办?

在使用宝塔Linux专业版管理多个站点时,可能会遇到帝国CMS更新栏目时出现404错误的问题。这类问题往往会给日常运维带来不便,因此我们需要仔细分析原因并采取有效的解决措施。以下是详细的解决方案:检查PHP版本兼容性:首先,确认帝国CMS所依赖的PHP版本是否与当前服务器环境…