查看: 4875|回复: 1

[分享] i.MXRT1170双核CM7与CM4互相激活之道

[复制链接]
  • TA的每日心情
    开心
    7 天前
  • 签到天数: 301 天

    连续签到: 2 天

    [LV.8]以坛为家I

    3868

    主题

    7472

    帖子

    0

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    39226
    最后登录
    2025-7-18
    发表于 2020-5-25 10:17:46 | 显示全部楼层 |阅读模式
    i.MXRT1170双核CM7与CM4互相激活之道


          今天痞子衡给大家分享的是恩智浦i.MXRT1170上Cortex-M7与Cortex-M4内核互相激活的方法。


    痞子衡最近在深耕i.MXRT1170这颗划时代的MCU,已经写了不少篇相关技术文章,涉及整体特点、Raw NAND启动、FlexRAM模块、ECC特性等,文章写得越多越发觉得i.MXRT1170是座宝矿,值得大家去仔细探索。话不多说,咱们继续挖矿吧,今天痞子衡为大家介绍i.MXRT1170双核间互相激活的方法。


    一、双核功能简介
    双核是i.MXRT1170除了1GHz主频之外的第二个显著特点,i.MX RT系列也是从RT1170开始首次引入了双核架构。i.MXRT1170包含了一个Cortex-M7内核(1GHz)以及一个Cortex-M4内核(400MHz),超强的Cortex-M7内核专注于音视频识别与处理、千兆以太网通讯控制等复杂任务上;低功耗Cortex-M4内核则做一些相对简单的键盘响应、传感器采集、电机控制等任务,即如下图所示:
    1.png
    二、双核激活方法
    i.MXRT1170虽然是双核(Cortex-M7与Cortex-M4),但这两个核并没有确定的主从关系,i.MXRT1170系统设计里每个核都既可以当主核也可以当从核(默认CM7是主核,CM4是从核),用户设置了主从关系之后,芯片上电后先从主核启动,然后由主核来激活从核启动。

    2.1 选定主核
    主核是在eFuse中选定的,fusemap中0x960[13:12]对应的是BT_CORE_CTRL和BT_CORE_SEL bit,默认两个bit都是0,即从CM7是主核,上电CM7启动,如果需要更改主核为CM4,则需要烧写eFuse。
    2.png
    这里顺便插一句,我们知道芯片上电都是先执行BootROM代码,既然CM7和CM4都可以当主核,那么这个BootROM代码需要既可以在CM4下执行,也可以在CM7下执行。这里借助的是Cortex-M处理器向下兼容、软件二进制向上兼容的特性,BootROM代码使用Cortex-M4指令集去编译即可。


    2.2 加载从核App(可选)
    选定了主核之后,主核App由BootROM加载执行,我们需要在主核App里添加代码来启动从核。启动从核的第一步是加载从核App,App从加载执行位置上可分为两种,一种是在Flash里原地执行,另一个是拷贝到RAM里执行,只有后者才需要先加载再执行。


    关于从核App执行位置,这里有必要好好聊一下,下面是CM7和CM4下各自系统内存映射表,从表里可以看到除了各自内核TCM空间仅对自己可见外,其余地址空间对两个核均是可见的(并且映射地址也是相同的),所以如果加载的从核App是在TCM里执行的,主核需要将从核App加载到从核TCM对应的OCRAM空间(CM4当从核时其TCM对应的是OCRAM(M4)空间,CM7当从核时其TCM空间无法被CM4通过OCRAM(M7)访问)。
    3.png
    4.png
    下面是加载从核App示例代码,appBuffer是从核App Image在外部Flash里存放的首地址,vectorAddr是加载的目标RAM首地址。为了防止Cache干扰后续从核取复位向量执行,主核在加载App前后最好均要清一下DCache。
    1. 1void copy_app_image(uint8_t *appBuffer, uint32_t appLength, uint32_t vectorAddr)
    2. 2{
    3. 3#if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
    4. 4    SCB_CleanInvalidateDCache_by_Addr((void *)vectorAddr, appLength);
    5. 5#endif
    6. 6
    7. 7    /* Copy app image to dest addrress. */
    8. 8    memcpy((void *)vectorAddr, appBuffer, appLength);
    9. 9
    10. 10#if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
    11. 11    SCB_CleanInvalidateDCache_by_Addr((void *)vectorAddr, appLength);
    12. 12#endif
    13. 13}
    复制代码
    2.3 指定从核初始中断向量表地址
    加载从核App完成之后,接下来便是设置从核启动所需的中断向量表位置,从核需要从中断向量表里取出初始栈地址(SP)和复位向量(PC)来执行。


    CM7启动初始向量表地址设置在IOMUXC_LPSR_GPR26里(对应SCB->VTOR[31:7]),CM4启动初始向量表地址设置在IOMUXC_LPSR_GPR0/1里(对应SCB->VTOR[31:3])。
    Note: A0版本芯片CM7启动初始向量表设置在IOMUXC_GPR19里;B0版本芯片CM7启动初始向量表设置改到了IOMUXC_LPSR_GPR26里。
    5.png
    下面是设置从核启动初始中断向量表地址的示例代码:
    1. 1void set_cm4_vector(uint32_t vectorAddr)
    2. 2{
    3. 3    IOMUXC_LPSR_GPR->GPR0 = IOMUXC_LPSR_GPR_GPR0_CM4_INIT_VTOR_LOW(vectorAddr);
    4. 4    IOMUXC_LPSR_GPR->GPR1 = IOMUXC_LPSR_GPR_GPR1_CM4_INIT_VTOR_HIGH(vectorAddr >> 16);
    5. 5}
    6. 6
    7. 7void set_cm7_vector(uint32_t vectorAddr)
    8. 8{
    9. 9    IOMUXC_LPSR_GPR->GPR26 = IOMUXC_LPSR_GPR_GPR26_CM7_INIT_VTOR(vectorAddr);
    10. 10}
    复制代码
    2.4 激活从核
    此时从核已经摩拳擦掌,等待来自主核的最后激活指令了。激活控制是在SRC->SCR寄存器里实现的,将BT_RELEASE_Mx位置1即可启动CMx从核。这里需要注意一点,如果是在调试,从核有可能已经被调试器的脚本激活过了,那么此时仅需要reset一下从核即可。
    6.png
    下面是激活从核启动的示例代码:
    1. 1void launch_cm4_core(void)
    2. 2{
    3. 3    /* If CM4 is already running (released by debugger), then reset the CM4.
    4. 4       If CM4 is not running, release it. */
    5. 5    if ((SRC->SCR & SRC_SCR_BT_RELEASE_M4_MASK) != 0)
    6. 6    {
    7. 7        SRC->CTRL_M4CORE |= SRC_SLICE_CTRL_SW_RESET_MASK;
    8. 8        while ((SRC->STAT_M4CORE & SRC_SLICE_STAT_UNDER_RST_MASK) != 0UL);
    9. 9    }
    10. 10    else
    11. 11    {
    12. 12        SRC->SCR |= SRC_SCR_BT_RELEASE_M4_MASK;
    13. 13    }
    14. 14}
    15. 15
    16. 16void launch_cm7_core(void)
    17. 17{
    18. 18    /* If CM7 is already running (released by debugger), then reset the CM7.
    19. 19       If CM7 is not running, release it. */
    20. 20    if ((SRC->SCR & SRC_SCR_BT_RELEASE_M7_MASK) != 0)
    21. 21    {
    22. 22        SRC->CTRL_M7CORE |= SRC_SLICE_CTRL_SW_RESET_MASK;
    23. 23        while ((SRC->STAT_M7CORE & SRC_SLICE_STAT_UNDER_RST_MASK) != 0UL);
    24. 24    }
    25. 25    else
    26. 26    {
    27. 27        SRC->SCR |= SRC_SCR_BT_RELEASE_M7_MASK;
    28. 28    }
    29. 29}
    复制代码
    三、一个典型示例
    最后给一个完整示例,主核是CM7,从核是CM4,从核App代码存储在0x60010000地址,App长度是32KB,从核APP是从ITCM起始地址(0x1FFE0000)开始链接的。CM7激活CM4完整代码如下:
    1. 1#define CM4_BUF_START 0x60010000U
    2. 2#define CM4_BUF_LEN   0x8000U
    3. 3#define CM4_CPY_START 0x20200000U
    4. 4#define CM4_APP_START 0x1FFE0000U
    5. 5
    6. 6int main(void)
    7. 7{
    8. 8    copy_app_image(CM4_BUF_START, CM4_BUF_LEN, CM4_CPY_START);
    9. 9    set_cm4_vector(CM4_APP_START);
    10. 10    launch_cm4_core();
    11. 11
    12. 12    while (1)
    13. 13    {
    14. 14    }
    15. 15}
    复制代码




    文章出处:痞子衡嵌入式


    qiandao qiandao
    回复

    使用道具 举报

    该用户从未签到

    0

    主题

    1

    帖子

    0

    新手上路

    Rank: 1

    积分
    6
    最后登录
    2022-8-29
    发表于 2022-8-29 10:31:37 | 显示全部楼层
    我不知道楼主是如何驱动激活M4的,我根本运行不了?报找不到CPU .用M7就没这回事。
    回复 支持 反对

    使用道具 举报

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

    本版积分规则

    关闭

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

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

    GMT+8, 2025-7-18 17:39 , Processed in 0.086025 second(s), 21 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

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