HI3556V200 Linux+Liteos雙系統(tǒng)學(xué)習(xí)(4)----雙系統(tǒng)通信 IPCM/virt_tty/sharefs
雙系統(tǒng)之間進(jìn)行交互主要有以下三種方式:
ipcm:用于雙系統(tǒng)之間數(shù)據(jù)傳輸汁汗、信令交互;
virt_tty:虛擬終端功能低缩,用于在Linux端調(diào)試Liteos;
sharefs:共享文件系統(tǒng)。
1 IPCM
HiSysLink 包含兩個(gè)模塊:IPCMSG 和 DATAFIFO啡省。一個(gè)用于小量數(shù)據(jù)間通信的圆,一個(gè)用于大量數(shù)據(jù)間傳輸贮配。
1.1 IPCMSG
IPCMSG適應(yīng)于小數(shù)據(jù)力九,數(shù)據(jù)一次性傳輸不大于1024個(gè)字節(jié)耍铜,例如信令交互,音頻數(shù)據(jù)傳輸跌前。延時(shí)比較低棕兼,毫秒甚至微秒級(jí)延時(shí),另外抵乓,IPCMSG是雙向通信的伴挚。
1.1.1 Linux 端示例代碼
示例代碼如下,通過IPCMSG_CLIENT_SendMsg函數(shù)將數(shù)據(jù)發(fā)送給【Liteos端】灾炭,通過CLIENT_HandleRecvMsg函數(shù)接收【Liteos端】發(fā)送過來的數(shù)據(jù)茎芋。
#include <stdio.h>
#include <sys/types.h>
#include <strings.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/mman.h>
static HI_S32 s_s32CommonIPCMsgID = 0; //消息ID
static pthread_t s_CommonRecvThrdId = 0;
#ifdef __cplusplus
#if __cplusplus
extern "C"{
#endif
#endif /* End of #ifdef __cplusplus */
//回復(fù)消息給liteos
int MSG_USER_LinuxResponse(HI_S32 s32MsgId, HI_IPCMSG_MESSAGE_S * pstMsg, int ret)
{
HI_IPCMSG_MESSAGE_S *respMsg;
//創(chuàng)建回復(fù)消息
respMsg = HI_IPCMSG_CreateRespMessage(pstMsg, ret, NULL, 0);
//發(fā)送異步消息 不需要等待liteos響應(yīng)
HI_IPCMSG_SendAsync(s32MsgId, respMsg, NULL);
//銷毀消息 釋放指針
HI_IPCMSG_DestroyMessage(respMsg);
return 0;
}
//發(fā)送指令給liteos端
//userCmd 自定義的指令
//pBody 數(shù)據(jù)指針
//u32BodyLen 數(shù)據(jù)長度
HI_S32 IPCMSG_CLIENT_SendMsg(COMM_USER_CMD_E userCmd, void* pBody, HI_S32 u32BodyLen)
{
HI_S32 s32Ret = HI_SUCCESS;
HI_IPCMSG_MESSAGE_S *pReq = NULL;
HI_IPCMSG_MESSAGE_S *pResp = NULL;
//創(chuàng)建消息
pReq = HI_IPCMSG_CreateMessage(IPCMSG_COMMON_MODID, userCmd, pBody, u32BodyLen);
if(NULL == pReq)
{
printf("HI_IPCMSG_CreateMessage failed!\n");
return HI_FAILURE;
}
//發(fā)送消息 阻塞等待回應(yīng)
//s_s32CommonIPCMsgID 消息ID
//AVPLAY_MSG_LONG_TIMEOUT timeout時(shí)間
s32Ret = HI_IPCMSG_SendSync(s_s32CommonIPCMsgID, pReq, &pResp, AVPLAY_MSG_LONG_TIMEOUT);
if (HI_SUCCESS != s32Ret)
{
printf("HI_IPCMSG_SendSync failed!\n");
HI_IPCMSG_DestroyMessage(pReq);
HI_IPCMSG_DestroyMessage(pResp);
return s32Ret;
}
s32Ret = pResp->s32RetVal;
//銷毀消息
HI_IPCMSG_DestroyMessage(pReq);
HI_IPCMSG_DestroyMessage(pResp);
return s32Ret;
}
//接收Liteos端的信息,并進(jìn)行處理
//s32MsgId 消息ID
//pstMsg 消息體
HI_S32 CLIENT_HandleRecvMsg(HI_S32 s32MsgId, HI_IPCMSG_MESSAGE_S *pstMsg)
{
HI_S32 s32Ret = HI_SUCCESS;
if (s32MsgId != s_s32CommonIPCMsgID)
{
printf( "ipcmsg receive msg from error id: %d\n", s32MsgId);
return s32Ret;
}
//IPCMSG_COMMON_MODID 自定義 用于簡單校驗(yàn)指令
if (pstMsg->u32Module != IPCMSG_COMMON_MODID)
{
printf( "ipcmsg receive msg from error module id: %d\n", pstMsg->u32Module);
return s32Ret;
}
//根據(jù)消息類型處理消息
switch(pstMsg->u32CMD)
{
case 1:
break;
default:
printf("linux error cmd %#x\n", pstMsg->u32CMD);
break;
}
MSG_USER_LinuxResponse(s32MsgId, pstMsg, s32Ret);
return s32Ret;
}
static HI_VOID* IPCMSG_CLIENT_RecvThread(void* arg)
{
prctl(15, "common_ipcmsg_cli_rcvThread", 0, 0, 0);
HI_S32* s32Id = (HI_S32*)arg;
LOGD_print("common receive from %d\n", *s32Id);
HI_IPCMSG_Run(*s32Id);
return NULL;
}
HI_S32 IPCMSG_CLIENT_Init()
{
HI_S32 s32Ret = HI_SUCCESS;
HI_IPCMSG_CONNECT_S stIpcMsgConnect;
stIpcMsgConnect.u32RemoteId = 1; //1:連接Liteos的CPU
stIpcMsgConnect.u32Port = IPMSG_COMMON_PORT; //IPMSG_COMMON_PORT:端口號(hào) 自定義
stIpcMsgConnect.u32Priority = 0; //0:普通優(yōu)先級(jí)
//添加服務(wù) IPCMSG_COMMON:服務(wù)名稱指針 自定義
if (HI_IPCMSG_AddService(IPCMSG_COMMON,&stIpcMsgConnect) != HI_SUCCESS)
{
printf("HI_IPCMSG_AddService IPCMSG_COMMON fail\n");
return HI_FAILURE;
}
//阻塞方式建立連接
//s_s32CommonIPCMsgID 消息ID
//IPCMSG_COMMON 服務(wù)名稱指針
//CLIENT_HandleRecvMsg 消息處理函數(shù)
if (HI_SUCCESS != HI_IPCMSG_Connect(&s_s32CommonIPCMsgID, IPCMSG_COMMON, (HI_IPCMSG_HANDLE_FN_PTR)CLIENT_HandleRecvMsg))
{
printf("HI_IPCMSG_Connect IPCMSG_COMMON fail\n");
HI_IPCMSG_DelService(IPCMSG_COMMON);
return HI_FAILURE;
}
//創(chuàng)建消息處理函數(shù)
s32Ret = pthread_create(&s_CommonRecvThrdId, NULL, IPCMSG_CLIENT_RecvThread, &s_s32CommonIPCMsgID);
if(s32Ret != HI_SUCCESS)
{
s_s32CommonIPCMsgID = 0;
HI_IPCMSG_Disconnect(s_s32CommonIPCMsgID);
HI_IPCMSG_DelService(IPCMSG_COMMON);
return HI_FAILURE;
}
return HI_SUCCESS;
}
int main()
{
HI_S32 s32Ret = HI_SUCCESS;
s32Ret = IPCMSG_CLIENT_Init();
if (s32Ret != 0)
{
printf("Media_Msg_Init Error!\n");
return s32Ret;
}
while(1)
sleep(10);
return s32Ret;
}
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* End of #ifdef __cplusplus */
1.1.2 Liteos端示例代碼
示例代碼如下蜈出,通過IPCMSG_SVR_SendMsg函數(shù)將數(shù)據(jù)發(fā)送給【Linux端】田弥,通過IPCMSG_SVR_HandleRecvMsg函數(shù)接收【Linux端】發(fā)送過來的數(shù)據(jù)
//雙系統(tǒng)通信模塊
#include <sys/prctl.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <stdio.h>
static pthread_t s_CommonRecvThrdId = 0;
static HI_S32 s32CommonSvrIPCMsgID = 0;
static HI_BOOL bCommonSvrInited = HI_FALSE;
#define COMMON_IPCMSG_THREAD_PRIORITY (7)
#define COMMON_IPCMSG_THREAD_STACKSIZE (0x10000)
#ifdef __cplusplus
#if __cplusplus
extern "C"{
#endif
#endif /* End of #ifdef __cplusplus */
//回復(fù)消息給linux
int MSG_USER_Response(HI_S32 s32MsgId, HI_IPCMSG_MESSAGE_S * pstMsg, HI_S32 ret)
{
HI_IPCMSG_MESSAGE_S *respMsg;
//創(chuàng)建回復(fù)消息
respMsg = HI_IPCMSG_CreateRespMessage(pstMsg, ret, NULL, 0);
//發(fā)送異步消息 不需要等待linux響應(yīng)
HI_IPCMSG_SendAsync(s32MsgId, respMsg, NULL);
//銷毀消息 釋放指針
HI_IPCMSG_DestroyMessage(respMsg);
return 0;
}
//發(fā)送指令給liunx端
//userCmd 自定義的指令
//pBody 數(shù)據(jù)指針
//u32BodyLen 數(shù)據(jù)長度
int IPCMSG_SVR_SendMsg(COMM_USER_CMD_E userCmd, void* pBody, int u32BodyLen)
{
HI_S32 s32Ret = HI_SUCCESS;
HI_IPCMSG_MESSAGE_S *pReq = NULL;
HI_IPCMSG_MESSAGE_S *pResp = NULL;
//創(chuàng)建消息
pReq = HI_IPCMSG_CreateMessage(IPCMSG_COMMON_MODID, userCmd, pBody, u32BodyLen);
if(NULL == pReq)
{
printf("HI_IPCMSG_CreateMessage failed!\n");
return HI_FAILURE;
}
//發(fā)送消息 阻塞等待回應(yīng)
//s_s32CommonIPCMsgID 消息ID
//AVPLAY_MSG_LONG_TIMEOUT timeout時(shí)間
s32Ret = HI_IPCMSG_SendSync(s32CommonSvrIPCMsgID, pReq, &pResp, AVPLAY_MSG_LONG_TIMEOUT);
if (HI_SUCCESS != s32Ret)
{
printf("HI_IPCMSG_SendSync failed!\n");
HI_IPCMSG_DestroyMessage(pReq);
HI_IPCMSG_DestroyMessage(pResp);
return s32Ret;
}
s32Ret = pResp->s32RetVal;
//銷毀消息
HI_IPCMSG_DestroyMessage(pReq);
HI_IPCMSG_DestroyMessage(pResp);
return s32Ret;
}
//接收Liteos端的信息,并進(jìn)行處理
//s32MsgId 消息ID
//pstMsg 消息體
static void IPCMSG_SVR_HandleRecvMsg(HI_S32 s32Id, HI_IPCMSG_MESSAGE_S* pMsg)
{
HI_S32 s32Ret = HI_FAILURE;
printf("common ipcmsg, receive msg id:%d, msg cmd %d \n", s32CommonSvrIPCMsgID, pMsg->u32CMD );
if(s32Id != s32CommonSvrIPCMsgID)
{
printf ("ipcmsg receive msg from error id: %d\n", s32Id);
return;
}
//IPCMSG_COMMON_MODID 自定義 用于簡單校驗(yàn)指令 和linux端保持一致
if(pMsg->u32Module != IPCMSG_COMMON_MODID)
{
printf ("ipcmsg receive msg from error module id: %d\n", pMsg->u32Module);
return;
}
//根據(jù)消息類型處理消息
switch(pMsg->u32CMD)
{
case 1:
break;
default:
printf ("unsupported cmd request from client\n");
break;
}
//回復(fù)消息給linux端
MSG_USER_Response(s32Id, pMsg, s32Ret);
}
//創(chuàng)建消息處理函數(shù)
static void* IPCMSG_SVR_RecvThread(void *arg)
{
prctl(PR_SET_NAME, "Hi_pTCommonMsg", 0, 0, 0);
HI_S32 s32Ret = HI_SUCCESS;
do
{
if(HI_TRUE == HI_IPCMSG_IsConnected(s32CommonSvrIPCMsgID))
{
HI_IPCMSG_Run(s32CommonSvrIPCMsgID);
}
else
{
s32Ret = HI_IPCMSG_Disconnect(s32CommonSvrIPCMsgID);
if(s32Ret != HI_SUCCESS)
{
printf ("SVR RecvThread HI_IPCMSG_Disconnect fail\n");
}
s32Ret = HI_IPCMSG_Connect(&s32CommonSvrIPCMsgID, IPCMSG_COMMON, IPCMSG_SVR_HandleRecvMsg);
if(s32Ret != HI_SUCCESS)
{
printf ("RecvThread HI_IPCMSG_Connect fail\n");
}
}
} while(1);
return NULL;
}
static void* IPCMSG_SVR_WaitClientConnect(void *arg)
{
pthread_attr_t attr;
prctl(PR_SET_NAME, "Hi_pCommonMsgwait", 0, 0, 0);
HI_IPCMSG_CONNECT_S stIpcMsgConnect;
stIpcMsgConnect.u32RemoteId = 0; //連接Linux的CPU
stIpcMsgConnect.u32Port = IPMSG_COMMON_PORT; //IPMSG_COMMON_PORT:端口號(hào) 自定義 和linux端一致
stIpcMsgConnect.u32Priority = 0; //0:普通優(yōu)先級(jí) 和linux端一致
//添加服務(wù) IPCMSG_COMMON:服務(wù)名稱指針 自定義 和linux端一致
if(HI_IPCMSG_AddService(IPCMSG_COMMON, &stIpcMsgConnect) != HI_SUCCESS)
{
printf ("HI_IPCMSG_AddService fail\n");
return NULL;
}
printf("thread wait for player client connect.......\n");
//阻塞方式建立連接
//s_s32CommonIPCMsgID 消息ID
//IPCMSG_COMMON 服務(wù)名稱指針 和linux端保持一致
//IPCMSG_SVR_HandleRecvMsg 消息處理函數(shù)
if (HI_SUCCESS != HI_IPCMSG_Connect(&s32CommonSvrIPCMsgID,IPCMSG_COMMON, IPCMSG_SVR_HandleRecvMsg))
{
printf ("HI_IPCMSG_Connect fail\n");
HI_IPCMSG_DelService(IPCMSG_COMMON);
return NULL;
}
printf("player ipc msg client&server connected id: %d\n", s32CommonSvrIPCMsgID);
if(0 != pthread_attr_init(&attr))
{
printf ("Error pthread_attr_init()!");
pthread_attr_destroy(&attr);
return NULL; //Thread attribute initialise error, then exit
}
if(0 != pthread_attr_setstacksize(&attr, COMMON_IPCMSG_THREAD_STACKSIZE))
{
printf ("Error pthread_attr_setstacksize()!");
pthread_attr_destroy(&attr);
return NULL; //Thread attribute initialise error, then exit
}
attr.inheritsched = PTHREAD_EXPLICIT_SCHED;
attr.schedparam.sched_priority = COMMON_IPCMSG_THREAD_PRIORITY;
//創(chuàng)建消息處理函數(shù)
if (0 != pthread_create(&s_CommonRecvThrdId, &attr, IPCMSG_SVR_RecvThread, &s32CommonSvrIPCMsgID))
{
pthread_attr_destroy(&attr);
printf ("pthread_create HI_AVPLAY_IPCMSG_SVR_RecvThread failed\n");
return NULL;
}
pthread_attr_destroy(&attr); //Destroying threads attribute structure,
// cannot be used again before restarting the initialization
return NULL;
}
int IPCMSG_SVR_Init()
{
int ret = 0;
extern int _ipcm_vdd_init(void);
printf("ipcm init ...\n");
_ipcm_vdd_init();
pthread_t waitConThrd;
if (0 != pthread_create(&waitConThrd, NULL, IPCMSG_SVR_WaitClientConnect, NULL))
{
printf( "pthread_create HI_AVPLAY_IPCMSG_SVR_WaitClientConnect failed\n");
return HI_FAILURE;
}
return ret;
}
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* End of #ifdef __cplusplus */
1.2 DATAFIFO
datafifo用于頻繁傳輸大量數(shù)據(jù)掏缎。datafifo只能單向傳輸皱蹦,寫端只能作為寫端煤杀,讀端只能作為讀端眷蜈。
示例代碼如下沪哺,在下面代碼中,Linux端作為寫端酌儒,將數(shù)據(jù)寫入datafifo辜妓。liteos作為讀端,從datafifo中讀取數(shù)據(jù)進(jìn)行處理忌怎。
1.2.1 Linux端示例代碼
Linux端調(diào)用 IPCDATAFIFO_WRITE_Data函數(shù)寫入數(shù)據(jù)籍滴。
#include <stdio.h>
#include <sys/types.h>
#include <strings.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/mman.h>
HI_U64 gDataFifoPhyAddr; //數(shù)據(jù)通路在Linux端的物理地址
HI_DATAFIFO_HANDLE gDataFifoHandle = HI_DATAFIFO_INVALID_HANDLE; //數(shù)據(jù)通路句柄
HI_U32 gDataFifoSize = DATAFIFO_NUM*DATAFIFO_NUM_SIZE;
#ifdef __cplusplus
#if __cplusplus
extern "C"{
#endif
#endif /* End of #ifdef __cplusplus */
//判斷datafifo是否為空
static HI_BOOL Is_DatafifoFull()
{
HI_S32 s32Ret;
HI_U32 u32AvailWriteLen = 0;
//NULL 觸發(fā)寫端的數(shù)據(jù)釋放回調(diào)函數(shù),同時(shí)更新寫端的讀尾指針
s32Ret = HI_DATAFIFO_Write(gDataFifoHandle, NULL);
if (HI_SUCCESS != s32Ret)
{
printf("write error:%x\n", s32Ret);
return HI_TRUE;
}
//獲取可以寫入的數(shù)據(jù)長度
s32Ret = HI_DATAFIFO_CMD(gDataFifoHandle, DATAFIFO_CMD_GET_AVAIL_WRITE_LEN, &u32AvailWriteLen);
if (HI_SUCCESS != s32Ret)
{
printf("get available write len error:%x\n", s32Ret);
return HI_TRUE;
}
printf("write len is %d\n", u32AvailWriteLen);
if (u32AvailWriteLen >= gDataFifoSize)
{
return HI_FALSE;
}
else
{
return HI_TRUE;
}
}
//數(shù)據(jù)釋放回調(diào)
void IPCDATAFIFO_WRITE_DataRelease(char* pDataBuf)
{
if (NULL == pDataBuf)
return;
//memset(pDataBuf, 0, gDataFifoSize);
}
//將數(shù)據(jù)傳輸給liteos端
//pDataBuf 數(shù)據(jù)指針
HI_S32 IPCDATAFIFO_WRITE_Data(char* pDataBuf)
{
HI_S32 s32Ret = HI_SUCCESS;
if (NULL == pDataBuf)
return HI_FAILURE;
//等待datafifo為空
while (Is_DatafifoFull())
{
usleep(10000); //10ms
//continue;
}
//寫數(shù)據(jù)
s32Ret = HI_DATAFIFO_Write(gDataFifoHandle, pDataBuf);
if (HI_SUCCESS != s32Ret)
{
printf("write error:%x\n", s32Ret);
return HI_FAILURE;
}
//通知寫入完成
s32Ret = HI_DATAFIFO_CMD(gDataFifoHandle, DATAFIFO_CMD_WRITE_DONE, NULL);
if (HI_SUCCESS != s32Ret)
{
printf("write done error:%x\n", s32Ret);
return HI_FAILURE;
}
return s32Ret;
}
//linux端 寫入者 初始化
HI_S32 IPCDATAFIFO_WRITE_Init()
{
HI_S32 s32Ret = HI_SUCCESS;
HI_DATAFIFO_PARAMS_S stDatafifo;
stDatafifo.u32EntriesNum = DATAFIFO_NUM+1; //循環(huán)buf數(shù)據(jù)個(gè)數(shù) 自定義
stDatafifo.u32CacheLineSize = DATAFIFO_NUM_SIZE; //每個(gè)數(shù)據(jù)的大小 自定義
stDatafifo.bDataReleaseByWriter = HI_TRUE;
stDatafifo.enOpenMode = DATAFIFO_WRITER; //角色寫入者
//打開數(shù)據(jù)通路
s32Ret = HI_DATAFIFO_Open(&gDataFifoHandle, &stDatafifo);
if (HI_SUCCESS != s32Ret)
{
printf("open datafifo error:%x\n", s32Ret);
return s32Ret;
}
//獲取數(shù)據(jù)通路在Linux端的物理地址
s32Ret = HI_DATAFIFO_CMD(gDataFifoHandle, DATAFIFO_CMD_GET_PHY_ADDR, &gDataFifoPhyAddr);
if (HI_SUCCESS != s32Ret)
{
printf("get datafifo phy addr error:%x\n", s32Ret);
return s32Ret;
}
//設(shè)置數(shù)據(jù)釋放回調(diào)函數(shù)
s32Ret = HI_DATAFIFO_CMD(gDataFifoHandle, DATAFIFO_CMD_SET_DATA_RELEASE_CALLBACK, IPCDATAFIFO_WRITE_DataRelease);
if (HI_SUCCESS != s32Ret)
{
printf("register callback funtion fail! s32Ret: 0x%x\n", s32Ret);
return s32Ret;
}
return s32Ret;
}
//liteos端 讀出者 初始化
//即將linux端寫入者創(chuàng)建的datafifo的物理地址通過IPCMSG告訴liteos端
HI_S32 IPCDATAFIFO_READ_Init()
{
HI_S32 s32Ret = HI_SUCCESS;
printf("IPCDATAFIFO_READ_Init phy addr is %llu!\n", gDataFifoPhyAddr);
//COMM_USER_CMD_DATA_FIFO_INIT 自定義的指令
s32Ret = IPCMSG_CLIENT_SendMsg(COMM_USER_CMD_DATA_FIFO_INIT, (void *)&gDataFifoPhyAddr, sizeof(HI_U64));
if (s32Ret != HI_SUCCESS)
{
printf("IPCDATAFIFO_READ_Init Error!\n");
}
return s32Ret;
}
int main()
{
HI_S32 s32Ret = HI_SUCCESS;
printf(" init\n");
s32Ret = IPCDATAFIFO_WRITE_Init();
if (s32Ret != 0)
{
printf("IPCDATAFIFO_WRITE_Init Error!\n");
return s32Ret;
}
s32Ret = IPCDATAFIFO_READ_Init();
if (s32Ret != 0)
{
printf("IPCDATAFIFO_WRITE_Init Error!\n");
return s32Ret;
}
return s32Ret;
}
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* End of #ifdef __cplusplus */
1.2.2 Liteos端示例代碼
Liteos端在IPCDATAFIFO_READ_Read函數(shù)中讀取數(shù)據(jù)榴啸。
#include <sys/prctl.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <stdio.h>
HI_U64 gDataPhyAddr; //寫入端創(chuàng)建的datafifo的物理地址
HI_DATAFIFO_HANDLE gDataHandle = HI_DATAFIFO_INVALID_HANDLE;
HI_U32 gDataSize = 400*1024;
#ifdef __cplusplus
#if __cplusplus
extern "C"{
#endif
#endif /* End of #ifdef __cplusplus */
static void* IPCDATAFIFO_READ_Read(void *arg)
{
HI_S32 s32Ret;
HI_U32 readLen;
HI_DATAFIFO_PARAMS_S stDatafifo;
char* recvData = NULL;
stDatafifo.u32EntriesNum = DATAFIFO_NUM+1; //循環(huán)buf數(shù)據(jù)個(gè)數(shù) 自定義 和Linux端保持一致
stDatafifo.u32CacheLineSize = DATAFIFO_NUM_SIZE;//每個(gè)數(shù)據(jù)的大小 自定義 和Linux端保持一致
stDatafifo.bDataReleaseByWriter = HI_TRUE;
stDatafifo.enOpenMode = DATAFIFO_READER; //角色 讀者
//通過物理地址打開
s32Ret = HI_DATAFIFO_OpenByAddr(&gDataHandle, &stDatafifo, gDataPhyAddr);
if (HI_SUCCESS != s32Ret)
{
printf("open datafifo error:%x\n", s32Ret);
//return HI_FAILURE;
}
printf("IPCDATAFIFO_READ_Read\n");
while(1)
{
readLen = 0;
s32Ret = HI_DATAFIFO_CMD(gDataHandle, DATAFIFO_CMD_GET_AVAIL_READ_LEN, &readLen);
if (HI_SUCCESS != s32Ret)
{
printf("get available read len error:%x\n", s32Ret);
//break;
}
if (readLen > 0)
{
s32Ret = HI_DATAFIFO_Read(gDataHandle, (HI_VOID **)&recvData);
if (HI_SUCCESS != s32Ret)
{
printf("read error:%x\n", s32Ret);
//break;
}
//數(shù)據(jù)處理
//todo...
s32Ret = HI_DATAFIFO_CMD(gDataHandle, DATAFIFO_CMD_READ_DONE, recvData);
if (HI_SUCCESS != s32Ret)
{
printf("break: read done error:%x\n", s32Ret);
//break;
}
}
}
return NULL;
}
//datafifo 讀端初始化
//pAddr 寫端創(chuàng)建的datafifo的物理地址
HI_S32 IPCDATAFIFO_READ_Init(HI_VOID* pAddr)
{
HI_S32 s32Ret = HI_SUCCESS;
unsigned int dataReadThrd;
gDataPhyAddr = *((HI_U64 *)pAddr);
printf("IPCDATAFIFO_READ_Init addr is %llu\n",gDataPhyAddr);
//讀線程
LOS_TASK_CREATE(dataReadThrd, "dataRead", IPCDATAFIFO_READ_Read, NULL, 0x19000, 11);
return s32Ret;
}
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* End of #ifdef __cplusplus */
1.3 驅(qū)動(dòng)安裝
在使用IPCMSG以及DATAFIFO前孽惰,需要在linux和liteos端分別調(diào)用對(duì)應(yīng)的驅(qū)動(dòng)。
在linux端需要安裝驅(qū)動(dòng)hi_ipcm.ko 鸥印,驅(qū)動(dòng)安裝成功之后勋功,會(huì)生成設(shè)備文件/dev/ipcm。
在liteos端調(diào)用_ipcm_vdd_init進(jìn)行初始化初始化库说。
2 virt_tty
由于硬件資源限制狂鞋,設(shè)備只有一個(gè)debug串口在Linux端部署,因此在代碼調(diào)試階段無法使用這個(gè)debug口查看liteos端的打印信息潜的。所以可以在Linux端使用虛擬串口功能來調(diào)試Liteos端骚揍。
在Linux端需要安裝驅(qū)動(dòng)hi_virt-tty.ko,并且在需要使用虛擬串口時(shí)候啰挪,使用指令virt-tty a7信不,然后就可以在終端上調(diào)試Liteos端的信息。
在Liteos端調(diào)用virt_tty_dev_init()進(jìn)行初始化工作亡呵。
3 sharefs
在Liteos端因?yàn)槭褂玫氖翘摂M文件系統(tǒng)抽活,所以不太方便存放一些文件,例如動(dòng)態(tài)庫之類的政己。
因此酌壕,需要啟動(dòng)共享機(jī)制,將Liteos需要的一些文件存放在Linux相應(yīng)的目錄下歇由,然后Liteos就可以訪問Linux上的目錄卵牍。
在Linux端設(shè)備執(zhí)行指令sharefs &,或者在應(yīng)用程序中使用sharefs_server_init() 函數(shù)并鏈接libsharefs 庫也可以沦泌。
在Liteos端使用sharefs_client_init函數(shù)進(jìn)行初始化即可糊昙。
-------------End---------------