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
77 #include "frescan_data.h" // frescan_data
78 #include "frescan_debug.h" // DEBUG, FRESCAN_ERROR
79 #include "frescan_servers.h" // frescan_servers_get_highest_prio
80 #include "frescan_queues.h" // frescan_pqueue_xxx, frescan_servers_dequeue
81 #include "frescan_id.h" // frescan_id_set_field
84 * frescan_hw_buffer_abort - abort the packet in the hw tx buffer
86 * This function aborts the packet that is currently in the hw transmission
87 * buffer of the chip. It is useful to prevent priority inversion when there
88 * is another packet with highest priority waiting in the frescan queues.
90 * NOTE: if the frame is already being transmitted it won't abort it. In both
91 * cases a IRQ will be raised and either 'frescan_hook_frame_sent' or
92 * 'frescan_hook_frame_aborted' will be called.
95 int frescan_hw_buffer_abort(frescan_network_t net)
99 ret = ioctl(frescan_data[net].fd, CAN_IOCTL_ABORT_FRAME, NULL);
101 FRESCAN_ERROR ("could not abort the frame\n");
109 * frescan_hw_buffer_update - update the hw tx buffer
111 * This function updates the hw tx buffer with the packet with highest
112 * priority (including fp packets and server packets).
114 * TODO: use copy of pointer
117 int frescan_hw_buffer_update(frescan_network_t net)
120 bool is_frame_in_chip, is_fp_highest_prio;
122 frescan_packet_t *packet;
123 frescan_prio_queue_t *pqueue;
124 frescan_prio_t fprio, sprio, prio;
127 ret = frescan_servers_get_highest_prio(net, &id, &sprio);
130 pqueue = frescan_data[net].queues.tx_fp_queue;
132 ret = frescan_pqueue_get_highest_prio(pqueue, &packet, &fprio);
135 if ((id == FRESCAN_MX_IDS) && (packet == NULL)) {
136 DEBUG(FRESCAN_HW_BUFFER_ENABLE_DEBUG, "(ss:0 fp:0)\n");
140 if ((id != FRESCAN_MX_IDS) && (packet == NULL)) {
141 DEBUG(FRESCAN_HW_BUFFER_ENABLE_DEBUG, "(ss:1 fp:0)\n");
142 is_fp_highest_prio = false;
145 if ((id == FRESCAN_MX_IDS) && (packet != NULL)) {
146 DEBUG(FRESCAN_HW_BUFFER_ENABLE_DEBUG, "(ss:0 fp:1)\n");
147 is_fp_highest_prio = true;
150 if ((id != FRESCAN_MX_IDS) && (packet != NULL)) {
151 DEBUG(FRESCAN_HW_BUFFER_ENABLE_DEBUG, "(ss:1 fp:1)\n");
152 is_fp_highest_prio = (fprio > sprio);
155 prio = (is_fp_highest_prio) ? fprio : sprio;
156 is_frame_in_chip = (frescan_data[net].last_packet != NULL);
158 if (is_frame_in_chip) {
159 if (prio > frescan_data[net].last_packet_prio) {
160 // TODO: if same server, dont abort
161 DEBUG(FRESCAN_HW_BUFFER_ENABLE_DEBUG, "abort frame\n");
162 ret = frescan_hw_buffer_abort(net);
166 DEBUG(FRESCAN_HW_BUFFER_ENABLE_DEBUG,
167 "frame in chip with highest or equal prio\n");
172 if (is_fp_highest_prio) {
173 ret = frescan_pqueue_dequeue(pqueue, &packet, &prio, 0);
176 ret = frescan_servers_dequeue(net, id, &packet, &prio);
179 frescan_id_set_field(&packet->frame->id,
184 if (packet->buffer_pending_bytes > 8) {
185 packet->frame->dlc = 8;
187 packet->frame->dlc = packet->buffer_pending_bytes;
190 memcpy(packet->frame->data,
191 packet->buffer_read_pointer,
194 packet->buffer_pending_bytes -= packet->frame->dlc;
195 packet->buffer_read_pointer += packet->frame->dlc;
197 frag_flag = (packet->buffer_pending_bytes > 0) ? 1 : 0;
199 (&packet->frame->id, FRESCAN_FIELD_FRAG_FLAG, frag_flag);
201 frescan_data[net].last_packet = packet;
202 frescan_data[net].last_packet_prio = prio;
204 DEBUG(FRESCAN_HW_BUFFER_ENABLE_DEBUG,
205 "frame->id:0x%X pend_bytes:%u dlc:%u fflag:%u\n",
207 packet->buffer_pending_bytes,
211 ret = write(frescan_data[net].fd,
212 (void *)packet->frame,
213 sizeof(struct can_frame_t));
215 if (ret != sizeof(struct can_frame_t)) {
216 FRESCAN_ERROR ("could not send frame\n");