硬汉嵌入式论坛

 找回密码
 立即注册
查看: 303|回复: 7
收起左侧

[LVGL] LVGL使用DTCM出现hardfault问题

[复制链接]

2

主题

7

回帖

13

积分

新手上路

积分
13
发表于 2025-4-8 09:25:25 | 显示全部楼层 |阅读模式
大哥们,我最近遇到个hardfault的问题想请教下大家。

MCU:STM32H7   LVGL版本:8.3.4
问题描述:LVGL的内存池使用STM32内部DTCM,DTCM为128KB,有效地址为0x20000000~0x2001FFFF。将内存分配给LVGL中的work_mem_int中,也就是LVGL内存池,运行一段时间后,会直接导致hardfault,排查原因为LVGL对0x20020000地址进行读访问导致地址不可用。
现在RAM地址给小了在测试了,拷机暂时还没再出现问题。我又做了个验证:将RAM地址给小,再将RAM存储区内容开机全初始化为0,然后运行LVGL程序,发现还是会偶现hardfault问题。我现在就是不太明白这个事情的根本原因,害怕RAM地址给小只是降低了出现概率没解决根本问题。
回复

使用道具 举报

2

主题

7

回帖

13

积分

新手上路

积分
13
 楼主| 发表于 2025-4-8 09:33:46 | 显示全部楼层
本帖最后由 lhh 于 2025-4-8 09:51 编辑

下边是发生hardfault时使用H7-TOOL进行异常分析的结果,顺便说下H7-TOOL异常分析的功能真好用,解释的很清晰。

2023-02-23 V1.0   
============================================================   
=========寄存器值读取========================================   
============================================================   
R0 = 0000000a   
R1 = 01602806   
R2 = 00000000   
R3 = 0660c819   
R4 = c02e9124   
R5 = 20020000   
R6 = c02d45b6   
R7 = 2000b492   
R8 = 000000ff   
R9 = 0000000e   
R10 = 000000d2   
R11 = 0000001c   
R12 = 000000ff   
R13(SP) = 24043a98   
R14(LR) = fffffffd   
R15(PC) = 08055fe6   
xPSR = a1000003   

   
------------------------------------------------------------------   
Read System Handler Control and State Register SHCSR = 0x00010000   
------------------------------------------------------------------   
MEMFAULTACT = 0   
BUSFAULTACT = 0   
USGFAULTACT = 0   
SVCALLACT = 0   
MONITORACT = 0   
PENDSVACT = 0   
SYSTICKACT = 0   
USGFAULTPENDED = 0   
MEMFAULTPENDED = 0   
BUSFAULTPENDED = 0   
SVCALLPENDED = 0   
MEMFAULTENA = 1, Memory management fault 异常使能   
BUSFAULTENA = 0   
USGFAULTENA = 0   

   
------------------------------------------------------------------   
Read HardFault Status Register HSFR Register = 0x40000000   
------------------------------------------------------------------   
VECTBL = 0, 中断向量表无Bus Fault   
FORCED = 1, forced Hard Fault   
            Indicates a forced Hard Fault, generated by escalation of a fault with configurable   
            priority that cannot be handled, either because of priority or because it is disabled   
            When this bit is set, the Hard Fault handler must read the other fault status registers   
            to find the cause of the fault   

   
------------------------------------------------------------------   
MemManage Status Register (MMFSR) = 0x00   
------------------------------------------------------------------   
IACCVIOL = 0, 无指令访问冲突错误   
DACCVIOL = 0,  无数据访问异常   
MUNSTKERR = 0,  出栈正常   
MSTKERR = 0,  入栈正常   
MLSPERR = 0,  浮点lazy stacking特性保存期间未发生故障   
MMARVALID = 0,  SCB->MMFAR寄存器没有记录异常地址   

   
------------------------------------------------------------------   
MemManage Address Register (MMFAR) = 0x20020000   
------------------------------------------------------------------   
Data address for a MemManage fault. This register is updated with the address of a location   
that produced a MemManage fault. The MMFSR shows the cause of the fault. This field is valid   
only when MMFSR.MMARVALID is set. In implementations without unique BFAR and MMFAR   
registers, the value of this register is UNKNOWN if BFSR.BFARVALID is set   

   
------------------------------------------------------------------   
BusFault Status Register (BFSR) = 0x82   
------------------------------------------------------------------   
IBUSERR = 0, 指令总线正常   
PRECISERR = 1, 精确的数据总线访问异常   
            a data bus error has occurred, and the PC value stacked for the exception return points to   
            the instruction that caused the fault.   
            When the processor sets this bit, it writes the faulting address to BFAR.   
IMPRECISERR = 0, 数据总线正常   
UNSTKERR = 0, 中断出栈时正常   
STKERR = 0, 中断入栈时正常   
LSPERR = 0, 浮点lazy stacking特性保存期间未生故障   
BFARVALID = 1, BFAR寄存器记录有效的异常地址   
            The processor sets this bit after a BusFault where the address is known. Other faults can set this   
            bit to 0, such as a MemManage fault occurring later. If a BusFault occurs and is escalated to a   
            HardFault because of priority, the HardFault handler must set this bit to 0. This prevents   
            problems if returning to a stacked active BusFault handler who is BFAR value has been   
            overwritten.   

   
------------------------------------------------------------------   
BusFault Address Register (BFAR) = 0x20020000   
------------------------------------------------------------------   
Data address for a precise BusFault. This register is updated with the address of a location that   
produced a BusFault. The BFSR shows the reason for the fault. This field is valid only when   
BFSR.BFARVALID is set. In implementations without unique BFAR and MMFAR registers, the   
value of this register is UNKNOWN if MMFSR.MMARVALID is set   

   
------------------------------------------------------------------   
UsageFault Status Register (UFSR) = 0x0000   
------------------------------------------------------------------   
UNDEFINSTR = 0, 处理器访问指令正常   
INVSTATE = 0, 没有无效状态   
INVPC = 0, PC加载正常   
NOCP = 0, 访问协处理正常   
UNALIGNED = 0, 内存对齐访问正常   
DIVBYZERO = 0,  无除数为0的异常, 或者没有使能除数为0的异常   

   
============================================================   
=========异常进一步分析======================================   
============================================================   
进入和退出中断使用PSP, 返回线程模, 进入中断前没有使用硬件浮点单元   
进入硬件异常前, 寄存器数值, 如果出现非精确异常, 这些值是不准确的:   
R0 = 00000000   
R1 = 240196fc   
R2 = 080b3618   
R3 = 0000084b   
R12 = 080ae17d   
LR = 080a8ab5   
PC = 080a8acc   
PSR = 61000000   


回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115433
QQ
发表于 2025-4-8 10:44:46 | 显示全部楼层
看下是不是DMA2D或者通用DMA对这个地址空间做加速UI处理了,如果有,这个DTCM仅支持MDMA。
回复

使用道具 举报

2

主题

7

回帖

13

积分

新手上路

积分
13
 楼主| 发表于 2025-4-8 13:38:57 | 显示全部楼层
eric2013 发表于 2025-4-8 10:44
看下是不是DMA2D或者通用DMA对这个地址空间做加速UI处理了,如果有,这个DTCM仅支持MDMA。

我检查了下DTCM的部分没有使用DMA
回复

使用道具 举报

1

主题

4

回帖

7

积分

新手上路

积分
7
发表于 2025-4-14 10:12:54 | 显示全部楼层
startup启动文件堆栈是不是太小了 改到0x1000去
回复

使用道具 举报

2

主题

7

回帖

13

积分

新手上路

积分
13
 楼主| 发表于 2025-4-14 10:31:49 | 显示全部楼层
13540437025 发表于 2025-4-14 10:12
startup启动文件堆栈是不是太小了 改到0x1000去

我现在都是0x2000
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115433
QQ
发表于 2025-4-15 09:50:53 | 显示全部楼层
lhh 发表于 2025-4-8 09:33
下边是发生hardfault时使用H7-TOOL进行异常分析的结果,顺便说下H7-TOOL异常分析的功能真好用,解释的很清 ...

根据这个提示是 0x20020000 地址访问异常了,超出了DTCM大小,我怀疑你的程序有内存访问溢出问题,也就是数组或者变量访问越界了。

另外就是野指针问题。

我觉得还可以这也排查下,看看是不是你的应用程序造成的,你换个简单的hello world字符展示,是不是没有溢出问题。
回复

使用道具 举报

677

主题

3458

回帖

5514

积分

论坛元老

积分
5514
发表于 2025-4-16 11:06:42 | 显示全部楼层
本帖最后由 hpdell 于 2025-4-16 11:08 编辑

我使用 lvgl 分配的内存池只给了 64KB , 也没有出现你说的那个情况呀, 我的内存池使用的 0x2400 xx , 你吧 sdram 的 SDRAM_MODEREG_BURST_LENGTH_4 改成这个试试看

我目前的单屏界面最大使用都没有超过 40KB , 所以我给 64KB 足够,你可以开启 lvgl 内存池监测 看看?

如果监测内存池超出了范围你可以调整界面布局使用的控件 以减少内存池的使用
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-4-25 15:12 , Processed in 1.099346 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表