查看: 856|回复: 0

【NXP OKdo E1双核Cortex M33开发板】+LPC55S69双核通讯实验

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

    连续签到: 1 天

    [LV.6]常住居民II

    发表于 2020-11-3 16:06:13 | 显示全部楼层 |阅读模式
    分享到:
    今天我来做一下LPC55S69的双核通讯实验,我们通过上面的分析已知通讯的关键就在是要mailbox寄存器。
    闲话不多说,我们在官方的hello_world_cm33_core0及其匹配的hello_world_cm33_core1.上面修改。
    我们定义core1程序一直在运行一个闪烁灯,而core0程序控制一个按键,按下按键可以打开或者关闭core1,并空闲状态不停输出"Hello world"。
    先在core0的main函数文件页面修改:
    先添加1个变量
    //按键的初始化
    1. ...
    2. uint8_t        led_flg=0;

    复制代码

    while函数里面。查询:
    1. <blockquote><blockquote>if(0 == IS_BUTTON_PRESSED())
    复制代码
    core1c程序的修改:
    main函数while:
    1. LED_GREEN_TOGGLE();
    2. delay();
    复制代码
    这里没有用到中断,仅简单看core0能否直观的控制core1.
    编译下载调试:
    串口输出(不知道怎么回事,调试双核时,虚拟串口无法正常输出,可能我哪边配置不对,仅调试台输出信息):
    1. Hello world!
    2. Hello world!
    3. Hello world!
    4. Hello world!
    5. Starting Secondary core.//开启
    6. The secondary core application has been started.
    7. Hello world!
    8. Hello world!
    9. Hello world!
    10. Hello world!
    11. Hello world!
    12. Stopping Secondary core.//关闭
    13. The secondary core application has been stopped.
    14. Hello world!
    15. Hello world!
    16. Hello world!
    复制代码
    CORE1打开时LED闪烁,关闭时LED保保持最后的状态不变。
    至少证明通讯成功,下面用core0程序里的按键进行控制core1程序里的LED亮灭,需要使用中断:
    这里定义发送1为开灯,发送2为关灯,发送接收得到数据不能为0,不然会被忽略
    在core0 mian函数页面添加变量:
    1. uint16_t Mail_DATA=0;//邮箱数据接收缓存
    2. uint8_t g_flg=0;//邮箱中断标志
    3. uint8_t        led_flg=0;//led状态
    复制代码
    while里面:
    1. if(g_flg==1)
    2. {
    3.         g_flg=0;
    4.         printf("Core0 receve data is : %d",Mail_DATA);

    5. }
    6. else
    7. {
    8.         //我们这添加控制核1打开的操作
    9.         if(0 == IS_BUTTON_PRESSED())
    10.         {
    11.                 while (0== IS_BUTTON_PRESSED())
    12.                 {
    13.                 }

    14.                 led_flg=1-led_flg;
    15.                 //printf("the led_flg is %d \r\n",led_flg);
    16.                 //发送数据不能为0,为0无效
    17.                 if(led_flg==1)
    18.                 {
    19.                         MAILBOX_SetValueBits(MAILBOX, kMAILBOX_CM33_Core1, 1);
    20.                 }
    21.                 else
    22.                 {

    23.                         MAILBOX_SetValueBits(MAILBOX, kMAILBOX_CM33_Core1, 2);
    24.                 }
    25.         }

    26.         LED_BLUE_TOGGLE();
    27.         delay();
    28. }
    复制代码
    mailbox的中断,例程已写好在mcmgr_internal_core_api_lpc55s69.c里面,
    我们直接修改下:
    添加外部变量引用:
    1. extern uint16_t Mail_DATA;
    2. extern uint8_t g_flg;
    复制代码
    在中断程序里面修改,没有破坏之前的结构(发送接收得到数据不能为0,不然会被忽略):
    1. void MAILBOX_IRQHandler(void)
    2. {
    3. #if defined(FSL_FEATURE_MAILBOX_SIDE_A)
    4.     mailbox_cpu_id_t cpu_id = kMAILBOX_CM33_Core0;
    5. #else
    6.     mailbox_cpu_id_t cpu_id = kMAILBOX_CM33_Core1;
    7. #endif
    8.     uint32_t data;
    9.     uint16_t eventType;
    10.     uint16_t eventData;

    11.     data = MAILBOX_GetValue(MAILBOX, cpu_id);
    12. <font color="#ff0000">    Mail_DATA=data;</font>
    13.     // To be MISRA compliant, return value needs to be checked even it could not never be 0
    14.     if (0U != data)
    15.     {
    16. <font color="#ff0000">            g_flg=1;</font>

    17.         MAILBOX_ClearValueBits(MAILBOX, cpu_id, data);

    18.         eventType = (uint16_t)(data >> 16u);
    19.         eventData = (uint16_t)(data & 0x0000FFFFu);

    20.         if (((mcmgr_event_type_t)eventType >= kMCMGR_RemoteCoreUpEvent) &&
    21.             ((mcmgr_event_type_t)eventType < kMCMGR_EventTableLength))
    22.         {
    23.             if (MCMGR_eventTable[(mcmgr_event_type_t)eventType].callback != ((void *)0))
    24.             {
    25.                 MCMGR_eventTable[(mcmgr_event_type_t)eventType].callback(
    26.                     eventData, MCMGR_eventTable[(mcmgr_event_type_t)eventType].callbackData);
    27.             }
    28.         }
    29.     }
    30. }
    复制代码
    对core1函数进行修改:
    main函数里面修改:
    定义变量:
    1. uint16_t Mailbox_data=0;
    2. uint8_t g_flag=0,led_flag=0;
    复制代码
    1. if(g_flag==1)
    2.             {
    3.                     g_flag=0;
    4.                     //printf("Core1 receiver data is : %d",Mailbox_data);
    5.                     led_flag=Mailbox_data;

    6.             }
    7.             else
    8.             {
    9.                     if(led_flag==1)
    10.                     {
    11.                             LED_GREEN_ON();

    12.                     }
    13.                     else if(led_flag==2)
    14.                         {
    15.                             LED_GREEN_OFF();
    16.                         }
    17.             }
    复制代码
    中断函数里面修改:
    1. <font color="#ff0000">extern uint16_t Mailbox_data;
    2. extern uint8_t g_flag;</font>

    3. void MAILBOX_IRQHandler(void)
    4. {
    5. #if defined(FSL_FEATURE_MAILBOX_SIDE_A)
    6.     mailbox_cpu_id_t cpu_id = kMAILBOX_CM33_Core0;
    7. #else
    8.     mailbox_cpu_id_t cpu_id = kMAILBOX_CM33_Core1;
    9. #endif
    10.     uint32_t data;
    11.     uint16_t eventType;
    12.     uint16_t eventData;

    13.     data = MAILBOX_GetValue(MAILBOX, cpu_id);
    14. <font color="#ff0000">    Mailbox_data=data;</font>
    15. //发送接收得到数据不能为0,不然会被忽略
    16.      //To be MISRA compliant, return value needs to be checked even it could not never be 0
    17.     if (0U != data)
    18.     {
    19. <font color="#ff0000">            g_flag=1;</font>

    20.         MAILBOX_ClearValueBits(MAILBOX, cpu_id, data);

    21.         eventType = (uint16_t)(data >> 16u);
    22.         eventData = (uint16_t)(data & 0x0000FFFFu);

    23.         if (((mcmgr_event_type_t)eventType >= kMCMGR_RemoteCoreUpEvent) &&
    24.             ((mcmgr_event_type_t)eventType < kMCMGR_EventTableLength))
    25.         {
    26.             if (MCMGR_eventTable[(mcmgr_event_type_t)eventType].callback != ((void *)0))
    27.             {
    28.                 MCMGR_eventTable[(mcmgr_event_type_t)eventType].callback(
    29.                     eventData, MCMGR_eventTable[(mcmgr_event_type_t)eventType].callbackData);
    30.             }
    31.         }
    32.     }
    33. }
    复制代码

    编译下载,现象如下:
    q4.gif
    例程比较简单,但是逻辑确实通用的,我们可以在这上面添加更多的外设控制。好了,双核通讯就到这了。
    这里说个题外话,就是这个函数 就是core0里面的MCMGR_StartCore(kMCMGR_Core1, CORE1_BOOT_ADDRESS, 5, kMCMGR_Start_Synchronous);
    其中还是很有意思的,kMCMGR_Start_Synchronous等待2个函数同步后再运行。展开MCMGR_StartCore函数:
    1. mcmgr_status_t MCMGR_StartCore(mcmgr_core_t coreNum, void *bootAddress, uint32_t startupData, mcmgr_start_mode_t mode)
    2. {
    3.     mcmgr_status_t ret;

    4.     if ((uint32_t)coreNum < g_mcmgrSystem.coreCount)
    5.     {
    6.         /* Pass the startupData - LSB first */
    7.         s_mcmgrCoresContext[coreNum].startupData = startupData;
    8.         /* the startup data is sent asynchronously */
    9.         ret = mcmgr_start_core_internal(coreNum, bootAddress);

    10.         if (ret == kStatus_MCMGR_Success)
    11.         {
    12.             if (mode == kMCMGR_Start_Synchronous)
    13.             {
    14.                 /* Wait until the second core reads and confirms the startup data */
    复制代码


    上面那个函数一直在等待core1准备好的状态。而core1里面:
    1. do
    2.     {
    3.         status = MCMGR_GetStartupData(&startupData);
    4.     } <font color="#ff0000">while (status != kStatus_MCMGR_Success);</font>
    复制代码

    在不停的查询当前状态,并刷新。我一开始想完全撇开mcmgr,但发现牵连还挺多就放弃了。哪位大佬能详细讲述一下mcmgr,包括新注册的建中断任务等。小弟感激不尽!



    回复

    使用道具 举报

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

    本版积分规则

    关闭

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

    手机版|小黑屋|与非网

    GMT+8, 2024-4-20 07:00 , Processed in 0.106052 second(s), 16 queries , MemCache On.

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

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2020, Tencent Cloud.