本文最后更新于 2024-09-20,文章内容可能已经过时。

前言

主要描述通过MDK不复位调试cortex-M系列芯片的方式,以及修改启动汇编排查hardFault的过程记录。

MDK下的不断电复位

使用Jlink SWD调试方式。

准备工作

  • 保证手上有与设备内部一致、未编译、未修改的源程序,任何编译修改均会触发重编,进而触发下载(如果把下载的reset去掉,再使用不复位调试会出现什么现象?

  • 去掉MDK的Reset after Connect

  • 去掉MDK的Load Application at Startup

  • 别忘记烧写程序,随后就可以断开烧写器等待bug出现。

异常发生后排查

  • 找到原工程,切记不要修改!不要编译!

  • 直接ctrl+F5或者调试按钮进入调试

  • 此时调试界面的watch窗口、调用堆栈窗口等均无效,也无断点可打,属于正常现象,因为还未加载符号表等调试信息

  • 找到下方的Command,输入以下指令

LOAD %L INCREMENTAL

  • 可以看到所有的变量、堆栈等均可正常观察,此时调试与正常调试无差异。

注1:进入调试就会暂停程序执行,这个算常识提一下;

注2:可以把LOAD %L INCREMENTAL写到ini里,初始化文件中调用,但我没试过,但都上不复位调试了,还是减少点变量赶紧把错误排查完吧~;

排查HardFault过程记录(修改启动汇编文件实现异常参数记录)

启动文件中的修改:

HardFault_Handler\
                PROC				
				MOVS r0, #4
				MOV r1, LR
				TST r0, r1
				BEQ stacking_used_MSP
				MRS R0, PSP
				B get_LR_and_branch
stacking_used_MSP
				MRS R0, MSP
get_LR_and_branch
				MOV R1, LR
				IMPORT  hard_fault_handler_c
				BL hard_fault_handler_c
                ENDP

声明跳转函数:

void hard_fault_handler_c(unsigned int * hardfault_args, unsigned lr_value)
{
	unsigned int stacked_r0;
	unsigned int stacked_r1;
	unsigned int stacked_r2;
	unsigned int stacked_r3;
	unsigned int stacked_r12;
	unsigned int stacked_lr;
	unsigned int stacked_pc;
	unsigned int stacked_psr;
	stacked_r0 = ((unsigned long) hardfault_args[0]);
	stacked_r1 = ((unsigned long) hardfault_args[1]);
	stacked_r2 = ((unsigned long) hardfault_args[2]);
	stacked_r3 = ((unsigned long) hardfault_args[3]);
	stacked_r12 = ((unsigned long) hardfault_args[4]);
	stacked_lr = ((unsigned long) hardfault_args[5]);
	stacked_pc = ((unsigned long) hardfault_args[6]);
	stacked_psr = ((unsigned long) hardfault_args[7]);
	while(1)
	{
		printf ("[Hard fault handler]\n");
		printf ("R0 = %x\n", stacked_r0);
		printf ("R1 = %x\n", stacked_r1);
		printf ("R2 = %x\n", stacked_r2);
		printf ("R3 = %x\n", stacked_r3);
		printf ("R12 = %x\n", stacked_r12);
		printf ("Stacked LR = %x\n", stacked_lr);
		printf ("Stacked PC = %x\n", stacked_pc);
		printf ("Stacked PSR = %x\n", stacked_psr);
		printf ("Current LR = %x\n", lr_value);

		for(int i = 10000;i>0;i--)
			for(int j = 1000;j>0;j--);
	}
}