阿哲
发表于: 2019-3-27 16:27:55 | 显示全部楼层

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

i.MX-RT1064-EVK-Boar.png

i.MX RT1064-EVK开发板


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

  1. /*
  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. }
复制代码

上述指令很有效,但直当我增加了滴答Tick和任务频率后,突然间,我再也无法使用调试器访问CPU :-(。在做了一些实验之后,这种现象似乎取决于开发板是否正在POR(上电复位)时进行调试访问。如果电路板没有进入电源循环,仍然可以进入调试模式。


无法与调试器连接

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


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

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

Segger J-Link可能无法在Coresight设置中找到内核:

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

P&E Multilink Universal可能会提示无法下载.ARP文件进行编程:

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

以上所有这些情况,都表示着调试器无法访问内核。


WFI:等待中断

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

WaitForInterrupt.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. CLOCK_SetMode(kCLOCK_ModeRun);
复制代码

这实际上会阻​​止CPU进入WAIT模式,并且在此阶段不会发生问题,因为只是禁用了WAIT模式。请参阅https://community.nxp.com/thread/492841#comment-1099054


默认情况下,CLPCR [LPM]位置1。第13.6.3.2.1章说,在这种情况下,我必须配置'备用中断控制器',它应该被启用。本文已禁用ARM内核的NVIC。这可以解释为什么例如SysTick在我的RTOS中不再运行。

entering-wait-mode.png

进入等待模式

恢复

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


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

Board-Default-Boot-Configuration.png

板默认引导配置

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

SW7-set-to-serial-download.png

SW7设置为串行下载

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

Attached-to-boot-ROM-Code.png

附加到引导ROM代码

但是,在此模式下无法访问0x7000'0000的内部闪存,我无法将其擦除或直接访问。


Boot Utility

“Serial Download”的DIP开关在NXP i.MX RT1064上执行引导加载程序。该引导加载程序通过主机上的特殊工具通过MCU的USB端口进行通信,该工具可用于下载新固件。


设置这样的实用程序并使用它并不是那么简单。本文使用的是Jay Heng的'NXP Boot Utility':这个工具使我能够通过几个步骤重新获得对开发板的访问权限。

1.    按照https://github.com/JayHeng/NXP-MCUBootUtility/中的说明进行操作

2.    在SW7设置为0001的情况下以串行下载模式启动电路板:

SW7-set-to-serial-download (1).png

SW7设置为串行下载

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

USB-HID-Device.png

USB HID设备

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

MCU-NXP-Boot-Utility.png

MCU NXP Boot Utility

5.  切换到“Master”模式:

Master-Mode.png

主模式


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

Connect-to-ROM.png

连接到ROM


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

Connected-to-ROM.png

连接到ROM


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

Connected.png

已连接


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

Boot-Device-Configured.png

已配置引导设备


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

Erasign-the-flash.png

擦除Flash


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

Erased-internal-flash-memory.png

擦除内部闪存


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

GUI-Flash-Tool.png

GUI Flash工具


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

Mass-Erase-with-Flash-Header.png

进行批量擦除


14.  这应该成功如下:

Flash-Erase-completed.png

Flash Erase已完成


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

Correct-Flash-Header-Present.png

正确的闪存数据头


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

Programming-Application.png

编程应用


17.  这应该成功:

Sucessful-Flash-Programming.png

成功编程Flash

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

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


故障排除

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

wrong-read-memory.png

错读内存

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

  1. C:\nxp\McuBootUtility\NXP-MCUBootUtility-1.0.0\tools\blhost\win\blhost -t 6573000 -u 0x15A2,0x0073 -j -- flash-erase-region 0x70000000 0x40000 9
复制代码

Executing-Flash-Erase-from-Cmd.exe_.png

从Cmd.exe执行Flash擦除


建议:Safety Belt

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

Safety-Belt-Code.png

安全带代码

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


总结

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

跳转到指定楼层
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题 13 | 回复: 15



手机版|

GMT+8, 2024-3-29 07:48 , Processed in 0.114551 second(s), 8 queries , Gzip On, MemCache On. Powered by Discuz! X3.5

YiBoard一板网 © 2015-2022 地址:河北省石家庄市长安区高营大街 ( 冀ICP备18020117号 )

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