# HG changeset patch # User Florian Pose # Date 1136553629 0 # Node ID ad5f969f263bf52d3fc8939f8be44179bddf8b1b # Parent f2d7a73d2f32b63afbda9aabfd36e4c3ffabc1da Prozessdatentimeout, Buszeit und weniger Klemmen. diff -r f2d7a73d2f32 -r ad5f969f263b drivers/ec_master.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; } diff -r f2d7a73d2f32 -r ad5f969f263b drivers/ec_master.h --- 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 *); diff -r f2d7a73d2f32 -r ad5f969f263b mini/ec_mini.c --- 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; diff -r f2d7a73d2f32 -r ad5f969f263b rt/msr_module.c --- 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; }