1回答

0收藏

[评测分享] 【NXP OKdo E1双核Cortex M33开发板 】基于Keil双核架构的研究3

#板卡评测 #板卡评测 2142 人阅读 | 1 人回复 | 2020-12-01

基于Keil双核架构的研究3
-共享内存
1.  设计思想
在Core0和Core1之间开辟一段SRAM,作为双核之间数据传递的共用内存。以Core0的RPMSG通讯作为触发信号,填充共享内存段的数据,然后Core1通过RPMSG信息通知Core0接收数据。这种方式对于传输数据频率较低,但传输数据量很大时还是非常有效的。
2.  软件实践
利用前次RPMSG-Lite的试验的结果,重新规划设计内存的试用情况,从0x20039800开始到0x20040000止,大约26K的内存空间用来作为核间通讯的共享内存。
  1. <div align="left">    #define DATA_SH_MEM_ADDR    0x20039800</div><div align="left">    #defineDATA_SH_MEM_SIZE    0x6800</div>
复制代码

构建一个结构体指针,用来管理共享内存。根据实际需要,可以将这段内存再次划分为多个段。
  1. typedef struct
  2. {
  3.   uint32_t type;
  4.   uint8_t dat[100];
  5.   uint16_t crc;
  6. }*DATA_SH_MEM_PTR;

  7. DATA_SH_MEM_PTR data_sh_mem_ptr = (DATA_SH_MEM_PTR)DATA_SH_MEM_ADDR;
复制代码

这里假设这种类型的结构体和使用方法。
Core1在接收到Core0发送的rpmsg信息后,在rpmsg的回调函数中填充共享内存,并且对填入的数据形成校验:
  1. /*Internal functions */
  2. staticint32_t my_ept_read_cb(void *payload, uint32_t payload_len, uint32_t src, void*priv)
  3. {
  4.     int32_t *has_received = priv;
  5.           int i;
  6.           uint16_t crc = 0;

  7.     if (payload_len <= sizeof(THE_MESSAGE))
  8.     {
  9.           (void)memcpy((void*)&msg, payload, payload_len);
  10.         remote_addr   = src;
  11.         *has_received = 1;
  12.           data_sh_mem_ptr->type= 0x01;      //type
  13.           for(i=0;i<100;i++)
  14.           {
  15.                data_sh_mem_ptr->dat =(uint8_t)msg.DATA;
  16.                crc +=data_sh_mem_ptr->dat;
  17.           }
  18.           data_sh_mem_ptr->crc= crc;
  19.     }
  20.     return RL_RELEASE;
  21. }
  22. 在主循环中,查看是否完成数据填充,完成填充后,发送rpmsg消息通知Core0进行共享内存数据解析。
  23. Core0在接收到Core1的rpmsg后,在回调函数中解析共享内存数据,并进行校验:
  24. <p>/* This is the read callback,note we are in a task context when this callback</p><p>is invoked, so kernelprimitives can be used freely */</p><p>static int32_tmy_ept_read_cb(void *payload, uint32_t payload_len, uint32_t src, void *priv)</p>{
  25.     int32_t *has_received = priv;
  26.     int i;
  27.     uint16_t crc = 0;

  28.     if (payload_len <= sizeof(THE_MESSAGE))
  29.     {
  30.           if(data_sh_mem_ptr->type == 0x01)      
  31.          {
  32.               data_sh_mem_ptr->type = 0x00;
  33.               for(i=0;i<100;i++)
  34.                  crc += data_sh_mem_ptr->dat;
  35.              if(crc == data_sh_mem_ptr->crc)
  36.              {
  37. <p>//                  (void)PRINTF("Primary corereceived sh mem data success\r\n");</p><p>                   (void)PRINTF("ss:DATA =%i\r\n", data_sh_mem_ptr->dat[0]);</p>             }
  38.               else
  39.               {
  40. <p>//                (void)PRINTF("Primary corereceived sh mem data failed\r\n");</p><p>                 (void)PRINTF("ff:crc0 = %ucrc1= %u \r\n", crc,data_sh_mem_ptr->crc);</p>              }
  41.           }

  42. <p>        (void)memcpy((void *)&msg, payload,payload_len);</p>        *has_received = 1;
  43.     }
  44.           count++;
  45.     return RL_RELEASE;
  46. }
复制代码

当Core0完成共享内存信息处理后,即完成一次Core0和Core1核间数据交换。Core0可以随即发起下一次数据交换,也可以采用周期性的方式触发下一次的数据交换。
为了保证数据传输的速度,不采用rpmsg数据同步,而是采用环形队列的方式管理共享内存空间,如果Core0查询的速度和环形队列空间的适当控制,可以保证实时数据传递,进行在一个CPU内部一样。

3.  效果验证

关注下面的标签,发现更多相似文章
分享到:
回复

使用道具 举报

回答|共 1 个

倒序浏览

沙发

story_xjj

发表于 2020-12-1 16:07:14 | 只看该作者

怎么变得这么乱啊
回复 支持 反对

使用道具 举报

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

本版积分规则

关闭

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