Removed X:Y addressing scheme, ec_slave_is_coupler(),
ec_master_calc_addressing(), coupler_index and coupler_subindex variables. Adapted lsec script and examples.
This commit is contained in:
parent
81524176a8
commit
b0c1fbaeb0
1
NEWS
1
NEWS
|
|
@ -23,6 +23,7 @@ Changes in version 1.3.0:
|
|||
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
|
||||
|
|
|
|||
2
TODO
2
TODO
|
|
@ -7,8 +7,6 @@ $Id$
|
|||
-------------------------------------------------------------------------------
|
||||
|
||||
* Release 1.3:
|
||||
- Remove addressing scheme "X:Y".
|
||||
- Remove ugly ec_slave_is_coupler().
|
||||
- Dynamic creation of EoE handlers.
|
||||
|
||||
* Future features:
|
||||
|
|
|
|||
|
|
@ -67,11 +67,11 @@ static void *r_count;
|
|||
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 @@ void run(unsigned long data)
|
|||
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) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
static void *r_dig_out;
|
||||
static void *r_ana_out;
|
||||
static void *r_count;
|
||||
//static void *r_freq;
|
||||
|
||||
ec_pdo_reg_t domain1_pdos[] = {
|
||||
{"2", Beckhoff_EL2004_Outputs, &r_dig_out},
|
||||
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 @@ void run(long data)
|
|||
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 @@ int __init init_mod(void)
|
|||
{
|
||||
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 @@ int __init init_mod(void)
|
|||
|
||||
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");
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -705,12 +705,11 @@ void ec_fsm_master_state_scan_slaves(ec_fsm_master_t *fsm /**< master state mach
|
|||
|
||||
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;
|
||||
|
|
|
|||
116
master/master.c
116
master/master.c
|
|
@ -460,12 +460,7 @@ int ec_master_enter_operation_mode(ec_master_t *master /**< EtherCAT master */)
|
|||
|
||||
// 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
|
||||
|
|
@ -1261,38 +1256,6 @@ void ec_master_check_sdo(unsigned long data /**< master pointer */)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
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 @@ ec_slave_t *ec_master_parse_slave_address(
|
|||
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;
|
||||
if (!address[0])
|
||||
goto out_invalid;
|
||||
|
||||
alias_requested = 0;
|
||||
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 (alias_not_found) {
|
||||
EC_ERR("Alias not found!\n");
|
||||
goto out_invalid;
|
||||
}
|
||||
}
|
||||
|
||||
if (!remainder[0]) { // absolute position
|
||||
if (alias_requested) {
|
||||
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);
|
||||
EC_ERR("Slave index out of range!\n");
|
||||
goto out_invalid;
|
||||
}
|
||||
}
|
||||
else if (remainder[0] == ':') { // field position
|
||||
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 == remainder || remainder2[0])
|
||||
goto out_invalid;
|
||||
|
||||
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;
|
||||
}
|
||||
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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
return list_entry(list, ec_slave_t, list);
|
||||
}
|
||||
else
|
||||
EC_ERR("Slave address \"%s\" - Invalid format!\n", original);
|
||||
|
||||
out_invalid:
|
||||
EC_ERR("Invalid slave address string \"%s\"!\n", original);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* Realtime interface
|
||||
*****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -182,7 +182,6 @@ void ec_master_queue_datagram(ec_master_t *, ec_datagram_t *);
|
|||
// 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 *);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
|
|
|||
|
|
@ -121,9 +121,6 @@ int ec_slave_init(ec_slave_t *slave, /**< EtherCAT slave */
|
|||
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 @@ size_t ec_slave_info(const ec_slave_t *slave, /**< EtherCAT slave */
|
|||
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);
|
||||
|
||||
|
|
@ -1127,19 +1120,6 @@ ec_sync_t *ec_slave_get_pdo_sync(
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
\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 @@ int ec_slave_validate(const ec_slave_t *slave, /**< EtherCAT slave */
|
|||
{
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -129,8 +129,6 @@ struct ec_slave
|
|||
// 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 @@ int ec_slave_fetch_sii_pdos(ec_slave_t *, const uint8_t *, size_t,
|
|||
|
||||
// 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 *);
|
||||
|
|
|
|||
134
script/lsec
134
script/lsec
|
|
@ -60,93 +60,99 @@ sub query
|
|||
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 = {};
|
||||
$slave = {};
|
||||
$slave_info_file = "$master_dir/$entry/info";
|
||||
open INFO, $slave_info_file or die
|
||||
"ERROR: Failed to open $slave_info_file.";
|
||||
|
||||
open INFO, "$master_dir/$entry/info" or die
|
||||
"ERROR: Failed to open $master_dir/$entry/info";
|
||||
while ($line = <INFO>) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
while ($line = <INFO>) {
|
||||
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;
|
||||
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;
|
||||
$fmt = sprintf " %%%is %%%is %%6i %%6i %%s\n",
|
||||
$ring_col_width, $alias_col_width;
|
||||
|
||||
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'});
|
||||
}
|
||||
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 {
|
||||
$fmt = sprintf " %%%is %%-%is %%-6s %%s\n", $ring_cols, $adv_cols;
|
||||
else { # normal display
|
||||
$fmt = sprintf " %%%is %%%is %%-6s %%s\n",
|
||||
$ring_col_width, $alias_col_width;
|
||||
|
||||
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'});
|
||||
}
|
||||
for $slave (@slaves) {
|
||||
&print_line if $slave->{'alias'} and !defined $opt{n};
|
||||
printf($fmt, $slave->{'ring_position'}, $slave->{'field_address'},
|
||||
$slave->{'state'}, $slave->{'name'});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -159,10 +165,10 @@ sub get_options
|
|||
&print_usage if defined $opt{h} or $#ARGV > -1 or !$optret;
|
||||
|
||||
if (defined $opt{m}) {
|
||||
$master_index = $opt{m};
|
||||
$master_index = $opt{m};
|
||||
}
|
||||
else {
|
||||
$master_index = 0;
|
||||
$master_index = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -189,7 +195,7 @@ sub get_terminal_width
|
|||
die "no TIOCGWINSZ " unless defined &TIOCGWINSZ;
|
||||
open(TTY, "+</dev/tty") or die "No tty: $!";
|
||||
unless (ioctl(TTY, &TIOCGWINSZ, $winsize='')) {
|
||||
die sprintf "$0: ioctl TIOCGWINSZ (%08x: $!)\n", &TIOCGWINSZ;
|
||||
die sprintf "$0: ioctl TIOCGWINSZ (%08x: $!)\n", &TIOCGWINSZ;
|
||||
}
|
||||
(my $row, my $col, my $xpixel, my $ypixel) = unpack('S4', $winsize);
|
||||
return $col;
|
||||
|
|
@ -198,7 +204,9 @@ sub get_terminal_width
|
|||
|
||||
sub print_line
|
||||
{
|
||||
for (my $i = 0; $i < $term_width; $i++) {print "-";}
|
||||
for (my $i = 0; $i < $term_width; $i++) {
|
||||
print "-";
|
||||
}
|
||||
print "\n";
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue