/**************************************************************************** * 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 #include #include #include #include #include #include /**************************************************************************** * 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 */ uint16_t avail; /* Available rx buffer of peer side */ uint16_t len; /* Data frame length */ uint8_t buf[0]; /* Payload buffer */ } end_packed_struct; struct rpmsg_port_list_s { uint16_t num; /* Number of buffers */ 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 */ uint16_t len; /* 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 { /* Notify driver there is buffer to be sent of the tx queue */ CODE void (*notify_tx_ready)(FAR struct rpmsg_port_s *port); /* Notify driver there is a buffer in rx queue is freed */ CODE void (*notify_rx_free)(FAR struct rpmsg_port_s *port); /* 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 */ char local_cpuname[RPMSG_NAME_SIZE]; /* 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. * ****************************************************************************/ static inline_function uint16_t rpmsg_port_queue_navail(FAR struct rpmsg_port_queue_s *queue) { 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 uint16_t rpmsg_port_queue_nused(FAR struct rpmsg_port_queue_s *queue) { return atomic_load(&queue->ready.num); } /**************************************************************************** * 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: * port - The port has established a connection. * local_cpuname - The local cpuname * * Returned Value: * Zero on success or an negative value on failure. * ****************************************************************************/ int rpmsg_port_register(FAR struct rpmsg_port_s *port, FAR const char *local_cpuname); /**************************************************************************** * 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 */