Store abort code in sdo request; output it in user space; added some
re_size checking in fsm_coe.
This commit is contained in:
parent
4a6d031f92
commit
1415090d15
3
TODO
3
TODO
|
|
@ -16,8 +16,7 @@ Version 1.4.0:
|
|||
* Update documentation.
|
||||
* Attach Pdo names from SII or Coe dictioary to Pdos read via CoE.
|
||||
* Add a -n (numeric) switch to ethercat command.
|
||||
* Remove Eoe cylces and Idle cycles.
|
||||
* Store Sdo abort code in sdo_request_t and output it in user space.
|
||||
* Remove Eoe cycles and Idle cycles.
|
||||
|
||||
Future issues:
|
||||
|
||||
|
|
|
|||
|
|
@ -628,6 +628,7 @@ long eccdev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
|||
if (request.req.state == EC_REQUEST_QUEUED) {
|
||||
list_del(&request.req.list);
|
||||
up(&master->sdo_sem);
|
||||
ec_sdo_request_clear(&request.req);
|
||||
retval = -EINTR;
|
||||
break;
|
||||
}
|
||||
|
|
@ -637,27 +638,31 @@ long eccdev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
|||
|
||||
// wait until master FSM has finished processing
|
||||
wait_event(master->sdo_queue, request.req.state != EC_REQUEST_BUSY);
|
||||
|
||||
data.abort_code = request.req.abort_code;
|
||||
|
||||
if (request.req.state != EC_REQUEST_SUCCESS) {
|
||||
data.data_size = 0;
|
||||
retval = -EIO;
|
||||
break;
|
||||
} else {
|
||||
if (request.req.data_size > data.target_size) {
|
||||
EC_ERR("Buffer too small.\n");
|
||||
ec_sdo_request_clear(&request.req);
|
||||
retval = -EOVERFLOW;
|
||||
break;
|
||||
}
|
||||
data.data_size = request.req.data_size;
|
||||
|
||||
if (copy_to_user((void __user *) data.target,
|
||||
request.req.data, data.data_size)) {
|
||||
ec_sdo_request_clear(&request.req);
|
||||
retval = -EFAULT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (request.req.data_size > data.target_size) {
|
||||
EC_ERR("Buffer too small.\n");
|
||||
retval = -EOVERFLOW;
|
||||
break;
|
||||
}
|
||||
data.data_size = request.req.data_size;
|
||||
|
||||
if (copy_to_user((void __user *) data.target,
|
||||
request.req.data, data.data_size)) {
|
||||
retval = -EFAULT;
|
||||
break;
|
||||
}
|
||||
if (__copy_to_user((void __user *) arg, &data, sizeof(data))) {
|
||||
retval = -EFAULT;
|
||||
break;
|
||||
}
|
||||
|
||||
ec_sdo_request_clear(&request.req);
|
||||
|
|
@ -721,6 +726,7 @@ long eccdev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
|||
if (request.req.state == EC_REQUEST_QUEUED) {
|
||||
list_del(&request.req.list);
|
||||
up(&master->sdo_sem);
|
||||
ec_sdo_request_clear(&request.req);
|
||||
retval = -EINTR;
|
||||
break;
|
||||
}
|
||||
|
|
@ -731,9 +737,14 @@ long eccdev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
|||
// wait until master FSM has finished processing
|
||||
wait_event(master->sdo_queue, request.req.state != EC_REQUEST_BUSY);
|
||||
|
||||
data.abort_code = request.req.abort_code;
|
||||
|
||||
if (request.req.state != EC_REQUEST_SUCCESS) {
|
||||
retval = -EIO;
|
||||
break;
|
||||
}
|
||||
|
||||
if (__copy_to_user((void __user *) arg, &data, sizeof(data))) {
|
||||
retval = -EFAULT;
|
||||
}
|
||||
|
||||
ec_sdo_request_clear(&request.req);
|
||||
|
|
|
|||
|
|
@ -430,11 +430,23 @@ void ec_fsm_coe_dict_response(ec_fsm_coe_t *fsm /**< finite state machine */)
|
|||
return;
|
||||
}
|
||||
|
||||
if (rec_size < 3) {
|
||||
EC_ERR("Received corrupted Sdo dictionary response (size %u).\n",
|
||||
rec_size);
|
||||
fsm->state = ec_fsm_coe_error;
|
||||
return;
|
||||
}
|
||||
|
||||
if (EC_READ_U16(data) >> 12 == 0x8 && // Sdo information
|
||||
(EC_READ_U8(data + 2) & 0x7F) == 0x07) { // error response
|
||||
EC_ERR("Sdo information error response at slave %u!\n",
|
||||
slave->ring_position);
|
||||
ec_canopen_abort_msg(EC_READ_U32(data + 6));
|
||||
if (rec_size < 10) {
|
||||
EC_ERR("Incomplete Sdo information error response:\n");
|
||||
ec_print_data(data, rec_size);
|
||||
} else {
|
||||
ec_canopen_abort_msg(EC_READ_U32(data + 6));
|
||||
}
|
||||
fsm->state = ec_fsm_coe_error;
|
||||
return;
|
||||
}
|
||||
|
|
@ -448,8 +460,8 @@ void ec_fsm_coe_dict_response(ec_fsm_coe_t *fsm /**< finite state machine */)
|
|||
return;
|
||||
}
|
||||
|
||||
if (rec_size < 8) {
|
||||
EC_ERR("Invalid data size!\n");
|
||||
if (rec_size < 8 || rec_size % 2) {
|
||||
EC_ERR("Invalid data size %u!\n", rec_size);
|
||||
ec_print_data(data, rec_size);
|
||||
fsm->state = ec_fsm_coe_error;
|
||||
return;
|
||||
|
|
@ -656,6 +668,13 @@ void ec_fsm_coe_dict_desc_response(ec_fsm_coe_t *fsm
|
|||
return;
|
||||
}
|
||||
|
||||
if (rec_size < 3) {
|
||||
EC_ERR("Received corrupted Sdo description response (size %u).\n",
|
||||
rec_size);
|
||||
fsm->state = ec_fsm_coe_error;
|
||||
return;
|
||||
}
|
||||
|
||||
if (EC_READ_U16(data) >> 12 == 0x8 && // Sdo information
|
||||
(EC_READ_U8 (data + 2) & 0x7F) == 0x07) { // error response
|
||||
EC_ERR("Sdo information error response at slave %u while"
|
||||
|
|
@ -666,6 +685,13 @@ void ec_fsm_coe_dict_desc_response(ec_fsm_coe_t *fsm
|
|||
return;
|
||||
}
|
||||
|
||||
if (rec_size < 8) {
|
||||
EC_ERR("Received corrupted Sdo description response (size %u).\n",
|
||||
rec_size);
|
||||
fsm->state = ec_fsm_coe_error;
|
||||
return;
|
||||
}
|
||||
|
||||
if (EC_READ_U16(data) >> 12 != 0x8 || // Sdo information
|
||||
(EC_READ_U8 (data + 2) & 0x7F) != 0x04 || // Object desc. response
|
||||
EC_READ_U16(data + 6) != sdo->index) { // Sdo index
|
||||
|
|
@ -872,6 +898,13 @@ void ec_fsm_coe_dict_entry_response(ec_fsm_coe_t *fsm
|
|||
return;
|
||||
}
|
||||
|
||||
if (rec_size < 3) {
|
||||
EC_ERR("Received corrupted Sdo entry description response "
|
||||
"(size %u).\n", rec_size);
|
||||
fsm->state = ec_fsm_coe_error;
|
||||
return;
|
||||
}
|
||||
|
||||
if (EC_READ_U16(data) >> 12 == 0x8 && // Sdo information
|
||||
(EC_READ_U8 (data + 2) & 0x7F) == 0x07) { // error response
|
||||
EC_ERR("Sdo information error response at slave %u while"
|
||||
|
|
@ -882,6 +915,13 @@ void ec_fsm_coe_dict_entry_response(ec_fsm_coe_t *fsm
|
|||
return;
|
||||
}
|
||||
|
||||
if (rec_size < 9) {
|
||||
EC_ERR("Received corrupted Sdo entry description response "
|
||||
"(size %u).\n", rec_size);
|
||||
fsm->state = ec_fsm_coe_error;
|
||||
return;
|
||||
}
|
||||
|
||||
if (EC_READ_U16(data) >> 12 != 0x8 || // Sdo information
|
||||
(EC_READ_U8(data + 2) & 0x7F) != 0x06 || // Entry desc. response
|
||||
EC_READ_U16(data + 6) != sdo->index || // Sdo index
|
||||
|
|
@ -895,7 +935,7 @@ void ec_fsm_coe_dict_entry_response(ec_fsm_coe_t *fsm
|
|||
}
|
||||
|
||||
if (rec_size < 16) {
|
||||
EC_ERR("Invalid data size!\n");
|
||||
EC_ERR("Invalid data size %u!\n", rec_size);
|
||||
ec_print_data(data, rec_size);
|
||||
fsm->state = ec_fsm_coe_error;
|
||||
return;
|
||||
|
|
@ -1191,7 +1231,7 @@ void ec_fsm_coe_down_response(ec_fsm_coe_t *fsm /**< finite state machine */)
|
|||
|
||||
if (rec_size < 6) {
|
||||
fsm->state = ec_fsm_coe_error;
|
||||
EC_ERR("Received data is too small (%u bytes):\n", rec_size);
|
||||
EC_ERR("Received data are too small (%u bytes):\n", rec_size);
|
||||
ec_print_data(data, rec_size);
|
||||
return;
|
||||
}
|
||||
|
|
@ -1205,9 +1245,10 @@ void ec_fsm_coe_down_response(ec_fsm_coe_t *fsm /**< finite state machine */)
|
|||
if (rec_size < 10) {
|
||||
EC_ERR("Incomplete Abort command:\n");
|
||||
ec_print_data(data, rec_size);
|
||||
} else {
|
||||
fsm->request->abort_code = EC_READ_U32(data + 6);
|
||||
ec_canopen_abort_msg(fsm->request->abort_code);
|
||||
}
|
||||
else
|
||||
ec_canopen_abort_msg(EC_READ_U32(data + 6));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1446,10 +1487,12 @@ void ec_fsm_coe_up_response(ec_fsm_coe_t *fsm /**< finite state machine */)
|
|||
EC_READ_U8 (data + 2) >> 5 == 0x4) { // abort Sdo transfer request
|
||||
EC_ERR("Sdo upload 0x%04X:%02X aborted on slave %u.\n",
|
||||
request->index, request->subindex, slave->ring_position);
|
||||
if (rec_size >= 10)
|
||||
ec_canopen_abort_msg(EC_READ_U32(data + 6));
|
||||
else
|
||||
if (rec_size >= 10) {
|
||||
request->abort_code = EC_READ_U32(data + 6);
|
||||
ec_canopen_abort_msg(request->abort_code);
|
||||
} else {
|
||||
EC_ERR("No abort message.\n");
|
||||
}
|
||||
fsm->state = ec_fsm_coe_error;
|
||||
return;
|
||||
}
|
||||
|
|
@ -1737,7 +1780,8 @@ void ec_fsm_coe_up_seg_response(ec_fsm_coe_t *fsm /**< finite state machine */)
|
|||
EC_READ_U8 (data + 2) >> 5 == 0x4) { // abort Sdo transfer request
|
||||
EC_ERR("Sdo upload 0x%04X:%02X aborted on slave %u.\n",
|
||||
request->index, request->subindex, slave->ring_position);
|
||||
ec_canopen_abort_msg(EC_READ_U32(data + 6));
|
||||
request->abort_code = EC_READ_U32(data + 6);
|
||||
ec_canopen_abort_msg(request->abort_code);
|
||||
fsm->state = ec_fsm_coe_error;
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@
|
|||
#define EC_IOCTL_SDO EC_IOWR(0x0a, ec_ioctl_sdo_t)
|
||||
#define EC_IOCTL_SDO_ENTRY EC_IOWR(0x0b, ec_ioctl_sdo_entry_t)
|
||||
#define EC_IOCTL_SDO_UPLOAD EC_IOWR(0x0c, ec_ioctl_sdo_upload_t)
|
||||
#define EC_IOCTL_SDO_DOWNLOAD EC_IOW(0x0d, ec_ioctl_sdo_download_t)
|
||||
#define EC_IOCTL_SDO_DOWNLOAD EC_IOWR(0x0d, ec_ioctl_sdo_download_t)
|
||||
#define EC_IOCTL_SII_READ EC_IOWR(0x0e, ec_ioctl_sii_t)
|
||||
#define EC_IOCTL_SII_WRITE EC_IOW(0x0f, ec_ioctl_sii_t)
|
||||
#define EC_IOCTL_CONFIG EC_IOWR(0x10, ec_ioctl_config_t)
|
||||
|
|
@ -253,6 +253,7 @@ typedef struct {
|
|||
|
||||
// outputs
|
||||
uint32_t data_size;
|
||||
uint32_t abort_code;
|
||||
} ec_ioctl_sdo_upload_t;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
@ -264,6 +265,9 @@ typedef struct {
|
|||
uint8_t sdo_entry_subindex;
|
||||
uint32_t data_size;
|
||||
uint8_t *data;
|
||||
|
||||
// outputs
|
||||
uint32_t abort_code;
|
||||
} ec_ioctl_sdo_download_t;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@ void ec_sdo_request_init(
|
|||
req->issue_timeout = 0; // no timeout
|
||||
req->response_timeout = 0; // immediate response required
|
||||
req->state = EC_REQUEST_INIT;
|
||||
req->abort_code = 0x00000000;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
@ -211,6 +212,7 @@ void ecrt_sdo_request_read(ec_sdo_request_t *req)
|
|||
{
|
||||
req->dir = EC_DIR_INPUT;
|
||||
req->state = EC_REQUEST_QUEUED;
|
||||
req->abort_code = 0x00000000;
|
||||
req->jiffies_start = jiffies;
|
||||
}
|
||||
|
||||
|
|
@ -220,6 +222,7 @@ void ecrt_sdo_request_write(ec_sdo_request_t *req)
|
|||
{
|
||||
req->dir = EC_DIR_OUTPUT;
|
||||
req->state = EC_REQUEST_QUEUED;
|
||||
req->abort_code = 0x00000000;
|
||||
req->jiffies_start = jiffies;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ struct ec_sdo_request {
|
|||
unsigned long jiffies_start; /**< Jiffies, when the request was issued. */
|
||||
unsigned long jiffies_sent; /**< Jiffies, when the upload/download
|
||||
request was sent. */
|
||||
uint32_t abort_code; /**< Sdo request abort code. Zero on success. */
|
||||
};
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -656,7 +656,13 @@ void Master::sdoDownload(
|
|||
|
||||
if (ioctl(fd, EC_IOCTL_SDO_DOWNLOAD, &data) < 0) {
|
||||
stringstream err;
|
||||
err << "Failed to download Sdo: " << strerror(errno);
|
||||
err << "Failed to download Sdo: ";
|
||||
if (errno == EIO && data.abort_code) {
|
||||
err << "Abort code 0x" << hex << setfill('0') << setw(8)
|
||||
<< data.abort_code;
|
||||
} else {
|
||||
err << strerror(errno);
|
||||
}
|
||||
delete [] data.data;
|
||||
throw MasterException(err.str());
|
||||
}
|
||||
|
|
@ -751,7 +757,13 @@ void Master::sdoUpload(
|
|||
|
||||
if (ioctl(fd, EC_IOCTL_SDO_UPLOAD, &data) < 0) {
|
||||
stringstream err;
|
||||
err << "Failed to upload Sdo: " << strerror(errno);
|
||||
err << "Failed to upload Sdo: ";
|
||||
if (errno == EIO && data.abort_code) {
|
||||
err << "Abort code 0x" << hex << setfill('0') << setw(8)
|
||||
<< data.abort_code;
|
||||
} else {
|
||||
err << strerror(errno);
|
||||
}
|
||||
delete [] data.target;
|
||||
close();
|
||||
throw MasterException(err.str());
|
||||
|
|
|
|||
Loading…
Reference in New Issue