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