TMS320C6678: 核间通信与核内通信问题

Part Number: TMS320C6678

0. 写在前面

在使用 C6678 进行多核编程时,在通信方面有一些疑惑,希望能得到各位工程师的解答。

1. 多核之间通信交互

这里以两个核(core0 和 core1)为例,它们使用 ListMP 传输数据。

core0 和 core1 的 cfg 节选如下:
var SHAREDMEM = 0x0C000000;
var SHAREDMEMSIZE = 0x40000;
var SDDR3_BASE = 0x80000000;
var SDDR3_SIZE = 0x50000;
/*
 *  Need to define the shared region. The IPC modules use this
 *  to make portable pointers. All processors need to add this
 *  call with their base address of the shared memory region.
 *  If the processor cannot access the memory, do not add it.
 */

var SharedRegion = xdc.useModule('ti.sdo.ipc.SharedRegion');
SharedRegion.numEntries = 2;
SharedRegion.translate = false;
SharedRegion.setEntryMeta(0,
    { base: SHAREDMEM,
      len: SHAREDMEMSIZE,
      ownerProcId: 0,
      isValid: true,
      cacheEnable: true,
      cacheLineSize: 64,
      createHeap: true,
      name: "MSMC_SHARED",
     });
SharedRegion.setEntryMeta(1,
    { base: SDDR3_BASE,
      len: SDDR3_SIZE,
      ownerProcId: 0,
      isValid: true,
      cacheEnable: true,
      cacheLineSize: 128,
      createHeap: true,
      name: "DDR3_SHARED",
     }); 


1.1 情况 1

假定要传输的数据结构体定义如下:
// IPC_Struct
typedef struct tag_imgIRLmp
{
    ListMP_Elem header;
    ImgIR ir;       // 红外图像结构体
    Int InitFlag;  // 0:代表跟踪状态,1:代表初始化帧 
} ImgIRLMP;

typedef struct tag_ImgIR
{
    UInt8 *pImg;
    int width;
    int height;
} ImgIR;


core0 部分代码如下,ListMP 句柄为 lmpIR_handle,下同:
/*
CORE 0
*/

ImgIRLMP *pImgIRLMP;
// Allocation
pImgIRLMP = (ImgIRLMP *)Memory_alloc(0, sizeof(ImgIRLMP), L1_CACHELINE_SIZE, &eb);
// Fill Data
pImgIRLMP->InitFlag = 10086;
// ...省略其它赋值

// Put Elem
ListMP_putHead(lmpIR_handle, (ListMP_Elem *)pImgIRLMP);

core1 部分代码如下:
/*
CORE 1
*/

ImgIRLMP *pImgIRLMP;
while((pImgIRLMP = (ImgIRLMP *)ListMP_getTail(lmpIR_handle)) == NULL);

问题:
1.`pImgIRLMP` 能否在 `heap0` 上申请内存空间?
2.是否应该为 `ImgIR` 的 `pImg` 申请内存空间?
3.是否应该释放 `pImgIRLMP` (等其它可能的变量)申请的空间?如果应该释放,在何时释放?如何释放?在 core0 处释放还是在 core1 处释放?
4. 是否有必要在装入链表前进行 `Cache_wb`?读取链表后进行 `Cache_inv`?如果是的话,只对 `pImgIRLMP` 进行相关操作吗?还是 `ImgIR` 的 `pImg` 也要进行?


1.2 情况 2

假定要传输的数据结构体如下:
// IPC_Struct
typedef struct tag_imgIRLmp
{
    ListMP_Elem header;
    ImgIR *pir;  // 这里是指针,和情况 1 不同
    Int InitFlag;   
} ImgIRLMP;

typedef struct tag_ImgIR
{
    UInt8 *pImg;
    int width;
    int height;
} ImgIR;

core0 和 core1 的代码同情况 1。

问题:
1.`pImgIRLMP` 能否在 `heap0` 上申请内存空间?
2.是否应该为 `ImgIRLMP` 的 `pir` 申请内存空间,是否应该为 `ImgIR` 的 `pImg` 申请内存空间?
3.是否应该释放 `pImgIRLMP` (等其它可能的变量)申请的空间?如果应该释放,在何时释放?如何释放?在 core0 处释放还是在 core1 处释放?
4. 是否有必要在装入链表前进行 `Cache_wb`?读取链表后进行 `Cache_inv`?如果是的话,只对 `pImgIRLMP` 进行相关操作吗?还是 `ImgIRLMP` 的 `pir`  和 `ImgIR` 的 `pImg` 也要进行?


2. 单核的核内交互

这里以 core0 为例,在不同的 cpp 文件中采用 Queue 进行交互。

core0 的 cfg 节选如下:
var SMSMC_BASE = 0x0C000000;
var SMSMC_SIZE = 0x00040000;
var SDDR3_BASE = 0x80000000;
var SDDR3_SIZE = 0x40000000;

var SharedRegion = xdc.useModule('ti.sdo.ipc.SharedRegion');
SharedRegion.numEntries = 2;
SharedRegion.translate = false;
SharedRegion.setEntryMeta(0,
    { base: SHAREDMEM,
      len: SHAREDMEMSIZE,
      ownerProcId: 0,
      isValid: true,
      cacheEnable: true,
      cacheLineSize: 64,
      createHeap: true,
      name: "MSMC_SHARED",
     });
SharedRegion.setEntryMeta(1,
    { base: SDDR3_BASE,
      len: SDDR3_SIZE,
      ownerProcId: 0,
      isValid: true,
      cacheEnable: true,
      cacheLineSize: 128,
      createHeap: true,
      name: "DDR3_SHARED",
     }); 

假定要传输的数据结构体如下:
typedef struct tag_DataPtQueElem
{
    Queue_Elem header;
    void *pIr;
    void *pImg2;
    void *pImg2;
    int frame_id;
} DataPtQueElem;

core0 在 send.cpp 发送数据, Queue 的句柄为 hDataPtQue,下同:
/*
send.cpp
*/

// global variables
#pragma DATA_SECTION(hw_image_data,".image");
uint8_t hw_image_data[HW_IMAGE_DATA_SIZE];
#pragma DATA_SECTION(my_image2, ".image")
uint8_t my_image2[MY_IMAGE_DATA_SIZE2]; 
#pragma DATA_SECTION(my_image3, ".image")
uint8_t my_image3[MY_IMAGE_DATA_SIZE3];

void send_func()
{
    DataPtQueElem *pElem;
    pElem = (DataPtQueElem*)Memory_alloc(0, sizeof(DataPtQueElem), L1_CACHELINE_SIZE, NULL);
    pElem->pIr = hw_image_data;
    pElem->pImg2 = my_image2;
    pElem->pImg3 = my_image3;
    pElem->frame_id = 10086;
    Queue_enqueue(hDataPtQue, (Queue_Elem *)pElem);
}

core0 在 recv.cpp 接收数据:
 
/*
recv.cpp
*/
DataPtQueElem *pElem;
pElem = (DataPtQueElem *)Queue_dequeue(hDataPtQue);

问题:
1.`pElem` 能否在 `heap0` 上申请内存空间?
2.是否应该为 `DataPtQueElem` 的 `pIr` 、`pImg2``pImg3`申请内存空间?
3.是否应该释放 `pElem` (等其它可能的变量)申请的空间?如果应该释放,在何时释放?如何释放?在 send.cpp 处释放还是在 recv.cpp 处释放?
4.是否有必要在装入队列前进行 `Cache_wb`?读取队列后进行 `Cache_inv`?如果是的话,只对 `pElem` 进行相关操作吗?还是 `DataPtQueElem` 的 `pIr`、 `pImg2` 和 `pImg3` 也要进行?