Prozessdatentimeout, Buszeit und weniger Klemmen.
authorFlorian Pose <fp@igh-essen.com>
Fri, 06 Jan 2006 13:20:29 +0000
changeset 47 ad5f969f263b
parent 46 f2d7a73d2f32
child 48 7e75772ea28c
Prozessdatentimeout, Buszeit und weniger Klemmen.
drivers/ec_master.c
drivers/ec_master.h
mini/ec_mini.c
rt/msr_module.c
--- a/drivers/ec_master.c	Fri Jan 06 10:17:35 2006 +0000
+++ b/drivers/ec_master.c	Fri Jan 06 13:20:29 2006 +0000
@@ -33,9 +33,7 @@
   master->rx_data_length = 0;
   master->domain_count = 0;
   master->debug_level = 0;
-  master->tx_time = 0;
-  master->rx_time = 0;
-  master->rx_tries = 0;
+  master->bus_time = 0;
 }
 
 /*****************************************************************************/
@@ -250,9 +248,6 @@
     printk(KERN_DEBUG "device send...\n");
   }
 
-  // Zeit nehmen
-  rdtscl(master->tx_time);
-
   // Send frame
   if (unlikely(EtherCAT_device_send(master->dev,
                                     master->tx_data,
@@ -995,18 +990,21 @@
 /**
    Sendet und empfängt Prozessdaten der angegebenen Domäne
 
-   @param master EtherCAT-Master
-          domain Domäne
+   @param master     EtherCAT-Master
+          domain     Domäne
+          timeout_us Timeout in Mikrosekunden
 
    @return 0 bei Erfolg, sonst < 0
 */
 
-int EtherCAT_process_data_cycle(EtherCAT_master_t *master,
-                                unsigned int domain)
-{
-  unsigned int i, tries;
-  EtherCAT_domain_t *dom = NULL;
-
+int EtherCAT_process_data_cycle(EtherCAT_master_t *master, unsigned int domain,
+                                unsigned int timeout_us)
+{
+  unsigned int i;
+  EtherCAT_domain_t *dom;
+  unsigned long start_ticks, end_ticks, timeout_ticks;
+
+  dom = NULL;
   for (i = 0; i < master->domain_count; i++) {
     if (master->domains[i].number == domain) {
       dom = master->domains + i;
@@ -1023,27 +1021,26 @@
                                       dom->logical_offset, dom->data_size,
                                       dom->data);
 
+  rdtscl(start_ticks); // Sendezeit nehmen
+
   if (unlikely(EtherCAT_simple_send(master, &dom->command) < 0)) {
     printk(KERN_ERR "EtherCAT: Could not send process data command!\n");
     return -1;
   }
 
-  udelay(3);
-
-#if 1
+  timeout_ticks = timeout_us * cpu_khz / 1000;
+
   // Warten
-  tries = 0;
-  EtherCAT_device_call_isr(master->dev);
-  while (unlikely(master->dev->state == ECAT_DS_SENT && tries < 100)) {
-    udelay(1);
+  do {
     EtherCAT_device_call_isr(master->dev);
-    tries++;
-  }
-
-  rdtscl(master->rx_time);
-  master->rx_tries = tries;
-
-  if (unlikely(tries == 100)) {
+    rdtscl(end_ticks); // Empfangszeit nehmen
+  }
+  while (unlikely(master->dev->state == ECAT_DS_SENT
+                  && end_ticks - start_ticks < timeout_ticks));
+
+  master->bus_time = (end_ticks - start_ticks) * 1000 / cpu_khz;
+
+  if (unlikely(end_ticks - start_ticks >= timeout_ticks)) {
     printk(KERN_ERR "EtherCAT: Timeout while receiving process data!\n");
     return -1;
   }
@@ -1060,7 +1057,6 @@
 
   // Daten vom Kommando in den Prozessdatenspeicher kopieren
   memcpy(dom->data, dom->command.data, dom->data_size);
-#endif
 
   return 0;
 }
--- a/drivers/ec_master.h	Fri Jan 06 10:17:35 2006 +0000
+++ b/drivers/ec_master.h	Fri Jan 06 13:20:29 2006 +0000
@@ -39,9 +39,7 @@
   EtherCAT_domain_t domains[ECAT_MAX_DOMAINS]; /** Prozessdatendomänen */
   unsigned int domain_count;
   int debug_level; /**< Debug-Level im Master-Code */
-  unsigned long tx_time; /**< Zeit des letzten Sendens */
-  unsigned long rx_time; /**< Zeit des letzten Empfangs */
-  unsigned int rx_tries; /**< Anzahl Warteschleifen beim letzen Enpfang */
+  unsigned int bus_time; /**< Letzte Bus-Zeit in Mikrosekunden */
 };
 
 /*****************************************************************************/
@@ -70,7 +68,8 @@
                           unsigned char);
 
 // Process data
-int EtherCAT_process_data_cycle(EtherCAT_master_t *, unsigned int);
+int EtherCAT_process_data_cycle(EtherCAT_master_t *, unsigned int,
+                                unsigned int);
 
 // Private functions
 void output_debug_data(const EtherCAT_master_t *);
--- a/mini/ec_mini.c	Fri Jan 06 10:17:35 2006 +0000
+++ b/mini/ec_mini.c	Fri Jan 06 13:20:29 2006 +0000
@@ -173,7 +173,7 @@
 
     // Prozessdaten lesen und schreiben
     rdtscl(k);
-    EtherCAT_process_data_cycle(ecat_master, 1);
+    EtherCAT_process_data_cycle(ecat_master, 1, 100);
     firstrun = 0;
 
     timer.expires += HZ / 1000;
--- a/rt/msr_module.c	Fri Jan 06 10:17:35 2006 +0000
+++ b/rt/msr_module.c	Fri Jan 06 13:20:29 2006 +0000
@@ -3,9 +3,8 @@
  *  msr_module.c
  *
  *  Kernelmodul für 2.6 Kernel zur Meßdatenerfassung, Steuerung und Regelung.
- *  Zeitgeber ist der Timerinterrupt (tq)
- *
- *  Autor: Wilhelm Hagemeister
+ *
+ *  Autor: Wilhelm Hagemeister, Florian Pose
  *
  *  (C) Copyright IgH 2002
  *  Ingenieurgemeinschaft IgH
@@ -40,7 +39,7 @@
 
 // Defines/Makros
 #define TSC2US(T1, T2) ((T2 - T1) * 1000UL / cpu_khz)
-#define HZREDUCTION (MSR_ABTASTFREQUENZ/HZ)
+#define HZREDUCTION (MSR_ABTASTFREQUENZ / HZ)
 
 /*****************************************************************************/
 /* Globale Variablen */
@@ -56,11 +55,11 @@
 // EtherCAT
 
 static EtherCAT_master_t *ecat_master = NULL;
-static unsigned long ecat_bus_time = 0;
+static unsigned int ecat_bus_time = 0;
+static unsigned int ecat_timeouts = 0;
 
 static EtherCAT_slave_t ecat_slaves[] =
 {
-#if 1
     // Block 1
     ECAT_INIT_SLAVE(Beckhoff_EK1100, 0),
     ECAT_INIT_SLAVE(Beckhoff_EL4102, 0),
@@ -69,10 +68,6 @@
     ECAT_INIT_SLAVE(Beckhoff_EL2004, 0),
     ECAT_INIT_SLAVE(Beckhoff_EL3102, 0),
     ECAT_INIT_SLAVE(Beckhoff_EL2004, 0),
-    ECAT_INIT_SLAVE(Beckhoff_EL2004, 0),
-    ECAT_INIT_SLAVE(Beckhoff_EL2004, 0),
-    ECAT_INIT_SLAVE(Beckhoff_EL2004, 0),
-    ECAT_INIT_SLAVE(Beckhoff_EL2004, 0),
 
     // Block 2
     ECAT_INIT_SLAVE(Beckhoff_EK1100, 1),
@@ -88,24 +83,6 @@
     ECAT_INIT_SLAVE(Beckhoff_EL1014, 1),
     ECAT_INIT_SLAVE(Beckhoff_EL1014, 1),
     ECAT_INIT_SLAVE(Beckhoff_EL1014, 1)
-#endif
-
-#if 0
-    // Block 3
-   ,ECAT_INIT_SLAVE(Beckhoff_EK1100, 2),
-    ECAT_INIT_SLAVE(Beckhoff_EL3162, 2),
-    ECAT_INIT_SLAVE(Beckhoff_EL3162, 2),
-    ECAT_INIT_SLAVE(Beckhoff_EL3162, 2),
-    ECAT_INIT_SLAVE(Beckhoff_EL3162, 2),
-    ECAT_INIT_SLAVE(Beckhoff_EL3102, 2),
-    ECAT_INIT_SLAVE(Beckhoff_EL3102, 2),
-    ECAT_INIT_SLAVE(Beckhoff_EL3102, 2),
-    ECAT_INIT_SLAVE(Beckhoff_EL4102, 2),
-    ECAT_INIT_SLAVE(Beckhoff_EL4102, 2),
-    ECAT_INIT_SLAVE(Beckhoff_EL4102, 2),
-    ECAT_INIT_SLAVE(Beckhoff_EL4102, 2),
-    ECAT_INIT_SLAVE(Beckhoff_EL4132, 2)
-#endif
 };
 
 #define ECAT_SLAVES_COUNT (sizeof(ecat_slaves) / sizeof(EtherCAT_slave_t))
@@ -157,7 +134,6 @@
 {
     static int ms = 0;
     static int cnt = 0;
-    static unsigned long int k = 0;
     static int firstrun = 1;
 
     static int klemme = 0;
@@ -166,9 +142,9 @@
     int wrap = 0;
 
     static unsigned int debug_counter = 0;
-    unsigned long t1, t2, t3, t4, t5, t6, t7;
+    unsigned long t1, t2, t3;
+    unsigned int bustime1, bustime2;
     static unsigned long lt = 0;
-    unsigned int tr1, tr2;
 
     rdtscl(t1);
 
@@ -200,33 +176,21 @@
         EtherCAT_write_value(&ecat_slaves[klemme], kanal, up_down);
     }
 
-#if 0
-    EtherCAT_write_value(&ecat_master->slaves[13], 1, ms > 500 ? 0 : 1);
-    EtherCAT_write_value(&ecat_master->slaves[14], 2, ms > 500 ? 0 : 1);
-    EtherCAT_write_value(&ecat_master->slaves[15], 3, ms > 500 ? 1 : 0);
-#endif
-
     // Prozessdaten schreiben
-    rdtscl(k);
+
     rdtscl(t2);
 
-    EtherCAT_process_data_cycle(ecat_master, 0);
-
-    t3 = ecat_master->tx_time;
-    t4 = ecat_master->rx_time;
-    tr1 = ecat_master->rx_tries;
-
-    EtherCAT_process_data_cycle(ecat_master, 1);
-
-    t5 = ecat_master->tx_time;
-    t6 = ecat_master->rx_time;
-    tr2 = ecat_master->rx_tries;
-
-    //EtherCAT_process_data_cycle(ecat_master, 2);
-
-    rdtscl(t7);
-
-    ecat_bus_time = TSC2US(t2, t7);
+    if (EtherCAT_process_data_cycle(ecat_master, 0, 40) < 0)
+        ecat_timeouts++;
+    bustime1 = ecat_master->bus_time;
+
+    if (EtherCAT_process_data_cycle(ecat_master, 1, 40) < 0)
+        ecat_timeouts++;
+    bustime2 = ecat_master->bus_time;
+
+    rdtscl(t3);
+
+    ecat_bus_time = TSC2US(t2, t3);
 
     // Daten lesen und skalieren
 #ifdef USE_MSR_LIB
@@ -235,12 +199,8 @@
 #endif
 
     if (debug_counter == MSR_ABTASTFREQUENZ) {
-      printk(KERN_DEBUG "%lu: %luŽµs + %luŽµs + %luŽµs + %luŽµs + %luŽµs +"
-             " %luŽµs = %luŽµs (%u %u)\n",
-             TSC2US(lt, t1),
-             TSC2US(t1, t2), TSC2US(t2, t3), TSC2US(t3, t4),
-             TSC2US(t4, t5), TSC2US(t5, t6), TSC2US(t6, t7),
-             TSC2US(t1, t7), tr1, tr2);
+      printk(KERN_DEBUG "%lu: %luŽµs + %uŽµs + %uŽµs = %luŽµs\n", TSC2US(lt, t1),
+             TSC2US(t1, t2), bustime1, bustime2, TSC2US(t1, t3));
       debug_counter = 0;
     }
 
@@ -318,6 +278,7 @@
 #endif
 
     msr_reg_kanal("/Taskinfo/EtherCAT/BusTime", "us", &ecat_bus_time, TUINT);
+    msr_reg_kanal("/Taskinfo/EtherCAT/Timeouts", "", &ecat_timeouts, TUINT);
 
     return 0;
 }