merge -c1619 branches/1.4-foe: Implemented going to bootstrap state BOOT.

This commit is contained in:
Florian Pose 2009-01-26 13:22:05 +00:00
parent 8d45915fc4
commit 5d4b915317
18 changed files with 222 additions and 105 deletions

3
NEWS
View File

@ -19,6 +19,9 @@ Changes since 1.4.0:
physical device.
* Improved error case return codes of many functions.
* Added 8139too driver for 2.6.25.
* Implemented the File Access over EtherCAT (FoE) mailbox protocol.
* Going to the Bootstrap state is now supported by the state machines and the
command-line tool.
Changes in 1.4.0:

View File

@ -226,10 +226,14 @@ int ec_cdev_ioctl_slave(
data.revision_number = slave->sii.revision_number;
data.serial_number = slave->sii.serial_number;
data.alias = slave->sii.alias;
data.rx_mailbox_offset = slave->sii.rx_mailbox_offset;
data.rx_mailbox_size = slave->sii.rx_mailbox_size;
data.tx_mailbox_offset = slave->sii.tx_mailbox_offset;
data.tx_mailbox_size = slave->sii.tx_mailbox_size;
data.boot_rx_mailbox_offset = slave->sii.boot_rx_mailbox_offset;
data.boot_rx_mailbox_size = slave->sii.boot_rx_mailbox_size;
data.boot_tx_mailbox_offset = slave->sii.boot_tx_mailbox_offset;
data.boot_tx_mailbox_size = slave->sii.boot_tx_mailbox_size;
data.std_rx_mailbox_offset = slave->sii.std_rx_mailbox_offset;
data.std_rx_mailbox_size = slave->sii.std_rx_mailbox_size;
data.std_tx_mailbox_offset = slave->sii.std_tx_mailbox_offset;
data.std_tx_mailbox_size = slave->sii.std_tx_mailbox_size;
data.mailbox_protocols = slave->sii.mailbox_protocols;
data.has_general_category = slave->sii.has_general;
data.coe_details = slave->sii.coe_details;

View File

@ -218,6 +218,7 @@ void ec_eoe_flush(ec_eoe_t *eoe /**< EoE handler */)
/**
Sends a frame or the next fragment.
\todo bootstrap mailboxes / use configured mailbox sizes
*/
int ec_eoe_send(ec_eoe_t *eoe /**< EoE handler */)
@ -231,12 +232,11 @@ int ec_eoe_send(ec_eoe_t *eoe /**< EoE handler */)
remaining_size = eoe->tx_frame->skb->len - eoe->tx_offset;
if (remaining_size <= eoe->slave->sii.tx_mailbox_size - 10) {
if (remaining_size <= eoe->slave->sii.std_tx_mailbox_size - 10) {
current_size = remaining_size;
last_fragment = 1;
}
else {
current_size = ((eoe->slave->sii.tx_mailbox_size - 10) / 32) * 32;
} else {
current_size = ((eoe->slave->sii.std_tx_mailbox_size - 10) / 32) * 32;
last_fragment = 0;
}

View File

@ -187,7 +187,7 @@ void ec_fsm_change_state_check(ec_fsm_change_t *fsm
if (datagram->working_counter == 0) {
if (datagram->jiffies_received - fsm->jiffies_start >= 3 * HZ) {
char state_str[EC_STATE_STRING_SIZE];
ec_state_string(fsm->requested_state, state_str);
ec_state_string(fsm->requested_state, state_str, 0);
fsm->state = ec_fsm_change_state_error;
EC_ERR("Failed to set state %s on slave %u: ",
state_str, fsm->slave->ring_position);
@ -204,7 +204,7 @@ void ec_fsm_change_state_check(ec_fsm_change_t *fsm
if (unlikely(datagram->working_counter > 1)) {
char state_str[EC_STATE_STRING_SIZE];
ec_state_string(fsm->requested_state, state_str);
ec_state_string(fsm->requested_state, state_str, 0);
fsm->state = ec_fsm_change_state_error;
EC_ERR("Failed to set state %s on slave %u: ",
state_str, fsm->slave->ring_position);
@ -247,7 +247,7 @@ void ec_fsm_change_state_status(ec_fsm_change_t *fsm
if (datagram->working_counter != 1) {
char req_state[EC_STATE_STRING_SIZE];
ec_state_string(fsm->requested_state, req_state);
ec_state_string(fsm->requested_state, req_state, 0);
fsm->state = ec_fsm_change_state_error;
EC_ERR("Failed to check state %s on slave %u: ",
req_state, slave->ring_position);
@ -271,7 +271,7 @@ void ec_fsm_change_state_status(ec_fsm_change_t *fsm
if (slave->current_state != fsm->old_state) { // state changed
char req_state[EC_STATE_STRING_SIZE], cur_state[EC_STATE_STRING_SIZE];
ec_state_string(slave->current_state, cur_state);
ec_state_string(slave->current_state, cur_state, 0);
if ((slave->current_state & 0x0F) != (fsm->old_state & 0x0F)) {
// Slave spontaneously changed its state just before the new state
@ -287,7 +287,7 @@ void ec_fsm_change_state_status(ec_fsm_change_t *fsm
// state change error
slave->error_flag = 1;
ec_state_string(fsm->requested_state, req_state);
ec_state_string(fsm->requested_state, req_state, 0);
EC_ERR("Failed to set %s state, slave %u refused state change (%s).\n",
req_state, slave->ring_position, cur_state);
@ -304,7 +304,7 @@ void ec_fsm_change_state_status(ec_fsm_change_t *fsm
if (datagram->jiffies_received - fsm->jiffies_start >= HZ) { // 1s
// timeout while checking
char state_str[EC_STATE_STRING_SIZE];
ec_state_string(fsm->requested_state, state_str);
ec_state_string(fsm->requested_state, state_str, 0);
fsm->state = ec_fsm_change_state_error;
EC_ERR("Timeout while setting state %s on slave %u.\n",
state_str, slave->ring_position);
@ -326,7 +326,7 @@ void ec_fsm_change_state_status(ec_fsm_change_t *fsm
const ec_code_msg_t al_status_messages[] = {
{0x0001, "Unspecified error"},
{0x0011, "Invalud requested state change"},
{0x0011, "Invalid requested state change"},
{0x0012, "Unknown requested state"},
{0x0013, "Bootstrap not supported"},
{0x0014, "No valid firmware"},
@ -498,7 +498,7 @@ void ec_fsm_change_state_check_ack(ec_fsm_change_t *fsm
if (!(slave->current_state & EC_SLAVE_STATE_ACK_ERR)) {
char state_str[EC_STATE_STRING_SIZE];
ec_state_string(slave->current_state, state_str);
ec_state_string(slave->current_state, state_str, 0);
if (fsm->mode == EC_FSM_CHANGE_MODE_FULL) {
fsm->state = ec_fsm_change_state_error;
}
@ -513,7 +513,7 @@ void ec_fsm_change_state_check_ack(ec_fsm_change_t *fsm
if (datagram->jiffies_received - fsm->jiffies_start >= HZ) { // 1s
// timeout while checking
char state_str[EC_STATE_STRING_SIZE];
ec_state_string(slave->current_state, state_str);
ec_state_string(slave->current_state, state_str, 0);
fsm->state = ec_fsm_change_state_error;
EC_ERR("Timeout while acknowledging state %s on slave %u.\n",
state_str, slave->ring_position);

View File

@ -1095,7 +1095,7 @@ void ec_fsm_coe_down_start(ec_fsm_coe_t *fsm /**< finite state machine */)
}
}
else { // request->data_size > 4, use normal transfer type
if (slave->sii.rx_mailbox_size < 6 + 10 + request->data_size) {
if (slave->sii.std_rx_mailbox_size < 6 + 10 + request->data_size) {
EC_ERR("SDO fragmenting not supported yet!\n");
fsm->state = ec_fsm_coe_error;
return;

View File

@ -214,12 +214,13 @@ int ec_foe_prepare_data_send( ec_fsm_foe_t *fsm ) {
remaining_size = fsm->tx_buffer_size - fsm->tx_buffer_offset;
if (remaining_size < fsm->slave->sii.tx_mailbox_size - EC_MBOX_HEADER_SIZE - EC_FOE_HEADER_SIZE) {
if (remaining_size < fsm->slave->sii.std_tx_mailbox_size
- EC_MBOX_HEADER_SIZE - EC_FOE_HEADER_SIZE) {
current_size = remaining_size;
fsm->tx_last_packet = 1;
}
else {
current_size = fsm->slave->sii.tx_mailbox_size - EC_MBOX_HEADER_SIZE - EC_FOE_HEADER_SIZE;
} else {
current_size = fsm->slave->sii.std_tx_mailbox_size
- EC_MBOX_HEADER_SIZE - EC_FOE_HEADER_SIZE;
}
if (!(data = ec_slave_mbox_prepare_send(fsm->slave, fsm->datagram,
@ -788,12 +789,12 @@ void ec_fsm_foe_state_data_read ( ec_fsm_foe_t *fsm ) {
fsm->rx_last_packet =
(rec_size + EC_MBOX_HEADER_SIZE + EC_FOE_HEADER_SIZE
!= fsm->slave->sii.rx_mailbox_size);
!= fsm->slave->sii.std_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) {
// either it was the last packet or a new packet will fit into the delivered buffer
(slave->sii.std_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");
#endif
@ -811,7 +812,7 @@ void ec_fsm_foe_state_data_read ( ec_fsm_foe_t *fsm ) {
printk (" rx_buffer_size = %d\n", fsm->rx_buffer_size);
printk (" rx_buffer_offset= %d\n", fsm->rx_buffer_offset);
printk (" rec_size = %d\n", rec_size);
printk (" rx_mailbox_size = %d\n", slave->sii.rx_mailbox_size);
printk (" rx_mailbox_size = %d\n", slave->sii.std_rx_mailbox_size);
printk (" rx_last_packet = %d\n", fsm->rx_last_packet);
// fsm->state = ec_fsm_state_wait_next_read;
fsm->request->result = FOE_READY;

View File

@ -201,7 +201,7 @@ void ec_fsm_master_state_broadcast(
if (states != fsm->slave_states) { // slave states changed?
char state_str[EC_STATE_STRING_SIZE];
fsm->slave_states = states;
ec_state_string(fsm->slave_states, state_str);
ec_state_string(fsm->slave_states, state_str, 1);
EC_INFO("Slave states: %s.\n", state_str);
}
} else {
@ -622,8 +622,8 @@ void ec_fsm_master_action_configure(
if (master->debug_level) {
char old_state[EC_STATE_STRING_SIZE],
new_state[EC_STATE_STRING_SIZE];
ec_state_string(slave->current_state, old_state);
ec_state_string(slave->requested_state, new_state);
ec_state_string(slave->current_state, old_state, 0);
ec_state_string(slave->requested_state, new_state, 0);
EC_DBG("Changing state of slave %u from %s to %s%s.\n",
slave->ring_position, old_state, new_state,
slave->force_config ? " (forced)" : "");

View File

@ -43,7 +43,7 @@ void ec_fsm_slave_config_state_start(ec_fsm_slave_config_t *);
void ec_fsm_slave_config_state_init(ec_fsm_slave_config_t *);
void ec_fsm_slave_config_state_clear_fmmus(ec_fsm_slave_config_t *);
void ec_fsm_slave_config_state_mbox_sync(ec_fsm_slave_config_t *);
void ec_fsm_slave_config_state_preop(ec_fsm_slave_config_t *);
void ec_fsm_slave_config_state_boot_preop(ec_fsm_slave_config_t *);
void ec_fsm_slave_config_state_sdo_conf(ec_fsm_slave_config_t *);
void ec_fsm_slave_config_state_pdo_sync(ec_fsm_slave_config_t *);
void ec_fsm_slave_config_state_pdo_conf(ec_fsm_slave_config_t *);
@ -53,7 +53,7 @@ void ec_fsm_slave_config_state_op(ec_fsm_slave_config_t *);
void ec_fsm_slave_config_enter_init(ec_fsm_slave_config_t *);
void ec_fsm_slave_config_enter_mbox_sync(ec_fsm_slave_config_t *);
void ec_fsm_slave_config_enter_preop(ec_fsm_slave_config_t *);
void ec_fsm_slave_config_enter_boot_preop(ec_fsm_slave_config_t *);
void ec_fsm_slave_config_enter_sdo_conf(ec_fsm_slave_config_t *);
void ec_fsm_slave_config_enter_pdo_conf(ec_fsm_slave_config_t *);
void ec_fsm_slave_config_enter_pdo_sync(ec_fsm_slave_config_t *);
@ -289,7 +289,7 @@ void ec_fsm_slave_config_enter_mbox_sync(
if (master->debug_level)
EC_DBG("Slave %u does not support mailbox communication.\n",
slave->ring_position);
ec_fsm_slave_config_enter_preop(fsm);
ec_fsm_slave_config_enter_boot_preop(fsm);
return;
}
@ -298,7 +298,29 @@ void ec_fsm_slave_config_enter_mbox_sync(
slave->ring_position);
}
if (slave->sii.sync_count >= 2) { // mailbox configuration provided
if (slave->requested_state == EC_SLAVE_STATE_BOOT) {
ec_sync_t sync;
ec_datagram_fpwr(datagram, slave->station_address, 0x0800,
EC_SYNC_PAGE_SIZE * 2);
memset(datagram->data, 0x00, EC_SYNC_PAGE_SIZE * 2);
ec_sync_init(&sync, slave);
sync.physical_start_address = slave->sii.boot_rx_mailbox_offset;
sync.control_register = 0x26;
sync.enable = 1;
ec_sync_page(&sync, 0, slave->sii.boot_rx_mailbox_size,
EC_DIR_INVALID, // use default direction
datagram->data);
ec_sync_init(&sync, slave);
sync.physical_start_address = slave->sii.boot_tx_mailbox_offset;
sync.control_register = 0x22;
sync.enable = 1;
ec_sync_page(&sync, 1, slave->sii.boot_tx_mailbox_size,
EC_DIR_INVALID, // use default direction
datagram->data + EC_SYNC_PAGE_SIZE);
} else if (slave->sii.sync_count >= 2) { // mailbox configuration provided
ec_datagram_fpwr(datagram, slave->station_address, 0x0800,
EC_SYNC_PAGE_SIZE * slave->sii.sync_count);
ec_datagram_zero(datagram);
@ -322,18 +344,18 @@ void ec_fsm_slave_config_enter_mbox_sync(
ec_datagram_zero(datagram);
ec_sync_init(&sync, slave);
sync.physical_start_address = slave->sii.rx_mailbox_offset;
sync.physical_start_address = slave->sii.std_rx_mailbox_offset;
sync.control_register = 0x26;
sync.enable = 1;
ec_sync_page(&sync, 0, slave->sii.rx_mailbox_size,
ec_sync_page(&sync, 0, slave->sii.std_rx_mailbox_size,
EC_DIR_INVALID, // use default direction
datagram->data);
ec_sync_init(&sync, slave);
sync.physical_start_address = slave->sii.tx_mailbox_offset;
sync.physical_start_address = slave->sii.std_tx_mailbox_offset;
sync.control_register = 0x22;
sync.enable = 1;
ec_sync_page(&sync, 1, slave->sii.tx_mailbox_size,
ec_sync_page(&sync, 1, slave->sii.std_tx_mailbox_size,
EC_DIR_INVALID, // use default direction
datagram->data + EC_SYNC_PAGE_SIZE);
}
@ -373,27 +395,33 @@ void ec_fsm_slave_config_state_mbox_sync(
return;
}
ec_fsm_slave_config_enter_preop(fsm);
ec_fsm_slave_config_enter_boot_preop(fsm);
}
/*****************************************************************************/
/** Request PREOP state.
*/
void ec_fsm_slave_config_enter_preop(
void ec_fsm_slave_config_enter_boot_preop(
ec_fsm_slave_config_t *fsm /**< slave state machine */
)
{
fsm->state = ec_fsm_slave_config_state_preop;
ec_fsm_change_start(fsm->fsm_change, fsm->slave, EC_SLAVE_STATE_PREOP);
fsm->state = ec_fsm_slave_config_state_boot_preop;
if (fsm->slave->requested_state != EC_SLAVE_STATE_BOOT) {
ec_fsm_change_start(fsm->fsm_change, fsm->slave, EC_SLAVE_STATE_PREOP);
} else { // BOOT
ec_fsm_change_start(fsm->fsm_change, fsm->slave, EC_SLAVE_STATE_BOOT);
}
ec_fsm_change_exec(fsm->fsm_change); // execute immediately
}
/*****************************************************************************/
/** Slave configuration state: PREOP.
/** Slave configuration state: BOOT/PREOP.
*/
void ec_fsm_slave_config_state_preop(
void ec_fsm_slave_config_state_boot_preop(
ec_fsm_slave_config_t *fsm /**< slave state machine */
)
{
@ -409,11 +437,13 @@ void ec_fsm_slave_config_state_preop(
return;
}
// slave is now in PREOP
// slave is now in BOOT/PREOP
slave->jiffies_preop = fsm->datagram->jiffies_received;
if (master->debug_level) {
EC_DBG("Slave %u is now in PREOP.\n", slave->ring_position);
EC_DBG("Slave %u is now in %s.\n", slave->ring_position,
slave->requested_state != EC_SLAVE_STATE_BOOT
? "PREOP" : "BOOT");
}
if (slave->current_state == slave->requested_state) {

View File

@ -237,7 +237,7 @@ void ec_fsm_slave_scan_state_state(
slave->current_state = EC_READ_U8(datagram->data);
if (slave->current_state & EC_SLAVE_STATE_ACK_ERR) {
char state_str[EC_STATE_STRING_SIZE];
ec_state_string(slave->current_state, state_str);
ec_state_string(slave->current_state, state_str, 0);
EC_WARN("Slave %u has state error bit set (%s)!\n",
slave->ring_position, state_str);
}
@ -469,13 +469,21 @@ void ec_fsm_slave_scan_state_sii_data(ec_fsm_slave_scan_t *fsm /**< slave state
EC_READ_U32(slave->sii_words + 0x000C);
slave->sii.serial_number =
EC_READ_U32(slave->sii_words + 0x000E);
slave->sii.rx_mailbox_offset =
slave->sii.boot_rx_mailbox_offset =
EC_READ_U16(slave->sii_words + 0x0014);
slave->sii.boot_rx_mailbox_size =
EC_READ_U16(slave->sii_words + 0x0015);
slave->sii.boot_tx_mailbox_offset =
EC_READ_U16(slave->sii_words + 0x0016);
slave->sii.boot_tx_mailbox_size =
EC_READ_U16(slave->sii_words + 0x0017);
slave->sii.std_rx_mailbox_offset =
EC_READ_U16(slave->sii_words + 0x0018);
slave->sii.rx_mailbox_size =
slave->sii.std_rx_mailbox_size =
EC_READ_U16(slave->sii_words + 0x0019);
slave->sii.tx_mailbox_offset =
slave->sii.std_tx_mailbox_offset =
EC_READ_U16(slave->sii_words + 0x001A);
slave->sii.tx_mailbox_size =
slave->sii.std_tx_mailbox_size =
EC_READ_U16(slave->sii_words + 0x001B);
slave->sii.mailbox_protocols =
EC_READ_U16(slave->sii_words + 0x001C);

View File

@ -115,6 +115,8 @@ typedef enum {
/**< INIT state (no mailbox communication, no IO) */
EC_SLAVE_STATE_PREOP = 0x02,
/**< PREOP state (mailbox communication, no IO) */
EC_SLAVE_STATE_BOOT = 0x03,
/**< Bootstrap state (mailbox communication, firmware update) */
EC_SLAVE_STATE_SAFEOP = 0x04,
/**< SAFEOP (mailbox communication and input update) */
EC_SLAVE_STATE_OP = 0x08,
@ -226,7 +228,7 @@ extern char *ec_master_version_str;
void ec_print_data(const uint8_t *, size_t);
void ec_print_data_diff(const uint8_t *, const uint8_t *, size_t);
size_t ec_state_string(uint8_t, char *);
size_t ec_state_string(uint8_t, char *, uint8_t);
ssize_t ec_mac_print(const uint8_t *, char *);
int ec_mac_is_zero(const uint8_t *);

View File

@ -135,10 +135,14 @@ typedef struct {
uint32_t revision_number;
uint32_t serial_number;
uint16_t alias;
uint16_t rx_mailbox_offset;
uint16_t rx_mailbox_size;
uint16_t tx_mailbox_offset;
uint16_t tx_mailbox_size;
uint16_t boot_rx_mailbox_offset;
uint16_t boot_rx_mailbox_size;
uint16_t boot_tx_mailbox_offset;
uint16_t boot_tx_mailbox_size;
uint16_t std_rx_mailbox_offset;
uint16_t std_rx_mailbox_size;
uint16_t std_tx_mailbox_offset;
uint16_t std_tx_mailbox_size;
uint16_t mailbox_protocols;
uint8_t has_general_category;
ec_sii_coe_details_t coe_details;

View File

@ -53,6 +53,7 @@ uint8_t *ec_slave_mbox_prepare_send(const ec_slave_t *slave, /**< slave */
{
size_t total_size;
int ret;
uint16_t mailbox_offset, mailbox_size;
if (unlikely(!slave->sii.mailbox_protocols)) {
EC_ERR("Slave %u does not support mailbox communication!\n",
@ -61,14 +62,22 @@ uint8_t *ec_slave_mbox_prepare_send(const ec_slave_t *slave, /**< slave */
}
total_size = EC_MBOX_HEADER_SIZE + size;
if (unlikely(total_size > slave->sii.rx_mailbox_size)) {
if (slave->current_state != EC_SLAVE_STATE_BOOT) {
mailbox_offset = slave->sii.std_rx_mailbox_offset;
mailbox_size = slave->sii.std_rx_mailbox_size;
} else {
mailbox_offset = slave->sii.boot_rx_mailbox_offset;
mailbox_size = slave->sii.boot_rx_mailbox_size;
}
if (unlikely(total_size > mailbox_size)) {
EC_ERR("Data size does not fit in mailbox!\n");
return ERR_PTR(-EOVERFLOW);
}
ret = ec_datagram_fpwr(datagram, slave->station_address,
slave->sii.rx_mailbox_offset,
slave->sii.rx_mailbox_size);
mailbox_offset, mailbox_size);
if (ret)
return ERR_PTR(ret);
@ -123,9 +132,19 @@ int ec_slave_mbox_prepare_fetch(const ec_slave_t *slave, /**< slave */
ec_datagram_t *datagram /**< datagram */
)
{
int ret = ec_datagram_fprd(datagram, slave->station_address,
slave->sii.tx_mailbox_offset,
slave->sii.tx_mailbox_size);
int ret;
uint16_t mailbox_offset, mailbox_size;
if (slave->current_state != EC_SLAVE_STATE_BOOT) {
mailbox_offset = slave->sii.std_tx_mailbox_offset;
mailbox_size = slave->sii.std_tx_mailbox_size;
} else {
mailbox_offset = slave->sii.boot_tx_mailbox_offset;
mailbox_size = slave->sii.boot_tx_mailbox_size;
}
ret = ec_datagram_fprd(datagram, slave->station_address,
mailbox_offset, mailbox_size);
if (ret)
return ret;
@ -164,13 +183,22 @@ uint8_t *ec_slave_mbox_fetch(const ec_slave_t *slave, /**< slave */
)
{
size_t data_size;
uint16_t mailbox_offset, mailbox_size;
if (slave->current_state != EC_SLAVE_STATE_BOOT) {
mailbox_offset = slave->sii.std_tx_mailbox_offset;
mailbox_size = slave->sii.std_tx_mailbox_size;
} else {
mailbox_offset = slave->sii.boot_tx_mailbox_offset;
mailbox_size = slave->sii.boot_tx_mailbox_size;
}
data_size = EC_READ_U16(datagram->data);
if (data_size + EC_MBOX_HEADER_SIZE > slave->sii.tx_mailbox_size) {
if (data_size + EC_MBOX_HEADER_SIZE > mailbox_size) {
EC_ERR("Corrupt mailbox response received from slave %u!\n",
slave->ring_position);
ec_print_data(datagram->data, slave->sii.tx_mailbox_size);
slave->ring_position);
ec_print_data(datagram->data, mailbox_size);
return ERR_PTR(-EPROTO);
}
@ -185,9 +213,10 @@ uint8_t *ec_slave_mbox_fetch(const ec_slave_t *slave, /**< slave */
slave->ring_position);
for (mbox_msg = mbox_error_messages; mbox_msg->code; mbox_msg++) {
if (mbox_msg->code != code) continue;
if (mbox_msg->code != code)
continue;
printk("Code 0x%04X: \"%s\".\n",
mbox_msg->code, mbox_msg->message);
mbox_msg->code, mbox_msg->message);
break;
}

View File

@ -358,8 +358,9 @@ void ec_print_data_diff(const uint8_t *d1, /**< first data */
/** Prints slave states in clear text.
*/
size_t ec_state_string(uint8_t states, /**< slave states */
char *buffer /**< target buffer
char *buffer, /**< target buffer
(min. EC_STATE_STRING_SIZE bytes) */
uint8_t multi /**< Show multi-state mask. */
)
{
off_t off = 0;
@ -370,24 +371,42 @@ size_t ec_state_string(uint8_t states, /**< slave states */
return off;
}
if (states & EC_SLAVE_STATE_INIT) {
off += sprintf(buffer + off, "INIT");
if (multi) { // multiple slaves
if (states & EC_SLAVE_STATE_INIT) {
off += sprintf(buffer + off, "INIT");
first = 0;
}
if (states & EC_SLAVE_STATE_PREOP) {
if (!first) off += sprintf(buffer + off, ", ");
off += sprintf(buffer + off, "PREOP");
first = 0;
}
if (states & EC_SLAVE_STATE_SAFEOP) {
if (!first) off += sprintf(buffer + off, ", ");
off += sprintf(buffer + off, "SAFEOP");
first = 0;
}
if (states & EC_SLAVE_STATE_OP) {
if (!first) off += sprintf(buffer + off, ", ");
off += sprintf(buffer + off, "OP");
}
} else { // single slave
if ((states & EC_SLAVE_STATE_MASK) == EC_SLAVE_STATE_INIT) {
off += sprintf(buffer + off, "INIT");
} else if ((states & EC_SLAVE_STATE_MASK) == EC_SLAVE_STATE_PREOP) {
off += sprintf(buffer + off, "PREOP");
} else if ((states & EC_SLAVE_STATE_MASK) == EC_SLAVE_STATE_BOOT) {
off += sprintf(buffer + off, "BOOT");
} else if ((states & EC_SLAVE_STATE_MASK) == EC_SLAVE_STATE_SAFEOP) {
off += sprintf(buffer + off, "SAFEOP");
} else if ((states & EC_SLAVE_STATE_MASK) == EC_SLAVE_STATE_OP) {
off += sprintf(buffer + off, "OP");
} else {
off += sprintf(buffer + off, "(invalid)");
}
first = 0;
}
if (states & EC_SLAVE_STATE_PREOP) {
if (!first) off += sprintf(buffer + off, ", ");
off += sprintf(buffer + off, "PREOP");
first = 0;
}
if (states & EC_SLAVE_STATE_SAFEOP) {
if (!first) off += sprintf(buffer + off, ", ");
off += sprintf(buffer + off, "SAFEOP");
first = 0;
}
if (states & EC_SLAVE_STATE_OP) {
if (!first) off += sprintf(buffer + off, ", ");
off += sprintf(buffer + off, "OP");
}
if (states & EC_SLAVE_STATE_ACK_ERR) {
if (!first) off += sprintf(buffer + off, " + ");
off += sprintf(buffer + off, "ERROR");

View File

@ -90,15 +90,19 @@ void ec_slave_init(
slave->sii_words = NULL;
slave->sii_nwords = 0;
slave->sii.alias = 0;
slave->sii.vendor_id = 0;
slave->sii.product_code = 0;
slave->sii.revision_number = 0;
slave->sii.serial_number = 0;
slave->sii.rx_mailbox_offset = 0;
slave->sii.rx_mailbox_size = 0;
slave->sii.tx_mailbox_offset = 0;
slave->sii.tx_mailbox_size = 0;
slave->sii.alias = 0x0000;
slave->sii.vendor_id = 0x00000000;
slave->sii.product_code = 0x00000000;
slave->sii.revision_number = 0x00000000;
slave->sii.serial_number = 0x00000000;
slave->sii.boot_rx_mailbox_offset = 0x0000;
slave->sii.boot_rx_mailbox_size = 0x0000;
slave->sii.boot_tx_mailbox_offset = 0x0000;
slave->sii.boot_tx_mailbox_size = 0x0000;
slave->sii.std_rx_mailbox_offset = 0x0000;
slave->sii.std_rx_mailbox_size = 0x0000;
slave->sii.std_tx_mailbox_offset = 0x0000;
slave->sii.std_tx_mailbox_size = 0x0000;
slave->sii.mailbox_protocols = 0;
slave->sii.strings = NULL;
@ -199,8 +203,8 @@ void ec_slave_set_state(ec_slave_t *slave, /**< EtherCAT slave */
if (slave->master->debug_level) {
char old_state[EC_STATE_STRING_SIZE],
cur_state[EC_STATE_STRING_SIZE];
ec_state_string(slave->current_state, old_state);
ec_state_string(new_state, cur_state);
ec_state_string(slave->current_state, old_state, 0);
ec_state_string(new_state, cur_state, 0);
EC_DBG("Slave %u: %s -> %s.\n",
slave->ring_position, old_state, cur_state);
}

View File

@ -54,10 +54,14 @@ typedef struct {
uint32_t product_code; /**< Vendor-specific product code. */
uint32_t revision_number; /**< Revision number. */
uint32_t serial_number; /**< Serial number. */
uint16_t rx_mailbox_offset; /**< Mailbox address (master to slave). */
uint16_t rx_mailbox_size; /**< Mailbox size (master to slave). */
uint16_t tx_mailbox_offset; /**< Mailbox address (slave to master). */
uint16_t tx_mailbox_size; /**< Mailbox size (slave to master). */
uint16_t boot_rx_mailbox_offset; /**< Bootstrap receive mailbox address. */
uint16_t boot_rx_mailbox_size; /**< Bootstrap receive mailbox size. */
uint16_t boot_tx_mailbox_offset; /**< Bootstrap transmit mailbox address. */
uint16_t boot_tx_mailbox_size; /**< Bootstrap transmit mailbox size. */
uint16_t std_rx_mailbox_offset; /**< Standard receive mailbox address. */
uint16_t std_rx_mailbox_size; /**< Standard receive mailbox size. */
uint16_t std_tx_mailbox_offset; /**< Standard transmit mailbox address. */
uint16_t std_tx_mailbox_size; /**< Standard transmit mailbox size. */
uint16_t mailbox_protocols; /**< Supported mailbox protocols. */
// Strings

View File

@ -284,6 +284,7 @@ string Command::alStateString(uint8_t state)
switch (state) {
case 1: return "INIT";
case 2: return "PREOP";
case 3: return "BOOT";
case 4: return "SAFEOP";
case 8: return "OP";
default: return "???";

View File

@ -216,12 +216,18 @@ void CommandSlaves::showSlaves(
list<string>::const_iterator protoIter;
cout << "Mailboxes:" << endl
<< " RX: 0x"
<< hex << setw(4) << si->rx_mailbox_offset << "/"
<< dec << si->rx_mailbox_size
<< " Bootstrap RX: 0x"
<< hex << setw(4) << si->boot_rx_mailbox_offset << "/"
<< dec << si->boot_rx_mailbox_size
<< ", TX: 0x"
<< hex << setw(4) << si->tx_mailbox_offset << "/"
<< dec << si->tx_mailbox_size << endl
<< hex << setw(4) << si->boot_tx_mailbox_offset << "/"
<< dec << si->boot_tx_mailbox_size << endl
<< " Standard RX: 0x"
<< hex << setw(4) << si->std_rx_mailbox_offset << "/"
<< dec << si->std_rx_mailbox_size
<< ", TX: 0x"
<< hex << setw(4) << si->std_tx_mailbox_offset << "/"
<< dec << si->std_tx_mailbox_size << endl
<< " Supported protocols: ";
if (si->mailbox_protocols & EC_MBOX_AOE) {

View File

@ -28,7 +28,7 @@ string CommandStates::helpString() const
<< getBriefDescription() << endl
<< endl
<< "Arguments:" << endl
<< " STATE can be 'INIT', 'PREOP', 'SAFEOP', or 'OP'." << endl
<< " STATE can be 'INIT', 'PREOP', 'BOOT', 'SAFEOP', or 'OP'." << endl
<< endl
<< "Command-specific options:" << endl
<< " --alias -a <alias>" << endl
@ -63,6 +63,8 @@ void CommandStates::execute(MasterDevice &m, const StringVector &args)
state = 0x01;
} else if (stateStr == "PREOP") {
state = 0x02;
} else if (stateStr == "BOOT") {
state = 0x03;
} else if (stateStr == "SAFEOP") {
state = 0x04;
} else if (stateStr == "OP") {