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` 也要进行?