Commit 0d41eba2 authored by Antonia Francis's avatar Antonia Francis

* Added doxygen comments

parent 886ec175
......@@ -20,11 +20,14 @@
#include <po_hi_messages.h>
#define DEVS_MAX 32 /** Maximum number of devices supported */
#define DEVS_MAX 32 /* Maximum number of devices supported */
#define PKT_SIZE __PO_HI_MESSAGES_MAX_SIZE + 42 /** Size of the packets exchanged */
#define PKT_SIZE __PO_HI_MESSAGES_MAX_SIZE + 42 /* Size of the packets exchanged */
/** Structure representing a GRPSW device */
/**
* \struct grspw_device.
* \brief Structure representing a GRPSW device.
*/
struct grspw_device {
/* GRSPW Device layout - must be the same as 'struct grspw_dev' */
void *dh;
......@@ -44,60 +47,79 @@ struct grspw_device {
/** Array listing all GRSPW devices */
static struct grspw_device devs[DEVS_MAX];
/** AUXILIARY INITIALIZATION FUNCTION :
* Initializing the devices.
/**
* \brief Auxiliary Initialization function to initialize the devices.
*
* Application thread
* Application thread : \n
* TDRX. SpaceWire DMA RX task. Handles reception of SpaceWire
* packets on all SpaceWire devices.
* packets on all SpaceWire devices. \n
* TDTX. SpaceWire DMA RX task. Handles transmission of SpaceWire
* packets on all SpaceWire devices.
* Then Semaphores : dma_sync_rx and dma_sync tx.
* Then the reception and transmission tasks are started.
* packets on all SpaceWire devices. \n
* Then Semaphores : dma_sync_rx and dma_sync tx. \n
* Then the reception and transmission tasks are started. \n
*/
void grspw_api_init(void);
/** Function that close and clean the idx GRSPW-device.
* All dma channels need to be closed before closing the device.
* Error messages are returned whether the dma isn't closed correctly
* Or if it's the case for the device.
* Used in test_app.
/**
* \brief Function that close and clean a GRSPW-device.
*
* All dma channels need to be closed before closing the device. \n
* Error messages are returned whether the dma isn't closed correctly,
* Or if it's the case for the device. \n
* \param idx identifier of the device.
*/
void dev_cleanup(int idx);
/** SpaceWire Routing table entry */
/**
* \struct route_entry;
* \brief SpaceWire Routing table entry.
*/
struct route_entry {
unsigned char dstadr[16];
/* 0 terminates array */
};
/** Function following a sending process:
* A packet is taking at the head of the tx_buf_list.
* Its data content is extracted from the "message" parameter.
* Its header is initialized according to the content of the p_route parameter.
* Its length is initalized thanks to the message_size parameter.
* The pkt is then added to the tx_list (to be sent).
* The dma_sem semaphore is used so that the tasks don't overlap.
/**
* \brief Function following a sending process.
*
* A packet is taken at the head of the tx_buf_list. \n
* Its data content is extracted from the "message" parameter. \n
* Its header is initialized according to the content of the p_route parameter. \n
* Its length is initalized thanks to the message_size parameter. \n
* The pkt is then added to the tx_list (to be sent). \n
* The dma_sem semaphore is used so that the tasks don't overlap. \n
* The dma_sync_tx is used so that the task isn't periodic but is triggered
* only when something is about to be sent.
* The function is called in the test_app Task, used with the sending command (x command).
*/
* only when something is about to be sent. \n
* The function is called in the main task and used with the sending command (x). \n
*
* \param device the identifier of the device.
* \param p_route a pointer toward the spacewire routing table.
* \param message which will contain the message.
* \param message_size the size of the message sent.
* \return size the size of the message sent.
*/
size_t grspw_sending
(int device,
struct route_entry * p_route,
void *message, int message_size);
/** Function following a receiving process:
* A packet is taking at the head of the tx_buf_list (of the specified device).
* Its data content is extracted from the "message" parameter.
* Its header is initialized according to the content of the p_route parameter.
* Its length is initalized thanks to the message_size parameter.
* The pkt is then added to the tx_list (to be sent).
* The dma_sem semaphore is used so that the tasks don't overlap.
/**
* \brief Function following a receiving process.
*
* A packet is taken at the head of the tx_buf_list (of the specified device). \n
* Its data content is extracted from the "message" parameter. \n
* Its header is initialized according to the content of the p_route parameter. \n
* Its length is initalized thanks to the message_size parameter. \n
* The pkt is then added to the tx_list (to be sent). \n
* The dma_sem semaphore is used so that the tasks don't overlap. \n
* The dma_sync_rx is used so that the task isn't periodic but is triggered
* only when something is about to be received.
* The function is called in the test_app Task, used qith the receiving command (r command).
*/
* only when something is about to be received. \n
* The function is called in the main Task, used qith the receiving command (r). \n
*
* \param device the identifier of the device.
* \param message which will contain the message.
* \return size the size of the message received.
*/
size_t grspw_receiving(int device,void *message);
......
......@@ -23,6 +23,29 @@
#include <request.h>
#include <po_hi_types.h>
/**
* \brief Initialize a global queue.
*
* In a distributed system, each task has
* its own global queue. This function is invoked by each thead to
* create its global queue, according to its information (number of
* ports, destination of each port ...).
* \param id id of the task associated to this queue.
* \param nb_ports number of ports for task 'id'.
* \param queue XXX.
* \param sizes size of the FIFO for each port, or __PO_HI_GQUEUE_FIFO_OUT if this is an out port.
* \param first XXX.
* \param offsets offset position for each queue in the global queue.
* \param woffsets
* \param n_dest number of destinations for each port.
* \param destinations destination for each port.
* \param used_size XXX.
* \param history XXX.
* \param recent XXX.
* \param empties XXX.
* \param total_fifo_sizes XXX.
*/
void __po_hi_gqueue_init (__po_hi_task_id id,
__po_hi_port_id_t nb_ports,
__po_hi_port_t queue[],
......@@ -37,103 +60,98 @@ void __po_hi_gqueue_init (__po_hi_task_id id,
__po_hi_request_t recent[],
__po_hi_port_id_t empties[],
__po_hi_uint32_t total_fifo_size);
/*
* Initialize a global queue. In a distributed system, each task has
* its own global queue. This function is invoked by each thead to
* create its global queue, according to its information (number of
* ports, destination of each port ...).
*
/**
* \brief Store a value for an OUT port.
*
* id : id of the task associated to this queue
* nb_ports : number of ports for task 'id'
* queue : XXX
* sizes : size of the FIFO for each port, or __PO_HI_GQUEUE_FIFO_OUT
* if this is an out port;
* first
* ofssets: offset position for each queue in the global
* queue
* woffsets :
* n_dest : number of destinations for each port;
* destinations : destination for each port;
* used_size : XXX
* history : XXX
* recent : XXX
* empties : XXX
* total_fifo_sizes: XXX
* \param id task-id which owns the global queue.
* \param port port that store the value (local).
* \param request pointer towards the request to store in the queue.
*/
void __po_hi_gqueue_store_out (__po_hi_task_id id,
__po_hi_local_port_t port,
__po_hi_request_t* request);
/* Store a value for an OUT port.
/*
* \brief Send a value for an out port.
*
* The id argument correspond to the task-id which own the global
* queue. The second argument is the port that store the value. The
* last argument is the request to store in the queue.
* \param id task-id which has the global queue.
* \param port number of the port that will send the data.
* \param request pointer towards the request to store in the queue.
*/
/*
int __po_hi_gqueue_send_output (__po_hi_task_id id,
__po_hi_port_t port);
*/
/*
* Send a value for an out port.
*
* The first argument is the id of the task which have the global
* queue. The second argument is the number of port that will send the
* data
*/
/**
* \brief Get the value on the specified port.
*
* If the port is an output, this function will return nothing,
* but will not produce an error.
*
* \param id task-id which owns the global queue.
* \param port number of port that received the data.
* \param request pointer to store the received data.
* \return 0 if there is no error in the assert.
*/
int __po_hi_gqueue_get_value(__po_hi_task_id id,
__po_hi_local_port_t port,
__po_hi_request_t* request);
/*
* Get the value on the specified port.
/**
* \brief Dequeue the value on a port.
*
* The id parameter corresponds to the task-id in the local
* process. The port argument is the number of the port that received
* the data. The request argument is a pointer to store the received
* data. If the port is an output, this function will return nothing,
* but will not produce an error.
* This function should not be called several times, until
* you know what you do.
*
* \param id task-id in the local process.
* \param port port number.
* \return __PO_HI_SUCCESS if there is no error in the assert.
*/
int __po_hi_gqueue_next_value(__po_hi_task_id id,
__po_hi_local_port_t port);
/*
* Dequeue the value on a port. The argument id is the task identifier
* in the local process. The second argument is the port number for
* the thread. This function should not be called several times, until
* you know what you do.
*/
/**
* \brief Return the number of events that are pending of a port.
*
* \param id task-identifier in the local process.
* \param port port identifier (or port number) for the thread.
* \return the number of events that are pending of a port.
*/
int __po_hi_gqueue_get_count(__po_hi_task_id id,
__po_hi_local_port_t port);
/*
* Return the number of events that are pending of a port. The first
* argument is the task identifier in the local process. The second
* argument is the port identifier (or port number) for the thread.
*/
/**
* \brief Wait until an event is received on any port for a given thread.
*
* When the function returns, the port argument will contrain the port-id that received the event.
*
* \param id thread identifier in the local process.
* \param port pointer to a port value.
*/
void __po_hi_gqueue_wait_for_incoming_event(__po_hi_task_id id,
__po_hi_local_port_t* port);
/*
* Wait until an event is received on any port for a given thread. The
* first argument is the thread identifier in the local process. The
* second argument is a pointer to a port value. When the function
* returns, the port argument will contrain the port-id that received
* the event.
*/
/**
* \brief Store a value in a IN port.
*
* The request argument contrains the request that will be stored in the queue.
*
* \param id task identifier in the local process.
* \param port port identifier for the local thread.
* \param request pointer towards what will be stored in the queue.
* \return the number of events that are pending of a port.
*/
__po_hi_port_id_t __po_hi_gqueue_store_in (__po_hi_task_id id,
__po_hi_local_port_t port,
__po_hi_request_t* request);
/*
* Store a value in a IN port. The first argument is the task
* identifier in the local process. The second argument is the port
* identifier for the local thread. The request argument contrains the
* request that will be stored in the queue.
*/
__po_hi_request_t* __po_hi_gqueue_get_most_recent_value
(const __po_hi_task_id task_id,
......@@ -147,21 +165,24 @@ __po_hi_port_t __po_hi_gqueue_get_destination (const __po_hi_task_id task_id,
uint8_t __po_hi_gqueue_get_destinations_number (const __po_hi_task_id task_id,
const __po_hi_local_port_t local_port);
/*
* Access the size of a port. The first argument is the task
* identifier in the local process. The second argument is the port
* identifier for the local thread.
*/
/**
* \brief Access the size of a port.
*
* \param id task identifier in the local process.
* \param port port identifier for the local thread.
* \return size of port.
*/
__po_hi_port_id_t __po_hi_gqueue_get_port_size(const __po_hi_task_id id,
const __po_hi_local_port_t port);
/*
* Access the used size of a port. The first argument is the task
* identifier in the local process. The second argument is the port
* identifier for the local thread.
/**
* \brief Access the used size of a port.
*
* \param id task identifier in the local process.
* \param port port identifier for the local thread.
* \return size of port.
*/
__po_hi_port_id_t __po_hi_gqueue_used_size( __po_hi_task_id id, __po_hi_local_port_t port);
__po_hi_port_id_t po_hi_gqueues_queue_is_empty(__po_hi_task_id id);
......
......@@ -16,10 +16,6 @@
#include <deployment.h>
#include <po_hi_gqueue.h>
//#define __PO_HI_PROTECTED_TYPE_REGULAR 0
//#define __PO_HI_PROTECTED_TYPE_PIP 1
//#define __PO_HI_PROTECTED_TYPE_PCP 2
#if defined (POSIX) || defined (RTEMS_POSIX) || defined (XENO_POSIX)
#include <stdlib.h>
#include <stdint.h>
......@@ -37,10 +33,14 @@
#include <windows.h>
#endif
typedef struct
/**
* \struct __po_hi_sem_t.
* \brief Structure defining a semaphore.
*/
typedef struct __po_hi_sem_t __po_hi_sem_t;
struct __po_hi_sem_t
{
#if defined (POSIX) || defined (RTEMS_POSIX) || defined (XENO_POSIX)
//protocol and priority to add
__po_hi_mutex_t mutex;
pthread_cond_t posix_condvar;
pthread_condattr_t posix_condattr;
......@@ -54,20 +54,125 @@ typedef struct
HANDLE win32_event;
CRITICAL_SECTION win32_criticalsection;
#endif
}__po_hi_sem_t;
};
/* USED TO WORK ON SEMAPHORES */
/** Basics functions on semaphores */
/**
* \brief A semaphore sem is initialized.
*
* \param sem Semaphore structure to be initialized.
* \param protocol Parameter used in the mutex initialization if there is one (Protected API).
* \param priority Parameter used in the mutex initialization if there is one (Protected API).
* \param nb Identifier of the task, used to name the synchronization object.
* \return __PO_HI_SUCCESS if successful.
* \return __PO_HI_ERROR_SEM_CREATE if there is an error.
*/
int __po_hi_sem_init(__po_hi_sem_t* sem, const __po_hi_mutex_protocol_t protocol, const int priority, int nb);
/**
* \brief A wait is done only on the condition variables of a semaphore.
*
* To ensure the protection, the po_hi_sem_mutex_wait must be used before.
* The lock must has been taken already (tested in POSIX by a trylock).
* This function is used when make a sem_wait is separated in two steps.
* First, Locking the mutex (role of po_hi_sem_mutex_wait).
* Second, Make a test and then making a condvar_wait (role of po_hi_sem_wait).
*
* \param sem Semaphore structure to be worked on.
* \return __PO_HI_SUCCESS if successful.
* \return __PO_HI_ERROR_SEM_WAIT if there is an error.
*/
int __po_hi_sem_wait(__po_hi_sem_t* sem);
/**
* \brief The mutex attribute of a semaphore is locked.
*
* This function is used when make a sem_wait is separated in two steps.
* First, Locking the mutex (role of po_hi_sem_mutex_wait).
* Second, Make a test and then making a condvar_wait (role of po_hi_sem_wait).
*
* This function is also used when only a mutex is needed in the gqueue.
* \param sem Semaphore structure to be worked on.
* \return __PO_HI_SUCCESS if successful.
* \return __PO_HI_ERROR_SEM_WAIT if there is an error.
*/
int __po_hi_sem_mutex_wait(__po_hi_sem_t* sem);
/**
* \brief The semaphore is released.
*
* The semaphore is COMPLETELY RELEASED. (both condvar and mutex).
* \param sem Semaphore structure to be worked on.
* \return __PO_HI_SUCCESS if successful.
* \return __PO_HI_ERROR_SEM_RELEASE if there is an error.
*/
int __po_hi_sem_release(__po_hi_sem_t* sem);
/**
* \brief The mutex attribute of a semaphore is released.
*
* This function is used when you don't want to do a condvar_signal, and
* want to let it stay on a wait mode.
* This function is also used when only a mutex is needed in the gqueue.
* \param sem Semaphore structure to be worked on.
* \return __PO_HI_SUCCESS if successful.
* \return __PO_HI_ERROR_SEM_RELEASE if there is an error.
*/
int __po_hi_sem_mutex_release(__po_hi_sem_t* sem);
/** Functions used to fill the __po_hi_gqueues_semaphores array */
/* USED TO WORK ON THE GQUEUE SEM ARRAY */
/**
* \brief Used to do the po_hi_sem_init function on a semaphore contained in the semaphore array.
*
* \param array The array of semaphores used in the gqueue.
* \param id Identifier of the task.
* \return __PO_HI_SUCCESS if successful.
* \return the result of that function applied to the specified semaphore if there is an error.
*/
int __po_hi_sem_init_gqueue(__po_hi_sem_t array[__PO_HI_NB_TASKS], __po_hi_task_id id);
/**
* \brief Used to do the po_hi_sem_wait function on a semaphore contained in the semaphore array.
*
* \param array The array of semaphores used in the gqueue.
* \param id Identifier of the task.
* \return __PO_HI_SUCCESS if successful.
* \return the result of that function applied to the specified semaphore if there is an error.
*/
int __po_hi_sem_wait_gqueue(__po_hi_sem_t array[__PO_HI_NB_TASKS], __po_hi_task_id id);
/**
* \brief Used to do the po_hi_sem_mutex_wait function on a semaphore contained in the semaphore array.
*
* \param array The array of semaphores used in the gqueue.
* \param id Identifier of the task.
* \return __PO_HI_SUCCESS if successful.
* \return the result of that function applied to the specified semaphore if there is an error.
*/
int __po_hi_sem_mutex_wait_gqueue(__po_hi_sem_t array[__PO_HI_NB_TASKS], __po_hi_task_id id);
/**
* \brief Used to do the po_hi_sem_release function on a semaphore contained in the semaphore array.
*
* \param array The array of semaphores used in the gqueue.
* \param id Identifier of the task.
* \return __PO_HI_SUCCESS if successful.
* \return the result of that function applied to the specified semaphore if there is an error.
*/
int __po_hi_sem_release_gqueue(__po_hi_sem_t array[__PO_HI_NB_TASKS], __po_hi_task_id id);
/**
* \brief Used to do the po_hi_sem_mutex_release function on a semaphore contained in the semaphore array.
*
* \param array The array of semaphores used in the gqueue.
* \param id Identifier of the task.
* \return __PO_HI_SUCCESS if successful.
* \return the result of that function applied to the specified semaphore if there is an error.
*/
int __po_hi_sem_mutex_release_gqueue(__po_hi_sem_t array[__PO_HI_NB_TASKS], __po_hi_task_id id);
#endif /* __PO_HI_SEMAPHORE_H__ */
......@@ -25,10 +25,9 @@
#include <rtems.h>
/** SpaceWire parameters */
/* SpaceWire parameters */
#define SPW_PROT_ID 3
/*****************************************************************************/
/* Configuration of the driver */
/* Total number of packets */
......@@ -46,21 +45,21 @@
/** Macros used with the GRSPW devices */
#define DEV(device) ((struct grspw_dev *)(device))
/**DECLARATION OF STRUCTURES AND RTEMS ELEMENTS */
/* DECLARATION OF STRUCTURES AND RTEMS ELEMENTS */
/* Declaration of the transmission/reception task used in test_app */
/* Declaration of the transmission/reception task used in test_app */
rtems_task dma_task_rx(rtems_task_argument unused);
rtems_task dma_task_tx(rtems_task_argument unused);
/* Tasks ID corresponding*/
rtems_id tid_dma_rx, tid_dma_tx;
/******************************************************************************/
/* Driver internal data structures */
/** Structure used as a bridge in the grspw_pkt data and header
implementation. */
/**
* \struct spwpkt.
* \brief Structure used as a bridge in the grspw_pkt data and header implementation.
*/
struct spwpkt {
struct grspw_pkt p;
......@@ -82,7 +81,7 @@ struct spwpkt pkts[DEVS_MAX][PKT_NBR];
/** Integer that will represent the maximum number of devices */
int nospw;
/** FORWARD DECLARATION OF ELEMENTS USED IN grspw_api_init FUNCTION */
/* FORWARD DECLARATION OF ELEMENTS USED IN grspw_api_init FUNCTION */
/* Declaration of semaphores responsible of the synchronization between tasks */
rtems_id dma_sem;
......@@ -95,22 +94,11 @@ extern int router_setup_custom(void);
void init_pkts(void);
int dev_init(int idx);
/** AUXILIARY INITIALIZATION FUNCTION :
* Initializing the devices.
*
* Application thread
* TDRX. SpaceWire DMA RX task. Handles reception of SpaceWire
* packets on all SpaceWire devices.
* TDTX. SpaceWire DMA RX task. Handles transmission of SpaceWire
* packets on all SpaceWire devices.
* Then Semaphores : dma_sync_rx and dma_sync tx.
* Then the reception and transmission tasks are started.
*/
void grspw_api_init(void){
int i;
extern struct router_hw_info router_hw;
/** INITIALIZING ROUTER PORTS, DEVICES AND DMA */
/* INITIALIZING ROUTER PORTS, DEVICES AND DMA */
/* Initialize two GRSPW AMBA ports */
printf("Setting up SpaceWire router\n");
if (router_setup_custom()) {
......@@ -202,14 +190,14 @@ void grspw_api_init(void){
rtems_task_start(tid_dma_tx, dma_task_tx, 0);
}
/** Function that initialize all packets of the application, splitting them in RX and TX packets.
* Using the spwpkt structure as a bridge to fill the different packets.
* The initialized TX packets are put in the tx_buf_list to be sent (in test_app).
/**
* \brief Function that initialize all packets of the application, splitting them in RX and TX packets.
*
* Using the spwpkt structure as a bridge to fill the different packets. \n
* The initialized TX packets are put in the tx_buf_list to be sent (in test_app). \n
* The initialized RX packets are put in the rx_list so that the "prepare" function (in dma_rx)
* put them in the rx_ready list, to provide empty packets for Reception.
* Used in test_app.
*/
* put them in the rx_ready list, to provide empty packets for Reception. \n
*/
void init_pkts(void){
struct spwpkt *pkt;
int i, j;
......@@ -252,14 +240,14 @@ void init_pkts(void){
}
}
/** Function playing with the timecode */
/* Function playing with the timecode */
void app_tc_isr(void *data, int tc);
void app_tc_isr(void *data, int tc){
struct grspw_device *dev = data;
printf("GRSPW%d: TC-ISR received 0x%02x\n", dev->index, tc);
}
/** Structure used to configure a GRSPW-device cfg attribute */
/** Variable used to configure a GRSPW-device cfg attribute */
struct grspw_config dev_def_cfg =
{
.adrcfg =
......@@ -312,11 +300,15 @@ struct grspw_config dev_def_cfg =
},
};
/** Function fully initializing the idx Device.
/**
* \brief Function fully initializing the idx Device.
*
* It especially returns an error message if only one port is available or
* if the device can't open correctly.
* It also resets all packets lists.
* Used in test_app.
* if the device can't open correctly. \n
* It also resets all packets lists. \
* \param idx identifier of the device.
* \return 0 if successful.
* \return -1 if there is an error.
*/
int dev_init(int idx){
struct grspw_device *dev = &devs[idx];
......@@ -401,11 +393,16 @@ int dev_init(int idx){
return 0;
}
/** Function that close all dma channels for a specified device idx.
/**
* \brief Function that close all dma channels for a specified device idx.
*
* If the dma channel is active,
* it is closed and the NULL value is imput in the dma array.
* If the closing is correctly done, returns 0.
* Used in dev_cleanup which is used in test_app.
* it is closed and the NULL value is imput in the dma array. \n
* If the closing is correctly done, returns 0. \n
*
* \param idx identifier of the device.
* \return 0 if a successful closing is done.
* \return the result of dma_close if there is an error.
*/
int dev_dma_close_all(int idx){
struct grspw_device *dev = &devs[idx];
......@@ -423,13 +420,6 @@ int dev_dma_close_all(int idx){
return 0;
}
/** Function that close and clean the idx GRSPW-device.
* All dma channels need to be closed before closing the device.
* Error messages are returned whether the dma isn't closed correctly