查看: 1778|回复: 0

[分享] 【OKdo E1双核Cortex M33开发板】双核代码之启动流程

[复制链接]
  • TA的每日心情
    开心
    2024-3-26 15:16
  • 签到天数: 266 天

    [LV.8]以坛为家I

    3301

    主题

    6548

    帖子

    0

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    32040
    最后登录
    2024-4-28
    发表于 2020-12-1 14:35:36 | 显示全部楼层 |阅读模式
    【OKdo E1双核Cortex M33开发板】双核代码之启动流程


    LPC55S69这个芯片最吸引人的无疑是它的双核部分,而NXP作为在双核MCU领域沉浸多年老厂商,这一款很新的芯片的双核部分已经非常成熟,下面我们以提供的一个双核实例,在keil5 ARM的开发环境进行分析。


    首先编译core1的代码。
    然后对core0的代码进行一些修改,因为这个板子上没有外部晶振,所以要将clock_config.c文件里面的BOARD_InitBootClocks函数修改如下。
    1. void BOARD_InitBootClocks(void)
    2. {
    3.   BOARD_BootClockFROHF96M();
    4. }
    复制代码
    运行后串口打印如下,之后一段时间后蓝灯开始闪烁。
    11.png
    其中串口打印是由core0实现,蓝灯闪烁是由core1实现。接下来我们来对这个双核的启动流程简要分析一下。
    首先是core1的部分,下图可以看出,它输出了一个名为core1_image.bin的文件
    12.png
    接下来是core0的部分,先看incbin.S,关键代码如下
    1. AREA M0CODE, DATA, READONLY, PREINIT_ARRAY, ALIGN=3
    2.         EXPORT m0_image_start
    3.         EXPORT m0_image_end
    4. m0_image_start
    5.         INCBIN core1_image.bin
    6. m0_image_end
    7.         END
    复制代码
    可以看到这里定义了一个段名为M0CODE的数据段,只读,8字节对齐。
    然后在这个数据段里面放入了core1编译输出的core1_image.bin文件,起始标记是m0_image_start,结尾标记是m0_image_end。


    接下来要看LPC55S69_cm33_core0_flash.scf文件,关键代码如下
    1. #define  m_core1_image_start           0x00072000
    2. #define  m_core1_image_size            0x00026000

    3. ......

    4. LR_CORE1_IMAGE m_core1_image_start {
    5.   CORE1_REGION m_core1_image_start m_core1_image_size {
    6.     * (.m0code)
    7.   }
    8. }
    复制代码
    这里是定义了一个区域,起始地址为0x00072000,长度为0x00026000(keil rom空间为0-0x98000,也就是最后一段)
    然后将m0code这个段放到这个地址上,也就是把core1_image.bin这个文件放到了0x00072000地址上。
    这里的地址是可以进行修改的,也就是可以根据代码的配置选择core1程序的存储位置,根据代码量删减,或者将core1生成的bin文件混淆到最终生成的文件里面,让别人很难进行逆向分析。


    最后看一下hello_world_core0.c文件,关键代码如下
    1. #define CORE1_BOOT_ADDRESS 0x20033000
    2. extern uint32_t Image$CORE1_REGION$Base;
    3. extern uint32_t Image$CORE1_REGION$Length;
    4. #define CORE1_IMAGE_START &Image$CORE1_REGION$Base

    5. ......

    6. uint32_t get_core1_image_size(void)
    7. {
    8.     uint32_t core1_image_size;
    9.     core1_image_size = (uint32_t)&Image$CORE1_REGION$Length;
    10.     return core1_image_size;
    11. }

    12. ......

    13.     core1_image_size = get_core1_image_size();
    14.     (void)memcpy((void *)(char *)CORE1_BOOT_ADDRESS, (void *)CORE1_IMAGE_START, core1_image_size);
    15.     (void)MCMGR_StartCore(kMCMGR_Core1, (void *)(char *)CORE1_BOOT_ADDRESS, 2, kMCMGR_Start_Synchronous);
    复制代码
    首先是get_core1_image_size函数,&Image$$CORE1_REGION$$Length是用来得到CORE1_REGION区域的大小,也就是core1_image.bin文件的大小。而Image$$CORE1_REGION$$Base则是CORE1_REGION区域的起点。


    下面就是把从CORE1_IMAGE_START开始的core1_image_size的数据复制到CORE1_BOOT_ADDRESS地址上。也就是把代码从rom里面搬到了ram里面。


    最后就是将core1从CORE1_BOOT_ADDRESS地址同步启动。


    简要总结一下,LPC55S69代码由两部分组成,以core0为主,core0启动起来之后,将core1的代码从rom复制到ram里面,然后再启动core1。其中core1代码在rom以及在ram里面的位置都是可以任意配置,非常灵活。

    转自网友:az158





    签到签到
    回复

    使用道具 举报

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

    本版积分规则

    关闭

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

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

    GMT+8, 2024-4-28 17:17 , Processed in 0.158753 second(s), 22 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

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