# HG changeset patch # User Florian Pose # Date 1232368578 0 # Node ID fae3a1759126ef91b0fe038f615fe37bab95b005 # Parent 11ec009e145d9f09f820ac8bca7bf2e46bc9a497 Improved FoE. diff -r 11ec009e145d -r fae3a1759126 master/cdev.c --- a/master/cdev.c Mon Jan 19 10:18:41 2009 +0000 +++ b/master/cdev.c Mon Jan 19 12:36:18 2009 +0000 @@ -1228,6 +1228,11 @@ up(&master->master_sem); + if (master->debug_level) { + EC_DBG("Scheduled FoE read request on slave %u.\n", + request.slave->ring_position); + } + // wait for processing through FSM if (wait_event_interruptible(master->foe_queue, request.req.state != EC_REQUEST_QUEUED)) { @@ -1246,11 +1251,12 @@ // wait until master FSM has finished processing wait_event(master->foe_queue, request.req.state != EC_REQUEST_BUSY); - data.abort_code = request.req.abort_code; + data.result = request.req.result; + data.error_code = request.req.error_code; if (master->debug_level) { - EC_DBG("%d bytes read via FoE (abort_code = 0x%x).\n", - request.req.data_size, request.req.abort_code); + EC_DBG("Read %d bytes via FoE (result = 0x%x).\n", + request.req.data_size, request.req.result); } if (request.req.state != EC_REQUEST_SUCCESS) { @@ -1275,7 +1281,12 @@ retval = -EFAULT; } + if (master->debug_level) + EC_DBG("FoE read request finished on slave %u.\n", + request.slave->ring_position); + ec_foe_request_clear(&request.req); + return retval; } @@ -1350,7 +1361,8 @@ // wait until master FSM has finished processing wait_event(master->foe_queue, request.req.state != EC_REQUEST_BUSY); - data.abort_code = request.req.abort_code; + data.result = request.req.result; + data.error_code = request.req.error_code; retval = request.req.state == EC_REQUEST_SUCCESS ? 0 : -EIO; diff -r 11ec009e145d -r fae3a1759126 master/foe.h --- a/master/foe.h Mon Jan 19 10:18:41 2009 +0000 +++ b/master/foe.h Mon Jan 19 12:36:18 2009 +0000 @@ -38,7 +38,7 @@ FOE_PROT_ERROR = 5, FOE_NODATA_ERROR = 6, FOE_PACKETNO_ERROR = 7, - FOE_OPMODE_ERROR = 8, + FOE_OPCODE_ERROR = 8, FOE_TIMEOUT_ERROR = 9, FOE_SEND_RX_DATA_ERROR = 10, FOE_RX_DATA_ACK_ERROR = 11, diff -r 11ec009e145d -r fae3a1759126 master/foe_request.c --- a/master/foe_request.c Mon Jan 19 10:18:41 2009 +0000 +++ b/master/foe_request.c Mon Jan 19 12:36:18 2009 +0000 @@ -1,6 +1,6 @@ /****************************************************************************** * - * $Id:$ + * $Id$ * * Copyright (C) 2008 Olav Zarges, imc Meßsysteme GmbH * @@ -41,6 +41,7 @@ #include #include "foe_request.h" +#include "foe.h" /*****************************************************************************/ @@ -68,7 +69,8 @@ req->issue_timeout = 0; // no timeout req->response_timeout = EC_FOE_REQUEST_RESPONSE_TIMEOUT; req->state = EC_REQUEST_INIT; - req->abort_code = 0x00000000; + req->result = FOE_BUSY; + req->error_code = 0x00000000; } /*****************************************************************************/ @@ -184,7 +186,7 @@ { req->dir = EC_DIR_INPUT; req->state = EC_REQUEST_QUEUED; - req->abort_code = 0x00000000; + req->result = FOE_BUSY; req->jiffies_start = jiffies; } @@ -194,7 +196,7 @@ { req->dir = EC_DIR_OUTPUT; req->state = EC_REQUEST_QUEUED; - req->abort_code = 0x00000000; + req->result = FOE_BUSY; req->jiffies_start = jiffies; } diff -r 11ec009e145d -r fae3a1759126 master/foe_request.h --- a/master/foe_request.h Mon Jan 19 10:18:41 2009 +0000 +++ b/master/foe_request.h Mon Jan 19 12:36:18 2009 +0000 @@ -1,6 +1,6 @@ /****************************************************************************** * - * $Id:$ + * $Id$ * * Copyright (C) 2008 Olav Zarges, imc Meßsysteme GmbH * @@ -68,7 +68,8 @@ unsigned long jiffies_sent; /**< Jiffies, when the upload/download request was sent. */ uint8_t *file_name; /**< Pointer to the filename. */ - uint32_t abort_code; /**< FoE request abort code. Zero on success. */ + uint32_t result; /**< FoE request abort code. Zero on success. */ + uint32_t error_code; /**< Error code from an FoE Error Request. */ } ec_foe_request_t; /*****************************************************************************/ diff -r 11ec009e145d -r fae3a1759126 master/fsm_foe.c --- a/master/fsm_foe.c Mon Jan 19 10:18:41 2009 +0000 +++ b/master/fsm_foe.c Mon Jan 19 12:36:18 2009 +0000 @@ -1,6 +1,6 @@ /****************************************************************************** * - * $Id:$ + * $Id$ * * Copyright (C) 2008 Olav Zarges, imc Meßsysteme GmbH * @@ -52,6 +52,8 @@ #define EC_MBOX_TYPE_FILEACCESS 0x04 +#define myDEBUG + /*****************************************************************************/ int ec_foe_prepare_data_send( ec_fsm_foe_t * ); @@ -188,18 +190,18 @@ // uint8_t Counter:4 #define EC_FOE_HEADER_SIZE 6 -// uint8_t OpMode +// uint8_t OpCode // uint8_t reserved // uint32_t PacketNo, Password, ErrorCode enum { - EC_FOE_OPMODE_RRQ = 1, - EC_FOE_OPMODE_WRQ = 2, - EC_FOE_OPMODE_DATA = 3, - EC_FOE_OPMODE_ACK = 4, - EC_FOE_OPMODE_ERR = 5, - EC_FOE_OPMODE_BUSY = 6 -} ec_foe_opmode_t; + EC_FOE_OPCODE_RRQ = 1, + EC_FOE_OPCODE_WRQ = 2, + EC_FOE_OPCODE_DATA = 3, + EC_FOE_OPCODE_ACK = 4, + EC_FOE_OPCODE_ERR = 5, + EC_FOE_OPCODE_BUSY = 6 +} ec_foe_opcode_t; /*****************************************************************************/ /** @@ -224,7 +226,7 @@ EC_MBOX_TYPE_FILEACCESS, current_size + EC_FOE_HEADER_SIZE))) return -1; - EC_WRITE_U8 ( data, EC_FOE_OPMODE_DATA ); // OpMode = DataBlock req. + EC_WRITE_U8 ( data, EC_FOE_OPCODE_DATA ); // OpCode = DataBlock req. EC_WRITE_U32( data + 2, fsm->tx_packet_no ); // PacketNo, Password memcpy(data + EC_FOE_HEADER_SIZE, fsm->tx_buffer + fsm->tx_buffer_offset, current_size); @@ -254,7 +256,7 @@ EC_MBOX_TYPE_FILEACCESS, current_size + EC_FOE_HEADER_SIZE))) return -1; - EC_WRITE_U16( data, EC_FOE_OPMODE_WRQ); // fsm write request + EC_WRITE_U16( data, EC_FOE_OPCODE_WRQ); // fsm write request EC_WRITE_U32( data + 2, fsm->tx_packet_no ); memcpy(data + EC_FOE_HEADER_SIZE, fsm->tx_filename, current_size); @@ -375,7 +377,7 @@ ec_datagram_t *datagram = fsm->datagram; ec_slave_t *slave = fsm->slave; uint8_t *data, mbox_prot; - uint16_t opMode; + uint8_t opCode; size_t rec_size; #ifdef myDEBUG @@ -408,9 +410,9 @@ return; } - opMode = EC_READ_U16(data); - - if ( opMode == EC_FOE_OPMODE_BUSY ) { + opCode = EC_READ_U8(data); + + if (opCode == EC_FOE_OPCODE_BUSY) { // slave ist noch nicht bereit if (ec_foe_prepare_data_send(fsm)) { ec_foe_set_tx_error(fsm, FOE_PROT_ERROR); @@ -421,7 +423,7 @@ return; } - if ( opMode == EC_FOE_OPMODE_ACK ) { + if (opCode == EC_FOE_OPCODE_ACK) { fsm->tx_packet_no++; fsm->tx_buffer_offset += fsm->tx_current_size; @@ -530,11 +532,15 @@ EC_MBOX_TYPE_FILEACCESS, current_size + EC_FOE_HEADER_SIZE))) return -1; - EC_WRITE_U16( data, EC_FOE_OPMODE_RRQ); // fsm read request - EC_WRITE_U32( data + 2, 0 ); - + EC_WRITE_U16(data, EC_FOE_OPCODE_RRQ); // fsm read request + EC_WRITE_U32(data + 2, 0x00000000); // no passwd memcpy(data + EC_FOE_HEADER_SIZE, fsm->rx_filename, current_size); + if (fsm->slave->master->debug_level) { + EC_DBG("FoE Read Request:\n"); + ec_print_data(data, current_size + EC_FOE_HEADER_SIZE); + } + return 0; } @@ -548,7 +554,7 @@ EC_MBOX_TYPE_FILEACCESS, EC_FOE_HEADER_SIZE))) return -1; - EC_WRITE_U16( data, EC_FOE_OPMODE_ACK); + EC_WRITE_U16( data, EC_FOE_OPCODE_ACK); EC_WRITE_U32( data + 2, foe->rx_expected_packet_no ); return 0; @@ -698,7 +704,7 @@ void ec_fsm_foe_state_data_read ( ec_fsm_foe_t *fsm ) { size_t rec_size; - uint8_t *data, opMode, packet_no, mbox_prot; + uint8_t *data, opCode, packet_no, mbox_prot; ec_datagram_t *datagram = fsm->datagram; ec_slave_t *slave = fsm->slave; @@ -706,6 +712,7 @@ #ifdef myDEBUG printk("ec_fsm_foe_state_data_read()\n"); #endif + if (datagram->state != EC_DATAGRAM_RECEIVED) { ec_foe_set_rx_error(fsm, FOE_RECEIVE_ERROR); EC_ERR("Failed to receive FoE DATA READ datagram for" @@ -733,37 +740,59 @@ return; } - opMode = EC_READ_U16(data); - - if (opMode == EC_FOE_OPMODE_BUSY) { + opCode = EC_READ_U8(data); + + if (opCode == EC_FOE_OPCODE_BUSY) { if (ec_foe_prepare_send_ack(fsm)) { ec_foe_set_rx_error(fsm, FOE_PROT_ERROR); } return; } - if (opMode != EC_FOE_OPMODE_DATA) { - ec_foe_set_rx_error(fsm, FOE_OPMODE_ERROR); + if (opCode == EC_FOE_OPCODE_ERR) { + fsm->request->error_code = EC_READ_U32(data + 2); + EC_ERR("Received FoE Error Request (code %08x) on slave %u.\n", + fsm->request->error_code, slave->ring_position); + if (rec_size > 6) { + uint8_t text[1024]; + strncpy(text, data + 6, min(rec_size - 6, sizeof(text))); + EC_ERR("FoE Error Text: %s\n", text); + } + ec_foe_set_rx_error(fsm, FOE_OPCODE_ERROR); + return; + } + + if (opCode != EC_FOE_OPCODE_DATA) { + EC_ERR("Received OPCODE %x, expected %x on slave %u.\n", + opCode, EC_FOE_OPCODE_DATA, slave->ring_position); + fsm->request->error_code = 0x00000000; + ec_foe_set_rx_error(fsm, FOE_OPCODE_ERROR); return; } packet_no = EC_READ_U16(data + 2); if (packet_no != fsm->rx_expected_packet_no) { + EC_ERR("Received unexpected packet number on slave %u.\n", + slave->ring_position); ec_foe_set_rx_error(fsm, FOE_PACKETNO_ERROR); return; } rec_size -= EC_FOE_HEADER_SIZE; - if ( fsm->rx_buffer_size >= fsm->rx_buffer_offset + rec_size ) { - memcpy ( fsm->rx_buffer + fsm->rx_buffer_offset, data + EC_FOE_HEADER_SIZE, rec_size ); + if (fsm->rx_buffer_size >= fsm->rx_buffer_offset + rec_size) { + memcpy(fsm->rx_buffer + fsm->rx_buffer_offset, + data + EC_FOE_HEADER_SIZE, rec_size); fsm->rx_buffer_offset += rec_size; } - fsm->rx_last_packet = (rec_size + EC_MBOX_HEADER_SIZE + EC_FOE_HEADER_SIZE != fsm->slave->sii.rx_mailbox_size); + fsm->rx_last_packet = + (rec_size + EC_MBOX_HEADER_SIZE + EC_FOE_HEADER_SIZE + != fsm->slave->sii.rx_mailbox_size); if (fsm->rx_last_packet || - slave->sii.rx_mailbox_size - EC_MBOX_HEADER_SIZE - EC_FOE_HEADER_SIZE + fsm->rx_buffer_offset <= fsm->rx_buffer_size) { + (slave->sii.rx_mailbox_size - EC_MBOX_HEADER_SIZE + - EC_FOE_HEADER_SIZE + fsm->rx_buffer_offset) <= fsm->rx_buffer_size) { // either it was the last packet or a new packet will fit into the delivered buffer #ifdef myDEBUG printk ("last_packet=true\n"); @@ -776,8 +805,8 @@ fsm->state = ec_fsm_foe_state_sent_ack; } else { - // no more data fits into the deliverd buffer - // ... wait for new read request (an den Treiber) + // no more data fits into the delivered buffer + // ... wait for new read request printk ("ERROR: data doesn't fit in receive buffer\n"); printk (" rx_buffer_size = %d\n", fsm->rx_buffer_size); printk (" rx_buffer_offset= %d\n", fsm->rx_buffer_offset); @@ -785,7 +814,7 @@ printk (" rx_mailbox_size = %d\n", slave->sii.rx_mailbox_size); printk (" rx_last_packet = %d\n", fsm->rx_last_packet); // fsm->state = ec_fsm_state_wait_next_read; - fsm->request->abort_code = FOE_READY; + fsm->request->result = FOE_READY; } } @@ -834,17 +863,19 @@ /*****************************************************************************/ -void ec_foe_set_tx_error( ec_fsm_foe_t *fsm, uint32_t errorcode ) { +void ec_foe_set_tx_error(ec_fsm_foe_t *fsm, uint32_t errorcode) +{ fsm->tx_errors++; - fsm->request->abort_code = errorcode; + fsm->request->result = errorcode; fsm->state = ec_fsm_foe_error; } /*****************************************************************************/ -void ec_foe_set_rx_error( ec_fsm_foe_t *fsm, uint32_t errorcode ) { +void ec_foe_set_rx_error(ec_fsm_foe_t *fsm, uint32_t errorcode) +{ fsm->rx_errors++; - fsm->request->abort_code = errorcode; + fsm->request->result = errorcode; fsm->state = ec_fsm_foe_error; } diff -r 11ec009e145d -r fae3a1759126 master/fsm_master.c --- a/master/fsm_master.c Mon Jan 19 10:18:41 2009 +0000 +++ b/master/fsm_master.c Mon Jan 19 12:36:18 2009 +0000 @@ -436,17 +436,14 @@ request->req.state = EC_REQUEST_BUSY; slave = request->slave; - EC_DBG("---- Master read command from queue ----\n"); - // found pending FOE write operation. execute it! if (master->debug_level) - EC_DBG("Writing FOE data to slave %u...\n", - request->slave->ring_position); + EC_DBG("Processing FoE request for slave %u.\n", + slave->ring_position); fsm->foe_request = &request->req; fsm->slave = slave; fsm->state = ec_fsm_master_state_foe_request; ec_fsm_foe_transfer(&fsm->fsm_foe, slave, &request->req); - //(&fsm->fsm_foe, request->slave, request->offset, request->words); ec_fsm_foe_exec(&fsm->fsm_foe); return 1; } @@ -471,6 +468,10 @@ if (ec_fsm_master_action_process_sdo(fsm)) return; + // Check for pending FoE requests + if (ec_fsm_master_action_process_foe(fsm)) + return; + // check, if slaves have an SDO dictionary to read out. for (slave = master->slaves; slave < master->slaves + master->slave_count; @@ -850,10 +851,11 @@ ec_foe_request_t *request = fsm->foe_request; ec_slave_t *slave = fsm->slave; - if (ec_fsm_foe_exec(&fsm->fsm_foe)) return; + if (ec_fsm_foe_exec(&fsm->fsm_foe)) + return; if (!ec_fsm_foe_success(&fsm->fsm_foe)) { - EC_ERR("Failed to handle FOE request to slave %u.\n", + EC_ERR("Failed to handle FoE request to slave %u.\n", slave->ring_position); request->state = EC_REQUEST_FAILURE; wake_up(&master->foe_queue); @@ -861,10 +863,10 @@ return; } - // finished writing FOE + // finished transferring FoE if (master->debug_level) - EC_DBG("Finished writing %u words of FOE data to slave %u.\n", - request->data_size, slave->ring_position); + EC_DBG("Successfully transferred %u bytes of FoE data from/to" + " slave %u.\n", request->data_size, slave->ring_position); request->state = EC_REQUEST_SUCCESS; wake_up(&master->foe_queue); diff -r 11ec009e145d -r fae3a1759126 master/ioctl.h --- a/master/ioctl.h Mon Jan 19 10:18:41 2009 +0000 +++ b/master/ioctl.h Mon Jan 19 12:36:18 2009 +0000 @@ -353,7 +353,8 @@ // outputs uint32_t data_size; - uint32_t abort_code; + uint32_t result; + uint32_t error_code; char file_name[32]; } ec_ioctl_slave_foe_t; diff -r 11ec009e145d -r fae3a1759126 tool/CommandFoeRead.cpp --- a/tool/CommandFoeRead.cpp Mon Jan 19 10:18:41 2009 +0000 +++ b/tool/CommandFoeRead.cpp Mon Jan 19 12:36:18 2009 +0000 @@ -1,6 +1,6 @@ /***************************************************************************** * - * $Id:$ + * $Id$ * ****************************************************************************/ @@ -10,6 +10,7 @@ #include "CommandFoeRead.h" #include "byteorder.h" +#include "foe.h" /*****************************************************************************/ @@ -83,7 +84,19 @@ m.readFoe(&data); } catch (MasterDeviceException &e) { delete [] data.buffer; - throw e; + if (data.result) { + if (data.result == FOE_OPCODE_ERROR) { + err << "FoE read aborted with error code 0x" + << setw(8) << setfill('0') << hex << data.error_code + << ": " << errorText(data.error_code); + } else { + err << "Failed to write via FoE: " + << resultText(data.result); + } + throwCommandException(err); + } else { + throw e; + } } // TODO --output-file diff -r 11ec009e145d -r fae3a1759126 tool/CommandFoeWrite.cpp --- a/tool/CommandFoeWrite.cpp Mon Jan 19 10:18:41 2009 +0000 +++ b/tool/CommandFoeWrite.cpp Mon Jan 19 12:36:18 2009 +0000 @@ -1,6 +1,6 @@ /***************************************************************************** * - * $Id:$ + * $Id$ * ****************************************************************************/ @@ -13,6 +13,7 @@ #include "CommandFoeWrite.h" #include "byteorder.h" +#include "foe.h" /*****************************************************************************/ @@ -120,9 +121,15 @@ } catch (MasterDeviceException &e) { if (data.buffer_size) delete [] data.buffer; - if (data.abort_code) { - err << "Failed to write via FoE: " - << errorString(data.abort_code); + if (data.result) { + if (data.result == FOE_OPCODE_ERROR) { + err << "FoE write aborted with error code 0x" + << setw(8) << setfill('0') << hex << data.error_code + << ": " << errorText(data.error_code); + } else { + err << "Failed to write via FoE: " + << resultText(data.result); + } throwCommandException(err); } else { throw e; diff -r 11ec009e145d -r fae3a1759126 tool/FoeCommand.cpp --- a/tool/FoeCommand.cpp Mon Jan 19 10:18:41 2009 +0000 +++ b/tool/FoeCommand.cpp Mon Jan 19 12:36:18 2009 +0000 @@ -16,9 +16,9 @@ /****************************************************************************/ -std::string FoeCommand::errorString(int abort_code) +std::string FoeCommand::resultText(int result) { - switch (abort_code) { + switch (result) { case FOE_BUSY: return "FOE_BUSY"; case FOE_READY: @@ -35,8 +35,8 @@ return "FOE_NODATA_ERROR"; case FOE_PACKETNO_ERROR: return "FOE_PACKETNO_ERROR"; - case FOE_OPMODE_ERROR: - return "FOE_OPMODE_ERROR"; + case FOE_OPCODE_ERROR: + return "FOE_OPCODE_ERROR"; case FOE_TIMEOUT_ERROR: return "FOE_TIMEOUT_ERROR"; case FOE_SEND_RX_DATA_ERROR: @@ -57,3 +57,35 @@ } /****************************************************************************/ + +std::string FoeCommand::errorText(int errorCode) +{ + switch (errorCode) { + case 0x00008001: + return "Not found."; + case 0x00008002: + return "Access denied."; + case 0x00008003: + return "Disk full."; + case 0x00008004: + return "Illegal."; + case 0x00008005: + return "Packet number wrong."; + case 0x00008006: + return "Already exists."; + case 0x00008007: + return "No user."; + case 0x00008008: + return "Bootstrap only."; + case 0x00008009: + return "Not Bootstrap."; + case 0x0000800a: + return "No rights."; + case 0x0000800b: + return "Program Error."; + default: + return "Unknown error code"; + } +} + +/****************************************************************************/ diff -r 11ec009e145d -r fae3a1759126 tool/FoeCommand.h --- a/tool/FoeCommand.h Mon Jan 19 10:18:41 2009 +0000 +++ b/tool/FoeCommand.h Mon Jan 19 12:36:18 2009 +0000 @@ -18,7 +18,8 @@ FoeCommand(const string &, const string &); protected: - static std::string errorString(int); + static std::string resultText(int); + static std::string errorText(int); }; /****************************************************************************/