2 * @file frescan_packets.h
4 * @brief FRESCAN packets definition and pool
15 * This file contains the FRESCAN packets definition and functions to
16 * allocate and free them from a global pool of packets statically
21 * See MaRTE OS license
25 #ifndef _MARTE_FRESCAN_PACKETS_H_
26 #define _MARTE_FRESCAN_PACKETS_H_
28 #include <time.h> // struct timespec
29 #include <stdint.h> // uint8_t ...
30 #include "frescan.h" // frescan_flags_t
31 #include <misc/linux_list.h> // struct list_head
32 #include <drivers/can.h> // can_frame_t
35 * frescan_packet_t - a frescan packet
37 * This structure is very important and it is used to store a FRESCAN packet.
38 * As we support fragmentation, a FRESCAN packet can be composed of several
39 * CAN frames. This 'frescan_packet_t' structure is used in two main cases:
41 * 1.- When we are sending data. In this case, the buffer pointers store the
42 * real data we want to sent and we use a 'buffer_read_pointer' to know
43 * how many bytes of the buffer we already sent. In 'frame', we store the
44 * last sent frame (with the corresponding CAN id fields). We will have
45 * to update the fragmentation fields as long as we send more packets.
46 * The 'fifo_list' is used to chained frescan packets of the same priority
47 * or that belong to the same sporadic server. Finally, 'flags', specify
48 * if we are sending ASYNC or SYNC. If we are sending SYNC the buffer
49 * pointers are pointing to the buffer sent by the user (zero copying),
50 * while if we use ASYNC, a copy of the data is done to the buffer.
52 * 2.- When we are receiving data, we only use 'frame' and 'fifo_list' fields.
53 * The IRQ handler of the chip allocates a CAN frame and calls to our hook.
54 * We store the pointer to that frame in 'frame' and we make a chain with
55 * frames of the same message (using the fragmentation fields). When we
56 * have all of them, we move the packet list to the corresponding
57 * receiving channel to wait for the user to perform a receive operation
58 * when we will copy the data and free both the packets and the frames.
60 * @flags: to know if the packet is to be sent SYNC or ASYNC, FP or SERVER...
61 * @frame: pointer to the last sent frame or the received frame
62 * @fifo_list: list to put several packets together
63 * @msg_list: list to put packets of the same message together
64 * @buffer_head: pointer to first byte of the buffer that is going to be sent
65 * @buffer_read_pointer: pointer to the part of the buffer being read
66 * @buffer_pending_bytes: bytes waiting to be sent
67 * @timestamp: time when the packet was enqueued (activation time)
68 * @pool_pos: position in the packets pool to know how to free it
70 * NOTE: the buffers could also be used on the receiving part to support
71 * sequential reads, instead of reading the whole message at once.
76 frescan_flags_t flags;
77 struct can_frame_t *frame;
78 struct list_head fifo_list;
79 struct list_head msg_list;
80 uint8_t *buffer_head; // only for sending packets
81 uint8_t *buffer_read_pointer; // only for sending packets
82 uint32_t buffer_pending_bytes; // only for sending packets
83 struct timespec timestamp;
87 #define FRESCAN_MX_PACKETS 100
90 * frescan_packets_init
92 * Initializes a pool of packets that will be managed internally
95 extern int frescan_packets_init();
98 * frescan_packets_alloc
100 * Allocates a frame from the pool of packets. On error it returns NULL
103 extern frescan_packet_t *frescan_packets_alloc();
106 * frescan_packets_free
108 * Frees a frame and returns it to the pool of packets.
111 extern int frescan_packets_free(frescan_packet_t *packet);
113 #endif // _MARTE_FRESCAN_PACKETS_H_