Tda4 IPC

rtos侧

RPMessageParams_init(&params);
params.requestedEndpt = ENDPOINT;
params.buf = buf;
params.bufSize = bufSize;

handle = RPMessage_create(&params, &myEndPt);
RPMessage_announce(RPMESSAGE_ALL, myEndPt, "rpmsg_chrdev");  //向所有处理器或仅向一个处理器宣布端点的可用性

while(TRUE)
{
    RPMessage_recv(handle, (Ptr)msg, &msg_len, &remoteEndPt, &remoteProcId,
                IPC_RPMESSAGE_TIMEOUT_FOREVER);

    ...
    /* do something with message */

    service_func(msg, msg_len, remoteEndPt, remoteProcId, resp, &resp_len);

    ...

    RPMessage_send(handle, remoteProcId, remoteEndPt, myEndPt, resp, resp_len);
}

参考下面code

//linux侧

系统默认初始化代码在rtos-sdk/vision_apps/utils/ipc/src/app_ipc_linux_rpmsg_char.c这里

使用方法见rtos-sdk/vision_apps/utils/ipc/src/app_ipc_linux_rpmsg_char.c

#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/eventfd.h>
#include <ti_rpmsg_char.h>
#include <utils/ipc/src/app_ipc_linux_priv.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

static uint32_t map_vision_apps_cpu_id_to_rpmsg_char_cpu_id(uint32_t cpu_id)
{
    uint32_t rpmsg_char_id = RPROC_ID_MAX;

    if (APP_IPC_CPU_MCU1_0 == cpu_id)
    {
        rpmsg_char_id = R5F_MCU0_0;
    }
    else if (APP_IPC_CPU_MCU1_1 == cpu_id)
    {
        rpmsg_char_id = R5F_MCU0_1;
    }
    else if (APP_IPC_CPU_MCU2_0 == cpu_id)
    {
        rpmsg_char_id = R5F_MAIN0_0;
    }
    else if (APP_IPC_CPU_MCU2_1 == cpu_id)
    {
        rpmsg_char_id = R5F_MAIN0_1;
    }
    else if (APP_IPC_CPU_MCU3_0 == cpu_id)
    {
        rpmsg_char_id = R5F_MAIN1_0;
    }
    else if (APP_IPC_CPU_MCU3_1 == cpu_id)
    {
        rpmsg_char_id = R5F_MAIN1_1;
    }
    #if defined (SOC_J721E)
    else if (APP_IPC_CPU_C6x_1 == cpu_id)
    {
        rpmsg_char_id = DSP_C66_0;
    }
    else if (APP_IPC_CPU_C6x_2 == cpu_id)
    {
        rpmsg_char_id = DSP_C66_1;
    }
    #endif
    else if (APP_IPC_CPU_C7x_1 == cpu_id)
    {
        rpmsg_char_id = DSP_C71_0;
    }
    #if 0 // TODO: Enable this once we have a Linux FS
    #if defined (SOC_J721S2)
    else if (APP_IPC_CPU_C7x_2 == cpu_id)
    {
        rpmsg_char_id = DSP_C71_1;
    }
    #endif
    #endif

    return rpmsg_char_id;
}

static void appIpcRpmsgRxHandler(uint32_t app_cpu_id, uint32_t payload)
{
    app_ipc_obj_t *obj = &g_app_ipc_obj;

    if(app_cpu_id<APP_IPC_CPU_MAX)
    {
        #ifdef APP_IPC_DEBUG
        appLogPrintf("IPC: RX: %s -> %s (port %d) msg = 0x%08x\n",
            appIpcGetCpuName(app_cpu_id),
            appIpcGetCpuName(appIpcGetSelfCpuId()),
            (uint32_t)obj->local_endpt[app_cpu_id],
            payload);
        #endif

        if((payload & 0xFFFF0000) == 0xDEAD0000)
        {
            /* echo message dont send to handler */
            printf("IPC: RX: %s -> %s (port %d) msg = 0x%08x\n",
                appIpcGetCpuName(app_cpu_id),
                appIpcGetCpuName(appIpcGetSelfCpuId()),
                (uint32_t)obj->prm.tiovx_rpmsg_port_id,
                payload);
        }
        else
        {
            if(obj->ipc_notify_handler)
            {
                obj->ipc_notify_handler(app_cpu_id, payload);
            }
        }
    }
}

void *appIpcRpmsgRxTaskMain(void *arg)
{
    app_ipc_obj_t *obj = &g_app_ipc_obj;
    uint32_t payload;
    uint32_t maxfd;
    uint32_t nfds;
    int32_t status;
    fd_set rfds;
    uint32_t i;
    uint32_t done;

    done = 0;
    while(!done)
    {
        maxfd  = 0;
        status = 0;

        FD_ZERO(&rfds);

        /* Initialize rx fds to wait on messages  */
        for(i = 0; i< APP_IPC_CPU_MAX; i++)
        {
            if(appIpcIsCpuEnabled(i) && i != appIpcGetSelfCpuId())
            {
                /* same file handle used for RX and TX */
                maxfd = MAX(maxfd, obj->tx_fds[i]);
                FD_SET(obj->tx_fds[i], &rfds);
            }
        }

        /* add fd to unblock from select and break from loop on exit */
        FD_SET(obj->unblockfd, &rfds);

        /* Add one to last fd created, this is mandated by select() */
        nfds = MAX(maxfd, obj->unblockfd) + 1;

        status = select(nfds, &rfds, NULL, NULL, NULL);

        if (status)
        {
            if (FD_ISSET(obj->unblockfd, &rfds))
            {
                /*
                 * Event was signalled to break the loop
                 *
                 * This is typically done during a shutdown sequence, where
                 * the intention of the client would be to ignore (i.e. not fetch)
                 * any pending messages in the transport's queue.
                 * Thus, we shall not check for nor return any messages.
                 */
                done = 1;
            }
            else
            {

                /* Process all messages received on different Rx sockets */
                for(i = 0; i< APP_IPC_CPU_MAX; i++)
                {
                    if(     appIpcIsCpuEnabled(i)
                        &&  i != appIpcGetSelfCpuId()
                        &&  FD_ISSET(obj->tx_fds[i], &rfds)
                        )
                    {
                        /* same file handle used for RX and TX */
                        status = read(
                                    obj->tx_fds[i],
                                    &payload, sizeof(uint32_t));
                        if(status > 0)
                        {
                            appIpcRpmsgRxHandler(
                                        i,
                                        payload);
                        }
                    }
                }
            }
        }
    }   /* while(! done) */
    return NULL;
}

int32_t appIpcSendNotifyPort(uint32_t dest_cpu_id, uint32_t payload, uint32_t port_id)
{
    int32_t status = -1;
    app_ipc_obj_t *obj = &g_app_ipc_obj;

    /* NOTE: port_id is unsed in this function */

    if( (dest_cpu_id<APP_IPC_CPU_MAX) && (obj->tx_fds[dest_cpu_id] > 0))
    {
        #ifdef APP_IPC_DEBUG
        appLogPrintf("IPC: TX: %s -> %s (port %d) msg = 0x%08x\n",
            appIpcGetCpuName(appIpcGetSelfCpuId()),
            appIpcGetCpuName(dest_cpu_id),
            (uint32_t)port_id,
            payload);
        #endif

        status = write(obj->tx_fds[dest_cpu_id], &payload, sizeof(payload));
        if(status < 0 || status != sizeof(payload))
        {
            appLogPrintf("IPC: TX: FAILED: %s -> %s (port %d) msg = 0x%08x\n",
                appIpcGetCpuName(appIpcGetSelfCpuId()),
                appIpcGetCpuName(dest_cpu_id),
                (uint32_t)port_id,
                payload);
        }
        else
        {
            status = 0;
        }
    }

    return status;
}

int32_t appIpcSendNotify(uint32_t dest_cpu_id, uint32_t payload)
{
    int32_t status = -1;
    app_ipc_obj_t *obj = &g_app_ipc_obj;

    if( (dest_cpu_id<APP_IPC_CPU_MAX) && (obj->tx_fds[dest_cpu_id] > 0))
    {
        status = appIpcSendNotifyPort(dest_cpu_id, payload,
            (uint32_t)obj->prm.tiovx_rpmsg_port_id);
    }

    return status;
}

int32_t appIpcCreateTxCh(uint32_t remote_app_cpu_id, uint32_t remote_endpt, uint32_t *local_endpt, rpmsg_char_dev_t **rcdev)
{
    int fd = -1;
    rpmsg_char_dev_t rcdev_local;
    char eptdev_name[32] = { 0 };
    uint32_t rproc_id;

    rproc_id = map_vision_apps_cpu_id_to_rpmsg_char_cpu_id(remote_app_cpu_id);

    sprintf(eptdev_name, "rpmsg-char-%d-%d", rproc_id, getpid());

    *rcdev = rpmsg_char_open(rproc_id,
                NULL,
                remote_endpt,
                eptdev_name,
                0
    );

    if (NULL != *rcdev)
    {
        rcdev_local = **rcdev;
        *local_endpt = rcdev_local.endpt;

        fd = rcdev_local.fd;
    }

    return fd;
}

int32_t appIpcDeleteCh(rpmsg_char_dev_t *rcdev)
{
    rpmsg_char_close(rcdev);

    return 0;
}

static void appIpcUnblockRpmsgTask(app_ipc_obj_t *obj)
{
    uint64_t     buf = 1;

    /* Write 8 bytes to shutdown */
    write(obj->unblockfd, &buf, sizeof(buf));
}

int32_t appIpcCreateRpmsgRxTask(app_ipc_obj_t *obj)
{
    pthread_attr_t thread_attr;
    int32_t status = 0;

    obj->unblockfd = eventfd(0, 0);
    if(obj->unblockfd < 0)
    {
        status = -1;
        printf("IPC: ERROR: Unable to create unblock event !!!\n");
    }
    if(status==0)
    {
        status |= pthread_attr_init(&thread_attr);
        if(status!=0)
        {
            printf("IPC: ERROR: Unable to set thread attr !!!\n");
        }
        if(status==0)
        {
            status |= pthread_create(&obj->task, &thread_attr, (void*)appIpcRpmsgRxTaskMain, obj);
        }
        pthread_attr_destroy(&thread_attr);
    }
    if(status!=0)
    {
        printf("IPC: ERROR: Unable to create RX thread !!!\n");
    }
    return status;
}

int32_t appIpcDeleteRpmsgRxTask(app_ipc_obj_t *obj)
{
    void *task_status;

    appIpcUnblockRpmsgTask(obj);
    pthread_join(obj->task, &task_status);
    close(obj->unblockfd);

    return 0;
}

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值