# HG changeset patch # User Florian Pose # Date 1173446655 0 # Node ID 78929d878b2c6a2ace4577015dd6e90b0be17ef6 # Parent 3ed80c8ed6169a1a51fe6c325b84e78f8baa9680 Removed X:Y addressing scheme, ec_slave_is_coupler(), ec_master_calc_addressing(), coupler_index and coupler_subindex variables. Adapted lsec script and examples. diff -r 3ed80c8ed616 -r 78929d878b2c NEWS --- a/NEWS Fri Mar 09 13:16:12 2007 +0000 +++ b/NEWS Fri Mar 09 13:24:15 2007 +0000 @@ -23,6 +23,7 @@ a prior call to ecrt_master_get_slave(). - ecrt_master_get_slave() got additional parameters to check for vendor ID and product code. + - Removed addressing scheme "X:Y" for ecrt_master_get_slave(). - Added ecrt_master_get_status() to get information about the bus. - Added functions to set up an alternative PDO mapping, i. e. ec_slave_pdo_mapping_clear(), ec_slave_pdo_mapping_add() and diff -r 3ed80c8ed616 -r 78929d878b2c TODO --- a/TODO Fri Mar 09 13:16:12 2007 +0000 +++ b/TODO Fri Mar 09 13:24:15 2007 +0000 @@ -7,8 +7,6 @@ ------------------------------------------------------------------------------- * Release 1.3: - - Remove addressing scheme "X:Y". - - Remove ugly ec_slave_is_coupler(). - Dynamic creation of EoE handlers. * Future features: diff -r 3ed80c8ed616 -r 78929d878b2c examples/mini/mini.c --- a/examples/mini/mini.c Fri Mar 09 13:16:12 2007 +0000 +++ b/examples/mini/mini.c Fri Mar 09 13:24:15 2007 +0000 @@ -67,11 +67,11 @@ static void *r_freq; #if 1 -ec_pdo_reg_t domain1_pdo_regs[] = { - {"2", Beckhoff_EL2004_Outputs, &r_dig_out}, - {"3", Beckhoff_EL4132_Output1, &r_ana_out}, - {"4", Beckhoff_EL5101_Value, &r_count}, - {"4", Beckhoff_EL5101_Frequency, &r_freq}, +const static ec_pdo_reg_t domain1_pdo_regs[] = { + {"2", Beckhoff_EL2004_Outputs, &r_dig_out}, + {"3", Beckhoff_EL4132_Output1, &r_ana_out}, + {"#888:1", Beckhoff_EL5101_Value, &r_count}, + {"4", Beckhoff_EL5101_Frequency, &r_freq}, {} }; #endif @@ -105,7 +105,7 @@ spin_unlock(&master_lock); if (master_status.bus_status != old_status.bus_status) { - printk(KERN_INFO PFX "bus status changed to %u.\n", + printk(KERN_INFO PFX "bus status changed to %i.\n", master_status.bus_status); } if (master_status.bus_tainted != old_status.bus_tainted) { diff -r 3ed80c8ed616 -r 78929d878b2c examples/rtai/rtai_sample.c --- a/examples/rtai/rtai_sample.c Fri Mar 09 13:16:12 2007 +0000 +++ b/examples/rtai/rtai_sample.c Fri Mar 09 13:24:15 2007 +0000 @@ -47,27 +47,36 @@ /*****************************************************************************/ // RTAI task frequency in Hz -#define FREQUENCY 4000 +#define FREQUENCY 2000 #define INHIBIT_TIME 20 #define TIMERTICKS (1000000000 / FREQUENCY) +#define PFX "ec_rtai_sample: " + /*****************************************************************************/ // RTAI -RT_TASK task; -SEM master_sem; -cycles_t t_last_cycle = 0, t_critical; +static RT_TASK task; +static SEM master_sem; +static cycles_t t_last_cycle = 0, t_critical; // EtherCAT -ec_master_t *master = NULL; -ec_domain_t *domain1 = NULL; +static ec_master_t *master = NULL; +static ec_domain_t *domain1 = NULL; +static ec_master_status_t master_status, old_status = {}; // data fields -void *r_dig_out; - -ec_pdo_reg_t domain1_pdos[] = { - {"2", Beckhoff_EL2004_Outputs, &r_dig_out}, +static void *r_dig_out; +static void *r_ana_out; +static void *r_count; +//static void *r_freq; + +const static ec_pdo_reg_t domain1_pdo_regs[] = { + {"2", Beckhoff_EL2004_Outputs, &r_dig_out}, + {"3", Beckhoff_EL4132_Output1, &r_ana_out}, + {"#888:1", Beckhoff_EL5101_Value, &r_count}, + //{"4", Beckhoff_EL5101_Frequency, &r_freq}, {} }; @@ -100,6 +109,26 @@ else { counter = FREQUENCY; blink = !blink; + + rt_sem_wait(&master_sem); + ecrt_master_get_status(master, &master_status); + rt_sem_signal(&master_sem); + + if (master_status.bus_status != old_status.bus_status) { + printk(KERN_INFO PFX "bus status changed to %i.\n", + master_status.bus_status); + } + if (master_status.bus_tainted != old_status.bus_tainted) { + printk(KERN_INFO PFX "tainted flag changed to %u.\n", + master_status.bus_tainted); + } + if (master_status.slaves_responding != + old_status.slaves_responding) { + printk(KERN_INFO PFX "slaves_responding changed to %u.\n", + master_status.slaves_responding); + } + + old_status = master_status; } rt_task_wait_period(); @@ -131,55 +160,55 @@ { RTIME tick_period, requested_ticks, now; - printk(KERN_INFO "=== Starting EtherCAT RTAI sample module... ===\n"); + printk(KERN_INFO PFX "Starting...\n"); rt_sem_init(&master_sem, 1); t_critical = cpu_khz * 1000 / FREQUENCY - cpu_khz * INHIBIT_TIME / 1000; if (!(master = ecrt_request_master(0))) { - printk(KERN_ERR "Requesting master 0 failed!\n"); + printk(KERN_ERR PFX "Requesting master 0 failed!\n"); goto out_return; } ecrt_master_callbacks(master, request_lock, release_lock, NULL); - printk(KERN_INFO "Creating domain...\n"); + printk(KERN_INFO PFX "Creating domain...\n"); if (!(domain1 = ecrt_master_create_domain(master))) { - printk(KERN_ERR "Domain creation failed!\n"); + printk(KERN_ERR PFX "Domain creation failed!\n"); goto out_release_master; } - printk(KERN_INFO "Registering PDOs...\n"); - if (ecrt_domain_register_pdo_list(domain1, domain1_pdos)) { - printk(KERN_ERR "PDO registration failed!\n"); + printk(KERN_INFO PFX "Registering PDOs...\n"); + if (ecrt_domain_register_pdo_list(domain1, domain1_pdo_regs)) { + printk(KERN_ERR PFX "PDO registration failed!\n"); goto out_release_master; } - printk(KERN_INFO "Activating master...\n"); + printk(KERN_INFO PFX "Activating master...\n"); if (ecrt_master_activate(master)) { - printk(KERN_ERR "Failed to activate master!\n"); + printk(KERN_ERR PFX "Failed to activate master!\n"); goto out_release_master; } - printk("Starting cyclic sample thread...\n"); + printk(KERN_INFO PFX "Starting cyclic sample thread...\n"); requested_ticks = nano2count(TIMERTICKS); tick_period = start_rt_timer(requested_ticks); - printk(KERN_INFO "RT timer started with %i/%i ticks.\n", + printk(KERN_INFO PFX "RT timer started with %i/%i ticks.\n", (int) tick_period, (int) requested_ticks); if (rt_task_init(&task, run, 0, 2000, 0, 1, NULL)) { - printk(KERN_ERR "Failed to init RTAI task!\n"); + printk(KERN_ERR PFX "Failed to init RTAI task!\n"); goto out_stop_timer; } now = rt_get_time(); if (rt_task_make_periodic(&task, now + tick_period, tick_period)) { - printk(KERN_ERR "Failed to run RTAI task!\n"); + printk(KERN_ERR PFX "Failed to run RTAI task!\n"); goto out_stop_task; } - printk(KERN_INFO "=== EtherCAT RTAI sample module started. ===\n"); + printk(KERN_INFO PFX "Initialized.\n"); return 0; out_stop_task: @@ -197,14 +226,14 @@ void __exit cleanup_mod(void) { - printk(KERN_INFO "=== Stopping EtherCAT RTAI sample module... ===\n"); + printk(KERN_INFO PFX "Unloading...\n"); rt_task_delete(&task); stop_rt_timer(); ecrt_release_master(master); rt_sem_delete(&master_sem); - printk(KERN_INFO "=== EtherCAT RTAI sample module stopped. ===\n"); + printk(KERN_INFO PFX "Stopped.\n"); } /*****************************************************************************/ diff -r 3ed80c8ed616 -r 78929d878b2c master/fsm_master.c --- a/master/fsm_master.c Fri Mar 09 13:16:12 2007 +0000 +++ b/master/fsm_master.c Fri Mar 09 13:24:15 2007 +0000 @@ -705,12 +705,11 @@ EC_INFO("Bus scanning completed.\n"); - ec_master_calc_addressing(master); - // set initial states of all slaves to PREOP to make mailbox // communication possible list_for_each_entry(slave, &master->slaves, list) { - ec_slave_request_state(slave, EC_SLAVE_STATE_PREOP); + if (slave->requested_state == EC_SLAVE_STATE_UNKNOWN) + ec_slave_request_state(slave, EC_SLAVE_STATE_PREOP); } fsm->state = ec_fsm_master_state_end; diff -r 3ed80c8ed616 -r 78929d878b2c master/master.c --- a/master/master.c Fri Mar 09 13:16:12 2007 +0000 +++ b/master/master.c Fri Mar 09 13:24:15 2007 +0000 @@ -460,12 +460,7 @@ // set initial slave states list_for_each_entry(slave, &master->slaves, list) { - if (ec_slave_is_coupler(slave)) { - ec_slave_request_state(slave, EC_SLAVE_STATE_OP); - } - else { - ec_slave_request_state(slave, EC_SLAVE_STATE_PREOP); - } + ec_slave_request_state(slave, EC_SLAVE_STATE_PREOP); } master->eoe_checked = 0; // allow starting EoE again @@ -1262,38 +1257,6 @@ /*****************************************************************************/ /** - Calculates Advanced Position Adresses. -*/ - -void ec_master_calc_addressing(ec_master_t *master /**< EtherCAT master */) -{ - uint16_t coupler_index, coupler_subindex; - uint16_t reverse_coupler_index, current_coupler_index; - ec_slave_t *slave; - - coupler_index = 0; - reverse_coupler_index = 0xFFFF; - current_coupler_index = 0x0000; - coupler_subindex = 0; - - list_for_each_entry(slave, &master->slaves, list) { - if (ec_slave_is_coupler(slave)) { - if (slave->sii_alias) - current_coupler_index = reverse_coupler_index--; - else - current_coupler_index = coupler_index++; - coupler_subindex = 0; - } - - slave->coupler_index = current_coupler_index; - slave->coupler_subindex = coupler_subindex; - coupler_subindex++; - } -} - -/*****************************************************************************/ - -/** Measures the time, a frame is on the bus. \return 0 in case of success, else < 0 */ @@ -1406,95 +1369,72 @@ unsigned long first, second; char *remainder, *remainder2; const char *original; - unsigned int alias_requested, alias_found; + unsigned int alias_requested = 0, alias_not_found = 1; ec_slave_t *alias_slave = NULL, *slave; original = address; - if (!address || address[0] == 0) return NULL; - - alias_requested = 0; + if (!address[0]) + goto out_invalid; + if (address[0] == '#') { alias_requested = 1; address++; } first = simple_strtoul(address, &remainder, 0); - if (remainder == address) { - EC_ERR("Slave address \"%s\" - First number empty!\n", original); - return NULL; - } + if (remainder == address) + goto out_invalid; if (alias_requested) { - alias_found = 0; list_for_each_entry(alias_slave, &master->slaves, list) { if (alias_slave->sii_alias == first) { - alias_found = 1; + alias_not_found = 0; break; } } - if (!alias_found) { - EC_ERR("Slave address \"%s\" - Alias not found!\n", original); - return NULL; - } - } - - if (!remainder[0]) { // absolute position - if (alias_requested) { + if (alias_not_found) { + EC_ERR("Alias not found!\n"); + goto out_invalid; + } + } + + if (!remainder[0]) { + if (alias_requested) { // alias addressing return alias_slave; } - else { + else { // position addressing list_for_each_entry(slave, &master->slaves, list) { if (slave->ring_position == first) return slave; } - EC_ERR("Slave address \"%s\" - Absolute position invalid!\n", - original); - } - } - else if (remainder[0] == ':') { // field position + EC_ERR("Slave index out of range!\n"); + goto out_invalid; + } + } + else if (alias_requested && remainder[0] == ':') { // field addressing + struct list_head *list; remainder++; second = simple_strtoul(remainder, &remainder2, 0); - if (remainder2 == remainder) { - EC_ERR("Slave address \"%s\" - Second number empty!\n", original); - return NULL; - } - - if (remainder2[0]) { - EC_ERR("Slave address \"%s\" - Invalid trailer!\n", original); - return NULL; - } - - if (alias_requested) { - if (!ec_slave_is_coupler(alias_slave)) { - EC_ERR("Slave address \"%s\": Alias slave must be bus coupler" - " in colon mode.\n", original); - return NULL; + if (remainder2 == remainder || remainder2[0]) + goto out_invalid; + + list = &alias_slave->list; + while (second--) { + list = list->next; + if (list == &master->slaves) { // last slave exceeded + EC_ERR("Slave index out of range!\n"); + goto out_invalid; } - list_for_each_entry(slave, &master->slaves, list) { - if (slave->coupler_index == alias_slave->coupler_index - && slave->coupler_subindex == second) - return slave; - } - EC_ERR("Slave address \"%s\" - Bus coupler %i has no %lu. slave" - " following!\n", original, alias_slave->ring_position, - second); - return NULL; - } - else { - list_for_each_entry(slave, &master->slaves, list) { - if (slave->coupler_index == first - && slave->coupler_subindex == second) return slave; - } - } - } - else - EC_ERR("Slave address \"%s\" - Invalid format!\n", original); - + } + return list_entry(list, ec_slave_t, list); + } + +out_invalid: + EC_ERR("Invalid slave address string \"%s\"!\n", original); return NULL; } - /****************************************************************************** * Realtime interface *****************************************************************************/ diff -r 3ed80c8ed616 -r 78929d878b2c master/master.h --- a/master/master.h Fri Mar 09 13:16:12 2007 +0000 +++ b/master/master.h Fri Mar 09 13:24:15 2007 +0000 @@ -182,7 +182,6 @@ // misc. void ec_master_output_stats(ec_master_t *); void ec_master_destroy_slaves(ec_master_t *); -void ec_master_calc_addressing(ec_master_t *); /*****************************************************************************/ diff -r 3ed80c8ed616 -r 78929d878b2c master/slave.c --- a/master/slave.c Fri Mar 09 13:16:12 2007 +0000 +++ b/master/slave.c Fri Mar 09 13:24:15 2007 +0000 @@ -121,9 +121,6 @@ slave->fmmu_count = 0; slave->pdos_registered = 0; - slave->coupler_index = 0; - slave->coupler_subindex = 0xFFFF; - slave->base_type = 0; slave->base_revision = 0; slave->base_build = 0; @@ -699,10 +696,6 @@ slave->error_flag ? "ERROR" : "ok"); off += sprintf(buffer + off, "Ring position: %i\n", slave->ring_position); - off += sprintf(buffer + off, "Advanced position: %i:%i\n", - slave->coupler_index, slave->coupler_subindex); - off += sprintf(buffer + off, "Coupler: %s\n", - ec_slave_is_coupler(slave) ? "yes" : "no"); off += sprintf(buffer + off, "Current consumption: %i mA\n\n", slave->sii_current_on_ebus); @@ -1128,19 +1121,6 @@ /*****************************************************************************/ /** - \return non-zero if slave is a bus coupler -*/ - -int ec_slave_is_coupler(const ec_slave_t *slave /**< EtherCAT slave */) -{ - // TODO: Better bus coupler criterion - return slave->sii_vendor_id == 0x00000002 - && slave->sii_product_code == 0x044C2C52; -} - -/*****************************************************************************/ - -/** \return 0 in case of success, else < 0 */ @@ -1192,9 +1172,10 @@ { if (vendor_id != slave->sii_vendor_id || product_code != slave->sii_product_code) { - EC_ERR("Invalid slave type at position %i - Requested: 0x%08X 0x%08X," - " found: 0x%08X 0x%08X\".\n", slave->ring_position, vendor_id, - product_code, slave->sii_vendor_id, slave->sii_product_code); + EC_ERR("Invalid slave type at position %i:\n", slave->ring_position); + EC_ERR(" Requested: 0x%08X 0x%08X\n", vendor_id, product_code); + EC_ERR(" Found: 0x%08X 0x%08X\n", + slave->sii_vendor_id, slave->sii_product_code); return -1; } return 0; diff -r 3ed80c8ed616 -r 78929d878b2c master/slave.h --- a/master/slave.h Fri Mar 09 13:16:12 2007 +0000 +++ b/master/slave.h Fri Mar 09 13:24:15 2007 +0000 @@ -129,8 +129,6 @@ // addresses uint16_t ring_position; /**< ring position */ uint16_t station_address; /**< configured station address */ - uint16_t coupler_index; /**< index of the last bus coupler */ - uint16_t coupler_subindex; /**< index of this slave after last coupler */ // base data uint8_t base_type; /**< slave type */ @@ -204,7 +202,6 @@ // misc. ec_sync_t *ec_slave_get_pdo_sync(ec_slave_t *, ec_direction_t); -int ec_slave_is_coupler(const ec_slave_t *); int ec_slave_validate(const ec_slave_t *, uint32_t, uint32_t); void ec_slave_sdo_dict_info(const ec_slave_t *, unsigned int *, unsigned int *); diff -r 3ed80c8ed616 -r 78929d878b2c script/lsec --- a/script/lsec Fri Mar 09 13:16:12 2007 +0000 +++ b/script/lsec Fri Mar 09 13:24:15 2007 +0000 @@ -60,109 +60,115 @@ my $master_dir; my $dirhandle; my $entry; + my $slave_info_file; my @slaves; my $slave; my $abs; my $line; - my $ring_cols; - my $adv_cols; + my $ring_col_width; + my $alias_col_width; my $fmt; - my $cols; + my $width; + my $last_alias; + my $alias_index; $master_dir = "/sys/ethercat/master" . $master_index; unless (opendir $dirhandle, $master_dir) { - print "Failed to open directory \"$master_dir\".\n"; - exit 1; + print "Failed to open directory \"$master_dir\".\n"; + exit 1; } while ($entry = readdir $dirhandle) { next unless $entry =~ /^slave(\d+)$/; - $slave = {}; - - open INFO, "$master_dir/$entry/info" or die - "ERROR: Failed to open $master_dir/$entry/info"; - - while ($line = ) { - if ($line =~ /^Name: (.*)$/) { - $slave->{'name'} = $1; - } - elsif ($line =~ /^Ring position: (\d+)$/) { - $slave->{'ring_position'} = $1; - } - elsif ($line =~ /^Advanced position: (\d+:\d+)$/) { - $slave->{'advanced_position'} = $1; - } - elsif ($line =~ /^State: (.+) /) { - $slave->{'state'} = $1; - } - elsif ($line =~ /^Coupler: ([a-z]+)$/) { - $slave->{'coupler'} = $1; - } - elsif ($line =~ /^Current consumption: (-?\d+) mA$/) { - $slave->{'current'} = $1; - } - } - - close INFO; - - push @slaves, $slave; + $slave = {}; + $slave_info_file = "$master_dir/$entry/info"; + open INFO, $slave_info_file or die + "ERROR: Failed to open $slave_info_file."; + + while ($line = ) { + if ($line =~ /^Name: (.*)$/) { + $slave->{'name'} = $1; + } + elsif ($line =~ /^Ring position: (\d+)$/) { + $slave->{'ring_position'} = $1; + } + elsif ($line =~ /Configured station alias: .* \((\d+)\)$/) { + $slave->{'alias'} = $1; + } + elsif ($line =~ /^State: (.+) /) { + $slave->{'state'} = $1; + } + elsif ($line =~ /^Current consumption: (-?\d+) mA$/) { + $slave->{'current'} = $1; + } + } + + close INFO; + push @slaves, $slave; } closedir $dirhandle; @slaves = sort { $a->{'ring_position'} <=> $b->{'ring_position'} } @slaves; - $ring_cols = 0; - $adv_cols = 0; + # create field addresses and calculate column widths + $ring_col_width = 0; + $alias_col_width = 0; + $last_alias = ""; for $slave (@slaves) { - $cols = length $slave->{'ring_position'}; - $ring_cols = $cols if ($cols > $ring_cols); - $cols = length $slave->{'advanced_position'}; - $adv_cols = $cols if ($cols > $adv_cols); + if ($slave->{'alias'}) { + $last_alias = $slave->{'alias'}; + $alias_index = 0; + } + if ($last_alias) { + $slave->{'field_address'} = "#" . $last_alias . ":" . $alias_index; + $width = length $slave->{'field_address'}; + $alias_col_width = $width if ($width > $alias_col_width); + } + $width = length $slave->{'ring_position'}; + $ring_col_width = $width if ($width > $ring_col_width); + $alias_index++; } if (defined $opt{'c'}) { # display power consumtion - $fmt = sprintf " %%%is %%-%is %%6i %%6i %%s\n", - $ring_cols, $adv_cols; - - my $current_sum = 0; - for $slave (@slaves) { - if ($slave->{'coupler'} eq "yes") { - &print_line if !defined $opt{n}; - $current_sum = 0; # reset current sum - } - $current_sum -= $slave->{'current'}; - printf($fmt, $slave->{'ring_position'}, - $slave->{'advanced_position'}, $slave->{'current'}, - $current_sum, $slave->{'name'}); - } + $fmt = sprintf " %%%is %%%is %%6i %%6i %%s\n", + $ring_col_width, $alias_col_width; + + my $current_sum = 0; + for $slave (@slaves) { + &print_line if $slave->{'alias'} and !defined $opt{n}; + $current_sum = 0 if $slave->{'current'} < 0; + $current_sum -= $slave->{'current'}; + printf($fmt, $slave->{'ring_position'}, $slave->{'field_address'}, + $slave->{'current'}, $current_sum, $slave->{'name'}); + } + } + else { # normal display + $fmt = sprintf " %%%is %%%is %%-6s %%s\n", + $ring_col_width, $alias_col_width; + + for $slave (@slaves) { + &print_line if $slave->{'alias'} and !defined $opt{n}; + printf($fmt, $slave->{'ring_position'}, $slave->{'field_address'}, + $slave->{'state'}, $slave->{'name'}); + } + } +} + +#------------------------------------------------------------------------------ + +sub get_options +{ + my $optret = getopts "m:cnh", \%opt; + + &print_usage if defined $opt{h} or $#ARGV > -1 or !$optret; + + if (defined $opt{m}) { + $master_index = $opt{m}; } else { - $fmt = sprintf " %%%is %%-%is %%-6s %%s\n", $ring_cols, $adv_cols; - - for $slave (@slaves) { - &print_line if $slave->{'coupler'} eq "yes" and !defined $opt{n}; - printf($fmt, $slave->{'ring_position'}, - $slave->{'advanced_position'}, $slave->{'state'}, - $slave->{'name'}); - } - } -} - -#------------------------------------------------------------------------------ - -sub get_options -{ - my $optret = getopts "m:cnh", \%opt; - - &print_usage if defined $opt{h} or $#ARGV > -1 or !$optret; - - if (defined $opt{m}) { - $master_index = $opt{m}; - } - else { - $master_index = 0; + $master_index = 0; } } @@ -189,7 +195,7 @@ die "no TIOCGWINSZ " unless defined &TIOCGWINSZ; open(TTY, "+