2 * @file frescan_types.h
4 * @brief types used in FRESCAN
15 * This file contains the types used in FRESCAN protocol
19 //----------------------------------------------------------------------
20 // Copyright (C) 2006 - 2009 by the FRESCOR consortium:
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
29 // Thales Communication S.A. FRANCE
30 // Visual Tools S.A. SPAIN
31 // Rapita Systems Ltd UK
34 // See http://www.frescor.org
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
42 // based on previous work (FSF) done in the FIRST project
44 // Copyright (C) 2005 Mälardalen University, SWEDEN
45 // Scuola Superiore S.Anna, ITALY
46 // Universidad de Cantabria, SPAIN
47 // University of York, UK
49 // This file is part of FNA (Frescor Network Adaptation)
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.
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 // -----------------------------------------------------------------------
73 #ifndef _FRESCAN_TYPES_H_
74 #define _FRESCAN_TYPES_H_
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
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"
88 #include <misc/linux_list.h> // struct list_head
89 #include <drivers/can.h> // can_frame_t
90 #include <misc/freelist.h> // freelist_t
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;
101 frescan_ss_t ss[FRESCAN_BWRES_MAX_GROUP_OPS];
102 } frescan_ss_group_t;
105 * frescan_flags_t - frescan flags
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
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
123 * frescan_send_params_t - send parameters
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)
134 frescan_network_t net;
136 frescan_channel_t channel;
137 frescan_flags_t flags;
142 } frescan_send_params_t;
145 * frescan_recv_params_t - receive parameters
147 * @net: the network to use
148 * @channel: the channel from which we want to extract a message
149 * @flags: FRESCAN_SYNC/ASYNC
153 frescan_network_t net;
154 frescan_channel_t channel;
155 frescan_flags_t flags;
156 } frescan_recv_params_t;
159 * frescan_init_params_t - initialization parameters
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.
172 frescan_network_t net;
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;
180 * frescan_packet_t - a frescan packet
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:
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.
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.
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
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.
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;
233 * frescan_repl_op_t - a replenishment operation
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
242 struct timespec when;
243 frescan_budget_t amount;
244 struct list_head repl_list;
249 * frescan_server_params_t - server parameters
251 * @budget: the budget in CAN 8-byte frames
252 * @period: the replenishment period for the server
253 * @prio: the priority of the server
257 frescan_budget_t budget;
258 struct timespec period;
260 } frescan_server_params_t;
263 * frescan_ss_data_t - sporadic server data
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
277 frescan_server_params_t committed_params;
278 frescan_server_params_t perceived_params;
279 frescan_network_t net;
281 frescan_prio_t current_priority;
282 frescan_budget_t pending_packets;
283 frescan_repl_op_t replenishments; // TODO: use struct list_head
285 struct timespec act_time;
286 frescan_packet_t packet_list; // TODO: use struct list_head
287 struct list_head servers_list;
291 * frescan_prio_queue_t - priority queue
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).
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.
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
306 * @max_prio: defines the number of priorities as (0 .. max_prio - 1)
307 * @sem: semaphore used for synchronization
311 frescan_network_t net;
312 frescan_packet_t *fifo_queues;
315 } frescan_prio_queue_t;
318 * frescan_queues_t - the set of FRESCAN queues for each instance of a protocol
320 * @tx_fp_queue: priority queue for the fixed priority packets
321 * @rx_channel_queues: a priority queue for each receiving channel
323 * TODO: add here the sporadic server queues...
327 frescan_prio_queue_t *tx_fp_queue;
328 frescan_prio_queue_t **rx_channel_queues;
329 uint32_t num_rx_channels;
335 typedef unsigned int frescan_bwres_robj_id_t; /* 0 .. MX_REPLY_OBJECTS-1 */
336 #define FRESCAN_ETIMEDOUT FOSA_ETIMEDOUT
339 * frescan_bwres_vres_t - a frescan virtual resource
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.
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;
359 frsh_contract_t contract;
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;
373 * frescan_bwres_request_data_t
375 * This are the data contained in a request to perform the negotiation of
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
391 typedef uint16_t frescan_bwres_request_id_t; /* 0 .. MX_REQUESTS */
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;
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;
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;
435 * frescan_bwres_sa_scenario_t - the scheduling analysis scenario
439 frescan_prio_t max_prio;
440 frescan_prio_t min_prio;
441 } frescan_bwres_sa_init_params_t;
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;
455 * frescan_network_data_t - data for each network instance
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
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
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)
484 FRESCAN_MLOCK_T lock;
485 frescan_node_t local_node;
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
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;
505 #endif // _FRESCAN_TYPES_H_