两年前我写过一篇《双核i.mxrt1170之cortex-m7与cortex-m4互相激活之道》,那篇文章从离线启动的角度介绍了跑双核应用的基本方法,基本上把双核启动的细节都介绍到了。 在应用开发的阶段,很多时候我们还是需要在线调试的,主核的调试没什么特别要注意的地方,从核的调试大家估计就有点陌生了,今天就给大家介绍下 iar 开发环境下调试从核工程的方法。
一、测试准备
首先需要准备好测试环境,包含必要的软件和硬件,我的环境如下:
集成开发环境:iar ew for arm v9.10.2,(https://www.iar.com/products/architectures/
软件开发包:sdk_2.11.0_mimxrt1170-evk(toolchain要包含iar),点此下载
软件驱动:j-link driver v7.56b,点此下载
硬件工具:j-link plus调试器
硬件开发板:mimxrt1170-evk (rev.c),含板载 dap-link 调试器
我们知道i.mx rt1170 其实主从核是在 fuse 里可配的,我们就以默认配置(cortex-m7 为主,cortex-m4 为从)为例来介绍,选取的测试工程是sdk_2.11.0_mimxrt1170-evkoardsevkmimxrt1170demo_appshello_worldcm4。
二、在iar下调试
使用iar 打开hello_world_demo_cm4.eww 工程,切换到 debug build (就是在 ram 中执行)。
2.1 工程选项处理器选 cortex-m4 核调试情况
我们先来看一下工程选项里处理器选择 cortex-m4,并且不使能任何额外脚本时调试情况。也就是说在明知主核cortex-m7 处于激活状态而 cortex-m4 处于未激活状态时,iar c-spy 调试组件能否工作。
分别测试了板载 dap-link 调试器以及外接 j-link 调试器,测试结果均是不能直接调试,dap-link 下提示 failed to connect tocpu,j-link 下提示select core is not same as the target core。
2.2 工程选项处理器选 nxp mimxrt1176xxxa_m4 调试情况
再来看一下工程选项里处理器选择 nxp mimxrt1176xxxa_m4 时调试情况(会调用相关脚本,在iar/j-link 里已经做好)。也就是虽然 cortex-m4 处于未激活状态,但是有配套脚本会负责激活工作。
j-link下是可以直接调试的,在 debug log 窗口,我们可以看到有 .jlinkscript 脚本执行的痕迹,脚本打印信息里显示其识别到cortex-m4 未激活,并且会做激活相关工作。
note: 这个跟 nxp mimxrt1176xxxa_m4 选择相关的 .jlinkscript 脚本在 jlink 驱动安装目录下,由于 log 里没有直接显示路径,那大概率已经被打包进 dll 文件里了,我们看不到具体脚本代码实现。
dap-link下也是可以直接调试的,在 debug log 窗口,我们可以看到 imxrt_1170.dmac 脚本被执行了,脚本打印信息里显示其识别到 cortex-m4未激活,并且会做激活相关工作。
note: 这个跟 nxp mimxrt1176xxxa_m4 选择相关的 imxrt_1170.dmac 脚本在 iar 安装目录下,具体路径已经在 log 里显示出来了,我们可以看到其具体脚本代码实现。
如果你细心观察,你会发现 dap-link 下必须要在工程选项 debugger / extraoptions里加 “--macro_paramenable_core=1” 语句才能正常调试,这是因为 imxrt_1170.dmac 脚本需要接受这个参数才能正常激活从核 cortex-m4。
2.3 自己实现用于从核调试的脚本
现在我们知道了调试从核 cortex-m4 工程必须要有专门脚本来负责激活从核才行,虽然 iar/j-link里已经做好这个脚本,但是两者行为是否统一我们不清楚(毕竟看不见 j-link 下脚本源码),而且这个脚本是随着 iar/j-link 版本而变化的,具有一定的不可控性。
为了完全掌控从核调试的主动性与确定性,最好我们自己重新实现 iar/j-link 下的调试脚本,在线调试时直接指定使用我们自己写的脚本,这样即使工程选项里处理器选择 cortex-m4 我们也能正常调试。
对于dap-link,我们新建一个 mimxrt1170_connect_cm4_user.mac 文件(具体内容见附录一)放到工程目录下,并且在 iar 选项里指定使用这个 mac 文件。这个 mac 文件语法详见 《iar内部c-spy调试组件配套宏文件(.mac)用法介绍》,其中最重要的是 execusercoreconnect() 保留宏函数里要做激活 cortex-m4 工作。
note: 如果希望调试从核 cortex-m4 时,主核 cortex-m7 依然在跑,可以注释掉mimxrt1170_connect_cm4_user.mac 文件里的 execusersetup() 函数。
对于j-link,我们新建一个 mimxrt1170_connect_cm4_user.jlinkscript 文件(具体内容见附录二)放到工程目录下,并且在 iar 选项里指定使用这个 jlinkscript 文件。这个 jlinkscript 文件语法详见 《jlink script文件基础及其在iar下调用方法》,其中最重要的是 inittarget() 用户自定义动作函数里要做激活 cortex-m4 工作。
note: 如果希望调试从核 cortex-m4 时,主核 cortex-m7 依然在跑,可以注释掉mimxrt1170_connect_cm4_user.jlinkscript 文件里的afterresettarget() 函数。
附录一、iar脚本(用于dap-link)
prepare_core_spin_code(cmversion){ __var start; if (cmversion == 7) { start = 0x2021ff00; __writememory32(start >> 7, 0x40c0c068, ap0_memory); } if (cmversion == 4) { start = 0x20200000; __writememory32(start & 0xffff, 0x40c0c000, ap0_memory); __writememory32(start >> 16, 0x40c0c004, ap0_memory); } __writememory32(start + 0x20, start, ap0_memory); __writememory32(0x223105, start + 0x4, ap0_memory);}release_core(cmversion){ if (cmversion == 7) { __writememory32(0x2, 0x40c04000, ap0_memory); } if (cmversion == 4) { __writememory32(0x1, 0x40c04000, ap0_memory); }}reset_core(cmversion){ __var reg; __var ctrladdr; __var stataddr; if (cmversion == 7) { ctrladdr = 0x40c042a4; stataddr = 0x40c042b0; } if (cmversion == 4) { ctrladdr = 0x40c04284; stataddr = 0x40c04290; } __writememory32(0x1, ctrladdr, ap0_memory); do { reg = __readmemory32(stataddr, ap0_memory); __delay(10); }while(reg & 0x1);}//_execdevicecoreconnect()execusercoreconnect(){ __probecmd(j.i swd /force); // dummy read __readapreg(2); __delay(10); // disable system reset caused by sysrstreq from each core __writememory32(0x3c00, 0x40c04004, ap0_memory); prepare_core_spin_code(4); release_core(4); // switch to ap1 __writedpreg(1<<24, 2);}execuserprereset(){ reset_core(4); release_core(4); __writedpreg(1<> 7); } if (cmversion == 4) { start = 0x20200000; mem_writeu32(0x40c0c000, start & 0xffff); mem_writeu32(0x40c0c004, start >> 16); } mem_writeu32(start, start + 0x20); // bootrom go_fatal_mode() mem_writeu32(start + 0x4, 0x223105);}void release_core(unsigned int cmversion){ if (cmversion == 7) { mem_writeu32(0x40c04000, 0x2); } if (cmversion == 4) { mem_writeu32(0x40c04000, 0x1); }}void reset_core(unsigned int cmversion){ unsigned int reg; unsigned int ctrladdr; unsigned int stataddr; if (cmversion == 7) { ctrladdr = 0x40c042a4; stataddr = 0x40c042b0; } if (cmversion == 4) { ctrladdr = 0x40c04284; stataddr = 0x40c04290; } mem_writeu32(ctrladdr, 1); do { reg = mem_readu32(stataddr); sys_sleep(10); }while (reg & 0x1);}void inittarget(void) { cpu = cortex_m7; // manually configure ap jlink_coresight_addap(0, coresight_ahb_ap); jlink_coresight_addap(1, coresight_ahb_ap); jlink_coresight_addap(2, coresight_apb_ap); // dummy read jlink_coresight_readap(jlink_coresight_ap_reg_idr); sys_sleep(10); // disable system reset caused by sysrstreq from each core mem_writeu32(0x40c04004, 0x3c00); prepare_core_spin_code(4); release_core(4); // switch to ap1 cpu = cortex_m4; coresight_indexahbaptouse = 1;}void resettarget(void){ coresight_indexahbaptouse = 0; reset_core(4); release_core(4); coresight_indexahbaptouse = 1;}void afterresettarget(void){ unsigned int reg; reg = mem_readu32(0x40c04000); if((reg & 0x2) == 0) { prepare_core_spin_code(7); reset_core(7); }}
如何设计出一个安全可靠的CAN总线拓扑
3.7V锂电升压5V1A 5V2A方案,移动电源应用参考
电容器组的作用是什么_电容器组运行注意事项
【节能学院】安科瑞餐饮油烟在线监测系统在云龙湖畔景区大中型餐饮油烟治理中的应用
微雪电子RS485 Board UART转485模块简介
IAR 开发环境下调试从核工程的方法(IAR篇)
S7-1500和S7-1200 F-CPU间Flexible F-Link通信
如何从Altium Designer中连接到我的Workspace?
最快速红外线传感器(Silicon Labs)
测试新唐nuc980串口功能的过程
宝马投四亿欧元的iNext电动汽车,竞争对手是特斯拉Model Y
LED显示屏在户外标识标牌领域的应用有哪些
MAXQ架构简介
关于谷歌物联网Android Things你需要知道的10点
你们会设计CPU取指执行电路吗?
三星S7升级安卓7.0了 然而Gear VR眼镜运行不了
pcb设计基础之稳压原理简述
台积电2nm工艺制程研发迎来突破
长期戴耳机听歌的危害,别让这些坏习惯害了你的听力!
芯海科技:国内MCU龙头企业,高尖端进口替代急先锋