许多MCU配置了一个独立的启动ROM,包含处理器复位并跳转到用户应用程序之前执行的代码。启动ROM的工作包含设置时钟,启用调试接口,根据不同的引导源初始化外围设备等等…当然,不同MCU的启动ROM行为并不相同。实际上,启动ROM的行为在同一设备的两个硬件版本之间也会有变化。
问题
调试体系架构没有规定如何设计启动ROM或其行为,因此在启动ROM执行之后,无法为MCU实现一种通用的复位方法,让其暂停在用户应用程序的第一条指令上。处理器需要一个特定的复位程序,它可以处理设备特定的启动ROM场景,如没有有效的映像,映像位于QSPI中,通过SD卡启动等等…实现这种特定于设备的复位非常具有挑战性,甚至是不可能的,而且非常耗时,因为现代MCU通常有多种启动路径。此外,由于某些原因,供应商通常不会记录启动ROM的行为。
解决方式
如果J-Link不支持使用设备或引导源的引导加载程序后的Reset&halt,则可以通过两个步骤轻松启用正确的复位:
2.1 修改启动代码
在startup代码中添加下列指令:
// // Perform a dummy read access from address 0x00000008 followed by two nop's // This is needed to support the reset strategy: Reset and Halt After Bootloader. // mov r0, 8 ldr r0,[r0] nop nop
2.2 修改Reset策略
复位策略需要设置为12。
如何改变J-Link使用的复位策略取决于所使用的环境。复位策略可以通过所使用环境设置配置,也可以通过J-Link命令字符串配置。如J-Link Commander,允许通过本机命令直接将J-Link命令字符串传递给J-Link DLL。如果这两个方式都不可用,使用通用方法。
2.2.1 J-Link Commander
启动J-Link Commander后,可以通过执行RSetType命令改变复位策略为
RSetType = 12
2.2.2 通用方法
如果使用的IDE 或应用没有提供选项配置使用的reset类型,也不能将J-Link命令字符串传递给J-Link DLL,我们建议使用J-Link脚本文件API函数JLINK_ExecCommand(“”)将它们包含到J-Link脚本文件中。
下面是一个J-Link脚本文件的示例,该文件通过JLINK_ExecCommand(…)传递J-Link命令字符串SetResetType到J-Link DLL。
/********************************************************************* * * ConfigTargetSettings * * Function description * Called before InitTarget(). Mainly used to set some global DLL variables to customize the * normal connect procedure. For ARM CoreSight devices this may be specifying the base * address of some CoreSight components (ETM, …) that cannot be auto-detected by J-Link * due to erroneous ROM tables etc. May also be used to specify the device name in case * debugger does not pass it to the DLL. * * Notes * (1) May not, under absolutely NO circumstances, call any API functions that perform target communication. * (2) Should only set some global DLL variables * * Return value * >= 0 O.K. * < 0 Error * -1 Unspecified error */ int ConfigTargetSettings(void) { // // Set reset strategy used by the J-Link to Reset + Halt After Bootloader Using Watchpoint. // JLINK_SYS_Report("-- Configure Reset Strategy --"); JLINK_ExecCommand("SetResetType = 12"); return 0; }
操作示例
基于SEGGER Cortex-M Trace参考板的SEGGER Embedded Studio工程示例项目,可以访问:https://wiki.segger.com/File:SEGGER_Cortex-M_Trace_Reference_Board_Blinky_ES_V550b.zip
该项目可以很容易地移植到其它基于Cortex-M的MCU。
3.1 使用J-Link Commander测试&验证
1、使用SES下载应用
2、使用J-Link Commander连接目标板
3、执行reset
4、检查PC==0x0800010E
5、修改reset策略为 Reset+Halt
6、执行Reset
7、检查PC==0x08000116
总结
正常复位后,MCU停在复位向量(Reset_Handler / 0x0800010E)处。
通过执行Reset&halt after bootloader复位策略后,MCU停在启动代码(0x08000116)处。
这确认了reset的行为与预期一致。
为了模拟引导加载程序,可以将修改的代码从启动代码移动到用户应用程序中的其它地方。执行reset应该显示CPU在代码移动到的地址处停止。
审核编辑:汤梓红
全部0条评论
快来发表一下你的评论吧 !