在之前第三章,笔者简单描述过多核通信,但是在复杂应用*享内存的合理使用我们是需要相关框架介入的。本章将围绕FreeRtos利用stream buffer(message buffer 也属于stream buffer 可以具体了解底层)实现共享内存池数据交互(部分参考sdk demo)。
1.首先指定一个共享内存区域,指定主从核确切区域
下面的宏,主从工程保持一致
#define APP_MESSAGE_BUFFER_EVENT_DATA (1U)
#define APP_MESSAGE_BUFFER_SIZE (128U)
#define APP_SH_MEM_PRIMARY_TO_SECONDARY_MB_OFFSET (0x0u)
#define APP_SH_MEM_SECONDARY_TO_PRIMARY_MB_OFFSET (0x4u)
#define APP_SH_MEM_PRIMARY_TO_SECONDARY_MB_STRUCT_OFFSET (0x40u)
#define APP_SH_MEM_SECONDARY_TO_PRIMARY_MB_STRUCT_OFFSET (0x80u)
#define APP_SH_MEM_PRIMARY_TO_SECONDARY_BUF_STORAGE_OFFSET (0x200u)
#define APP_SH_MEM_SECONDARY_TO_PRIMARY_BUF_STORAGE_OFFSET (0x800u)
#define SH_MEM_TOTAL_SIZE (2048u)
//共享内存起始地址 前2*4Byte为描述core0 core1的基地址
#define APP_SH_MEM_BASE (0x202c0000u) //&Image$$RPMSG_SH_MEM$$Base
//core0 core1 基地址记录创建函数返回的句柄,这里主从要保持一致
#define xPrimaryToSecondaryMessageBuffer (*(MessageBufferHandle_t *)(APP_SH_MEM_BASE + APP_SH_MEM_PRIMARY_TO_SECONDARY_MB_OFFSET))
#define xSecondaryToPrimaryMessageBuffer (*(MessageBufferHandle_t *)(APP_SH_MEM_BASE + APP_SH_MEM_SECONDARY_TO_PRIMARY_MB_OFFSET))
//core0 core1 缓存数据描述信息
#define xPrimaryToSecondaryMessageBufferStruct (*(StaticStreamBuffer_t *)(APP_SH_MEM_BASE + APP_SH_MEM_PRIMARY_TO_SECONDARY_MB_STRUCT_OFFSET))
#define xSecondaryToPrimaryMessageBufferStruct (*(StaticStreamBuffer_t *)(APP_SH_MEM_BASE + APP_SH_MEM_SECONDARY_TO_PRIMARY_MB_STRUCT_OFFSET))
//core0 core1 数据缓存区域
#define ucPrimaryToSecondaryBufferStorage (*(uint8_t *)(APP_SH_MEM_BASE + APP_SH_MEM_PRIMARY_TO_SECONDARY_BUF_STORAGE_OFFSET))
#define ucSecondaryToPrimaryBufferStorage (*(uint8_t *)(APP_SH_MEM_BASE + APP_SH_MEM_SECONDARY_TO_PRIMARY_BUF_STORAGE_OFFSET))
2.创建静态的stream buffer(必须静态,这样主从核才知道确切位置)
/****************************************************M7*****************************************************/
//m7核先clear共享区域
(void)memset((void *)0x202c0000, 0, SH_MEM_TOTAL_SIZE);
/*注:必须静态创建,因为主从必须知道参数确切地址才行*/
//返回参数:分配缓冲区句柄,实际传递的是该缓冲区描述区域地址 /* The buffer size in bytes. */ /* Statically allocated buffer storage area. */ /* Message buffer handle. */
xPrimaryToSecondaryMessageBuffer = xMessageBufferCreateStatic(APP_MESSAGE_BUFFER_SIZE,&ucPrimaryToSecondaryBufferStorage,&xPrimaryToSecondaryMessageBufferStruct);
/****************************************************M4*****************************************************/
xSecondaryToPrimaryMessageBuffer = xMessageBufferCreateStatic(APP_MESSAGE_BUFFER_SIZE,&ucSecondaryToPrimaryBufferStorage,&xSecondaryToPrimaryMessageBufferStruct);
3.内存池的读写(多核通信实现)
/****************************************************m7*****************************************************/
void xTASK_ReceiveMsg(void* pvParameters)
{
size_t xReceivedBytes;
for(;;)
{
//查询m4内存池参数
xReceivedBytes = xMessageBufferReceive(xSecondaryToPrimaryMessageBuffer, (void *)&GlobData, sizeof(GlobDataTypedef), portMAX_DELAY);
vTaskDelay(10);
}
}
/****************************************************m4*****************************************************/
void xTASK_ReceiveMsg(void *pvParameters)
{
size_t xReceivedBytes;
while(1)
{
//查询m7内存池参数
xReceivedBytes = xMessageBufferReceive(xPrimaryToSecondaryMessageBuffer, (void *)&GlobDataDefault, sizeof(GlobDataTypedef), portMAX_DELAY);
//msg.cmd += 0x10;
GlobDataDefault.presetNow++;
//用于测试,将从m7内核拿到的数据,m4再发给m7
(void)xMessageBufferSend(xSecondaryToPrimaryMessageBuffer, (void *)&GlobDataDefault, sizeof(GlobDataTypedef), 0);
vTaskDelay(10);
}
}
4.实现流程框图