查看: 2041|回复: 1

[评测分享] 【NXP OKdo E1双核Cortex M33开发板】+LPC55S69双核通讯之我见

[复制链接]
  • TA的每日心情
    慵懒
    2022-10-25 08:55
  • 签到天数: 103 天

    连续签到: 1 天

    [LV.6]常住居民II

    发表于 2020-10-30 16:00:47 | 显示全部楼层 |阅读模式
    分享到:
    本帖最后由 胤幻1988 于 2020-10-30 16:06 编辑

    LPC55S69主打的功能就是双核和TrustZone数据安全,今天我们来测试一下LPC55S69的双核。LPC55S69包含两个M33,核0和核1,两者的唯一区别就是核0不能运用MPU(内存保护单元),FPU(浮点运算单元),DSP,ETM(嵌入式追踪宏单元)和TrustZone。几乎都是跟数据相关的部分。这就注定了核0更倾向于做算法,而核1更倾向于控制外设。具体可看它的block图:
    SH2.png

    SH1.png
    两者运行的程序,完全是互相独立的,外设部分为2个核共有。那这两个核如何通讯呢。NXP提供了一个邮箱的机制,本质就是共用的一个叫MAILBOX的寄存器来实现数据的传输。
    下面不多说,我们打开官方DEMO板的多核示例:
    SH3.png
    它这里呢,把mailbox又封装了一层,用的一个叫mcmgr的文件:
    SH4.png
    具体打开,最底层的还是对mailbox寄存器进行操作。对于这个我决定并不是封装的越多越好,入门的应该越简单清晰越好。
    SH5.png
    核0作为主核,启动什么的也按照它开始进行。核1作为辅助核,在核0开启并初始化它程序对应的外设后后,才会复制核1的代码到RAM并打开核1。
    两个核都开启后,核0通过自己对应的数据地址向核1对应的数据地址发送一个数据,产生一个mailbox中断,在中断里核1接收,并读出核0发送的数据。

    核1可按照对应的数据,做出相应的外设控制,或者回传一些数据给核0。就这样2者实现了通讯。当然这是最简单的描述,实际上它将这一邮箱列队机制更加完善了,也比我描述的复杂多了,但是本质还是一样。
    我们看看mcmgr系统里面具体函数:
    SH8.png
    SH6.png
    SH7.png
    SH9.png
    重点在与真正中断调用的函数是我们一开始注册的那个函数.下面我们先看core0里面的mailbox是如何一步一步实现的:
    先看它提到的第一个函数:MCMGR_Init();
    我们进入定义看下:
    C1.png
    我们看到它初始化了2种中断处理的函数:MCMGR_StartupDataEventHandler和MCMGR_FeedStartupDataEventHandler
    我们先看MCMGR_StartupDataEventHandler:
    C2.png
    我们看下这个mcmgr_core_context_t * 这个结构体是啥东东:
    C3.png
    看看核各个状态的组合:mcmgr_core_state_t,并赋值:
    C4.png
    看完这个结构体定义我们就知道MCMGR_StartupDataEventHandler是干啥的了:
       switch (coreContext->state)//查询当前核的状态
        {
            //如果是低核,返回低核状态
            case kMCMGR_StartupGettingLowCoreState:
                coreContext->startupData = startupDataChunk; /* Receive the low part */
                coreContext->state       = kMCMGR_StartupGettingHighCoreState;
                (void)MCMGR_TriggerEvent(kMCMGR_FeedStartupDataEvent, (uint16_t)kMCMGR_StartupGettingHighCoreState);
                break;
            //如果是低核,返回高核状态
            case kMCMGR_StartupGettingHighCoreState:
                coreContext->startupData |= ((uint32_t)startupDataChunk) << 16;
                coreContext->state = kMCMGR_RunningCoreState;
                (void)MCMGR_TriggerEvent(kMCMGR_FeedStartupDataEvent, (uint16_t)kMCMGR_RunningCoreState);
                break;

            default:
                /* All the cases have been listed above, the default clause should not be reached. */
                break;
        }

    我们接下来看:MCMGR_FeedStartupDataEventHandler
    K1.png
    K2.png
    K3.png

    K4.png
    联合上下文得知为想当前核邮箱写入设定状态值并更新结构体当前核的启动状态。
    我们再看 mcmgr_late_init_internal
    K5.png
    那么 MCMGR_Init()主要就是启动了mailbox并注册了2种中断种类。
    我们再看main函数里面的
    Z2.png
    Z1.png
    启动了Core1.
    我们再看void SystemInitHook(void)函数,看看它是干啥的:
    /*!
    * @brief Application-specific implementation of the SystemInitHook() weak function.
    */
    void SystemInitHook(void)
    {
        /* Initialize MCMGR - low level multicore management library. Call this
           function as close to the reset entry as possible to allow CoreUp event
           triggering. The SystemInitHook() weak function overloading is used in this
           application. */
        MCMGR_EarlyInit();
    }

    展开MCMGR_EarlyInit():
    mcmgr_status_t MCMGR_EarlyInit(void)
    {
        mcmgr_core_t coreNum = MCMGR_GetCurrentCore();
        if ((uint32_t)coreNum < g_mcmgrSystem.coreCount)
        {
            return mcmgr_early_init_internal(coreNum);
        }
        return kStatus_MCMGR_Error;
    }

    mcmgr_status_t mcmgr_early_init_internal(mcmgr_core_t coreNum)
    {
        if ((uint32_t)coreNum < g_mcmgrSystem.coreCount)
        {
            MAILBOX_Init(MAILBOX);

            /* Trigger core up event here, core is starting! */
            return MCMGR_TriggerEvent(kMCMGR_RemoteCoreUpEvent, 0);
        }
        return kStatus_MCMGR_Error;
    }

    static inline void MAILBOX_Init(MAILBOX_Type *base)
    {
    #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
        CLOCK_EnableClock(kCLOCK_Mailbox);
    #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
    #if !(defined(FSL_FEATURE_MAILBOX_HAS_NO_RESET) && FSL_FEATURE_MAILBOX_HAS_NO_RESET)
        /* Reset the MAILBOX module */
        RESET_PeripheralReset(kMAILBOX_RST_SHIFT_RSTn);
    #endif
    }

    mcmgr_status_t MCMGR_TriggerEvent(mcmgr_event_type_t type, uint16_t eventData)
    {
        return MCMGR_TriggerEventCommon(type, eventData, false);
    }

    static mcmgr_status_t MCMGR_TriggerEventCommon(mcmgr_event_type_t type, uint16_t eventData, bool forcedWrite)
    {
        uint32_t remoteData;
        if (type >= kMCMGR_EventTableLength)
        {
            return kStatus_MCMGR_Error;
        }

        mcmgr_core_t coreNum = MCMGR_GetCurrentCore();
        if ((uint32_t)coreNum < g_mcmgrSystem.coreCount)
        {
            remoteData = (((uint32_t)type) << 16) | eventData;
            return mcmgr_trigger_event_internal(remoteData, forcedWrite);
        }
        return kStatus_MCMGR_Error;
    }

    mcmgr_status_t mcmgr_trigger_event_internal(uint32_t remoteData, bool forcedWrite)
    {
    #if defined(FSL_FEATURE_MAILBOX_SIDE_A)
        mailbox_cpu_id_t cpu_id = kMAILBOX_CM33_Core1;
    #else
        mailbox_cpu_id_t cpu_id = kMAILBOX_CM33_Core0;
    #endif
        /* When forcedWrite is false, wait until the Mailbox Interrupt request register is cleared,
           i.e. until previously sent data is processed. */
        if (false == forcedWrite)
        {
            while (0U != MAILBOX_GetValue(MAILBOX, cpu_id))
            {
            }
        }
        MAILBOX_SetValueBits(MAILBOX, cpu_id, remoteData);
        return kStatus_MCMGR_Success;
    }

    可以看出,这个钩子函数,一直在运行,当运行的核变化时它就将通过发送一个核更新的标志。但是我个人很不喜欢这样的层层封装方式,下次我直接控制mailbox来实双核的通讯。






    回复

    使用道具 举报

  • TA的每日心情
    擦汗
    2024-9-30 02:33
  • 签到天数: 444 天

    连续签到: 1 天

    [LV.9]以坛为家II

    发表于 2020-11-25 08:16:20 | 显示全部楼层
    看你第一个图片标注,是不是标反了?
    回复 支持 反对

    使用道具 举报

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

    本版积分规则

    关闭

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

    手机版|小黑屋|与非网

    GMT+8, 2024-10-18 16:42 , Processed in 0.133636 second(s), 18 queries , MemCache On.

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

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.