ARM学习(41)NXP MCU总线挂死,CPU could not be halted以及无法连接Jink
笔者最近在用NXP的MCU,经常会碰到CPU could not be halted,今天就来聊一下原因和如何解决
1、背景情况说明
如下图所示,笔者在遇到Ozone链接的时候,CPU could not be halted的情况,原因就是访问了非法地址,或者在SDRAM没初始化的时候,就访问了其地址。
2、解决方案
原因就是芯片访问异常地址,然后没有地址保护,CPU一直等待总线返回,导致其他外设无法使用总线,则就无法连接jink,CPU也显示一直在忙,无法停下来。
比如下面这段代码,就会导致总线挂死,因为0xF0000000是非法地址。
int* test_data_ptr = ( int*)0xF0000000;
*test_data_ptr = 0x1234;
printf("*test_data_ptr=%d\r\n",*test_data_ptr);
2.1 芯片上电就卡死,无法烧录
芯片上电就卡死,说明跑到了异常程序,就无法连接jink了,如何不跑到异常程序呢?
解决方案:可以修改程序启动方式,让其停留在rom 代码里面,则可以正常烧录。以NXP54016为例,如下表和图所示。详细可以看笔者这篇文章ARM学习(0)NXP MCU BootLoader的理解与实现。
Boot mode | ISP2 | ISP1 | ISP0 | note |
---|---|---|---|---|
Auto boot | 1 | 1 | 1 | Image有效,则跳入Image程序,否则停留ROM |
ISP(UART/SPI/IIC) | 1 | 1 | 0 | 停留在ISP ROM |
所以修改ISP BOOT0引脚为低电平之后,则芯片上电会停留在ROM里面,此时可以烧录程序。
2.2 芯片异常地址保护
如果正面分析问题。如何解决非法地址访问就挂死的情况呢?
解决方案:通过MPU进行地址保护,将非法地址配成无法访问的属性,一旦CPU访问,则会被MPU抓住现场,进入异常。
还是上面的例子,访问0xF0000000,CM4下面的MPU配置如下:
void mpu_config()
{
/* Disable MPU */
ARM_MPU_Disable();
MPU->RBAR = ARM_MPU_RBAR(0, 0xF0000000);
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_NONE, 0, 0, 1, 0, 0, ARM_MPU_REGION_SIZE_1MB);
/* Enable MPU */
ARM_MPU_Enable(MPU_CTRL_PRIVDEFENA_Msk | MPU_CTRL_HFNMIENA_Msk);
}
配置之后,异常地址会被MPU抓住,如下面图所示,进入MemFault异常处理函数,异常地址有效且异常地址为:0xF0000000,
还可以看到PC的异常位置,0x1000340A地址,就是数据写入到异常地址的指令。
3、参考
1、NXP_LPC540_UM.pdf
2、Ozone 调试信息
Device "LPC54016" selected.
Found SW-DP with ID 0x2BA01477
DPv0 detected
Scanning AP map to find all available APs
AP[1]: Stopped AP scan as end of AP map has been reached
AP[0]: AHB-AP (IDR: 0x24770011)
Iterating through AP map to find AHB-AP to use
AP[0]: Core found
AP[0]: AHB-AP ROM base: 0xE00FF000
CPUID register: 0x410FC241. Implementer code: 0x41 (ARM)
Found Cortex-M4 r0p1, Little endian.
FPUnit: 6 code (BP) slots and 2 literal slots
CoreSight components:
ROMTbl[0] @ E00FF000
ROMTbl[0][0]: E000E000, CID: B105E00D, PID: 000BB00C SCS-M7
ROMTbl[0][1]: E0001000, CID: B105E00D, PID: 003BB002 DWT
ROMTbl[0][2]: E0002000, CID: B105E00D, PID: 002BB003 FPB
ROMTbl[0][3]: E0000000, CID: B105E00D, PID: 003BB001 ITM
ROMTbl[0][4]: E0040000, CID: B105900D, PID: 000BB9A1 TPIU
ROMTbl[0][5]: E0041000, CID: B105900D, PID: 000BB925 ETM
Connected to target device.
ResetTarget() start
ResetTarget() end
AfterResetTarget() start
AfterResetTarget() end
Elf.GetBaseAddr(); // returns 0x0
Target.ReadU32 (0x00000000); // returns 0x30000
Target.SetReg ("SP", 0x30000);
Elf.GetEntryPointPC(); // returns 0x1000025C
Target.SetReg ("PC", 0x1000025C);
J-Link: Flash download: Bank 0 @ 0x10000000: 1 range affected (65536 bytes)
J-Link: Flash download: Total: 1.025s (Prepare: 0.274s, Compare: 0.325s, Erase: 0.116s, Program & Verify: 0.302s, Restore: 0.006s)
J-Link: Flash download: Program & Verify speed: 212 KB/s
Elf.GetBaseAddr(); // returns 0x0
Target.ReadU32 (0x00000000); // returns 0x30000
Target.SetReg ("SP", 0x30000);
Elf.GetEntryPointPC(); // returns 0x1000025C
Target.SetReg ("PC", 0x1000025C);
Debug.Continue();
Startup complete (PC=0x10000570)
Debug.Halt();
CPU could not be halted
Debug.Halt();
CPU could not be halted
Debug.Halt();
CPU could not be halted
Debug.Halt();
CPU could not be halted
Debug.Halt();
CPU could not be halted
Debug.Stop();
CPU could not be halted
Could not read memory location 0x2000042C when trying to clear soft RAM BP
Failed to clear soft BP in RAM @ 0x2000042C
Could not start CPU core. (ErrorCode: -2)
Could not read memory location 0x2000042C when trying to clear soft RAM BP
Failed to clear soft BP in RAM @ 0x2000042C
Could not start CPU core. (ErrorCode: -2)
Disconnected from target device.
Debug.Start();
Device "LPC54016" selected.
Found SW-DP with ID 0x2BA01477
Failed to power up DAP
Found SW-DP with ID 0x2BA01477
Failed to power up DAP
Found SW-DP with ID 0x2BA01477
Failed to power up DAP
Found SW-DP with ID 0x2BA01477
Failed to power up DAP
作者:张一西