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 - 2008 FRESCOR consortium partners:
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
29 * Thales Communication S.A. FRANCE
30 * Visual Tools S.A. SPAIN
31 * Rapita Systems Ltd UK
34 * See http://www.frescor.org for a link to partners' websites
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
41 * This file is part of FRESCAN
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)
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.
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
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 * -----------------------------------------------------------------------
69 #ifndef _FRESCAN_TYPES_H_
70 #define _FRESCAN_TYPES_H_
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
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"
84 #include <misc/linux_list.h> // struct list_head
85 #include <drivers/can.h> // can_frame_t
86 #include <misc/freelist.h> // freelist_t
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;
97 frescan_ss_t ss[FRESCAN_BWRES_MAX_GROUP_OPS];
101 * frescan_flags_t - frescan flags
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
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
119 * frescan_send_params_t - send parameters
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)
130 frescan_network_t net;
132 frescan_channel_t channel;
133 frescan_flags_t flags;
138 } frescan_send_params_t;
141 * frescan_recv_params_t - receive parameters
143 * @net: the network to use
144 * @channel: the channel from which we want to extract a message
145 * @flags: FRESCAN_SYNC/ASYNC
149 frescan_network_t net;
150 frescan_channel_t channel;
151 frescan_flags_t flags;
152 } frescan_recv_params_t;
155 * frescan_init_params_t - initialization parameters
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.
168 frescan_network_t net;
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;
176 * frescan_packet_t - a frescan packet
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:
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.
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.
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
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.
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;
229 * frescan_repl_op_t - a replenishment operation
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
238 struct timespec when;
239 frescan_budget_t amount;
240 struct list_head repl_list;
245 * frescan_server_params_t - server parameters
247 * @budget: the budget in CAN 8-byte frames
248 * @period: the replenishment period for the server
249 * @prio: the priority of the server
253 frescan_budget_t budget;
254 struct timespec period;
256 } frescan_server_params_t;
259 * frescan_ss_data_t - sporadic server data
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
273 frescan_server_params_t committed_params;
274 frescan_server_params_t perceived_params;
275 frescan_network_t net;
277 frescan_prio_t current_priority;
278 frescan_budget_t pending_packets;
279 frescan_repl_op_t replenishments; // TODO: use struct list_head
281 struct timespec act_time;
282 frescan_packet_t packet_list; // TODO: use struct list_head
283 struct list_head servers_list;
287 * frescan_prio_queue_t - priority queue
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).
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.
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
302 * @max_prio: defines the number of priorities as (0 .. max_prio - 1)
303 * @sem: semaphore used for synchronization
307 frescan_network_t net;
308 frescan_packet_t *fifo_queues;
311 } frescan_prio_queue_t;
314 * frescan_queues_t - the set of FRESCAN queues for each instance of a protocol
316 * @tx_fp_queue: priority queue for the fixed priority packets
317 * @rx_channel_queues: a priority queue for each receiving channel
319 * TODO: add here the sporadic server queues...
323 frescan_prio_queue_t *tx_fp_queue;
324 frescan_prio_queue_t **rx_channel_queues;
325 uint32_t num_rx_channels;
331 typedef unsigned int frescan_bwres_robj_id_t; /* 0 .. MX_REPLY_OBJECTS-1 */
332 #define FRESCAN_ETIMEDOUT FOSA_ETIMEDOUT
335 * frescan_bwres_vres_t - a frescan virtual resource
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.
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;
355 frsh_contract_t contract;
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;
369 * frescan_bwres_request_data_t
371 * This are the data contained in a request to perform the negotiation of
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
387 typedef uint16_t frescan_bwres_request_id_t; /* 0 .. MX_REQUESTS */
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;
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;
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;
431 * frescan_bwres_sa_scenario_t - the scheduling analysis scenario
435 frescan_prio_t max_prio;
436 frescan_prio_t min_prio;
437 } frescan_bwres_sa_init_params_t;
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;
450 * frescan_network_data_t - data for each network instance
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
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
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)
479 FRESCAN_MLOCK_T lock;
480 frescan_node_t local_node;
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
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;
500 #endif // _FRESCAN_TYPES_H_