查看: 5802|回复: 0

[分享] 恢复对执行WFI的NXP i.MX RT1064-EVK开发板的调试访问

[复制链接]
  • TA的每日心情
    开心
    2025-7-11 08:53
  • 签到天数: 301 天

    连续签到: 2 天

    [LV.8]以坛为家I

    3868

    主题

    7472

    帖子

    0

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    39227
    最后登录
    2025-7-18
    发表于 2020-3-4 15:45:47 | 显示全部楼层 |阅读模式
    恢复对执行WFI的NXP i.MX RT1064-EVK开发板的调试访问



    使用控制器的低功耗模式非常具有挑战性。它会严重影响微处理器或微控制器的调试功能。我使用Tickless空闲模式将FreeRTOS应用程序移植到NXP i.MX RT1064开发板上,突然之间,开发板对任何调试器连接都没有响应。幸运的是,该开发板会并没有真正的变砖,但我花了很长时间才找到恢复它的方法。因此,当您最终遇到“变砖”的i.MX RT1064开发板时,本文可能对您有所帮助。

    1.png

    i.MX RT1064-EVK开发板



    我使用FreeRTOS Tickkless模式来降低开发板的功耗。在该模式下,RTOS调用一个钩子HOOK,我可以在其中将CPU或开发板进入低功耗模式,并且它可以被接下来的任何中断唤醒,不管是Tick中断还是其他中断。最简单的方法是使用WFI(等待中断)指令:

    1. <font size="3" face="微软雅黑">/*
    2. ** ===================================================================
    3. ** Description :
    4. ** Used in tickless idle mode only, but required in this mode.
    5. ** Hook for the application to enter low power mode.
    6. ** Parameters :
    7. ** NAME - DESCRIPTION
    8. ** expectedIdleTicks - expected idle
    9. ** time, in ticks
    10. ** Returns : Nothing
    11. ** ===================================================================
    12. */
    13. void McuRTOS_vOnPreSleepProcessing(portTickType expectedIdleTicks)
    14. {
    15. (void)expectedIdleTicks; /* not used */
    16. __asm volatile("dsb");
    17. __asm volatile("wfi"); /* wait for interrupt: the next interrupt will wake us up */
    18. __asm volatile("isb");
    19. }</font>
    复制代码
    上述指令很有效,但直当我增加了滴答Tick和任务频率后,突然间,我再也无法使用调试器访问CPU :-(。在做了一些实验之后,这种现象似乎取决于开发板是否正在POR(上电复位)时进行调试访问。如果电路板没有进入电源循环,仍然可以进入调试模式。


    无法与调试器连接


    现象是调试器无法与内核通信,并且它收到了无效或错误的CpuID。这时,您可能会看到类似的东西,以下是我使用不同调试器(LinkServer、P&E和SEGGER)时Eclipse中的控制台输出:


    LPC-Link2或ARM DAPLink(i.MX RT1064-EVK上的板载默认调试接口):可能会报告有关错误CpuID的信息:

    1. <font size="3" face="微软雅黑">Using memory from core 0 after searching for a good core
    2. connection failed - Ep(03). Invalid ID for processor... Retrying
    3. Using memory from core 0 after searching for a good core
    4. On debug connection reset using system reset
    5. Failed on connect: Ep(03). Invalid ID for processor.
    6. Connected&Reset. Was: NotConnected. DpID: 0BD11477. CpuID: 00000FFF. Info: <None>
    7. Last stub error 0: OK
    8. Last sticky error: 0x0 AIndex: 0
    9. Debug bus selected: MemAp 0
    10. DAP Speed test unexecuted or failed
    11. Debug protocol: SWD. RTCK: Disabled. Vector catch: Disabled.
    12. (100) Target Connection Failed</font>
    复制代码
    Segger J-Link可能无法在Coresight设置中找到内核:
    1. <font size="3" face="微软雅黑">Connecting to J-Link...
    2. J-Link is connected.
    3. Device "MIMXRT1064DVL6A" selected.
    4. Firmware: J-Trace PRO V1 Cortex-M compiled Oct 25 2018 11:48:19
    5. Hardware: V1.00
    6. S/N: 751000175
    7. Feature(s): RDI, FlashBP, FlashDL, JFlash, GDB
    8. Checking target voltage...
    9. Target voltage: 3.30 V
    10. Listening on TCP/IP port 2331
    11. Connecting to target...InitTarget() start
    12. InitTarget()
    13. _TargetHalt: CPU halted
    14. InitTarget() end
    15. Found SW-DP with ID 0x0BD11477
    16. Scanning AP map to find all available APs
    17. AP[1]: Stopped AP scan as end of AP map has been reached
    18. AP[0]: AHB-AP (IDR: 0x04770041)
    19. Iterating through AP map to find AHB-AP to use
    20. AP[0]: Skipped. Invalid implementer code read from CPUIDVal[31:24] = 0xFF
    21. InitTarget() start
    22. InitTarget()
    23. _TargetHalt: CPU halted
    24. InitTarget() end
    25. Found SW-DP with ID 0x0BD11477
    26. Scanning AP map to find all available APs
    27. AP[1]: Stopped AP scan as end of AP map has been reached
    28. AP[0]: AHB-AP (IDR: 0x04770041)
    29. Iterating through AP map to find AHB-AP to use
    30. AP[0]: Core found
    31. AP[0]: AHB-AP ROM base: 0xE00FD000
    32. CPUID register: 0x411FC271. Implementer code: 0x41 (ARM)
    33. Found Cortex-M7 r1p1, Little endian.
    34. FPUnit: 8 code (BP) slots and 0 literal slots
    35. CoreSight components:
    36. ROMTbl[0] @ E00FD000
    37. ROMTbl[0][0]: E00FE000, CID: B105100D, PID: 000BB4C8 ROM Table
    38. ROMTbl[1] @ E00FE000
    39. ROMTbl[1][0]: E00FF000, CID: B105100D, PID: 000BB4C7 ROM Table
    40. ROMTbl[2] @ E00FF000
    41. ROMTbl[2][0]: E000E000, CID: B105E00D, PID: 000BB00C SCS-M7
    42. ROMTbl[2][1]: E0001000, CID: B105E00D, PID: 000BB002 DWT
    43. ROMTbl[2][2]: E0002000, CID: B105E00D, PID: 000BB00E FPB-M7
    44. ROMTbl[2][3]: E0000000, CID: B105E00D, PID: 000BB001 ITM
    45. ROMTbl[1][1]: E0041000, CID: B105900D, PID: 001BB975 ETM-M7
    46. ROMTbl[1][2]: E0042000, CID: B105900D, PID: 004BB906 CTI
    47. ROMTbl[0][1]: E0040000, CID: B105900D, PID: 000BB9A9 TPIU-M7
    48. ROMTbl[0][2]: E0043000, CID: B105F00D, PID: 001BB101 TSG
    49. Cache: Separate I- and D-cache.

    50. I-Cache L1: 32 KB, 512 Sets, 32 Bytes/Line, 2-Way
    51. D-Cache L1: 32 KB, 256 Sets, 32 Bytes/Line, 4-Way
    52. ERROR: Could not find core in Coresight setup
    53. ERROR: Could not connect to target.
    54. Target connection failed. GDBServer will be closed...Restoring target state and closing J-Link connection...
    55. Shutting down...
    56. Could not connect to target.
    57. Please check power, connection and settings.

    58. Server has been shut down.</font>
    复制代码
    P&E Multilink Universal可能会提示无法下载.ARP文件进行编程:
    1. <font size="3" face="微软雅黑">Initializing.
    2. Target has been RESET and is active.
    3. 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

    4. Initializing.
    5. Initialized.

    6. ;version 1.00, 08/29/2018, Copyright 2018 P&E Microcomputer Systems, www.pemicro.com

    7. ;device nxp, imxrt1064, 1x32x1meg,

    8. ;begin_cs device=$70000000, length=$00400000, ram=$00000000

    9. Loading programming algorithm ...
    10. 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
    11. Error loading programming algorithm - load aborted.
    12. Error occured during Flash programming.
    13. PE-ERROR: Error downloading to the device.
    14. Disconnected from "127.0.0.1" via 127.0.0.1
    15. Disconnected from "127.0.0.1" via 127.0.0.1
    16. Target Disconnected.</font>
    复制代码
    以上所有这些情况,都表示着调试器无法访问内核。


    WFI:等待中断


    本例中,问题发生在使用'WFI',它用于FreeRTOS的tickless空闲模式。 'WFI'是'等待中断'ARM指令:它将挂起内核节省功耗,并在下一次中断到来时唤醒并继续执行

    2.png

    WaitForInterrupt



    如果RTOS不经常进入低功耗模式,这对我来说很好。但是一旦内核进入低功耗模式,大约100 Hz,调试器就无法再连接了。我认为是调试器能够与内核通信,但是无法完成挂起序列,直到内核再次再次执行WFI:或者换句话说:调试连接需要10 ms以上才能暂停内核。如果内核在连接序列期间进入低功耗模式,则调试器将无法连接。


    这是我在任何其他正在使用的Cortex-M上都没有看到的问题,可能是因为i.MX RT的执行速度比正在使用的其他人快得多(600 MHz!)。



    我尝试了不同的方法来恢复电路板(例如尝试从IDE中擦除FLASH),但是没有用。我尝试使用SEGGER J-Link命令行工具来访问内核:但没有成功。




    GPC(通用电源控制器)


    i.MX RT1064控制器有一个GPC(通用电源控制器)。


    在应用程序的开始调用

    1. <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中不再运行。

    3.png

    进入等待模式



    恢复


    另一种(更简单)恢复方法如下:1)确保没有调试连接处于活动状态。 b)开发板上电,等待它进入WAIT模式(在这种状态下你将无法访问它)。 c)按下电路板上的SW02按钮2秒钟,然后松开。 d)开发板现在应该重新启动,并且某种程度上SW02按下已将CPU设置为阻止进入等待模式的状态。 e)现在我可以再次调试电路板。




    那么如何重新获得调试器对内核的访问权限呢?我的另一个想法是以不同的模式从不同的内存启动处理器,阻止它在其中执行带有WFI的代码。恩智浦i.MX RT1064提供三种不同的启动模式,可以使用电路板上的开关进行配置:

    4.png

    板默认引导配置



    我将电路板启动模式更改为“串行下载”模式(SW7设置为0001)。

    5.png

    SW7设置为串行下载



    有了这个,处理器正在执行引导ROM代码,我能够再次使用调试器。

    6.png

    附加到引导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的情况下以串行下载模式启动电路板:

    7.png

    SW7设置为串行下载



    3.    电路板应枚举为USB HID设备,vID为0x1FC9,PID为0x0135

    8.png

    USB HID设备



    4.    启动NXP-MCUBootUtility-1.0.0 \ bin \ NXP-MCUBootUtility.exe。选择器件并使用USB-HID。它应列出上面讨论的VID和PID。如果没有,请检查USB连接。

    9.png

    MCU NXP Boot Utility



    5.  切换到“Master”模式:

    10.png

    主模式



    6.  禁用“One Step”选项,然后连接到ROM:

    11.png

    连接到ROM



    7.  有了这个,我们应该连接到ROM,你可以在一个单独的控制台窗口中看到执行的主机bootloader程序(sdphost)命令。

    12.png

    连接到ROM



    8.  接下来单击“Connecte to Flashloader”按钮,状态现在应为绿色:

    13.png

    已连接



    9.  按“配置启动设备”按钮,状态将变为蓝色。请注意有关设备状态中FlexSPI NOR内存配置的部分。只有使用这样的设置,工具才能使用内部FLASH正常运行,并使用0x0的偏移量(否则您必须指定偏移量或地址0x70000000):

    14.png

    已配置引导设备



    10.  转到“Boot Device Memory”选项卡。将起始地址配置为0x70000000,大小为0x400000,然后按Erase。您可以在日志中验证正确的命令(如果失败,请参阅下面的故障排除部分):

    15.png

    擦除Flash



    11.  现在应该擦除指定的内存区域。使用“读取”按钮进行验证(如果失败,请参阅下面的故障排除部分):

    16.png

    擦除内部闪存



    12.  这已将所有闪存单元设置为0xffff'fffff。缺少的是编程正确的Flash描述符。这是通过MCUXpresso IDE完成的。在MCUXpresso IDE中打开GUI Flash Tool,为RT1064选择一个工作项目(例如blinky):

    17.png

    GUI Flash工具



    13.   然后进行批量擦除(请注意,这将执行批量擦除并编程):

    18.png

    进行批量擦除



    14.  这应该成功如下:

    19.png

    Flash Erase已完成



    15.  使用Utility检查闪存现在应该显示它具有正确的数据头:

    20.png

    正确的闪存数据头



    16.  现在使用MCUXpresso GUI Flash编程器为MCU编写一个“已知良好”的应用程序(例如,一个闪烁的):

    21.png

    编程应用



    17.  这应该成功:

    22.png

    成功编程Flash



    18.  现在将SW7设置为从内部FLASH(SW7:0010)启动,复位开发板,并运行编程的应用程序(例如,blinky)。


    19.  现在开发板恢复调试了。


    故障排除


    在某些情况下,Boot Utility似乎不会发送正确的参数。您可以在日志和控制台输出中看到此信息,如下所示:

    23.png

    错读内存



    在这种情况下,从日志中复制命令行,将其粘贴到系统控制台,例如,我使用了以下(当实用程序仍在运行时):

    1. <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>
    复制代码
    24.png

    从Cmd.exe执行Flash擦除



    建议:Safety Belt


    我推荐用于任何其他低功耗实验的是添加一种安全带代码:上电后系统等待(并闪烁)一段时间以允许我在进入“危险”区域之前连接到它低功耗模式:

    25.png

    安全带代码



    这允许我在出现问题时捕获目标。这样的代码在生产系统中甚至可能是有帮助的,例如,如果在上电期间按下按钮,则执行此操作。

    总结


    处理“无Flash”器件可能会非常棘手。虽然恩智浦i.MX RT1064具有片上器件,但它实际上就像是内部绑定的QSPI闪存器件。为了让CPU从中启动,需要在其中放置明确定义的数据头(Flash描述)。如果此数据头已损坏,应用程序行为不正常,或内存被擦除,则调试器可能无法再访问MCU。本文的这种情况下,FreeRTOS应用程序执行WFI指令的速度非常快,以至于无法再访问MCU。 MCUXpresso IDE、i.MX RT1064引导程序(串行加载程序)和NXP Boot Utility的组合最终帮助我“恢复正常”。如果您遇到相同的情况,上述步骤和说明有望为您提供帮助。







    作者:阿哲       文章出处:点击

    qiandao qiandao
    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /3 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2025-7-19 05:35 , Processed in 0.088274 second(s), 20 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

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