]> rtime.felk.cvut.cz Git - frescor/fna.git/blobdiff - src_frescan/frescan_hw_buffer.c
BUG corrected: when sending two packets one after the other very fast, the second...
[frescor/fna.git] / src_frescan / frescan_hw_buffer.c
index f2996c710bb7e1bf29c9e27f39f9e6fa5cfbb00b..bc66efb876635edfa4020a70acff3c5ff5ffaab3 100644 (file)
  *
  * @license
  *
- * See MaRTE OS license
+ * -----------------------------------------------------------------------
+ *  Copyright (C) 2006 - 2008 FRESCOR consortium partners:
+ *
+ *    Universidad de Cantabria,              SPAIN
+ *    University of York,                    UK
+ *    Scuola Superiore Sant'Anna,            ITALY
+ *    Kaiserslautern University,             GERMANY
+ *    Univ. Politécnica  Valencia,           SPAIN
+ *    Czech Technical University in Prague,  CZECH REPUBLIC
+ *    ENEA                                   SWEDEN
+ *    Thales Communication S.A.              FRANCE
+ *    Visual Tools S.A.                      SPAIN
+ *    Rapita Systems Ltd                     UK
+ *    Evidence                               ITALY
+ *
+ *    See http://www.frescor.org for a link to partners' websites
+ *
+ *           FRESCOR project (FP6/2005/IST/5-034026) is funded
+ *        in part by the European Union Sixth Framework Programme
+ *        The European Union is not liable of any use that may be
+ *        made of this code.
+ *
+ *  This file is part of FRESCAN
+ *
+ *  FRESCAN is free software; you can  redistribute it and/or  modify
+ *  it under the terms of  the GNU General Public License as published by
+ *  the Free Software Foundation;  either  version 2, or (at  your option)
+ *  any later version.
+ *
+ *  FRESCAN  is distributed  in  the hope  that  it  will  be useful,  but
+ *  WITHOUT  ANY  WARRANTY;     without  even the   implied   warranty  of
+ *  MERCHANTABILITY  or  FITNESS FOR  A  PARTICULAR PURPOSE. See  the  GNU
+ *  General Public License for more details.
+ *
+ *  You should have  received a  copy of  the  GNU  General Public License
+ *  distributed  with  FRESCAN;  see file COPYING.   If not,  write to the
+ *  Free Software  Foundation,  59 Temple Place  -  Suite 330,  Boston, MA
+ *  02111-1307, USA.
+ *
+ * As a special exception, including FRESCAN header files in a file,
+ * instantiating FRESCAN generics or templates, or linking other files
+ * with FRESCAN objects to produce an executable application, does not
+ * by itself cause the resulting executable application to be covered
+ * by the GNU General Public License. This exception does not
+ * however invalidate any other reasons why the executable file might be
+ * covered by the GNU Public License.
+ * -----------------------------------------------------------------------
  *
  */
 
 #include "frescan_hw_buffer.h"
 
 #include <string.h> // memcpy
+#include <assert.h>
 
-#include "frescan_data.h"    // the_networks
-#include "frescan_debug.h"   // DEBUG, ERROR
+#include "frescan_data.h"    // frescan_data
+#include "frescan_debug.h"   // DEBUG, FRESCAN_ERROR
 #include "frescan_servers.h" // frescan_servers_get_highest_prio
 #include "frescan_queues.h"  // frescan_pqueue_xxx, frescan_servers_dequeue
 #include "frescan_id.h"      // frescan_id_set_field
  * buffer of the chip. It is useful to prevent priority inversion when there
  * is another packet with highest priority waiting in the frescan queues.
  *
- * TODO: implement it
+ * NOTE: if the frame is already being transmitted it won't abort it. In both
+ * cases a IRQ will be raised and either 'frescan_hook_frame_sent' or
+ * 'frescan_hook_frame_aborted' will be called.
  */
 
 int frescan_hw_buffer_abort(frescan_network_t net)
 {
-//         int ret;
-//
-//         ret = ioctl(the_networks[net].fd,
-//                     CAN_IOCTL_ABORT_FRAME, NULL);
-//         if (ret == -1) {
-//                 ERROR ("could not abort the frame\n");
-//                 return -1;
-//         }
-        ERROR ("NOT IMPLEMENTED\n");
-        return -1;
+        int ret;
+
+        ret = ioctl(frescan_data[net].fd, CAN_IOCTL_ABORT_FRAME, NULL);
+        if (ret == -1) {
+                FRESCAN_ERROR ("could not abort the frame\n");
+                return -1;
+        }
+
+        return 0;
 }
 
 /**
@@ -77,12 +125,12 @@ int frescan_hw_buffer_update(frescan_network_t net)
         frescan_ss_t id;
 
         ret = frescan_servers_get_highest_prio(net, &id, &sprio);
-        if (ret != 0) return ret;
+        assert(ret == 0);
 
-        pqueue = the_networks[net].queues.tx_fp_queue;
+        pqueue = frescan_data[net].queues.tx_fp_queue;
 
         ret = frescan_pqueue_get_highest_prio(pqueue, &packet, &fprio);
-        if (ret != 0) return ret;
+        assert(ret == 0);
 
         if ((id == FRESCAN_MX_IDS) && (packet == NULL)) {
                 DEBUG(FRESCAN_HW_BUFFER_ENABLE_DEBUG, "(ss:0 fp:0)\n");
@@ -105,25 +153,28 @@ int frescan_hw_buffer_update(frescan_network_t net)
         }
 
         prio = (is_fp_highest_prio) ? fprio : sprio;
-        is_frame_in_chip = (the_networks[net].last_packet != NULL);
-
-        if (is_frame_in_chip &&
-           (prio > the_networks[net].last_packet_prio)) {
-                DEBUG(FRESCAN_HW_BUFFER_ENABLE_DEBUG,"abort frame\n");
-                ret = frescan_hw_buffer_abort(net);
-                if (ret != 0) {
-                        ERROR ("could not abort frame\n");
-                        return ret;
+        is_frame_in_chip = (frescan_data[net].last_packet != NULL);
+
+        if (is_frame_in_chip) {
+                if (prio > frescan_data[net].last_packet_prio) {
+                        // TODO: if same server, dont abort
+                        DEBUG(FRESCAN_HW_BUFFER_ENABLE_DEBUG, "abort frame\n");
+                        ret = frescan_hw_buffer_abort(net);
+                        assert(ret == 0);
+                        return 0;
+                } else {
+                        DEBUG(FRESCAN_HW_BUFFER_ENABLE_DEBUG,
+                              "frame in chip with highest or equal prio\n");
+                        return 0;
                 }
-                return 0;
         }
 
         if (is_fp_highest_prio) {
                 ret = frescan_pqueue_dequeue(pqueue, &packet, &prio, 0);
-                if (ret != 0) return ret;
+                assert(ret == 0);
         } else {
                 ret = frescan_servers_dequeue(net, id, &packet, &prio);
-                if (ret != 0) return ret;
+                assert(ret == 0);
 
                 frescan_id_set_field(&packet->frame->id,
                                       FRESCAN_FIELD_PRIO,
@@ -147,8 +198,8 @@ int frescan_hw_buffer_update(frescan_network_t net)
         frescan_id_set_field
                         (&packet->frame->id, FRESCAN_FIELD_FRAG_FLAG, frag_flag);
 
-        the_networks[net].last_packet = packet;
-        the_networks[net].last_packet_prio = prio;
+        frescan_data[net].last_packet = packet;
+        frescan_data[net].last_packet_prio = prio;
 
         DEBUG(FRESCAN_HW_BUFFER_ENABLE_DEBUG,
               "frame->id:0x%X pend_bytes:%u dlc:%u fflag:%u\n",
@@ -157,12 +208,12 @@ int frescan_hw_buffer_update(frescan_network_t net)
               packet->frame->dlc,
               frag_flag);
 
-        ret = write(the_networks[net].fd,
+        ret = write(frescan_data[net].fd,
                     (void *)packet->frame,
                     sizeof(struct can_frame_t));
 
         if (ret != sizeof(struct can_frame_t)) {
-                ERROR ("could not send frame\n");
+                FRESCAN_ERROR ("could not send frame\n");
                 return ret;
         }