2024-01-04 14:10:44 +08:00
|
|
|
/****************************************************************************
|
|
|
|
* drivers/rpmsg/rpmsg_port.h
|
|
|
|
*
|
|
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
|
|
* contributor license agreements. See the NOTICE file distributed with
|
|
|
|
* this work for additional information regarding copyright ownership. The
|
|
|
|
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
|
|
|
* "License"); you may not use this file except in compliance with the
|
|
|
|
* License. You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
|
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
|
|
* License for the specific language governing permissions and limitations
|
|
|
|
* under the License.
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
#ifndef __DRIVERS_RPMSG_RPMSG_PORT_H
|
|
|
|
#define __DRIVERS_RPMSG_RPMSG_PORT_H
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Included Files
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
#include <stdbool.h>
|
2024-05-27 19:14:33 +08:00
|
|
|
|
|
|
|
#include <metal/atomic.h>
|
|
|
|
|
2024-01-04 14:10:44 +08:00
|
|
|
#include <nuttx/list.h>
|
|
|
|
#include <nuttx/spinlock.h>
|
|
|
|
#include <nuttx/semaphore.h>
|
|
|
|
#include <nuttx/rpmsg/rpmsg.h>
|
|
|
|
#include <nuttx/rpmsg/rpmsg_port.h>
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Public Types
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
/* This header is for physical layer's use */
|
|
|
|
|
|
|
|
begin_packed_struct struct rpmsg_port_header_s
|
|
|
|
{
|
|
|
|
uint16_t crc; /* CRC of current port data frame */
|
|
|
|
uint16_t cmd; /* Reserved for uart/spi port driver */
|
2024-05-29 16:21:19 +08:00
|
|
|
uint16_t avail; /* Available rx buffer of peer side */
|
|
|
|
uint16_t len; /* Data frame length */
|
2024-01-04 14:10:44 +08:00
|
|
|
uint8_t buf[0]; /* Payload buffer */
|
|
|
|
} end_packed_struct;
|
|
|
|
|
|
|
|
struct rpmsg_port_list_s
|
|
|
|
{
|
2024-05-29 16:21:19 +08:00
|
|
|
uint16_t num; /* Number of buffers */
|
2024-01-04 14:10:44 +08:00
|
|
|
sem_t sem; /* Used to wait for buffer */
|
|
|
|
spinlock_t lock; /* List lock */
|
|
|
|
struct list_node head; /* List head */
|
|
|
|
};
|
|
|
|
|
|
|
|
struct rpmsg_port_queue_s
|
|
|
|
{
|
|
|
|
/* Indicate buffers current queue managed is dynamic alloced */
|
|
|
|
|
|
|
|
bool alloced;
|
|
|
|
|
|
|
|
/* Buffer array's base address of current queue managed */
|
|
|
|
|
|
|
|
FAR void *buf;
|
|
|
|
|
|
|
|
/* Node related to buffer for buffer management */
|
|
|
|
|
|
|
|
FAR struct list_node *node;
|
|
|
|
|
|
|
|
/* Length of buffers current queue managed */
|
|
|
|
|
2024-05-29 16:21:19 +08:00
|
|
|
uint16_t len;
|
2024-01-04 14:10:44 +08:00
|
|
|
|
|
|
|
/* Free list of buffers which have not been occupied data yet */
|
|
|
|
|
|
|
|
struct rpmsg_port_list_s free;
|
|
|
|
|
|
|
|
/* Ready list of buffers which have been occupied data already */
|
|
|
|
|
|
|
|
struct rpmsg_port_list_s ready;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct rpmsg_port_s;
|
|
|
|
|
|
|
|
typedef void (*rpmsg_port_rx_cb_t)(FAR struct rpmsg_port_s *port,
|
|
|
|
FAR struct rpmsg_port_header_s *hdr);
|
|
|
|
|
|
|
|
struct rpmsg_port_ops_s
|
|
|
|
{
|
2024-05-27 19:14:33 +08:00
|
|
|
/* Notify driver there is buffer to be sent of the tx queue */
|
|
|
|
|
|
|
|
CODE void (*notify_tx_ready)(FAR struct rpmsg_port_s *port);
|
2024-01-04 14:10:44 +08:00
|
|
|
|
2024-05-27 19:14:33 +08:00
|
|
|
/* Notify driver there is a buffer in rx queue is freed */
|
|
|
|
|
|
|
|
CODE void (*notify_rx_free)(FAR struct rpmsg_port_s *port);
|
2024-01-04 14:10:44 +08:00
|
|
|
|
|
|
|
/* Register callback function which should be invoked when there is
|
|
|
|
* date received to the rx queue by driver
|
|
|
|
*/
|
|
|
|
|
|
|
|
CODE void (*register_callback)(FAR struct rpmsg_port_s *port,
|
|
|
|
rpmsg_port_rx_cb_t callback);
|
|
|
|
};
|
|
|
|
|
|
|
|
struct rpmsg_port_s
|
|
|
|
{
|
|
|
|
struct rpmsg_s rpmsg;
|
|
|
|
struct rpmsg_device rdev; /* Rpmsg device object */
|
|
|
|
struct rpmsg_port_queue_s txq; /* Port tx queue */
|
|
|
|
struct rpmsg_port_queue_s rxq; /* Port rx queue */
|
|
|
|
|
2024-06-19 19:54:54 +08:00
|
|
|
char local_cpuname[RPMSG_NAME_SIZE];
|
|
|
|
|
2024-01-04 14:10:44 +08:00
|
|
|
/* Remote cpu name of this port connected to */
|
|
|
|
|
|
|
|
char cpuname[RPMSG_NAME_SIZE];
|
|
|
|
|
|
|
|
/* Ops need implemented by drivers under port layer */
|
|
|
|
|
|
|
|
const FAR struct rpmsg_port_ops_s *ops;
|
|
|
|
};
|
|
|
|
|
|
|
|
#ifndef __ASSEMBLY__
|
|
|
|
#ifdef __cplusplus
|
|
|
|
#define EXTERN extern "C"
|
|
|
|
extern "C"
|
|
|
|
{
|
|
|
|
#else
|
|
|
|
#define EXTERN extern
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Public Function Prototypes
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Name: rpmsg_port_queue_get_available_buffer
|
|
|
|
*
|
|
|
|
* Description:
|
|
|
|
* Get buffer from free list of the queue.
|
|
|
|
*
|
|
|
|
* Input Parameters:
|
|
|
|
* queue - The queue to be getten from.
|
|
|
|
* wait - If wait or not when there is no available buffer of the queue.
|
|
|
|
*
|
|
|
|
* Returned Value:
|
|
|
|
* A struct rpmsg_port_header_s's pointer on success or NULL on failure.
|
|
|
|
* The len of struct rpmsg_port_header_s indicates the sum of struct
|
|
|
|
* rpmsg_port_header_s's size and the data size can be used.
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
FAR struct rpmsg_port_header_s *
|
|
|
|
rpmsg_port_queue_get_available_buffer(FAR struct rpmsg_port_queue_s *queue,
|
|
|
|
bool wait);
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Name: rpmsg_port_queue_return_buffer
|
|
|
|
*
|
|
|
|
* Description:
|
|
|
|
* Return buffer to free list of the queue.
|
|
|
|
*
|
|
|
|
* Input Parameters:
|
|
|
|
* queue - The queue to be returned to.
|
|
|
|
* hdr - Pointer to the struct rpmsg_port_header_s to be returned.
|
|
|
|
*
|
|
|
|
* Returned Value:
|
|
|
|
* No return value.
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
void rpmsg_port_queue_return_buffer(FAR struct rpmsg_port_queue_s *queue,
|
|
|
|
FAR struct rpmsg_port_header_s *hdr);
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Name: rpmsg_port_queue_get_buffer
|
|
|
|
*
|
|
|
|
* Description:
|
|
|
|
* Get buffer from ready list of the queue.
|
|
|
|
*
|
|
|
|
* Input Parameters:
|
|
|
|
* queue - The queue to be getten from.
|
|
|
|
* wait - If wait or not when there is no used buffer of the queue.
|
|
|
|
*
|
|
|
|
* Returned Value:
|
|
|
|
* A struct rpmsg_port_header_s's pointer on success or NULL on failure.
|
|
|
|
* The len of struct rpmsg_port_header_s indicates the sum of struct
|
|
|
|
* rpmsg_port_header_s's size and the data size has be used.
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
FAR struct rpmsg_port_header_s *
|
|
|
|
rpmsg_port_queue_get_buffer(FAR struct rpmsg_port_queue_s *queue,
|
|
|
|
bool wait);
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Name: rpmsg_port_queue_add_buffer
|
|
|
|
*
|
|
|
|
* Description:
|
|
|
|
* Add buffer to ready list of the queue.
|
|
|
|
*
|
|
|
|
* Input Parameters:
|
|
|
|
* queue - The queue to be added to.
|
|
|
|
* hdr - Pointer to the struct rpmsg_port_header_s to be added. The
|
|
|
|
* length of it must be set before this function invoked.
|
|
|
|
*
|
|
|
|
* Returned Value:
|
|
|
|
* No return value.
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
void rpmsg_port_queue_add_buffer(FAR struct rpmsg_port_queue_s *queue,
|
|
|
|
FAR struct rpmsg_port_header_s *hdr);
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Name: rpmsg_port_queue_navail
|
|
|
|
*
|
|
|
|
* Description:
|
|
|
|
* Get available buffer number of free list of the queue.
|
|
|
|
*
|
|
|
|
* Input Parameters:
|
|
|
|
* queue - The queue is to be calculated.
|
|
|
|
*
|
|
|
|
* Returned Value:
|
|
|
|
* Number of available buffers.
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
2024-05-27 19:14:33 +08:00
|
|
|
static inline_function
|
2024-05-29 16:21:19 +08:00
|
|
|
uint16_t rpmsg_port_queue_navail(FAR struct rpmsg_port_queue_s *queue)
|
2024-05-27 19:14:33 +08:00
|
|
|
{
|
|
|
|
return atomic_load(&queue->free.num);
|
|
|
|
}
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Name: rpmsg_port_queue_nused
|
|
|
|
*
|
|
|
|
* Description:
|
|
|
|
* Get used buffer number of ready list of the queue.
|
|
|
|
*
|
|
|
|
* Input Parameters:
|
|
|
|
* queue - The queue is to be calculated.
|
|
|
|
*
|
|
|
|
* Returned Value:
|
|
|
|
* Number of used buffers.
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
static inline_function
|
2024-05-29 16:21:19 +08:00
|
|
|
uint16_t rpmsg_port_queue_nused(FAR struct rpmsg_port_queue_s *queue)
|
2024-05-27 19:14:33 +08:00
|
|
|
{
|
|
|
|
return atomic_load(&queue->ready.num);
|
|
|
|
}
|
2024-01-04 14:10:44 +08:00
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Name: rpmsg_port_initialize
|
|
|
|
*
|
|
|
|
* Description:
|
|
|
|
* Init port layer by port's configuration. rpmsg port layer creates and
|
|
|
|
* manages queues used for communication of two cpus.
|
|
|
|
*
|
|
|
|
* Input Parameters:
|
|
|
|
* port - The port to be inited.
|
|
|
|
* cfg - Port configuration.
|
|
|
|
* ops - Operation implemented by drivers under port layer.
|
|
|
|
*
|
|
|
|
* Returned Value:
|
|
|
|
* Zero on success or an negative value on failure.
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
int rpmsg_port_initialize(FAR struct rpmsg_port_s *port,
|
|
|
|
FAR const struct rpmsg_port_config_s *cfg,
|
|
|
|
FAR const struct rpmsg_port_ops_s *ops);
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Name: rpmsg_port_uninitialize
|
|
|
|
*
|
|
|
|
* Description:
|
|
|
|
* uninit rpmsg port.
|
|
|
|
*
|
|
|
|
* Input Parameters:
|
|
|
|
* port - The port to be uninited.
|
|
|
|
*
|
|
|
|
* Returned Value:
|
|
|
|
* No return value.
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
void rpmsg_port_uninitialize(FAR struct rpmsg_port_s *port);
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Name: rpmsg_port_register
|
|
|
|
*
|
|
|
|
* Description:
|
|
|
|
* Invoked to create a rpmsg character device when a connection between
|
|
|
|
* two cpus has established.
|
|
|
|
*
|
|
|
|
* Input Parameters:
|
2024-06-19 19:54:54 +08:00
|
|
|
* port - The port has established a connection.
|
|
|
|
* local_cpuname - The local cpuname
|
2024-01-04 14:10:44 +08:00
|
|
|
*
|
|
|
|
* Returned Value:
|
|
|
|
* Zero on success or an negative value on failure.
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
2024-06-19 19:54:54 +08:00
|
|
|
int rpmsg_port_register(FAR struct rpmsg_port_s *port,
|
|
|
|
FAR const char *local_cpuname);
|
2024-01-04 14:10:44 +08:00
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Name: rpmsg_port_unregister
|
|
|
|
*
|
|
|
|
* Description:
|
|
|
|
* Invoked to unregister the rpmsg character device.
|
|
|
|
*
|
|
|
|
* Input Parameters:
|
|
|
|
* port - The port has established a connection.
|
|
|
|
*
|
|
|
|
* Returned Value:
|
|
|
|
* No return value.
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
void rpmsg_port_unregister(FAR struct rpmsg_port_s *port);
|
|
|
|
|
|
|
|
#undef EXTERN
|
|
|
|
#ifdef __cplusplus
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#endif
|
|
|
|
#endif /* __DRIVERS_RPMSG_RPMSG_PORT_H */
|