[STM32C0] 实战经验 | STM32C0 HAL库的SPI驱动导致的Hardfault问题分析

[复制链接]
 楼主| STM新闻官 发表于 2025-5-30 14:24 | 显示全部楼层 |阅读模式
本帖最后由 STM新闻官 于 2025-6-27 15:22 编辑

8234268394ec1beb59.png

01问题描述

客户在项目开发中使用STM32C071作为主控MCU,驱动代码使用了版本STM32Cube_FW_C0_V1.2.0,应用程序调用SPI HAL API与NFC模块通信,SPI工作在Master模式,调用HAL_SPI_Transmit函数发送数据的时候,出现Hardfault现象,同时客户反馈同样的应用程序代码在STM32G0平台上,没有出现类似的问题,客户不得其解。根据客户反馈的现象,本文分析其原因以及解决方法。
02问题原因

移植客户调用SPI HAL的代码片段到NUCLEO_C031C6开发板上,复现了同样的问题,经过单步调试跟踪,定位到下面语句导致了Hardfault,如下图所示。 1361168394f0aadc10.png

▲ 图1. 导致Hardfault的语句
跟踪汇编代码,导致Hardfault的指令是LDRH,查看Cortex-M0+编程手册,明确了目的地址不对齐,会导致Hardfault异常,而LDRH访问的是16位数据,所以其访问的地址必须按照双字节对齐,也就是说hspi->pTxBuffer的地址必须是双字节对齐。查看变量值,hspi->pTxBuffer的地址为0x2000014B,显然不是一个符合对齐规则的地址。 1663768394f03ed18e.png

▲ 图2. Address alignment
那么问题来了,同样应用层代码,为何在STM32G0平台上没有出现问题,通过比较SPI HAL库驱动代码,STM32C0的驱动对数据类型进行了强制转换,该操作导致了问题。 4685168394efc6cfe6.png

▲ 图3. STM32G0 SPI HAL


3549268394ef454318.png

▲ 图4. STM32C0 SPI HAL

所以,基于STM32C0的这部分代码是存在隐患的,如果应用代码传递的数据buffer地址不是双字节对齐,就会导致这个问题。

03解决方案

针对问题原因,这里有两种解决方案。第一种方案,要求应用程序传递的数据Buffer地址按照双字节对齐,这个实现起来很容易,不同的编译器有不同的关键字设置变量地址对齐属性,如KEIL可以使用 __attribute__((aligned(2)))关键字即可保证变量地址是双字节对齐的。


第二种方案,微调SPI HAL代码,避免地址不对齐,参考代码如下。

1782868394ee9378fc.png

▲ 图5. 地址对齐
因为客户的应用代码有多出调用SPI HAL的语句,没法保证每个地方传递的数据Buffer地址都是按照双字节对齐的,所以最终采用了第二种方案解决其问题。

04注意事项

STM32C0 SPI HAL代码的隐患导致了该问题,在使用SPI HAL的过程中需要注意。

▼▼▼



相关阅读





 楼主| STM新闻官 发表于 2025-5-30 14:27 | 显示全部楼层
codingtuzi 发表于 2025-6-1 21:42 | 显示全部楼层
嵌入式开发内存对齐是一个非常重要的概念,一定要时刻铭记
小迷糊仙 发表于 2025-6-3 22:22 | 显示全部楼层
学习了 辛苦楼主
您需要登录后才可以回帖 登录 | 注册

本版积分规则

认证:意法半导体(中国)投资有限公司
简介:您的嵌入式应用将得益于意法半导体领先的产品架构、技术、多源产地和全方位支持。意法半导体微控制器和微处理器拥有广泛的产品线,包含低成本的8位单片机和基于ARM® Cortex®-M0、M0+、M3、M4、M33、M7及A7内核并具备丰富外设选择的32位微控制器及微处理器。

1349

主题

1618

帖子

23

粉丝
快速回复 在线客服 返回列表 返回顶部