From e9c68fda2965f46855b237f6f7c603664721ee8c Mon Sep 17 00:00:00 2001 From: Florian Pose Date: Mon, 27 Mar 2006 09:53:59 +0000 Subject: [PATCH] Watch-Kommando --- master/master.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++-- master/master.h | 3 ++ mini/mini.c | 17 ++++++------ todo.txt | 6 +++- 4 files changed, 87 insertions(+), 12 deletions(-) diff --git a/master/master.c b/master/master.c index 8a175768..25aae5fd 100644 --- a/master/master.c +++ b/master/master.c @@ -101,6 +101,10 @@ void ec_master_reset(ec_master_t *master master->command_index = 0; master->debug_level = 0; master->timeout = 100; // us + + master->slaves_responding = 0; + master->slave_states = EC_SLAVE_STATE_UNKNOWN; + master->stats.timeouts = 0; master->stats.delayed = 0; master->stats.corrupted = 0; @@ -389,7 +393,7 @@ int ec_master_simple_io(ec_master_t *master, /**< EtherCAT-Master */ } // Keine direkte Antwort. Dem Slave Zeit lassen... - udelay(10); + udelay(100); if (unlikely(--response_tries_left)) { EC_ERR("No response in simple-IO!\n"); @@ -679,6 +683,58 @@ void ec_fmmu_config(const ec_fmmu_t *fmmu, /**< Sync-Manager */ EC_WRITE_U16(data + 14, 0x0000); // res. } +/*****************************************************************************/ + +/** + Gibt Überwachungsinformationen aus. +*/ + +void ec_master_process_watch_command(ec_master_t *master + /**< EtherCAT-Master */ + ) +{ + unsigned int first; + + first = 1; + + if (master->watch_command.working_counter != master->slaves_responding || + master->watch_command.data[0] != master->slave_states) + { + master->slaves_responding = master->watch_command.working_counter; + master->slave_states = master->watch_command.data[0]; + + EC_INFO("%i slave%s responding (", master->slaves_responding, + master->slaves_responding == 1 ? "" : "s"); + + if (master->slave_states & EC_SLAVE_STATE_INIT) { + printk("INIT"); + first = 0; + } + if (master->slave_states & EC_SLAVE_STATE_PREOP) { + if (!first) { + printk(", "); + first = 0; + } + printk("PREOP"); + } + if (master->slave_states & EC_SLAVE_STATE_SAVEOP) { + if (!first) { + printk(", "); + first = 0; + } + printk("SAVEOP"); + } + if (master->slave_states & EC_SLAVE_STATE_OP) { + if (!first) { + printk(", "); + first = 0; + } + printk("OP"); + } + printk(")\n"); + } +} + /****************************************************************************** * * Echtzeitschnittstelle @@ -836,6 +892,9 @@ int ecrt_master_activate(ec_master_t *master /**< EtherCAT-Master */) return -1; } + master->slaves_responding = master->slave_count; + master->slave_states = EC_SLAVE_STATE_OP; + return 0; } @@ -952,6 +1011,10 @@ void ecrt_master_async_send(ec_master_t *master) return; } + // Watch-Kommando hinzufügen + ec_command_init_brd(&master->watch_command, 0x130, 2); + ec_master_queue_command(master, &master->watch_command); + // Rahmen senden ec_master_send_commands(master); } @@ -966,8 +1029,6 @@ void ecrt_master_async_receive(ec_master_t *master) { ec_command_t *command, *next; - ec_master_output_stats(master); - ec_device_call_isr(master->device); // Alle empfangenen Kommandos aus der Liste entfernen @@ -989,6 +1050,12 @@ void ecrt_master_async_receive(ec_master_t *master) } list_del_init(&command->list); } + + // Watch-Kommando verarbeiten + ec_master_process_watch_command(master); + + // Statistiken ausgeben + ec_master_output_stats(master); } /*****************************************************************************/ diff --git a/master/master.h b/master/master.h index 0af61143..284343b7 100644 --- a/master/master.h +++ b/master/master.h @@ -50,6 +50,9 @@ struct ec_master struct list_head commands; /**< Kommando-Liste */ uint8_t command_index; /**< Aktueller Kommando-Index */ struct list_head domains; /**< Liste der Prozessdatendomänen */ + ec_command_t watch_command; /**< Kommando zum Überwachen der Slaves */ + unsigned int slaves_responding; /**< Anzahl antwortender Slaves */ + ec_slave_state_t slave_states; /**< Zustände der antwortenden Slaves */ int debug_level; /**< Debug-Level im Master-Code */ ec_stats_t stats; /**< Rahmen-Statistiken */ unsigned int timeout; /**< Timeout für synchronen Datenaustausch */ diff --git a/mini/mini.c b/mini/mini.c index 1fa40627..43f84a4c 100644 --- a/mini/mini.c +++ b/mini/mini.c @@ -29,7 +29,7 @@ ec_master_t *master = NULL; ec_domain_t *domain1 = NULL; // Datenfelder -void *r_ssi_input, *r_ssi_status, *r_4102[3]; +//void *r_ssi_input, *r_ssi_status, *r_4102[3]; // Kanäle uint32_t k_pos; @@ -37,13 +37,10 @@ uint8_t k_stat; ec_field_init_t domain1_fields[] = { {NULL, "1", "Beckhoff", "EL1014", "InputValue", 0}, - {NULL, "2", "Beckhoff", "EL1014", "InputValue", 0}, - {NULL, "3", "Beckhoff", "EL1014", "InputValue", 0}, - {NULL, "4", "Beckhoff", "EL1014", "InputValue", 0}, - {NULL, "5", "Beckhoff", "EL1014", "InputValue", 0}, - {NULL, "6", "Beckhoff", "EL2004", "OutputValue", 0}, - {NULL, "7", "Beckhoff", "EL2004", "OutputValue", 0}, - {NULL, "8", "Beckhoff", "EL2004", "OutputValue", 0}, + {NULL, "2", "Beckhoff", "EL2004", "OutputValue", 0}, + //{NULL, "3", "Beckhoff", "EL3162", "InputValue", 0}, + {NULL, "4", "Beckhoff", "EL4132", "OutputValue", 0}, + {NULL, "6", "Beckhoff", "EL5001", "InputValue", 0}, {} }; @@ -127,6 +124,7 @@ int __init init_mini_module(void) //ecrt_master_debug(master, 2); +#if 0 if (ecrt_master_sdo_write(master, "1", 0x4061, 1, 0, 1) || ecrt_master_sdo_write(master, "1", 0x4061, 2, 1, 1) || ecrt_master_sdo_write(master, "1", 0x4061, 3, 1, 1) || @@ -139,6 +137,7 @@ int __init init_mini_module(void) printk(KERN_ERR "EtherCAT: Failed to configure SSI!\n"); goto out_deactivate; } +#endif //ecrt_master_debug(master, 0); @@ -166,8 +165,10 @@ int __init init_mini_module(void) return 0; +#if 0 out_deactivate: ecrt_master_deactivate(master); +#endif out_release_master: ecrt_release_master(master); diff --git a/todo.txt b/todo.txt index 0af89320..6b70f9b5 100644 --- a/todo.txt +++ b/todo.txt @@ -3,12 +3,16 @@ TODO-Liste EtherCAT-Treiber $Id$ -- Zyklisches Kommando: BRD auf 0x130 für Status und Anzahl Klemmen - Anzahl Frames, die die Karte Puffern kann +- Mehrere Frames versenden +- Kommandos mit dynamischem Speicher +- Konfiguration Inkrementalgeberklemme +- SSI-Klemme - SysFS-Interface implementieren - SDO Dictionary der Slaves auslesen und im SysFS darstellen - Typeninformation aus Master entfernen / XML-Dateien aus User-Space lesen - DLL-Link-States auslesen und Topologie berechnen - Ethernet over EtherCAT (EoE) - eepro100-Kartentreiber +- Installationsanleitung / Dokumentation - Userspace-Tool zum Konfigurieren und visualisieren