查看: 1932|回复: 1

[评测分享] 【NXP OKdo E1双核Cortex M33开发板】+ 4.双核代码之启动流程小议

[复制链接]
  • TA的每日心情
    慵懒
    2024-7-12 21:42
  • 签到天数: 229 天

    连续签到: 1 天

    [LV.7]常住居民III

    发表于 2020-11-10 21:34:37 | 显示全部楼层 |阅读模式
    分享到:
    本帖最后由 az158 于 2020-11-10 22:56 编辑

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

    首先编译core1的代码。
    然后对core0的代码进行一些修改,因为这个板子上没有外部晶振,所以要将clock_config.c文件里面的BOARD_InitBootClocks函数修改如下。

    1. void BOARD_InitBootClocks(void)
    2. {
    3.   BOARD_BootClockFROHF96M();
    4. }
    复制代码

    运行后串口打印如下,之后一段时间后蓝灯开始闪烁。
    QQ截图20201110213223.png

    其中串口打印是由core0实现,蓝灯闪烁是由core1实现。接下来我们来对这个双核的启动流程简要分析一下。
    首先是core1的部分,下图可以看出,它输出了一个名为core1_image.bin的文件
    QQ截图20201110213609.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里面的位置都是可以任意配置,非常灵活。



    回复

    使用道具 举报

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

    本版积分规则

    关闭

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

    手机版|小黑屋|与非网

    GMT+8, 2024-11-23 10:00 , Processed in 0.132332 second(s), 19 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.