查看: 8383|回复: 7

[原创] 【LPC54114双核任务二】+双核之间通讯

[复制链接]
  • TA的每日心情
    开心
    2025-1-21 08:52
  • 签到天数: 861 天

    连续签到: 1 天

    [LV.10]以坛为家III

    75

    主题

    2523

    帖子

    24

    金牌会员

    Rank: 6Rank: 6

    积分
    5867
    最后登录
    2025-1-22
    发表于 2017-6-27 16:08:03 | 显示全部楼层 |阅读模式
    本帖最后由 leo121_3006061 于 2017-6-27 16:08 编辑

    LPC54114双核(M4 /M0+),如何实现双核之间的通信,NXP官方提供Multicore Software Development Kit (MCSDK) ,双核的管理如下图所示
    dual core.jpg
    可以看出MCSDK由三个组件组成

    1.  Multicore Manager (MCMGR)
         1). 维护系统里所有核的信息     2).为第二核加载代码(当代码在ram里时,此功能才可用)
         3).第二或辅助核的开启和关闭
         4).维护共享的内存区域的地址映射表
    我们可以通过sdk自带的例程Hello world 来理解Multicore Manager,为了更好的运行例程,我稍加修改了一下。
    大致上,分别创建两个独立的keil工程,分别是m0+核与m4核,然后首先编译m0+核工程,再编译m4并且附加m0+一并且下载到开发板。
    第一步 ,在m0核的keil工程里实现6,7的LED闪烁,下边附上部分代码。
    1. int main(void)
    2. {
    3.     uint32_t startupData, i;



    4.     /* Initialize MCMGR before calling its API */
    5.     MCMGR_Init();

    6.     /* Get the startup data */
    7.     MCMGR_GetStartupData(kMCMGR_Core1, &startupData);

    8.     /* Make a noticable delay after the reset */
    9.     /* Use startup parameter from the master core... */
    10.     for (i = 0; i < startupData; i++)
    11.         delay();

    12.     /* Init board hardware.*/
    13.     /* enable clock for GPIO */
    14.     CLOCK_EnableClock(kCLOCK_Gpio0);
    15.     CLOCK_EnableClock(kCLOCK_Gpio1);
    16.     BOARD_InitPins_Core1();
    17.     /* Configure LED */
    18.    // LED_INIT();
    19. led_init();
    20.     /* Signal the other core we are ready */
    21.     MCMGR_SignalReady(kMCMGR_Core1);

    22.     while (1)
    23.     {
    24.         delay();

    25.                         led_toggle(6); //
    26.                          led_toggle(7);
    27.     }
    复制代码
    然后修改如下图所示--user, $K\ARM\ARMCC\bin\fromelf.exe --bincombined --bincombined_base=0x20010000 --output=$Lcore1_image.bin !L,然后编译,不要下载。
    user complie.jpg
    第二步 再创建m4核的工程,我也稍微做了修改,为了减少篇幅,请看部分代码,此部分是当key建按下时m0+核停止运行。
    1. /* Define the init structure for the switches*/
    2.     gpio_pin_config_t sw_config = {kGPIO_DigitalInput, 0};

    3.     /* Init board hardware.*/
    4.     /* attach 12 MHz clock to FLEXCOMM0 (debug console) */
    5.     CLOCK_AttachClk(kFRO12M_to_FLEXCOMM0);

    6.     BOARD_InitPins_Core0();
    7.     BOARD_BootClockFROHF48M();
    8.     BOARD_InitDebugConsole();

    9.     /* Init switches */
    10.     GPIO_PinInit(BOARD_SW1_GPIO, BOARD_SW1_GPIO_PORT, BOARD_SW1_GPIO_PIN, &sw_config);
    11.     GPIO_PinInit(BOARD_SW2_GPIO, BOARD_SW2_GPIO_PORT, BOARD_SW2_GPIO_PIN, &sw_config);

    12. #ifdef CORE1_IMAGE_COPY_TO_RAM
    13.     /* Calculate size of the image  - not required on LPCExpresso. LPCExpresso copies image to RAM during startup
    14.      * automatically */
    15.     uint32_t core1_image_size;
    16.     core1_image_size = get_core1_image_size();
    17.     PRINTF("Copy Secondary core image to address: 0x%x, size: %d\n", CORE1_BOOT_ADDRESS, core1_image_size);

    18.     /* Copy Secondary core application from FLASH to RAM. Primary core code is executed from FLASH, Secondary from RAM
    19.      * for maximal effectivity.*/
    20.     memcpy(CORE1_BOOT_ADDRESS, (void *)CORE1_IMAGE_START, core1_image_size);
    21. #endif
    22. key_init();
    23.     /* Initialize MCMGR before calling its API */
    24.     MCMGR_Init();

    25.     /* Boot Secondary core application */
    26.     PRINTF("Starting Secondary core.\n");
    27.     MCMGR_StartCore(kMCMGR_Core1, CORE1_BOOT_ADDRESS, 1, kMCMGR_Start_Synchronous);

    28.     /* Print the initial banner from Primary core */
    29.     PRINTF("\r\nHello World from the Primary Core!\r\n\n");

    30.     PRINTF("Press the Key1 button to Stop Secondary core.\r\n");
    31.     PRINTF("Press the Key2 button to Start Secondary core.\r\n");

    32.     while (1)
    33.     {


    34.                         if(key_value(0)==0)
    35.                         {
    36.                                         MCMGR_StopCore(kMCMGR_Core1);
    37.                                         PRINTF("Stopped Secondary core.\n");
    38.                                         delay();
    39.                         
    40.                         
    41.                         }
    42.                         if(key_value(0)==1)
    43.                         {
    44.                                         MCMGR_StartCore(kMCMGR_Core1, CORE1_BOOT_ADDRESS, 5, kMCMGR_Start_Synchronous);
    45.                                         PRINTF("Started Secondary core.\n");
    46.                                         delay();
    47.                         
    48.                         }
    49.     }
    复制代码
    第三步编译m4并附加m0+(此步骤是代码里有),一并下载到开发板,打开串口调试工具,显示如下图所示信息
    seial.jpg

    通过上面的步骤,很容易了解利用M4控制M0+的起停。

    2.  Remote Processor Messaging - Lite (RPMsg-Lite)主要为异构多核之间通讯提供接口。
         推荐资源 http://github.com/NXPmicro/rpmsg-lite和官方的sdk接下来通过简单的修改官方的sdk就可以实现本次任务的要求,附上代码
    m0+核的代码(只有修改的部分)

    1. #define RPMSG_LITE_LINK_ID (RL_PLATFORM_LPC5411x_M4_M0_LINK_ID)
    2. #define MCMGR_USED
    3. #define LOCAL_EPT_ADDR (30)

    4. typedef struct the_message
    5. {
    6.     uint32_t DATA;
    7. } THE_MESSAGE, *THE_MESSAGE_PTR;

    8. /*******************************************************************************
    9. * Prototypes
    10. ******************************************************************************/

    11. /*******************************************************************************
    12. * Code
    13. ******************************************************************************/

    14. THE_MESSAGE volatile msg = {0};
    15. unsigned long remote_addr = 0;

    16. /* Internal functions */
    17. static int my_ept_read_cb(void *payload, int payload_len, unsigned long src, void *priv)
    18. {
    19.     int *has_received = priv;

    20.     if (payload_len <= sizeof(THE_MESSAGE))
    21.     {
    22.         memcpy((void *)&msg, payload, payload_len);
    23.         remote_addr = src;
    24.         *has_received = 1;
    25.                         PRINTF("The m0+ core received msg from m4 core\r\n");
    26.                         PRINTF("Message: Size=%x, DATA = %i\n\r", payload_len, msg.DATA);<font color="#ff0000">//接到m4内核传递的消息并且通过uart打印出来,m0+核相当于转发消息</font>
    27.     }
    28.     return RL_RELEASE;
    29. }

    30. /*!
    31. * @brief Main function
    32. */
    33. int main(void)
    34. {
    35.         char ch=0;
    36.     volatile int has_received = 0;
    37.     struct rpmsg_lite_ept_static_context my_ept_context;
    38.     struct rpmsg_lite_endpoint *my_ept;
    39.     struct rpmsg_lite_instance rpmsg_ctxt;
    40.     struct rpmsg_lite_instance *my_rpmsg;

    41.     /* Initialize standard SDK demo application pins */
    42.     BOARD_InitPins_Core1();
    43.        
    44.          /* Initialize standard SDK demo application pins */
    45.     /* attach 12 MHz clock to FLEXCOMM0 (debug console) */
    46.     CLOCK_AttachClk(kFRO12M_to_FLEXCOMM0);

    47.     BOARD_InitDebugConsole();

    48. #ifdef MCMGR_USED
    49.     uint32_t startupData;

    50.     /* Initialize MCMGR before calling its API */
    51.     MCMGR_Init();

    52.     /* Get the startup data */
    53.     MCMGR_GetStartupData(kMCMGR_Core1, &startupData);

    54.     my_rpmsg = rpmsg_lite_remote_init((void *)startupData, RPMSG_LITE_LINK_ID, RL_NO_FLAGS, &rpmsg_ctxt);

    55.     /* Signal the other core we are ready */
    56.     MCMGR_SignalReady(kMCMGR_Core1);
    57. #else
    58.     my_rpmsg = rpmsg_lite_remote_init((void *)RPMSG_LITE_SHMEM_BASE, RPMSG_LITE_LINK_ID, RL_NO_FLAGS, &rpmsg_ctxt);
    59. #endif /* MCMGR_USED */

    60.     while (!rpmsg_lite_is_link_up(my_rpmsg))
    61.         ;

    62.     my_ept = rpmsg_lite_create_ept(my_rpmsg, LOCAL_EPT_ADDR, my_ept_read_cb, (void *)&has_received, &my_ept_context);
    63. #ifdef RPMSG_LITE_NS_USED
    64.     rpmsg_ns_announce(my_rpmsg, my_ept, RPMSG_LITE_NS_ANNOUNCE_STRING, RL_NS_CREATE);
    65. #endif /*RPMSG_LITE_NS_USED*/
    66.     has_received = 0;
    67.                 //msg.DATA=ch;
    68.     while (1) //rx received data
    69.     {
    70.                          ch= GETCHAR();
    71.                         msg.DATA=ch-49;
    72.                        
    73.         if (msg.DATA)<font color="#ff0000">//从uart传递过来的值,转发给m4核</font>
    74.         {
    75.             has_received = 0;
    76.            // msg.DATA++;
    77.             rpmsg_lite_send(my_rpmsg, my_ept, remote_addr, (char *)&msg, sizeof(THE_MESSAGE), RL_DONT_BLOCK);
    78.         }
    79.     }

    80.     rpmsg_lite_destroy_ept(my_rpmsg, my_ept);
    81.     my_ept = NULL;
    82.     rpmsg_lite_deinit(my_rpmsg);
    83.     msg.DATA = 0;

    84.     /* End of example */

    85. }
    复制代码
    m4核代码
    1. static int my_ept_read_cb(void *payload, int payload_len, unsigned long src, void *priv)
    2. {
    3.     int *has_received = priv;

    4.     if (payload_len <= sizeof(THE_MESSAGE))
    5.     {
    6.         memcpy((void *)&msg, payload, payload_len);
    7.         *has_received = 1;
    8.     }
    9.                 msg.DATA++; <font color="#ff0000">//接收从m0+核传递过来的数据;为了区别原始数据,进行++操作</font>
    10.    // PRINTF("Primary core received a msg\n\r");
    11.    // PRINTF("Message: Size=%x, DATA = %i\n\r", payload_len, msg.DATA);
    12.     return RL_RELEASE;
    13. }

    14. /*!
    15. * @brief Main function
    16. */
    17. int main(void)
    18. {
    19.     volatile int has_received;
    20.     struct rpmsg_lite_ept_static_context my_ept_context;
    21.     struct rpmsg_lite_endpoint *my_ept;
    22.     struct rpmsg_lite_instance rpmsg_ctxt;
    23.     struct rpmsg_lite_instance *my_rpmsg;

    24.     /* Initialize standard SDK demo application pins */
    25.     /* attach 12 MHz clock to FLEXCOMM0 (debug console) */
    26.     CLOCK_AttachClk(kFRO12M_to_FLEXCOMM0);

    27.     BOARD_InitPins_Core0();
    28.     BOARD_BootClockFROHF48M();
    29.     BOARD_InitDebugConsole();

    30. #ifdef CORE1_IMAGE_COPY_TO_RAM
    31.     /* Calculate size of the image */
    32.     uint32_t core1_image_size;
    33.     core1_image_size = get_core1_image_size();
    34.    //PRINTF("Copy CORE1 image to address: 0x%x, size: %d\n", CORE1_BOOT_ADDRESS, core1_image_size);

    35.     /* Copy application from FLASH to RAM */
    36.     memcpy(CORE1_BOOT_ADDRESS, (void *)CORE1_IMAGE_START, core1_image_size);
    37. #endif

    38.     /* Initialize MCMGR before calling its API */
    39.     MCMGR_Init();

    40.     /* Boot Secondary core application */
    41.     MCMGR_StartCore(kMCMGR_Core1, CORE1_BOOT_ADDRESS, (uint32_t)rpmsg_lite_base, kMCMGR_Start_Synchronous);

    42.     // Print the initial banner
    43.    // PRINTF("\r\nRPMsg demo starts\n\n\r");

    44.     my_rpmsg = rpmsg_lite_master_init(rpmsg_lite_base, SH_MEM_TOTAL_SIZE, RPMSG_LITE_LINK_ID, RL_NO_FLAGS, &rpmsg_ctxt);

    45.     my_ept = rpmsg_lite_create_ept(my_rpmsg, LOCAL_EPT_ADDR, my_ept_read_cb, (void *)&has_received, &my_ept_context);

    46.     has_received = 0;

    47.     /* Send the first message to the remoteproc */
    48.     msg.DATA = 10;<font color="#ff0000">//初次运行通过m0+核传递的数据</font>
    49.     rpmsg_lite_send(my_rpmsg, my_ept, REMOTE_EPT_ADDR, (char *)&msg, sizeof(THE_MESSAGE), RL_DONT_BLOCK);

    50. while (msg.DATA <= 100)
    51.     {
    52.         if (has_received)
    53.       {
    54.             has_received = 0;
    55.             msg.DATA++;
    56.             rpmsg_lite_send(my_rpmsg, my_ept, 30, (char *)&msg, sizeof(THE_MESSAGE), RL_DONT_BLOCK);
    57.         }
    58.     }

    59.     rpmsg_lite_destroy_ept(my_rpmsg, my_ept);
    60.     my_ept = NULL;
    61.     rpmsg_lite_deinit(my_rpmsg);

    62.     // Print the ending banner
    63.     //PRINTF("\r\nRPMsg demo ends\n\n\r");
    64.   
    复制代码
    运行效果如下图所示
    seial1.jpg

    上述过程是利用共享内存,来实现消息传输的。


    3. Embedded Remote Procedure Call (eRPC)
    eRPC Getting Started User's Guide.pdf (970.6 KB, 下载次数: 60)
    该会员没有填写今日想说内容.
    回复

    使用道具 举报

  • TA的每日心情

    2021-1-28 20:09
  • 签到天数: 317 天

    连续签到: 1 天

    [LV.8]以坛为家I

    61

    主题

    1582

    帖子

    6

    金牌会员

    Rank: 6Rank: 6

    积分
    9404
    最后登录
    2022-5-12
    发表于 2017-6-27 16:40:08 | 显示全部楼层
    赞一个
    好好
    回复

    使用道具 举报

  • TA的每日心情
    奋斗
    2018-3-27 15:23
  • 签到天数: 49 天

    连续签到: 1 天

    [LV.5]常住居民I

    0

    主题

    109

    帖子

    0

    中级会员

    Rank: 3Rank: 3

    积分
    333
    最后登录
    2018-6-28
    发表于 2017-6-27 16:58:57 | 显示全部楼层
    看不大懂
    该会员没有填写今日想说内容.
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2020-3-29 09:54
  • 签到天数: 418 天

    连续签到: 1 天

    [LV.9]以坛为家II

    21

    主题

    2928

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    3307
    最后登录
    2021-4-7
    发表于 2017-6-27 19:21:25 | 显示全部楼层
    赞。。。
    该会员没有填写今日想说内容.
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2025-1-21 08:52
  • 签到天数: 861 天

    连续签到: 1 天

    [LV.10]以坛为家III

    75

    主题

    2523

    帖子

    24

    金牌会员

    Rank: 6Rank: 6

    积分
    5867
    最后登录
    2025-1-22
     楼主| 发表于 2017-6-27 20:35:30 来自手机 | 显示全部楼层
    小马哥-1650185 发表于 2017-6-27 16:40
    赞一个

    感谢鼓励
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2025-1-21 08:52
  • 签到天数: 861 天

    连续签到: 1 天

    [LV.10]以坛为家III

    75

    主题

    2523

    帖子

    24

    金牌会员

    Rank: 6Rank: 6

    积分
    5867
    最后登录
    2025-1-22
     楼主| 发表于 2017-6-27 20:36:03 来自手机 | 显示全部楼层
    Paderboy 发表于 2017-6-27 19:21
    赞。。。

    感谢鼓励
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2025-1-21 08:52
  • 签到天数: 861 天

    连续签到: 1 天

    [LV.10]以坛为家III

    75

    主题

    2523

    帖子

    24

    金牌会员

    Rank: 6Rank: 6

    积分
    5867
    最后登录
    2025-1-22
     楼主| 发表于 2017-6-27 20:37:04 来自手机 | 显示全部楼层
    nxp_helloworld 发表于 2017-6-27 16:58
    看不大懂

    写的不太好,多多包涵
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    擦汗
    2018-12-22 00:46
  • 签到天数: 10 天

    连续签到: 1 天

    [LV.3]偶尔看看II

    8

    主题

    70

    帖子

    0

    中级会员

    Rank: 3Rank: 3

    积分
    204
    最后登录
    2019-1-5
    发表于 2018-3-7 23:39:23 | 显示全部楼层
    双核感觉很神奇的样子
    今天天气不错!签到!
    回复 支持 反对

    使用道具 举报

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

    本版积分规则

    关闭

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

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

    GMT+8, 2025-8-31 06:41 , Processed in 0.097891 second(s), 27 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

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