# HG changeset patch # User Florian Pose # Date 1132314380 0 # Node ID a51289e6cb2d76b97de3fff4c83ed05a4ba52252 # Parent 5a42f6d1085c65f5f1f091f66f28211c023e9276 Warten beim Empfangen der Prozessdaten, Bugfix und kleinere Verbesserungen. diff -r 5a42f6d1085c -r a51289e6cb2d drivers/ec_command.c --- a/drivers/ec_command.c Fri Nov 18 10:30:01 2005 +0000 +++ b/drivers/ec_command.c Fri Nov 18 11:46:20 2005 +0000 @@ -112,7 +112,7 @@ const unsigned char *data) { if (node_address == 0x0000) - EC_DBG(KERN_WARNING "WARNING: Using node address 0x0000!\n"); + EC_DBG(KERN_WARNING "EtherCAT: Using node address 0x0000!\n"); ECAT_FUNC_HEADER; diff -r 5a42f6d1085c -r a51289e6cb2d drivers/ec_device.c --- a/drivers/ec_device.c Fri Nov 18 10:30:01 2005 +0000 +++ b/drivers/ec_device.c Fri Nov 18 11:46:20 2005 +0000 @@ -253,28 +253,30 @@ @param ecd EtherCAT-Gerät @param data Zeiger auf den Speicherbereich, in den die - empfangenen Daten kopiert werden sollen - @param size Größe des angegebenen Speicherbereichs + empfangenen Daten kopiert werden sollen @return Anzahl der kopierten Bytes bei Erfolg, sonst < 0 */ int EtherCAT_device_receive(EtherCAT_device_t *ecd, - unsigned char *data, - unsigned int size) -{ - int cnt; - + unsigned char *data) +{ if (ecd->state != ECAT_DS_RECEIVED) { EC_DBG(KERN_ERR "EtherCAT: receive - Nothing received!\n"); return -1; } - cnt = min(ecd->rx_data_length, size); - memcpy(data,ecd->rx_data, cnt); - - return cnt; + if (ecd->rx_data_length > ECAT_FRAME_BUFFER_SIZE) + { + EC_DBG(KERN_ERR "EtherCAT: receive - Reveived frame too long (%i Bytes)!\n", + ecd->rx_data_length); + return -1; + } + + memcpy(data, ecd->rx_data, ecd->rx_data_length); + + return ecd->rx_data_length; } /***************************************************************/ diff -r 5a42f6d1085c -r a51289e6cb2d drivers/ec_device.h --- a/drivers/ec_device.h Fri Nov 18 10:30:01 2005 +0000 +++ b/drivers/ec_device.h Fri Nov 18 11:46:20 2005 +0000 @@ -77,7 +77,7 @@ int EtherCAT_device_close(EtherCAT_device_t *); int EtherCAT_device_send(EtherCAT_device_t *, unsigned char *, unsigned int); -int EtherCAT_device_receive(EtherCAT_device_t *, unsigned char *, unsigned int); +int EtherCAT_device_receive(EtherCAT_device_t *, unsigned char *); void EtherCAT_device_call_isr(EtherCAT_device_t *); void EtherCAT_device_debug(EtherCAT_device_t *); diff -r 5a42f6d1085c -r a51289e6cb2d drivers/ec_globals.h --- a/drivers/ec_globals.h Fri Nov 18 10:30:01 2005 +0000 +++ b/drivers/ec_globals.h Fri Nov 18 11:46:20 2005 +0000 @@ -15,17 +15,7 @@ /** Maximale Größe eines EtherCAT-Frames */ -#define ECAT_FRAME_BUFFER_SIZE 1600 - -/** - Anzahl der Kommandos in einem Master-Kommandoring -*/ -#define ECAT_COMMAND_RING_SIZE 10 - -/** - Anzahl der Versuche beim Asynchronen Senden/Empfangen -*/ -#define ECAT_NUM_RETRIES 10 +#define ECAT_FRAME_BUFFER_SIZE 1500 /** NULL-Define, falls noch nicht definiert. diff -r 5a42f6d1085c -r a51289e6cb2d drivers/ec_master.c --- a/drivers/ec_master.c Fri Nov 18 10:30:01 2005 +0000 +++ b/drivers/ec_master.c Fri Nov 18 11:46:20 2005 +0000 @@ -25,7 +25,7 @@ @param master Zeiger auf den zu initialisierenden EtherCAT-Master - @param dev Zeiger auf das EtherCAT-gerät, mit dem der + @param dev Zeiger auf das EtherCAT-Gerät, mit dem der Master arbeiten soll @return 0 bei Erfolg, sonst < 0 (= dev ist NULL) @@ -96,10 +96,12 @@ if (EtherCAT_simple_send(master, cmd) < 0) return -1; - tries_left = 100; - while (cmd->state == ECAT_CS_SENT && tries_left) - { - udelay(10); + EtherCAT_device_call_isr(master->dev); + + tries_left = 1000; + while (master->dev->state == ECAT_DS_SENT && tries_left) + { + udelay(1); EtherCAT_device_call_isr(master->dev); tries_left--; } @@ -137,6 +139,13 @@ length = cmd->data_length + 12; framelength = length + 2; + + if (framelength > ECAT_FRAME_BUFFER_SIZE) + { + EC_DBG(KERN_ERR "EtherCAT: Frame too long (%i)!\n", framelength); + return -1; + } + if (framelength < 46) framelength = 46; if (master->debug_level > 0) @@ -223,32 +232,32 @@ int EtherCAT_simple_receive(EtherCAT_master_t *master, EtherCAT_command_t *cmd) { - unsigned int rx_data_length, length; + unsigned int length; + int receive_ret; unsigned char command_type, command_index; - rx_data_length = EtherCAT_device_receive(master->dev, master->rx_data, - ECAT_FRAME_BUFFER_SIZE); - - if (rx_data_length < 2) + if ((receive_ret = EtherCAT_device_receive(master->dev, + master->rx_data)) < 0) + { + return -1; + } + + master->rx_data_length = (unsigned int) receive_ret; + + if (master->rx_data_length < 2) { EC_DBG(KERN_ERR "EtherCAT: Received frame with incomplete EtherCAT header!\n"); - EC_DBG(KERN_DEBUG "EtherCAT: tx_data content:\n"); - output_debug_data(master->tx_data, master->tx_data_length); - EC_DBG(KERN_DEBUG "EtherCAT: rx_data content:\n"); - output_debug_data(master->rx_data, rx_data_length); + output_debug_data(master); return -1; } // Länge des gesamten Frames prüfen length = ((master->rx_data[1] & 0x07) << 8) | (master->rx_data[0] & 0xFF); - if (length > rx_data_length) + if (length > master->rx_data_length) { EC_DBG(KERN_ERR "EtherCAT: Received corrupted frame (length does not match)!\n"); - EC_DBG(KERN_DEBUG "EtherCAT: tx_data content:\n"); - output_debug_data(master->tx_data, master->tx_data_length); - EC_DBG(KERN_DEBUG "EtherCAT: rx_data content:\n"); - output_debug_data(master->rx_data, rx_data_length); + output_debug_data(master); return -1; } @@ -256,13 +265,10 @@ command_index = master->rx_data[2 + 1]; length = (master->rx_data[2 + 6] & 0xFF) | ((master->rx_data[2 + 7] & 0x07) << 8); - if (rx_data_length - 2 < length + 12) + if (master->rx_data_length - 2 < length + 12) { EC_DBG(KERN_ERR "EtherCAT: Received frame with incomplete command data!\n"); - EC_DBG(KERN_DEBUG "EtherCAT: tx_data content:\n"); - output_debug_data(master->tx_data, master->tx_data_length); - EC_DBG(KERN_DEBUG "EtherCAT: rx_data content:\n"); - output_debug_data(master->rx_data, rx_data_length); + output_debug_data(master); return -1; } @@ -283,10 +289,7 @@ else { EC_DBG(KERN_WARNING "EtherCAT: WARNING - Send/Receive anomaly!\n"); - EC_DBG(KERN_DEBUG "EtherCAT: tx_data content:\n"); - output_debug_data(master->tx_data, master->tx_data_length); - EC_DBG(KERN_DEBUG "EtherCAT: rx_data content:\n"); - output_debug_data(master->rx_data, rx_data_length); + output_debug_data(master); } master->dev->state = ECAT_DS_READY; @@ -991,8 +994,24 @@ int EtherCAT_read_process_data(EtherCAT_master_t *master) { + unsigned int tries_left; + EtherCAT_device_call_isr(master->dev); + tries_left = 1000; + while (master->dev->state == ECAT_DS_SENT && tries_left) + { + udelay(1); + EtherCAT_device_call_isr(master->dev); + tries_left--; + } + + if (!tries_left) + { + EC_DBG(KERN_ERR "EtherCAT: Timeout while receiving process data!\n"); + return -1; + } + if (EtherCAT_simple_receive(master, &master->process_data_command) < 0) { EC_DBG(KERN_ERR "EtherCAT: Could not receive cyclic command!\n"); @@ -1029,58 +1048,37 @@ /***************************************************************/ /** - Setzt einen Byte-Wert im Speicher. - - @param data Startadresse - @param offset Byte-Offset - @param value Wert -*/ - -void set_byte(unsigned char *data, - unsigned int offset, - unsigned char value) -{ - data[offset] = value; -} - -/***************************************************************/ - -/** - Setzt einen Word-Wert im Speicher. - - @param data Startadresse - @param offset Byte-Offset - @param value Wert -*/ - -void set_word(unsigned char *data, - unsigned int offset, - unsigned int value) -{ - data[offset] = value & 0xFF; - data[offset + 1] = (value & 0xFF00) >> 8; -} - -/***************************************************************/ - -/** Gibt Frame-Inhalte zwecks Debugging aus. @param data Startadresse @param length Länge der Daten */ -void output_debug_data(unsigned char *data, unsigned int length) +void output_debug_data(const EtherCAT_master_t *master) { unsigned int i; + EC_DBG(KERN_DEBUG "EtherCAT: tx_data content (%i Bytes):\n", + master->tx_data_length); + EC_DBG(KERN_DEBUG); - for (i = 0; i < length; i++) - { - EC_DBG("%02X ", data[i]); + for (i = 0; i < master->tx_data_length; i++) + { + EC_DBG("%02X ", master->tx_data[i]); if ((i + 1) % 16 == 0) EC_DBG("\n" KERN_DEBUG); } EC_DBG("\n"); -} - -/***************************************************************/ + + EC_DBG(KERN_DEBUG "EtherCAT: rx_data content (%i Bytes):\n", + master->rx_data_length); + + EC_DBG(KERN_DEBUG); + for (i = 0; i < master->rx_data_length; i++) + { + EC_DBG("%02X ", master->rx_data[i]); + if ((i + 1) % 16 == 0) EC_DBG("\n" KERN_DEBUG); + } + EC_DBG("\n"); +} + +/***************************************************************/ diff -r 5a42f6d1085c -r a51289e6cb2d drivers/ec_master.h --- a/drivers/ec_master.h Fri Nov 18 10:30:01 2005 +0000 +++ b/drivers/ec_master.h Fri Nov 18 11:46:20 2005 +0000 @@ -44,6 +44,7 @@ unsigned char rx_data[ECAT_FRAME_BUFFER_SIZE]; /**< Statische Speicher für eine Kopie des Rx-Buffers im EtherCAT-Gerät */ + unsigned int rx_data_length; /**< Länge der Daten im Empfangsspeicher */ unsigned char *process_data; /**< Zeiger auf Speicher mit Prozessdaten */ unsigned int process_data_length; /**< Länge der Prozessdaten */ @@ -82,9 +83,7 @@ void EtherCAT_clear_process_data(EtherCAT_master_t *); // Private functions -void set_byte(unsigned char *, unsigned int, unsigned char); -void set_word(unsigned char *, unsigned int, unsigned int); -void output_debug_data(unsigned char *, unsigned int); +void output_debug_data(const EtherCAT_master_t *); /***************************************************************/