在线时间4746 小时
UID3441752
注册时间2017-11-21
NXP金币82795
TA的每日心情 | 开心 2025-7-11 08:53 |
---|
签到天数: 301 天 连续签到: 2 天 [LV.8]以坛为家I
管理员
  
- 积分
- 39227
- 最后登录
- 2025-7-18
|
恢复对执行WFI的NXP i.MX RT1064-EVK开发板的调试访问
使用控制器的低功耗模式非常具有挑战性。它会严重影响微处理器或微控制器的调试功能。我使用Tickless空闲模式将FreeRTOS应用程序移植到NXP i.MX RT1064开发板上,突然之间,开发板对任何调试器连接都没有响应。幸运的是,该开发板会并没有真正的变砖,但我花了很长时间才找到恢复它的方法。因此,当您最终遇到“变砖”的i.MX RT1064开发板时,本文可能对您有所帮助。
i.MX RT1064-EVK开发板
我使用FreeRTOS Tickkless模式来降低开发板的功耗。在该模式下,RTOS调用一个钩子HOOK,我可以在其中将CPU或开发板进入低功耗模式,并且它可以被接下来的任何中断唤醒,不管是Tick中断还是其他中断。最简单的方法是使用WFI(等待中断)指令:
- <font size="3" face="微软雅黑">/*
- ** ===================================================================
- ** Description :
- ** Used in tickless idle mode only, but required in this mode.
- ** Hook for the application to enter low power mode.
- ** Parameters :
- ** NAME - DESCRIPTION
- ** expectedIdleTicks - expected idle
- ** time, in ticks
- ** Returns : Nothing
- ** ===================================================================
- */
- void McuRTOS_vOnPreSleepProcessing(portTickType expectedIdleTicks)
- {
- (void)expectedIdleTicks; /* not used */
- __asm volatile("dsb");
- __asm volatile("wfi"); /* wait for interrupt: the next interrupt will wake us up */
- __asm volatile("isb");
- }</font>
复制代码 上述指令很有效,但直当我增加了滴答Tick和任务频率后,突然间,我再也无法使用调试器访问CPU :-(。在做了一些实验之后,这种现象似乎取决于开发板是否正在POR(上电复位)时进行调试访问。如果电路板没有进入电源循环,仍然可以进入调试模式。
无法与调试器连接
现象是调试器无法与内核通信,并且它收到了无效或错误的CpuID。这时,您可能会看到类似的东西,以下是我使用不同调试器(LinkServer、P&E和SEGGER)时Eclipse中的控制台输出:
LPC-Link2或ARM DAPLink(i.MX RT1064-EVK上的板载默认调试接口):可能会报告有关错误CpuID的信息:
- <font size="3" face="微软雅黑">Using memory from core 0 after searching for a good core
- connection failed - Ep(03). Invalid ID for processor... Retrying
- Using memory from core 0 after searching for a good core
- On debug connection reset using system reset
- Failed on connect: Ep(03). Invalid ID for processor.
- Connected&Reset. Was: NotConnected. DpID: 0BD11477. CpuID: 00000FFF. Info: <None>
- Last stub error 0: OK
- Last sticky error: 0x0 AIndex: 0
- Debug bus selected: MemAp 0
- DAP Speed test unexecuted or failed
- Debug protocol: SWD. RTCK: Disabled. Vector catch: Disabled.
- (100) Target Connection Failed</font>
复制代码 Segger J-Link可能无法在Coresight设置中找到内核:
- <font size="3" face="微软雅黑">Connecting to J-Link...
- J-Link is connected.
- Device "MIMXRT1064DVL6A" selected.
- Firmware: J-Trace PRO V1 Cortex-M compiled Oct 25 2018 11:48:19
- Hardware: V1.00
- S/N: 751000175
- Feature(s): RDI, FlashBP, FlashDL, JFlash, GDB
- Checking target voltage...
- Target voltage: 3.30 V
- Listening on TCP/IP port 2331
- Connecting to target...InitTarget() start
- InitTarget()
- _TargetHalt: CPU halted
- InitTarget() end
- Found SW-DP with ID 0x0BD11477
- 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: 0x04770041)
- Iterating through AP map to find AHB-AP to use
- AP[0]: Skipped. Invalid implementer code read from CPUIDVal[31:24] = 0xFF
- InitTarget() start
- InitTarget()
- _TargetHalt: CPU halted
- InitTarget() end
- Found SW-DP with ID 0x0BD11477
- 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: 0x04770041)
- Iterating through AP map to find AHB-AP to use
- AP[0]: Core found
- AP[0]: AHB-AP ROM base: 0xE00FD000
- CPUID register: 0x411FC271. Implementer code: 0x41 (ARM)
- Found Cortex-M7 r1p1, Little endian.
- FPUnit: 8 code (BP) slots and 0 literal slots
- CoreSight components:
- ROMTbl[0] @ E00FD000
- ROMTbl[0][0]: E00FE000, CID: B105100D, PID: 000BB4C8 ROM Table
- ROMTbl[1] @ E00FE000
- ROMTbl[1][0]: E00FF000, CID: B105100D, PID: 000BB4C7 ROM Table
- ROMTbl[2] @ E00FF000
- ROMTbl[2][0]: E000E000, CID: B105E00D, PID: 000BB00C SCS-M7
- ROMTbl[2][1]: E0001000, CID: B105E00D, PID: 000BB002 DWT
- ROMTbl[2][2]: E0002000, CID: B105E00D, PID: 000BB00E FPB-M7
- ROMTbl[2][3]: E0000000, CID: B105E00D, PID: 000BB001 ITM
- ROMTbl[1][1]: E0041000, CID: B105900D, PID: 001BB975 ETM-M7
- ROMTbl[1][2]: E0042000, CID: B105900D, PID: 004BB906 CTI
- ROMTbl[0][1]: E0040000, CID: B105900D, PID: 000BB9A9 TPIU-M7
- ROMTbl[0][2]: E0043000, CID: B105F00D, PID: 001BB101 TSG
- Cache: Separate I- and D-cache.
- I-Cache L1: 32 KB, 512 Sets, 32 Bytes/Line, 2-Way
- D-Cache L1: 32 KB, 256 Sets, 32 Bytes/Line, 4-Way
- ERROR: Could not find core in Coresight setup
- ERROR: Could not connect to target.
- Target connection failed. GDBServer will be closed...Restoring target state and closing J-Link connection...
- Shutting down...
- Could not connect to target.
- Please check power, connection and settings.
- Server has been shut down.</font>
复制代码 P&E Multilink Universal可能会提示无法下载.ARP文件进行编程:
- <font size="3" face="微软雅黑">Initializing.
- Target has been RESET and is active.
- CMD>CM C:\nxp\MCUXpressoIDE_10.3.0_2200\ide\plugins\com.pemicro.debug.gdbjtag.pne_3.9.2.201812122206\win32\gdi\P&E\supportFiles_ARM\NXP\iMX\nxp_imxrt1064_1x32x1meg.arp
-
- Initializing.
- Initialized.
-
- ;version 1.00, 08/29/2018, Copyright 2018 P&E Microcomputer Systems, www.pemicro.com
-
- ;device nxp, imxrt1064, 1x32x1meg,
-
- ;begin_cs device=$70000000, length=$00400000, ram=$00000000
-
- Loading programming algorithm ...
- Error loading .ARP file : C:\nxp\MCUXpressoIDE_10.3.0_2200\ide\plugins\com.pemicro.debug.gdbjtag.pne_3.9.2.201812122206\win32\gdi\P&E\supportFiles_ARM\NXP\iMX\nxp_imxrt1064_1x32x1meg.arp at address 00000000
- Error loading programming algorithm - load aborted.
- Error occured during Flash programming.
- PE-ERROR: Error downloading to the device.
- Disconnected from "127.0.0.1" via 127.0.0.1
- Disconnected from "127.0.0.1" via 127.0.0.1
- Target Disconnected.</font>
复制代码 以上所有这些情况,都表示着调试器无法访问内核。
WFI:等待中断
本例中,问题发生在使用'WFI',它用于FreeRTOS的tickless空闲模式。 'WFI'是'等待中断'ARM指令:它将挂起内核节省功耗,并在下一次中断到来时唤醒并继续执行
WaitForInterrupt
如果RTOS不经常进入低功耗模式,这对我来说很好。但是一旦内核进入低功耗模式,大约100 Hz,调试器就无法再连接了。我认为是调试器能够与内核通信,但是无法完成挂起序列,直到内核再次再次执行WFI:或者换句话说:调试连接需要10 ms以上才能暂停内核。如果内核在连接序列期间进入低功耗模式,则调试器将无法连接。
这是我在任何其他正在使用的Cortex-M上都没有看到的问题,可能是因为i.MX RT的执行速度比正在使用的其他人快得多(600 MHz!)。
我尝试了不同的方法来恢复电路板(例如尝试从IDE中擦除FLASH),但是没有用。我尝试使用SEGGER J-Link命令行工具来访问内核:但没有成功。
GPC(通用电源控制器)
i.MX RT1064控制器有一个GPC(通用电源控制器)。
在应用程序的开始调用
- <font size="3" face="微软雅黑">CLOCK_SetMode(kCLOCK_ModeRun);</font>
复制代码 这实际上会阻止CPU进入WAIT模式,并且在此阶段不会发生问题,因为只是禁用了WAIT模式。请参阅http://community.nxp.com/thread/492841#comment-1099054。
默认情况下,CLPCR [LPM]位置1。第13.6.3.2.1章说,在这种情况下,我必须配置'备用中断控制器',它应该被启用。本文已禁用ARM内核的NVIC。这可以解释为什么例如SysTick在我的RTOS中不再运行。
进入等待模式
恢复
另一种(更简单)恢复方法如下:1)确保没有调试连接处于活动状态。 b)开发板上电,等待它进入WAIT模式(在这种状态下你将无法访问它)。 c)按下电路板上的SW02按钮2秒钟,然后松开。 d)开发板现在应该重新启动,并且某种程度上SW02按下已将CPU设置为阻止进入等待模式的状态。 e)现在我可以再次调试电路板。
那么如何重新获得调试器对内核的访问权限呢?我的另一个想法是以不同的模式从不同的内存启动处理器,阻止它在其中执行带有WFI的代码。恩智浦i.MX RT1064提供三种不同的启动模式,可以使用电路板上的开关进行配置:
板默认引导配置
我将电路板启动模式更改为“串行下载”模式(SW7设置为0001)。
SW7设置为串行下载
有了这个,处理器正在执行引导ROM代码,我能够再次使用调试器。
附加到引导ROM代码
但是,在此模式下无法访问0x7000'0000的内部闪存,我无法将其擦除或直接访问。
Boot Utility
“Serial Download”的DIP开关在NXP i.MX RT1064上执行引导加载程序。该引导加载程序通过主机上的特殊工具通过MCU的USB端口进行通信,该工具可用于下载新固件。
设置这样的实用程序并使用它并不是那么简单。本文使用的是Jay Heng的'NXP Boot Utility':这个工具使我能够通过几个步骤重新获得对开发板的访问权限。
1. 按照http://github.com/JayHeng/NXP-MCUBootUtility/中的说明进行操作
2. 在SW7设置为0001的情况下以串行下载模式启动电路板:
SW7设置为串行下载
3. 电路板应枚举为USB HID设备,vID为0x1FC9,PID为0x0135
USB HID设备
4. 启动NXP-MCUBootUtility-1.0.0 \ bin \ NXP-MCUBootUtility.exe。选择器件并使用USB-HID。它应列出上面讨论的VID和PID。如果没有,请检查USB连接。
MCU NXP Boot Utility
5. 切换到“Master”模式:
主模式
6. 禁用“One Step”选项,然后连接到ROM:
连接到ROM
7. 有了这个,我们应该连接到ROM,你可以在一个单独的控制台窗口中看到执行的主机bootloader程序(sdphost)命令。
连接到ROM
8. 接下来单击“Connecte to Flashloader”按钮,状态现在应为绿色:
已连接
9. 按“配置启动设备”按钮,状态将变为蓝色。请注意有关设备状态中FlexSPI NOR内存配置的部分。只有使用这样的设置,工具才能使用内部FLASH正常运行,并使用0x0的偏移量(否则您必须指定偏移量或地址0x70000000):
已配置引导设备
10. 转到“Boot Device Memory”选项卡。将起始地址配置为0x70000000,大小为0x400000,然后按Erase。您可以在日志中验证正确的命令(如果失败,请参阅下面的故障排除部分):
擦除Flash
11. 现在应该擦除指定的内存区域。使用“读取”按钮进行验证(如果失败,请参阅下面的故障排除部分):
擦除内部闪存
12. 这已将所有闪存单元设置为0xffff'fffff。缺少的是编程正确的Flash描述符。这是通过MCUXpresso IDE完成的。在MCUXpresso IDE中打开GUI Flash Tool,为RT1064选择一个工作项目(例如blinky):
GUI Flash工具
13. 然后进行批量擦除(请注意,这将执行批量擦除并编程):
进行批量擦除
14. 这应该成功如下:
Flash Erase已完成
15. 使用Utility检查闪存现在应该显示它具有正确的数据头:
正确的闪存数据头
16. 现在使用MCUXpresso GUI Flash编程器为MCU编写一个“已知良好”的应用程序(例如,一个闪烁的):
编程应用
17. 这应该成功:
成功编程Flash
18. 现在将SW7设置为从内部FLASH(SW7:0010)启动,复位开发板,并运行编程的应用程序(例如,blinky)。
19. 现在开发板恢复调试了。
故障排除
在某些情况下,Boot Utility似乎不会发送正确的参数。您可以在日志和控制台输出中看到此信息,如下所示:
错读内存
在这种情况下,从日志中复制命令行,将其粘贴到系统控制台,例如,我使用了以下(当实用程序仍在运行时):
- <font size="3" face="微软雅黑">C:\nxp\McuBootUtility\NXP-MCUBootUtility-1.0.0\tools\blhost\win\blhost -t 6573000 -u 0x15A2,0x0073 -j -- flash-erase-region 0x70000000 0x40000 9</font>
复制代码
从Cmd.exe执行Flash擦除
建议:Safety Belt
我推荐用于任何其他低功耗实验的是添加一种安全带代码:上电后系统等待(并闪烁)一段时间以允许我在进入“危险”区域之前连接到它低功耗模式:
安全带代码
这允许我在出现问题时捕获目标。这样的代码在生产系统中甚至可能是有帮助的,例如,如果在上电期间按下按钮,则执行此操作。
总结
处理“无Flash”器件可能会非常棘手。虽然恩智浦i.MX RT1064具有片上器件,但它实际上就像是内部绑定的QSPI闪存器件。为了让CPU从中启动,需要在其中放置明确定义的数据头(Flash描述)。如果此数据头已损坏,应用程序行为不正常,或内存被擦除,则调试器可能无法再访问MCU。本文的这种情况下,FreeRTOS应用程序执行WFI指令的速度非常快,以至于无法再访问MCU。 MCUXpresso IDE、i.MX RT1064引导程序(串行加载程序)和NXP Boot Utility的组合最终帮助我“恢复正常”。如果您遇到相同的情况,上述步骤和说明有望为您提供帮助。
作者:阿哲 文章出处:点击
|
|