Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
TASTE
PolyORB-HI-C
Commits
0d41eba2
Commit
0d41eba2
authored
May 28, 2018
by
Antonia Francis
Browse files
* Added doxygen comments
parent
886ec175
Changes
9
Hide whitespace changes
Inline
Side-by-side
include/drivers/grspw_api.h
View file @
0d41eba2
...
...
@@ -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
);
...
...
include/po_hi_gqueue.h
View file @
0d41eba2
...
...
@@ -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
);
...
...
include/po_hi_semaphore.h
View file @
0d41eba2
...
...
@@ -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__ */
src/drivers/grspw_api.c
View file @
0d41eba2
...
...
@@ -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).
* The initialized
R
X packets are put in the
rx
_list
s
o
that the "prepare" function (in dma_rx)
*
put them in the rx_ready list, to provide empty packets for Reception.
*
Used 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
T
X packets are put in the
tx_buf
_list
t
o
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. \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
);
}
/**
Structur
e used to configure a GRSPW-device cfg attribute */
/**
Variabl
e 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.