From ce0ec04bab7960d5b8c441e0d4f9d563b1262cb3 Mon Sep 17 00:00:00 2001 From: Florian Pose <fp@igh-essen.com> Date: Mon, 9 Jun 2008 13:45:22 +0000 Subject: [PATCH] Implemented SII read. --- TODO | 3 +-- master/cdev.c | 35 +++++++++++++++++++++++++++++++ master/ioctl.h | 54 +++++++++++++++++++++++++++++------------------- tools/Master.cpp | 41 ++++++++++++++++++++++++++++++++++++ tools/Master.h | 1 + tools/main.cpp | 3 +++ 6 files changed, 114 insertions(+), 23 deletions(-) diff --git a/TODO b/TODO index 8ee1b2be..92089a8b 100644 --- a/TODO +++ b/TODO @@ -8,12 +8,11 @@ $Id$ Version 1.4.0: -* Slaves as array. * Replace all Sysfs files via the new ethercat tool. - Slave alias write - - Slave SII write - Slave info (flags, mailbox, general) - Config info (alias, position, type, Pdos, Sdos) +* Slaves as array. * Remove the end state of the master state machine. * Supply new ec_master_state_t. * Implement ecrt_slave_config_state(). diff --git a/master/cdev.c b/master/cdev.c index 2baf6541..907f748a 100644 --- a/master/cdev.c +++ b/master/cdev.c @@ -196,6 +196,7 @@ long eccdev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) data.sync_count = slave->sii.sync_count; data.sdo_count = ec_slave_sdo_count(slave); + data.sii_nwords = slave->sii_nwords; if (slave->sii.name) { strncpy(data.name, slave->sii.name, @@ -760,6 +761,40 @@ long eccdev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) break; } + case EC_IOCTL_SII_READ: + { + ec_ioctl_sii_read_t data; + const ec_slave_t *slave; + + if (copy_from_user(&data, (void __user *) arg, sizeof(data))) { + retval = -EFAULT; + break; + } + + if (!(slave = ec_master_find_slave( + master, 0, data.slave_position))) { + EC_ERR("Slave %u does not exist!\n", data.slave_position); + retval = -EINVAL; + break; + } + + if (!data.nwords + || data.offset + data.nwords > slave->sii_nwords) { + EC_ERR("Invalid SII read offset/size %u/%u for slave " + "SII size %u!\n", data.offset, + data.nwords, slave->sii_nwords); + retval = -EINVAL; + break; + } + + if (copy_to_user((void __user *) data.words, + slave->sii_words + data.offset, data.nwords * 2)) { + retval = -EFAULT; + break; + } + break; + } + default: retval = -ENOTTY; } diff --git a/master/ioctl.h b/master/ioctl.h index 94b6ba77..ed7db262 100644 --- a/master/ioctl.h +++ b/master/ioctl.h @@ -67,23 +67,24 @@ #define EC_IOCTL_SDO_ENTRY EC_IOWR(0x0c, ec_ioctl_sdo_entry_t) #define EC_IOCTL_SDO_UPLOAD EC_IOWR(0x0d, ec_ioctl_sdo_upload_t) #define EC_IOCTL_SDO_DOWNLOAD EC_IOW(0x0e, ec_ioctl_sdo_download_t) +#define EC_IOCTL_SII_READ EC_IOWR(0x0f, ec_ioctl_sii_read_t) /*****************************************************************************/ typedef struct { - unsigned int slave_count; + uint32_t slave_count; uint8_t mode; struct { uint8_t address[6]; uint8_t attached; - unsigned int tx_count; - unsigned int rx_count; + uint32_t tx_count; + uint32_t rx_count; } devices[2]; } ec_ioctl_master_t; /*****************************************************************************/ -#define EC_IOCTL_SLAVE_NAME_SIZE 104 +#define EC_IOCTL_SLAVE_NAME_SIZE 100 typedef struct { // input @@ -98,6 +99,7 @@ typedef struct { uint8_t state; uint8_t sync_count; uint16_t sdo_count; + uint32_t sii_nwords; char name[EC_IOCTL_SLAVE_NAME_SIZE]; } ec_ioctl_slave_t; @@ -106,7 +108,7 @@ typedef struct { typedef struct { // inputs uint16_t slave_position; - unsigned int sync_index; + uint32_t sync_index; // outputs uint16_t physical_start_address; @@ -124,8 +126,8 @@ typedef struct { typedef struct { // inputs uint16_t slave_position; - unsigned int sync_index; - unsigned int pdo_pos; + uint32_t sync_index; + uint32_t pdo_pos; // outputs uint8_t dir; @@ -141,9 +143,9 @@ typedef struct { typedef struct { // inputs uint16_t slave_position; - unsigned int sync_index; - unsigned int pdo_pos; - unsigned int entry_pos; + uint32_t sync_index; + uint32_t pdo_pos; + uint32_t entry_pos; // outputs uint16_t index; @@ -156,37 +158,37 @@ typedef struct { typedef struct { // inputs - unsigned int index; + uint32_t index; // outputs - unsigned int data_size; + uint32_t data_size; uint32_t logical_base_address; uint16_t working_counter; uint16_t expected_working_counter; - unsigned int fmmu_count; + uint32_t fmmu_count; } ec_ioctl_domain_t; /*****************************************************************************/ typedef struct { // inputs - unsigned int domain_index; - unsigned int fmmu_index; + uint32_t domain_index; + uint32_t fmmu_index; // outputs uint16_t slave_config_alias; uint16_t slave_config_position; uint8_t fmmu_dir; uint32_t logical_address; - unsigned int data_size; + uint32_t data_size; } ec_ioctl_domain_fmmu_t; /*****************************************************************************/ typedef struct { // inputs - unsigned int domain_index; - unsigned int data_size; + uint32_t domain_index; + uint32_t data_size; unsigned char *target; } ec_ioctl_data_t; @@ -236,11 +238,11 @@ typedef struct { uint16_t slave_position; uint16_t sdo_index; uint8_t sdo_entry_subindex; - unsigned int target_size; + uint32_t target_size; uint8_t *target; // outputs - unsigned int data_size; + uint32_t data_size; } ec_ioctl_sdo_upload_t; /*****************************************************************************/ @@ -250,10 +252,20 @@ typedef struct { uint16_t slave_position; uint16_t sdo_index; uint8_t sdo_entry_subindex; - unsigned int data_size; + uint32_t data_size; uint8_t *data; } ec_ioctl_sdo_download_t; /*****************************************************************************/ +typedef struct { + // inputs + uint16_t slave_position; + uint16_t offset; + uint32_t nwords; + uint16_t *words; +} ec_ioctl_sii_read_t; + +/*****************************************************************************/ + #endif diff --git a/tools/Master.cpp b/tools/Master.cpp index c28c232c..42d5f62c 100644 --- a/tools/Master.cpp +++ b/tools/Master.cpp @@ -606,6 +606,47 @@ void Master::sdoUpload( /****************************************************************************/ +void Master::siiRead(int slavePosition) +{ + ec_ioctl_sii_read_t data; + ec_ioctl_slave_t slave; + unsigned int i; + + if (slavePosition < 0) { + stringstream err; + err << "'sii_read' requires a slave! Please specify --slave."; + throw MasterException(err.str()); + } + data.slave_position = slavePosition; + + open(Read); + + getSlave(&slave, slavePosition); + + if (!slave.sii_nwords) + return; + + data.offset = 0; + data.nwords = slave.sii_nwords; + data.words = new uint16_t[data.nwords]; + + if (ioctl(fd, EC_IOCTL_SII_READ, &data) < 0) { + stringstream err; + delete [] data.words; + err << "Failed to read SII: " << strerror(errno); + throw MasterException(err.str()); + } + + for (i = 0; i < data.nwords; i++) { + uint16_t *w = data.words + i; + cout << *(uint8_t *) w << *((uint8_t *) w + 1); + } + + delete [] data.words; +} + +/****************************************************************************/ + void Master::requestStates( int slavePosition, const vector<string> &commandArgs diff --git a/tools/Master.h b/tools/Master.h index c3f117c9..f41d1935 100644 --- a/tools/Master.h +++ b/tools/Master.h @@ -50,6 +50,7 @@ class Master void listSdos(int, bool = false); void sdoDownload(int, const string &, const vector<string> &); void sdoUpload(int, const string &, const vector<string> &); + void siiRead(int); void requestStates(int, const vector<string> &); void generateXml(int); diff --git a/tools/main.cpp b/tools/main.cpp index a7773c7b..d2be8c2a 100644 --- a/tools/main.cpp +++ b/tools/main.cpp @@ -41,6 +41,7 @@ void printUsage() << " sdos List Sdo dictionaries." << endl << " sdo_download (sd) Write an Sdo entry." << endl << " sdo_upload (su) Read an Sdo entry." << endl + << " sii_read (sr) Output a slave's SII contents." << endl << " state Request slave states." << endl << " xml Generate slave information xmls." << endl << "Global options:" << endl @@ -183,6 +184,8 @@ int main(int argc, char **argv) master.sdoDownload(slavePosition, dataTypeStr, commandArgs); } else if (command == "sdo_upload" || command == "su") { master.sdoUpload(slavePosition, dataTypeStr, commandArgs); + } else if (command == "sii_read" || command == "sr") { + master.siiRead(slavePosition); } else if (command == "state") { master.requestStates(slavePosition, commandArgs); } else if (command == "xml") { -- GitLab