2 * @file frescan_hw_buffer.c
4 * @brief functions to manage the hw transmission buffer
15 * This file contains the functions needed to manage the hw transmission buffer.
16 * This is needed to update the transmission buffer of the CAN chip with the
17 * message with highest priority. This could involve having to abort the
18 * frame that is currently in the buffer.
22 * -----------------------------------------------------------------------
23 * Copyright (C) 2006 - 2008 FRESCOR consortium partners:
25 * Universidad de Cantabria, SPAIN
26 * University of York, UK
27 * Scuola Superiore Sant'Anna, ITALY
28 * Kaiserslautern University, GERMANY
29 * Univ. Politécnica Valencia, SPAIN
30 * Czech Technical University in Prague, CZECH REPUBLIC
32 * Thales Communication S.A. FRANCE
33 * Visual Tools S.A. SPAIN
34 * Rapita Systems Ltd UK
37 * See http://www.frescor.org for a link to partners' websites
39 * FRESCOR project (FP6/2005/IST/5-034026) is funded
40 * in part by the European Union Sixth Framework Programme
41 * The European Union is not liable of any use that may be
44 * This file is part of FRESCAN
46 * FRESCAN is free software; you can redistribute it and/or modify
47 * it under the terms of the GNU General Public License as published by
48 * the Free Software Foundation; either version 2, or (at your option)
51 * FRESCAN is distributed in the hope that it will be useful, but
52 * WITHOUT ANY WARRANTY; without even the implied warranty of
53 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
54 * General Public License for more details.
56 * You should have received a copy of the GNU General Public License
57 * distributed with FRESCAN; see file COPYING. If not, write to the
58 * Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
61 * As a special exception, including FRESCAN header files in a file,
62 * instantiating FRESCAN generics or templates, or linking other files
63 * with FRESCAN objects to produce an executable application, does not
64 * by itself cause the resulting executable application to be covered
65 * by the GNU General Public License. This exception does not
66 * however invalidate any other reasons why the executable file might be
67 * covered by the GNU Public License.
68 * -----------------------------------------------------------------------
72 #include "frescan_hw_buffer.h"
74 #include <string.h> // memcpy
76 #include "frescan_data.h" // the_networks
77 #include "frescan_debug.h" // DEBUG, FRESCAN_ERROR
78 #include "frescan_servers.h" // frescan_servers_get_highest_prio
79 #include "frescan_queues.h" // frescan_pqueue_xxx, frescan_servers_dequeue
80 #include "frescan_id.h" // frescan_id_set_field
83 * frescan_hw_buffer_abort - abort the packet in the hw tx buffer
85 * This function aborts the packet that is currently in the hw transmission
86 * buffer of the chip. It is useful to prevent priority inversion when there
87 * is another packet with highest priority waiting in the frescan queues.
89 * NOTE: if the frame is already being transmitted it won't abort it. In both
90 * cases a IRQ will be raised and either 'frescan_hook_frame_sent' or
91 * 'frescan_hook_frame_aborted' will be called.
94 int frescan_hw_buffer_abort(frescan_network_t net)
98 ret = ioctl(the_networks[net].fd, CAN_IOCTL_ABORT_FRAME, NULL);
100 FRESCAN_ERROR ("could not abort the frame\n");
108 * frescan_hw_buffer_update - update the hw tx buffer
110 * This function updates the hw tx buffer with the packet with highest
111 * priority (including fp packets and server packets).
113 * TODO: use copy of pointer
116 int frescan_hw_buffer_update(frescan_network_t net)
119 bool is_frame_in_chip, is_fp_highest_prio;
121 frescan_packet_t *packet;
122 frescan_prio_queue_t *pqueue;
123 frescan_prio_t fprio, sprio, prio;
126 ret = frescan_servers_get_highest_prio(net, &id, &sprio);
127 if (ret != 0) return ret;
129 pqueue = the_networks[net].queues.tx_fp_queue;
131 ret = frescan_pqueue_get_highest_prio(pqueue, &packet, &fprio);
132 if (ret != 0) return ret;
134 if ((id == FRESCAN_MX_IDS) && (packet == NULL)) {
135 DEBUG(FRESCAN_HW_BUFFER_ENABLE_DEBUG, "(ss:0 fp:0)\n");
139 if ((id != FRESCAN_MX_IDS) && (packet == NULL)) {
140 DEBUG(FRESCAN_HW_BUFFER_ENABLE_DEBUG, "(ss:1 fp:0)\n");
141 is_fp_highest_prio = false;
144 if ((id == FRESCAN_MX_IDS) && (packet != NULL)) {
145 DEBUG(FRESCAN_HW_BUFFER_ENABLE_DEBUG, "(ss:0 fp:1)\n");
146 is_fp_highest_prio = true;
149 if ((id != FRESCAN_MX_IDS) && (packet != NULL)) {
150 DEBUG(FRESCAN_HW_BUFFER_ENABLE_DEBUG, "(ss:1 fp:1)\n");
151 is_fp_highest_prio = (fprio > sprio);
154 prio = (is_fp_highest_prio) ? fprio : sprio;
155 is_frame_in_chip = (the_networks[net].last_packet != NULL);
157 if (is_frame_in_chip &&
158 (prio > the_networks[net].last_packet_prio)) {
159 DEBUG(FRESCAN_HW_BUFFER_ENABLE_DEBUG,"abort frame\n");
160 ret = frescan_hw_buffer_abort(net);
162 FRESCAN_ERROR ("could not abort frame\n");
168 if (is_fp_highest_prio) {
169 ret = frescan_pqueue_dequeue(pqueue, &packet, &prio, 0);
170 if (ret != 0) return ret;
172 ret = frescan_servers_dequeue(net, id, &packet, &prio);
173 if (ret != 0) return ret;
175 frescan_id_set_field(&packet->frame->id,
180 if (packet->buffer_pending_bytes > 8) {
181 packet->frame->dlc = 8;
183 packet->frame->dlc = packet->buffer_pending_bytes;
186 memcpy(packet->frame->data,
187 packet->buffer_read_pointer,
190 packet->buffer_pending_bytes -= packet->frame->dlc;
191 packet->buffer_read_pointer += packet->frame->dlc;
193 frag_flag = (packet->buffer_pending_bytes > 0) ? 1 : 0;
195 (&packet->frame->id, FRESCAN_FIELD_FRAG_FLAG, frag_flag);
197 the_networks[net].last_packet = packet;
198 the_networks[net].last_packet_prio = prio;
200 DEBUG(FRESCAN_HW_BUFFER_ENABLE_DEBUG,
201 "frame->id:0x%X pend_bytes:%u dlc:%u fflag:%u\n",
203 packet->buffer_pending_bytes,
207 ret = write(the_networks[net].fd,
208 (void *)packet->frame,
209 sizeof(struct can_frame_t));
211 if (ret != sizeof(struct can_frame_t)) {
212 FRESCAN_ERROR ("could not send frame\n");