雙系統(tǒng)學(xué)習(xí):雙系統(tǒng)通信

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---------------

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市谢谦,隨后出現(xiàn)的幾起案子释牺,更是在濱河造成了極大的恐慌萝衩,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,591評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件没咙,死亡現(xiàn)場(chǎng)離奇詭異猩谊,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)祭刚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門牌捷,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人涡驮,你說我怎么就攤上這事暗甥。” “怎么了捉捅?”我有些...
    開封第一講書人閱讀 162,823評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵撤防,是天一觀的道長。 經(jīng)常有香客問我棒口,道長寄月,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,204評(píng)論 1 292
  • 正文 為了忘掉前任陌凳,我火速辦了婚禮剥懒,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘合敦。我一直安慰自己初橘,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,228評(píng)論 6 388
  • 文/花漫 我一把揭開白布充岛。 她就那樣靜靜地躺著保檐,像睡著了一般。 火紅的嫁衣襯著肌膚如雪崔梗。 梳的紋絲不亂的頭發(fā)上夜只,一...
    開封第一講書人閱讀 51,190評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音蒜魄,去河邊找鬼扔亥。 笑死,一個(gè)胖子當(dāng)著我的面吹牛谈为,可吹牛的內(nèi)容都是我干的旅挤。 我是一名探鬼主播,決...
    沈念sama閱讀 40,078評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼伞鲫,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼粘茄!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,923評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤柒瓣,失蹤者是張志新(化名)和其女友劉穎儒搭,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體芙贫,經(jīng)...
    沈念sama閱讀 45,334評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡搂鲫,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,550評(píng)論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了屹培。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片默穴。...
    茶點(diǎn)故事閱讀 39,727評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡怔檩,死狀恐怖褪秀,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情薛训,我是刑警寧澤媒吗,帶...
    沈念sama閱讀 35,428評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站乙埃,受9級(jí)特大地震影響闸英,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜介袜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,022評(píng)論 3 326
  • 文/蒙蒙 一甫何、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧遇伞,春花似錦辙喂、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至渐排,卻和暖如春炬太,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背驯耻。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評(píng)論 1 269
  • 我被黑心中介騙來泰國打工亲族, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人可缚。 一個(gè)月前我還...
    沈念sama閱讀 47,734評(píng)論 2 368
  • 正文 我出身青樓霎迫,卻偏偏與公主長得像,于是被迫代替她去往敵國和親城看。 傳聞我的和親對(duì)象是個(gè)殘疾皇子女气,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,619評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容