]> rtime.felk.cvut.cz Git - frescor/fna.git/blob - src_frescan/frescan_types.h
add group negotiations to frescan and change all the requests and messages to map...
[frescor/fna.git] / src_frescan / frescan_types.h
1 /*!
2  * @file frescan_types.h
3  *
4  * @brief types used in FRESCAN
5  *
6  * @version 0.01
7  *
8  * @date 16-Nov-2008
9  *
10  * @author
11  *      Daniel Sangorrin
12  *
13  * @comments
14  *
15  * This file contains the types used in FRESCAN protocol
16  *
17  * @license
18  *
19  * -----------------------------------------------------------------------
20  *  Copyright (C) 2006 - 2008 FRESCOR consortium partners:
21  *
22  *    Universidad de Cantabria,              SPAIN
23  *    University of York,                    UK
24  *    Scuola Superiore Sant'Anna,            ITALY
25  *    Kaiserslautern University,             GERMANY
26  *    Univ. Politécnica  Valencia,           SPAIN
27  *    Czech Technical University in Prague,  CZECH REPUBLIC
28  *    ENEA                                   SWEDEN
29  *    Thales Communication S.A.              FRANCE
30  *    Visual Tools S.A.                      SPAIN
31  *    Rapita Systems Ltd                     UK
32  *    Evidence                               ITALY
33  *
34  *    See http://www.frescor.org for a link to partners' websites
35  *
36  *           FRESCOR project (FP6/2005/IST/5-034026) is funded
37  *        in part by the European Union Sixth Framework Programme
38  *        The European Union is not liable of any use that may be
39  *        made of this code.
40  *
41  *  This file is part of FRESCAN
42  *
43  *  FRESCAN is free software; you can  redistribute it and/or  modify
44  *  it under the terms of  the GNU General Public License as published by
45  *  the Free Software Foundation;  either  version 2, or (at  your option)
46  *  any later version.
47  *
48  *  FRESCAN  is distributed  in  the hope  that  it  will  be useful,  but
49  *  WITHOUT  ANY  WARRANTY;     without  even the   implied   warranty  of
50  *  MERCHANTABILITY  or  FITNESS FOR  A  PARTICULAR PURPOSE. See  the  GNU
51  *  General Public License for more details.
52  *
53  *  You should have  received a  copy of  the  GNU  General Public License
54  *  distributed  with  FRESCAN;  see file COPYING.   If not,  write to the
55  *  Free Software  Foundation,  59 Temple Place  -  Suite 330,  Boston, MA
56  *  02111-1307, USA.
57  *
58  * As a special exception, including FRESCAN header files in a file,
59  * instantiating FRESCAN generics or templates, or linking other files
60  * with FRESCAN objects to produce an executable application, does not
61  * by itself cause the resulting executable application to be covered
62  * by the GNU General Public License. This exception does not
63  * however invalidate any other reasons why the executable file might be
64  * covered by the GNU Public License.
65  * -----------------------------------------------------------------------
66  *
67  */
68
69 #ifndef _FRESCAN_TYPES_H_
70 #define _FRESCAN_TYPES_H_
71
72 #include <stdint.h>  // uint8_t, uint32_t..
73 #include <stdbool.h> // bool
74 #include <unistd.h>  // size_t
75 #include <time.h>    // struct timespec, timer_t
76 #include <semaphore.h> // sem_t
77
78 #include "frsh.h" // for frsh_contract_t
79 #include "fsa.h"  // for frsh_sa_scenario_t
80 #include "fosa_opaque_types.h" // for FOSA_ETIMEDOUT
81 #include "fosa_threads_and_signals.h"   // fosa_thread_id_t
82 #include "frescan_config.h"
83
84 #include <misc/linux_list.h> // struct list_head
85 #include <drivers/can.h>     // can_frame_t
86 #include <misc/freelist.h>   // freelist_t
87
88 typedef uint8_t frescan_network_t;
89 typedef uint8_t frescan_node_t;
90 typedef uint8_t frescan_channel_t;
91 typedef uint8_t frescan_prio_t;
92 typedef uint8_t frescan_ss_t;
93 typedef uint32_t frescan_budget_t;
94
95 typedef struct {
96         int           size;
97         frescan_ss_t  ss[FRESCAN_BWRES_MAX_GROUP_OPS];
98 } frescan_ss_group_t;
99
100 /**
101  * frescan_flags_t - frescan flags
102  *
103  * @FRESCAN_SS: send the message using sporadic servers
104  * @FRESCAN_FP: send the message using fixed priorities
105  * @FRESCAN_POLL: no buffer copy, only pointer and use the ID to poll status
106  * @FRESCAN_SYNC: no buffer copy, only pointer and block until it is sent
107  * @FRESCAN_ASYNC: use buffer copy and return immediately
108  */
109
110 typedef enum {
111         FRESCAN_SS    = 1<<4,  // sporadic server
112         FRESCAN_FP    = 1<<3,  // fixed priorities
113         FRESCAN_POLL  = 1<<2,  // polling
114         FRESCAN_SYNC  = 1<<1,  // synchronous
115         FRESCAN_ASYNC = 1      // asynchronous
116 } frescan_flags_t;
117
118 /**
119  * frescan_send_params_t - send parameters
120  *
121  * @net: the network to use
122  * @to: the node where the message shoud be sent to
123  * @channel: the channel in 'to' where the message shoud be sent to
124  * @flags: the flags (see frescan_flags_t)
125  * @prio: the priority for the message if (flags & FRESCAN_FP)
126  * @ss: the sporadic server for the message if (flags & FRESCAN_SS)
127  */
128
129 typedef struct {
130         frescan_network_t net;
131         frescan_node_t to;
132         frescan_channel_t channel;
133         frescan_flags_t flags;
134         union {
135                 frescan_prio_t prio;
136                 frescan_ss_t ss;
137         };
138 } frescan_send_params_t;
139
140 /**
141  * frescan_recv_params_t - receive parameters
142  *
143  * @net: the network to use
144  * @channel: the channel from which we want to extract a message
145  * @flags: FRESCAN_SYNC/ASYNC
146  */
147
148 typedef struct {
149         frescan_network_t net;
150         frescan_channel_t channel;
151         frescan_flags_t flags;
152 } frescan_recv_params_t;
153
154 /**
155  * frescan_init_params_t - initialization parameters
156  *
157  * @net: network to initialize (minor number ie: /dev/can0 -> 0)
158  * @node: set the local node identificator
159  * @tx_fp_max_prio: maximum number of priorities for the fixed priority
160  *                  transmission queues. (prio = 0 .. max_prio - 1)
161  * @rx_num_of_channels: number of rx channels (0 .. rx_num_of_channels - 1)
162  * @rx_channel_max_prio: array (range rx_num_of_channels) saying the number
163  *                       of priorities for each channel. If this parameter is
164  *                       NULL tx_fp_max_prio will be used for all queues.
165  */
166
167 typedef struct {
168         frescan_network_t net;
169         frescan_node_t node;
170         uint32_t tx_fp_max_prio;
171         uint32_t rx_num_of_channels;
172         uint32_t *rx_channel_max_prio;
173 } frescan_init_params_t;
174
175 /**
176  * frescan_packet_t - a frescan packet
177  *
178  * This structure is very important and it is used to store a FRESCAN packet.
179  * As we support fragmentation, a FRESCAN packet can be composed of several
180  * CAN frames. This 'frescan_packet_t' structure is used in two main cases:
181  *
182  * 1.- When we are sending data. In this case, the buffer pointers store the
183  *     real data we want to sent and we use a 'buffer_read_pointer' to know
184  *     how many bytes of the buffer we already sent. In 'frame', we store the
185  *     last sent frame (with the corresponding CAN id fields). We will have
186  *     to update the fragmentation fields as long as we send more packets.
187  *     The 'fifo_list' is used to chained frescan packets of the same priority
188  *     or that belong to the same sporadic server. Finally, 'flags', specify
189  *     if we are sending ASYNC or SYNC. If we are sending SYNC the buffer
190  *     pointers are pointing to the buffer sent by the user (zero copying),
191  *     while if we use ASYNC, a copy of the data is done to the buffer.
192  *
193  * 2.- When we are receiving data, we only use 'frame' and 'fifo_list' fields.
194  *     The IRQ handler of the chip allocates a CAN frame and calls to our hook.
195  *     We store the pointer to that frame in 'frame' and we make a chain with
196  *     frames of the same message (using the fragmentation fields). When we
197  *     have all of them, we move the packet list to the corresponding
198  *     receiving channel to wait for the user to perform a receive operation
199  *     when we will copy the data and free both the packets and the frames.
200  *
201  * @flags: to know if the packet is to be sent SYNC or ASYNC, FP or SERVER...
202  * @frame: pointer to the last sent frame or the received frame
203  * @fifo_list: list to put several packets together
204  * @msg_list: list to put packets of the same message together
205  * @buffer_head: pointer to first byte of the buffer that is going to be sent
206  * @buffer_read_pointer: pointer to the part of the buffer being read
207  * @buffer_pending_bytes: bytes waiting to be sent
208  * @timestamp: time when the packet was enqueued (activation time)
209  * @pool_pos: position in the packets pool to know how to free it
210  *
211  * NOTE: the buffers could also be used on the receiving part to support
212  * sequential reads, instead of reading the whole message at once.
213  *
214  */
215
216 typedef struct {
217         frescan_flags_t flags;
218         struct can_frame_t *frame;
219         struct list_head fifo_list;
220         struct list_head msg_list;
221         uint8_t *buffer_head;         // only for sending packets
222         uint8_t *buffer_read_pointer; // only for sending packets
223         uint32_t buffer_pending_bytes; // only for sending packets
224         struct timespec timestamp;
225         int pool_pos;
226 } frescan_packet_t;
227
228 /**
229  * frescan_repl_op_t - a replenishment operation
230  *
231  * @when: when the replenishment operation is programmed at
232  * @amount: number of frames to add to the available budget
233  * @repl_list: to chain the replenishments for a certain sporadic server
234  * @pool_pos: to know how to free it from the replenishment pool
235  */
236
237 typedef struct {
238         struct timespec when;
239         frescan_budget_t amount;
240         struct list_head repl_list;
241         int pool_pos;
242 } frescan_repl_op_t;
243
244 /**
245  * frescan_server_params_t - server parameters
246  *
247  * @budget: the budget in CAN 8-byte frames
248  * @period: the replenishment period for the server
249  * @prio: the priority of the server
250  */
251
252 typedef struct {
253         frescan_budget_t budget;
254         struct timespec  period;
255         frescan_prio_t prio;
256 } frescan_server_params_t;
257
258 /**
259  * frescan_ss_data_t - sporadic server data
260  *
261  * @committed_params: the committed params (C,T,Prio) for the server
262  * @perceived_params: the params perceived by the user (we can lie to him)
263  * @current_priority: the current priority (0=background)
264  * @repl_list: the list of pending replenishment operations
265  * @repl_timer: the timer for the replenishments associated to this server
266  *     NOTE: we could use a single timer for all but for now this is simpler
267  * @act_time: the last activation time for the server
268  * @packet_list: the packets enqueued on this server
269  * @servers_list: the list of servers
270  */
271
272 typedef struct {
273         frescan_server_params_t committed_params;
274         frescan_server_params_t perceived_params;
275         frescan_network_t       net;
276         frescan_ss_t            id;
277         frescan_prio_t          current_priority;
278         frescan_budget_t        pending_packets;
279         frescan_repl_op_t       replenishments; // TODO: use struct list_head
280         timer_t                 repl_timer;
281         struct timespec         act_time;
282         frescan_packet_t        packet_list; // TODO: use struct list_head
283         struct list_head        servers_list;
284 } frescan_ss_data_t;
285
286 /**
287  * frescan_prio_queue_t - priority queue
288  *
289  * FRESCAN priority queues are implemented as an array of one 'fifo_queue' for
290  * each priority. Where the 'fifo_queues' are implemented using the
291  * 'struct list_head fifo_list;' field of each packet structure (Linux lists).
292  *
293  * So far mutual exclusion is achieved by disabling interrupts and
294  * synchronization is done using a semaphore. This is because the queues
295  * are accesed concurrently from user threads and the IRQ handler.
296  *
297  * @net: the network this priority queue belongs to (mainly for locking)
298  * @fifo_queues: an array of packets for each priority where each packet
299  *               is just the head of a fifo_list. The array is allocated
300  *               from the heap, using malloc, at initialization with range
301  *               0..max_prio-1
302  * @max_prio: defines the number of priorities as (0 .. max_prio - 1)
303  * @sem: semaphore used for synchronization
304  */
305
306 typedef struct {
307         frescan_network_t net;
308         frescan_packet_t *fifo_queues;
309         uint32_t max_prio;
310         sem_t sem;
311 } frescan_prio_queue_t;
312
313 /**
314  * frescan_queues_t - the set of FRESCAN queues for each instance of a protocol
315  *
316  * @tx_fp_queue: priority queue for the fixed priority packets
317  * @rx_channel_queues: a priority queue for each receiving channel
318  *
319  * TODO: add here the sporadic server queues...
320  */
321
322 typedef struct {
323         frescan_prio_queue_t *tx_fp_queue;
324         frescan_prio_queue_t **rx_channel_queues;
325         uint32_t num_rx_channels;
326 } frescan_queues_t;
327
328
329 // BWRES TYPES
330
331 typedef unsigned int frescan_bwres_robj_id_t; /* 0 .. MX_REPLY_OBJECTS-1 */
332 #define FRESCAN_ETIMEDOUT FOSA_ETIMEDOUT
333
334 /**
335  * frescan_bwres_vres_t - a frescan virtual resource
336  *
337  * @contract: the contract of the virtual resource
338  * @node: the node where the vres belongs to
339  * @ss: the sporadic server identifier
340  * @list: the list of vres. Note that this is the list of all the vres
341  *      in the network instace. As this is a master-slave protocol the master
342  *      knows everything about the contracts of the rest of nodes.
343  */
344
345 typedef enum {
346         FRESCAN_BWRES_MC_PERIOD_DEC = 1<<5,
347         FRESCAN_BWRES_MC_PERIOD_INC = 1<<4,
348         FRESCAN_BWRES_MC_BUDGET_DEC = 1<<3,
349         FRESCAN_BWRES_MC_BUDGET_INC = 1<<2,
350         FRESCAN_BWRES_MC_PRIO_DEC   = 1<<1,
351         FRESCAN_BWRES_MC_PRIO_INC   = 1
352 } frescan_bwres_mode_change_type_t;
353
354 typedef struct {
355         frsh_contract_t    contract;
356         frescan_node_t     node;
357         frescan_ss_t       ss;
358         frsh_sa_vres_id_t  fsa_vres_global_id;
359         struct list_head   list;
360         // mode change variables
361         frsh_sa_time_t old_c;
362         frsh_sa_time_t old_t;
363         frsh_sa_prio_t old_p;
364         frescan_bwres_mode_change_type_t mode_change_type;
365         struct list_head                 mode_change_list;
366 } frescan_bwres_vres_t;
367
368 /**
369  * frescan_bwres_request_data_t
370  *
371  * This are the data contained in a request to perform the negotiation of
372  * contracts.
373  *
374  * @type: indicates the type of the request
375  * @contract: a contract to (re)negotiate
376  * @contract_ref: a pointer to the contract to (re)negotiate (optimization)
377  * @ss: the local sporadic server ID
378  * @request_node: the node that performed the request
379  * @req: the request id of the SLAVE to identify the request in the reply
380  * @return_value: the value returned in a Reply (accepted or not)
381  * @final_values: the values for the ss after the negotiation
382  * @net: the network instance where this request belongs to
383  * @robj: a reply object to wait until a negotiation is completed
384  *
385  */
386
387 typedef uint16_t frescan_bwres_request_id_t; /* 0 .. MX_REQUESTS */
388
389 typedef enum {
390         FRESCAN_BWRES_REQ_GN         =  0,  // group negotiation
391         FRESCAN_BWRES_REP_GN         =  1,  // negotiation reply
392         FRESCAN_BWRES_REQ_MC         =  2,  // mode change
393         FRESCAN_BWRES_REQ_RES        =  3,  // reservation negotiation
394         FRESCAN_BWRES_REQ_RES_GET    =  4,  // reservation get values
395         FRESCAN_BWRES_REP_RES_GET    =  5,  // reservation get values reply
396         FRESCAN_BWRES_REQ_RES_SET    =  6,  // reservation set values
397         FRESCAN_BWRES_REQ_RES_COMMIT =  7,  // reservation commit
398         FRESCAN_BWRES_REQ_RES_CANCEL =  8,  // reservation cancel
399 } frescan_bwres_request_type_t;
400
401 typedef enum {
402         FRESCAN_BWRES_REQ_ACCEPTED      =  0,  // negotiation accepted
403         FRESCAN_BWRES_REQ_NOT_ACCEPTED  =  1,  // negotiation not accepted
404         FRESCAN_BWRES_REQ_ERROR         =  2,  // there was an error
405 } frescan_bwres_request_retval_t;
406
407 typedef struct {
408         frescan_network_t               net;
409         frescan_bwres_request_type_t    type;
410         frescan_bwres_request_id_t      req;
411         frescan_node_t                  request_node;
412         frescan_bwres_request_retval_t  return_value;
413         frescan_bwres_robj_id_t         robj;
414         // contracts and ss groups
415         frsh_contracts_group_t  *contracts_to_neg;
416         frsh_contracts_group_t  *contracts_to_reneg;
417         frescan_ss_group_t      *ss_to_reneg;
418         frescan_ss_group_t      *ss_to_cancel;
419         frescan_ss_group_t      *ss_new;
420         // contracts and ss groups data (to store the info at master node)
421         frsh_contracts_group_t  contracts_to_neg_data;
422         frsh_contracts_group_t  contracts_to_reneg_data;
423         frescan_ss_group_t      ss_to_reneg_data;
424         frescan_ss_group_t      ss_to_cancel_data;
425         frescan_ss_group_t      ss_new_data;
426         // for FRESCAN_BWRES_REQ_MC
427         frescan_bwres_mode_change_type_t mode_change_type;
428 } frescan_bwres_request_data_t;
429
430 /**
431  * frescan_bwres_sa_scenario_t - the scheduling analysis scenario
432  */
433
434 typedef struct {
435         frescan_prio_t    max_prio;
436         frescan_prio_t    min_prio;
437 } frescan_bwres_sa_init_params_t;
438
439 typedef struct {
440         frescan_bwres_sa_init_params_t init_params;
441         frescan_bwres_vres_t vres_pool[FRESCAN_MX_NODES][FRESCAN_MX_IDS];
442         frescan_bwres_vres_t vres_head; // TODO: use struct list_head
443         freelist_t fsa_vres_global_id_freelist;
444         frsh_sa_scenario_t fsa_scenario;
445         frsh_contracts_group_t backup_contracts_to_reneg;
446         frsh_contracts_group_t backup_contracts_to_cancel;
447 } frescan_bwres_sa_scenario_t;
448
449 /**
450  * frescan_network_data_t - data for each network instance
451  *
452  * @local_node: the local node id for that network. The implementation does not
453  * support several interfaces for the same network.
454  * @fd: file descriptor associated to /dev/canXX
455  * @repl_thread_id: replenishment thread id
456  * @manager_thread_id: manager thread id
457  * @acceptor_thread_id: acceptor thread id
458  * @neg_messages_ss_id: sporadic server for negotiation messages
459  * @queues: the queues of this network instance
460  * @last_packet: pointer to the last packet from which a frame was inserted
461  *               in the chip and its transmission is not complete.
462  * @last_packet_prio: prio of the packet in the buffer
463  * @id_queues: queues to store received packets while the whole message is
464  *             not complete (fragmentation). (id = 0 .. FRESCAN_MX_IDS - 1)
465  * @id_fp_queues: the same as id_queues but for fp messages, which have
466  *                id=FRESCAN_MX_IDS and are distinguised through their
467  *                priorities.
468  * @scenario: the scheduling analysis scenario for the network
469  * @mode_change_list: list of sa_vres that have changes to commit
470  * @mode_change_type: what type of changes are to commit
471  *
472  * the implementation can handle several FRESCAN networks at the same time
473  * in the same node, so we need a place to store its internal data. The data
474  * is allocated as an array where the index is the MINOR number (which also
475  * identifies the /dev/canx device for that network)
476  */
477
478 typedef struct {
479         FRESCAN_MLOCK_T lock;
480         frescan_node_t local_node;
481         int fd;
482         fosa_thread_id_t repl_thread_id;
483         frescan_packet_t *last_packet;
484         frescan_prio_t last_packet_prio;
485         frescan_queues_t queues;
486         frescan_packet_t *id_queues[FRESCAN_MX_NODES][FRESCAN_MX_IDS];      // TODO: alloc at init
487         frescan_packet_t *id_fp_queues[FRESCAN_MX_NODES][FRESCAN_MX_PRIOS]; // TODO: alloc at init
488         frescan_ss_data_t ss_data[FRESCAN_MX_IDS];
489         freelist_t ss_id_freelist;
490         frescan_ss_data_t ss_active_head; // TODO: use struct list_head
491         // BWRES data
492         fosa_thread_id_t manager_thread_id;
493         fosa_thread_id_t acceptor_thread_id;
494         frescan_ss_t neg_messages_ss_id;
495         frescan_bwres_sa_scenario_t scenario;
496         struct list_head mode_change_list[FRESCAN_MX_NODES];
497         frescan_bwres_mode_change_type_t mode_change_type[FRESCAN_MX_NODES];
498 } frescan_network_data_t;
499
500 #endif // _FRESCAN_TYPES_H_