S32DS平台上使用DWT模块进行代码时间计算和利用脚本文件进行问题定位

DWT(Data Watchpoint And Trace Unit),是 ARM Cortex M 系列内核(ARM
Cortex-M V7(K1 M4F, K3, M7))提供的数据监测点和跟踪单元,以支持数据断点
功能。
。CYCCNT 是一个 32BIT 的 UP
计数器,记录内核时钟的运行个数,内核时钟跳动一次,改计数器就加 1,对
K3X4 内核时钟最高 160M,每个时钟节拍周期是 6.25ns,最长能记录 26.84S。
要实现时间测量功能,总共涉及到三个寄存器,DEMCR, DWT_CTRL,
DWT_CYCCNT,分别用于开启 DWT 功能,开启 CYCCNT 及获得系统时钟计数
值。关于这三个寄存器更详细的说明,请参考”Armv7-M Architecture
Ref

  1. 修改在S32K3xx【xx是型号】.mac 文件(该文件是 PE Micro 调试工具下的一个脚本文件)
    在该
    脚本里可以执行一些寄存器的初始化,该脚本在 CPU Core 运行起来之前由调
    试器加载,解释,并执行)开启 DWT,和 CYCCNT 并清空 CYCNT。
REM Enable DWT CYCCNT:
mm.1 $E000EDFC $010007F0
mm.1 $E0001000 $40000001
mm.1 $E0001004 $00000000
delay 20

注意:在这里我找不到实际调用的文件,所以我在main.c直接往地址写入了。

(*(volatile uint32*)0xE000EDFC) =0x010007F0; (*(volatile uint32*)0xE0001000) =0x40000001; (*(volatile uint32*)0xE0001004) =0x00000000;

  1. 在 Expressions 窗口添加 DWT_CTRL 和 DWT_CYCCNT 寄存器

利用脚本文件进行hardfault问题定位

set language c
define armex
	printf "EXEC_RETURN (LR):\n",
	info registers $lr
		if (((unsigned int)$lr & 0x04) == 0x4)
			printf "Uses PSP 0x%x return.\n",$psp
			set $armex_base = (unsigned int)$psp
		else
			printf "Uses MSP 0x%x return.\n", $msp
			set $armex_base =(unsigned int)$msp
		end
		
		printf "xPSR 		0x%x\n",*($armex_base+28)
		printf "ReturnAddress 		0x%x\n",*($armex_base+24)
		printf "LR(R14) 		0x%x\n",*($armex_base+20)
		printf "R12 		0x%x\n",*($armex_base+16)
		printf "R3 		0x%x\n",*($armex_base+12)
		printf "R2 		0x%x\n",*($armex_base+8)
		printf "R1 		0x%x\n",*($armex_base+4)
		printf "R0 		0x%x\n",*($armex_base)
		printf "Return instruction:\n"
		x/i *($armex_base +24)
		printf "LR instruction:\n"
		x/i *($armex_base+20)
end

document armex
ARMv7 Exception entry bebavior.
xPSR, ReturnAddress,LR,R12,R14,R3,R2,R1,and R0
end
			

在 Window->Preferences->GDB 配置.gdbinit 脚本路径

HardFault 产生后,在 Debugger Console 窗口输入自定义的 armex 命令,可以
看到之前手工分析的栈数据回溯被自动的解析出来。根据这些信息可以看到,
代码执行到 0x0040196b 后执行了非法地址 0xe000000 访问导致了 HardFault.

查看堆栈信息定位hardfault问题

Cortex-M MCU 在接收到
一个异常后,芯片硬件会自动将 8 个通用寄存器(依次为 R0~R3, R12, LR, PC,
xPSR)压入到当前栈空间。Cortex-M MCU 有两个栈 MSP 主栈和 PSP 线程
栈。异常发生后 LR 会被更新为异常返回时需要用到的特殊值
EXC_RETURN,其中 BIT2 指示了当前用到的栈是 MSP 还是 PSP。了解到了
异常时 MCU 寄存器保存情况,我们就很容易找到发生异常时的指令地址即
PC

(注:S32DS 的 Registers 窗口只能看到 MSP,看不到 PSP), 如图根据 SP:
0x2042efc0,可以看到异常产生后保存在 MSP 栈上的 8 个通用寄存器的值,
PC:0xe000000, 异常时的 PC,该地址是一个非法的地址。LR:
0x0040196b,异常返回地址,根据这些信息可以看到,代码执行到
0x0040196b 后执行了非法地址 0xe000000 访问导致了 HardFault

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值