查看: 9895|回复: 14

[分享] 调试i.MXRT1170从核工程怎么搞?在线教学

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

    连续签到: 2 天

    [LV.8]以坛为家I

    3934

    主题

    7555

    帖子

    0

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    40177
    最后登录
    2025-9-4
    发表于 2022-6-20 11:18:16 | 显示全部楼层 |阅读模式
    调试i.MXRT1170从核工程怎么搞?在线教学


    大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家分享的是i.MXRT1170下单独在线调试从核工程的方法(基于IAR)。


    两年前痞子衡写过一篇《双核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.MXRT1170 其实主从核是在 Fuse 里可配的,我们就以默认配置(Cortex-M7 为主,Cortex-M4 为从)为例来介绍,选取的测试工程是 \SDK_2.11.0_MIMXRT1170-EVK\boards\evkmimxrt1170\demo_apps\hello_world\cm4。


    二、在IAR下调试
    使用 IAR 打开 hello_world_demo_cm4.eww 工程,切换到 debug build (就是在 RAM 中执行)。


    2.1 工程选项处理器选 Cortex-M4 核调试情况
    我们先来看一下工程选项里处理器选择 Cortex-M4,并且不使能任何额外脚本时调试情况。也就是说在明知主核 Cortex-M7 处于激活状态而 Cortex-M4 处于未激活状态时,IAR C-SPY 调试组件能否工作。
    11.png
    痞子衡分别测试了板载 DAP-Link 调试器以及外接 J-Link 调试器,测试结果均是不能直接调试,DAP-Link 下提示 "Failed to connect to CPU",J-Link 下提示 "Select core is not same as the target core"。
    12.png
    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 文件里了,我们看不到具体脚本代码实现。
    13.png
    DAP-Link 下也是可以直接调试的,在 Debug Log 窗口,我们可以看到 iMXRT_1170.dmac 脚本被执行了,脚本打印信息里显示其识别到 Cortex-M4 未激活,并且会做激活相关工作。


    Note: 这个跟 NXP MIMXRT1176xxxA_M4 选择相关的 iMXRT_1170.dmac 脚本在 IAR 安装目录下,具体路径已经在 log 里显示出来了,我们可以看到其具体脚本代码实现。
    14.png
    如果你细心观察,你会发现 DAP-Link 下必须要在工程选项 Debugger / Extra Options 里加 “--macro_param enable_core=1” 语句才能正常调试,这是因为 iMXRT_1170.dmac 脚本需要接受这个参数才能正常激活从核 Cortex-M4。
    15.png
    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() 函数。
    16.png
    对于 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() 函数。
    17.png
    附录一、IAR 脚本(用于DAP-Link)
    1. prepare_core_spin_code(cmVersion)
    2. {
    3.     __var start;
    4.     if (cmVersion == 7)
    5.     {
    6.         start = 0x2021FF00;
    7.         __writeMemory32(start >> 7, 0x40c0c068,  "AP0_Memory");
    8.     }
    9.     if (cmVersion == 4)
    10.     {
    11.         start = 0x20200000;
    12.         __writeMemory32(start & 0xFFFF, 0x40c0c000,  "AP0_Memory");
    13.         __writeMemory32(start >> 16,    0x40c0c004,  "AP0_Memory");
    14.     }
    15.     __writeMemory32(start + 0x20, start, "AP0_Memory");
    16.     __writeMemory32(0x223105, start + 0x4, "AP0_Memory");
    17. }

    18. release_core(cmVersion)
    19. {
    20.     if (cmVersion == 7)
    21.     {
    22.         __writeMemory32(0x2, 0x40c04000, "AP0_Memory");
    23.     }
    24.     if (cmVersion == 4)
    25.     {
    26.         __writeMemory32(0x1, 0x40c04000, "AP0_Memory");
    27.     }
    28. }

    29. reset_core(cmVersion)
    30. {
    31.     __var reg;
    32.     __var ctrlAddr;
    33.     __var statAddr;
    34.     if (cmVersion == 7)
    35.     {
    36.         ctrlAddr = 0x40c042a4;
    37.         statAddr = 0x40c042b0;
    38.     }
    39.     if (cmVersion == 4)
    40.     {
    41.         ctrlAddr = 0x40c04284;
    42.         statAddr = 0x40c04290;
    43.     }
    44.     __writeMemory32(0x1, ctrlAddr, "AP0_Memory");
    45.     do
    46.     {
    47.         reg = __readMemory32(statAddr, "AP0_Memory");
    48.         __delay(10);
    49.     }while(reg & 0x1);
    50. }

    51. //_ExecDeviceCoreConnect()
    52. execUserCoreConnect()
    53. {
    54.     __probeCmd("j.i swd /force");
    55.     // dummy read
    56.     __readAPReg(2);
    57.     __delay(10);
    58.     // Disable system reset caused by sysrstreq from each core
    59.     __writeMemory32(0x3c00, 0x40C04004, "AP0_Memory");
    60.     prepare_core_spin_code(4);
    61.     release_core(4);
    62.     // switch to AP1
    63.     __writeDPReg(1<<24, 2);
    64. }

    65. execUserPreReset()
    66. {
    67.     reset_core(4);
    68.     release_core(4);
    69.     __writeDPReg(1<<24, 2);
    70. }

    71. execUserSetup()
    72. {
    73.     __var reg;
    74.     reg = __readMemory32(0x40c04000, "AP0_Memory");
    75.     if((reg & 0x2) == 0)
    76.     {
    77.         prepare_core_spin_code(7);
    78.         reset_core(7);
    79.     }
    80. }
    复制代码
    附录二、J-Link 脚本
    1. void prepare_core_spin_code(unsigned int cmVersion)
    2. {
    3.     unsigned int start;
    4.     if (cmVersion == 7)
    5.     {
    6.         start = 0x2021FF00;
    7.         MEM_WriteU32(0x40c0c068,  start >> 7);
    8.     }
    9.     if (cmVersion == 4)
    10.     {
    11.         start = 0x20200000;
    12.         MEM_WriteU32(0x40c0c000,  start & 0xFFFF);
    13.         MEM_WriteU32(0x40C0c004,  start >> 16);
    14.     }
    15.     MEM_WriteU32(start,       start + 0x20);
    16.     // BootROM go_fatal_mode()
    17.     MEM_WriteU32(start + 0x4, 0x223105);
    18. }

    19. void release_core(unsigned int cmVersion)
    20. {
    21.     if (cmVersion == 7)
    22.     {
    23.         MEM_WriteU32(0x40C04000, 0x2);
    24.     }
    25.     if (cmVersion == 4)
    26.     {
    27.         MEM_WriteU32(0x40C04000, 0x1);
    28.     }
    29. }

    30. void reset_core(unsigned int cmVersion)
    31. {
    32.     unsigned int reg;
    33.     unsigned int ctrlAddr;
    34.     unsigned int statAddr;

    35.     if (cmVersion == 7)
    36.     {
    37.         ctrlAddr = 0x40c042a4;
    38.         statAddr = 0x40c042b0;
    39.     }
    40.     if (cmVersion == 4)
    41.     {
    42.         ctrlAddr = 0x40c04284;
    43.         statAddr = 0x40c04290;
    44.     }

    45.     MEM_WriteU32(ctrlAddr, 1);
    46.     do
    47.     {
    48.         reg = MEM_ReadU32(statAddr);
    49.         SYS_Sleep(10);
    50.     }while (reg & 0x1);
    51. }

    52. void InitTarget(void)
    53. {
    54.     CPU = CORTEX_M7;
    55.     // Manually configure AP
    56.     JLINK_CORESIGHT_AddAP(0, CORESIGHT_AHB_AP);
    57.     JLINK_CORESIGHT_AddAP(1, CORESIGHT_AHB_AP);
    58.     JLINK_CORESIGHT_AddAP(2, CORESIGHT_APB_AP);
    59.     // Dummy read
    60.     JLINK_CORESIGHT_ReadAP(JLINK_CORESIGHT_AP_REG_IDR);
    61.     SYS_Sleep(10);
    62.     // Disable system reset caused by sysrstreq from each core
    63.     MEM_WriteU32(0x40C04004, 0x3c00);
    64.     prepare_core_spin_code(4);
    65.     release_core(4);
    66.     // Switch to AP1
    67.     CPU = CORTEX_M4;
    68.     CORESIGHT_IndexAHBAPToUse = 1;
    69. }

    70. void ResetTarget(void)
    71. {
    72.     CORESIGHT_IndexAHBAPToUse = 0;
    73.     reset_core(4);
    74.     release_core(4);
    75.     CORESIGHT_IndexAHBAPToUse = 1;
    76. }

    77. void AfterResetTarget(void)
    78. {
    79.     unsigned int reg;
    80.     reg = MEM_ReadU32(0x40c04000);
    81.     if((reg & 0x2) == 0)
    82.     {
    83.         prepare_core_spin_code(7);
    84.         reset_core(7);
    85.     }
    86. }
    复制代码
    至此,i.MXRT1170下单独在线调试从核工程的方法痞子衡便介绍完毕了,掌声在哪里~~~





    qiandao qiandao
    回复

    使用道具 举报

  • TA的每日心情
    奋斗
    昨天 14:40
  • 签到天数: 1206 天

    连续签到: 2 天

    [LV.10]以坛为家III

    6

    主题

    7372

    帖子

    1

    金牌会员

    Rank: 6Rank: 6

    积分
    9399
    最后登录
    2025-9-3
    发表于 2022-6-20 15:03:15 | 显示全部楼层
    好文分享
    该会员没有填写今日想说内容.
    回复

    使用道具 举报

  • TA的每日心情
    奋斗
    4 天前
  • 签到天数: 869 天

    连续签到: 1 天

    [LV.10]以坛为家III

    69

    主题

    3282

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    10414
    最后登录
    2025-9-3
    发表于 2022-6-21 18:31:08 | 显示全部楼层
    赞一个  学习了
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2022-7-28 08:50
  • 签到天数: 67 天

    连续签到: 1 天

    [LV.6]常住居民II

    0

    主题

    203

    帖子

    0

    中级会员

    Rank: 3Rank: 3

    积分
    328
    最后登录
    2022-7-28
    发表于 2022-6-23 09:43:00 | 显示全部楼层
    学习了学习了
    今天天气不错!签到!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    昨天 00:00
  • 签到天数: 1787 天

    连续签到: 10 天

    [LV.Master]伴坛终老

    15

    主题

    1万

    帖子

    1

    金牌会员

    Rank: 6Rank: 6

    积分
    21718
    最后登录
    2025-9-3
    发表于 2022-6-23 09:53:13 | 显示全部楼层
    学习学习
    回复

    使用道具 举报

  • TA的每日心情
    奋斗
    昨天 19:46
  • 签到天数: 1483 天

    连续签到: 52 天

    [LV.10]以坛为家III

    2

    主题

    3531

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    7083
    最后登录
    2025-9-3
    发表于 2022-6-23 11:14:44 | 显示全部楼层
    图文讲解,很详细,非常棒!
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    昨天 20:15
  • 签到天数: 1348 天

    连续签到: 13 天

    [LV.10]以坛为家III

    0

    主题

    7513

    帖子

    1

    金牌会员

    Rank: 6Rank: 6

    积分
    7186
    最后登录
    2025-9-3
    发表于 2022-6-23 15:32:36 | 显示全部楼层
    调试i.MXRT1170
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    昨天 22:06
  • 签到天数: 1282 天

    连续签到: 205 天

    [LV.10]以坛为家III

    1

    主题

    3025

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    7801
    最后登录
    2025-9-3
    发表于 2022-6-23 15:33:38 | 显示全部楼层
    好文学习
    哎...今天够累的,签到来了~
    回复

    使用道具 举报

  • TA的每日心情
    奋斗
    昨天 21:04
  • 签到天数: 2496 天

    连续签到: 28 天

    [LV.Master]伴坛终老

    17

    主题

    5501

    帖子

    5

    金牌会员

    Rank: 6Rank: 6

    积分
    11467
    最后登录
    2025-9-3
    发表于 2022-6-23 17:54:32 | 显示全部楼层
    有开发板就按教程试试吧。。。
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2023-12-7 11:35
  • 签到天数: 72 天

    连续签到: 1 天

    [LV.6]常住居民II

    0

    主题

    533

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    1525
    最后登录
    2024-1-17
    发表于 2022-6-23 21:16:43 | 显示全部楼层
    学习了,感谢大佬
    开心
    回复 支持 反对

    使用道具 举报

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

    本版积分规则

    关闭

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

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

    GMT+8, 2025-9-4 08:33 , Processed in 0.121788 second(s), 31 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

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