Unverified Commit d58d58db authored by Jerome Hugues's avatar Jerome Hugues Committed by GitHub

Merge pull request #27 from antcis/doxygen

Doxygen
parents a9ea08f6 abdfb96e
......@@ -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.
*
* 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.
/**
* \brief Auxiliary Initialization function to initialize the devices.
*
* Application thread : \n
* TDRX. SpaceWire DMA RX task. Handles reception of SpaceWire
* packets on all SpaceWire devices. \n
* TDTX. SpaceWire DMA RX task. Handles transmission of SpaceWire
* 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.
* 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).
*/
/**
* \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. \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);
......
......@@ -2,14 +2,20 @@
#include <request.h>
#include <po_hi_time.h>
/** Nature of the task traced */
/**
* \enum events.
* \brief Nature of the task traced.
*/
typedef enum {
PERIODIC = 1,
SPORADIC = -1,
ANY = 0,
} events;
/** Step in which the traced-task is */
/**
* \enum steps.
* \brief Step in which the traced-task is.
*/
typedef enum {
/* The task has just been creatd */
CREATION = 0,
......@@ -19,7 +25,10 @@ typedef enum {
GET_VALUE = 4,
} steps;
/** Structure stored when an event is recorded */
/**
* \struct characteristics.
* \brief Structure stored when an event is recorded.
*/
typedef struct characteristics characteristics;
struct characteristics{
......@@ -34,20 +43,32 @@ struct characteristics{
__po_hi_request_t *p_request;
};
/** Function initializing the mutex */
/**
* \brief Function initializing the mutex.
*/
void trace_initialize();
/** Function used to trace a task. */
/* The stored events (under the form of "characteristics" structures) are sent in an array
/**
* \brief Function used to trace a task.
*
* The stored events (under the form of "characteristics" structures) are sent in an array
* and written in the history.txt file.
* t_id is the task_id.
* p_src and p_dest are the GLOBAL source and destination ports if they exists / are retrievable.
* port_src and port_dest are the LOCAL source and destination ports if they exists / are retrievable.
* p_req is a pointer toward the request if it exists and is retrievable.
* CONVENTION :
*
* WARNING.
* If an operation is made without movement, that is to say with no source or destination (such as waiting for an event),
* the concerned port is stored in the "src" port.
*/
*
* \param event The nature of the task.
* \param status The step in which the task is.
* \param task_id Identifier of the task.
* \param p_src and p_dest, the GLOBAL source and destination ports if they exists / are retrievable.
* \param port_src and port_dest, the LOCAL source and destination ports if they exists / are retrievable.
* \param p_req a pointer toward the request if it exists and is retrievable.
*
* \return __PO_HI_SUCCESS if successful.
* \return __PO_HI_INVALID if there is an error with the txt file.
* \return __PO_HI_UNAVAILABLE is the time isn't retrievable.
*/
int record_event
(int event,
int status,
......
......@@ -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 ...).
*
*
* 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
*/
/**
* \brief Store a value for an OUT port.
*
* \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.
*
* 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.
*/
/*
* \brief Send a value for an out port.
*
* \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.
*
* 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.
*/
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
/**
* \brief Dequeue the value on a port.
*
* 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);
/**
* \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;
};
/** Basics functions on semaphores */
/* USED TO WORK 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 */