API — Functions


#include <cyg/io/rpmsg.h>

struct rpmsg_device *cyg_rpmsg_open(char *devname);

int cyg_rpmsg_close(struct rpmsg_device *dev);

void cyg_rpmsg_poll(void);

typedef int (*rpmsg_ept_cb)(struct rpmsg_endpoint *ept, const void *data, int len, uint32_t src, void *priv);

typedef int (*rpmsg_ns_unbind_cb)(struct rpmsg_endpoint *ept);

int rpmsg_create_ept(struct rpmsg_endpoint *ept, struct rpmsg_device *dev, const char *name, uint32_t src, uint32_t dst, rpmsg_ept_cb cb, rpmsg_ns_unbind_cb ns_unbind_cb);

void rpmsg_destroy_ept(struct rpmsg_endpoint *ept);

unsigned int is_rpmsg_ept_ready(struct rpmsg_endpoint *ept);

int rpmsg_send(struct rpmsg_endpoint *ept, const void *data, int len);

int rpmsg_sendto(struct rpmsg_endpoint *ept, const void *data, int len, uint32_t dst);

int rpmsg_send_offchannel(struct rpmsg_endpoint *ept, uint32_t src, uint32_t dst, const void *data, int len);

int rpmsg_trysend(struct rpmsg_endpoint *ept, const void *data, int len);

int rpmsg_trysendto(struct rpmsg_endpoint *ept, const void *data, int len, uint32_t dst);

int rpmsg_trysend_offchannel(struct rpmsg_endpoint *ept, uint32_t src, uint32_t dst, const void *data, int len);

int rpmsg_send_offchannel_raw(struct rpmsg_endpoint *ept, uint32_t src, uint32_t dst, const void *data, int len, int wait);


The RPMSG API follows the standard API in most details. The main difference is that currently it is oriented towards supporting the Xvisor VMSG infrastructure, which differs from the standard in some ways. As a result the name service functionality is not supported, and there are some eCos specific extensions.

The eCos extensions provide a mechanism for managing RPMSG devices. The function cyg_rpmsg_open() looks for an RPMSG device with the given name and returns a pointer to it. The function cyg_rpmsg_close() closes a device down when it is no longer needed. The function cyg_rpmsg_poll() is used in systems where interrupts are disabled to process RPMSG transfers; where interrupts are enabled the RPMSG package calls this function internally and the application does not need to do it itself.

The remaining API functions follow the OpenAMP API with the exception of the name server functionality.

The function rpmsg_create_ept() initializes an application-supplied endpoint object with a name, addresses and callbacks; any messages directed to the given destination address will cause the callback on this endpoint to be called. An RPMSG client should create an endpoint to communicate with a remote node. The client should provide at least a channel name and a callback for message notification. By default the endpoint source address should be set to RPMSG_ADDR_ANY.

The function rpmsg_destroy_ept() unregisters the endpoint from the device.

The function is_rpmsg_ept_ready() returns 1 if the endpoint has both local and destination addresses set, 0 otherwise.

The function rpmsg_send() sends data of length len based on the endpoint ept. The message will be sent to the remote node which the channel belongs to, using the endpoint's source and destination addresses. If there are no TX buffers available, the function will block until one becomes available, or a timeout of 15 seconds elapses. When the latter happens, RPMSG_ERR_NO_BUFF is returned. The function returns the number of bytes sent if successful, or a negative error code on failure.

The function rpmsg_sendto() functions in the same way as rpmsg_send() except that the destination address is taken from the dst argument and not the endpoint.

The function rpmsg_send_offchannel() functions in the same way as rpmsg_send() except that both the source and destination addresses are taken from the src and dst argument and not the endpoint.

The functions rpmsg_trysend(), rpmsg_trysendto() and rpmsg_trysend_offchannel() function in the same way as their non-try equivalents except that when no buffers are available they return immediately with RPMSG_ERR_NO_BUFF.

The function rpmsg_send_offchannel_raw() allows all options supported by the previous functions to be specified as arguments.

When a message is received for an endpoint it is passed to the application by calling the callback function registered when the endpoint was created. The endpoint, data pointer and length and the source endpoint address are passed in. The callback is made from a thread that is part of the RPMSG subsystem. The callback is permitted to call any functions that are allowed from a thread but should avoid doing anything that might take a long time since it would block processing of new messages for other endpoints.

The following code shows an example of the use of this API. For clarity, error checking code is omitted.

void rpmsg_test( void )
    struct rpmsg_device *rdev = NULL;
    struct rpmsg_endpoint ept;
    int err;
    int i;
    uint32_t src = 0x501;
    uint32_t dst = 0x502;

    // Locate device "rpmsg0"
    rdev = cyg_rpmsg_open( "rpmsg0" );

    // Create an endpoint for the given src and dst pair
    err = rpmsg_create_ept( &ept, rdev,
                            "ecos-ept0", src, dst,
                            rpmsg_ept_cb, NULL );

    // Send some messages, we assume the peer will
    // reply in some way.
    for( i = 0; i < 100; i++ )
        char msg[40];

        int len = diag_sprintf( msg, "%3d 1234567", i );

        err = rpmsg_send( &ept, msg, len );

        diag_printf("SENT: %4d %04lx %s\n", len, dst, (char *)msg);


    // Close the device when we are finished

// Receive callback
int rpmsg_ept_cb(struct rpmsg_endpoint *ept, void *data,
                 size_t len, uint32_t src, void *priv)
    // Handle received message

    diag_printf("GOT : %4d %04lx %s\n", len, src, data);

    return RPMSG_SUCCESS;