OpenEtherCATsociety / SOEM

Simple Open Source EtherCAT Master
Other
1.34k stars 683 forks source link

timeout error when trying to switch from OP state to Pre-OP state #428

Closed julius280 closed 3 years ago

julius280 commented 4 years ago

Hello guys,

I'm a student trying to understand EtherCAT. So far using SOEM worked pretty good and got me nice insights in how EtherCAT works. Thank you for this really nice library!

Following problem appeared: When im in operational state and I want to set state back to pre operational state, my slave got timeout error. The state change works, so I'm just confused by the timeout error. I'm using the following two lines to switch states:

ec_slave[0].state = EC_STATE_PRE_OP; ec_writestate(0);

I think that the slave still assume to get process data and the missing income of process data results in the error. I've also tried to find some additional information in available EtherCAT documentation. According to the following EtherCAT material it should be possible to switch back to Pre-Op state:

https://www.ethercat.org/download/documents/EtherCAT_Device_Protocol_Poster.pdf

The following part of that documentation is about EtherCAT states: EtherCATState

I don't fully understand the marked section (red rectangle). What does it mean with "Clear SM2, SM3, FMMU0 and FMMU1"? At the moment I don't to do that. Can this be the reason for the timeout? If so, how can I clear these with SOEM?

I'm sorry if this is a really basic question, but I hope somebody can help me!

Thank you!

Julius

ArthurKetels commented 4 years ago

The Ecat state machine does not allow OP->pre-OP transition (as also the above schematic shows). The expected behavior of the slave is to refuse the state transition and remain in OP. Therefore lack of PDO updates will cause a watchdog trigger. Hence your observed slave behavior is normal.

You can go from OP to safe-OP (this is what you want), or from OP to Init.

julius280 commented 4 years ago

Thank you!

I just thought I can go from OP to Pre-OP because of the rightest arrow pointing from OP to pre-OP. If I want to go to Init instead, do I need to do some preparation before changing to there (Clear SM0 / SM1?)?

ArthurKetels commented 4 years ago

The graph is a bit misleading I agree, it is pointing from OP to Boot. And boot is considered to be a special case of init. BTW not many slaves support this.

Another question to you would be, why do you want to go from OP to pre-OP? I cant not imagine a normal use case.

As stated in the Ecat documentation a return to init shall reset all slave internal state to init. So you do not have to do anything special. But when a master initializes a slave it is good practice to reset all SM and FMMU. But you can do this at any moment after the slave has transitioned to init. As you can see in below code snippet from SOEM, it is already taken care of.

static void ecx_set_slaves_to_default(ecx_contextt context) { uint8 b; uint16 w; uint8 zbuf[64]; memset(&zbuf, 0x00, sizeof(zbuf)); b = 0x00; ecx_BWR(context->port, 0x0000, ECT_REG_DLPORT , sizeof(b) , &b, EC_TIMEOUTRET3); / deact loop manual / w = htoes(0x0004); ecx_BWR(context->port, 0x0000, ECT_REG_IRQMASK , sizeof(w) , &w, EC_TIMEOUTRET3); / set IRQ mask / ecx_BWR(context->port, 0x0000, ECT_REG_RXERR , 8 , &zbuf, EC_TIMEOUTRET3); / reset CRC counters / ecx_BWR(context->port, 0x0000, ECT_REG_FMMU0 , 16 3 , &zbuf, EC_TIMEOUTRET3); / reset FMMU's / ecx_BWR(context->port, 0x0000, ECT_REG_SM0 , 8 4 , &zbuf, EC_TIMEOUTRET3); / reset SyncM / b = 0x00; ecx_BWR(context->port, 0x0000, ECT_REG_DCSYNCACT , sizeof(b) , &b, EC_TIMEOUTRET3); / reset activation register / ecx_BWR(context->port, 0x0000, ECT_REG_DCSYSTIME , 4 , &zbuf, EC_TIMEOUTRET3); / reset system time+ofs / w = htoes(0x1000); ecx_BWR(context->port, 0x0000, ECT_REG_DCSPEEDCNT , sizeof(w) , &w, EC_TIMEOUTRET3); / DC speedstart / w = htoes(0x0c00); ecx_BWR(context->port, 0x0000, ECT_REG_DCTIMEFILT , sizeof(w) , &w, EC_TIMEOUTRET3); / DC filt expr / b = 0x00; ecx_BWR(context->port, 0x0000, ECT_REG_DLALIAS , sizeof(b) , &b, EC_TIMEOUTRET3); / Ignore Alias register / b = EC_STATE_INIT | EC_STATE_ACK; ecx_BWR(context->port, 0x0000, ECT_REG_ALCTL , sizeof(b) , &b, EC_TIMEOUTRET3); / Reset all slaves to Init / b = 2; ecx_BWR(context->port, 0x0000, ECT_REG_EEPCFG , sizeof(b) , &b, EC_TIMEOUTRET3); / force Eeprom from PDI / b = 0; ecx_BWR(context->port, 0x0000, ECT_REG_EEPCFG , sizeof(b) , &b, EC_TIMEOUTRET3); / set Eeprom to master */ }

Off course if you reset a slave to init manually, you are in charge of setting the appropriate slave registers.

julius280 commented 4 years ago

My intention for moving from OP to pre-OP was that I want to pause the control of the slave and then later bring it back to OP when I'm ready to continuing controlling the slave. But for me pre-OP is not a fixed decision. I just thought it would be a good state for pausing. Do you think it is better to close it and later when I'm restarting the controlling (maybe 5 min later or so) I should initialize everything again?

My general intention is that when I stop the control of the slave in OP state, there should be no errors on the slave (like the timeout) appear. What would you consider to leave OP state without any errors? Just closing? Go back to Init?

Thank you really for this fast response and good answers!

ArthurKetels commented 4 years ago

When using a servo drive as slave you might as well disable the motion state machine (if DS402 compatible) or the enable state of the controller. The advantage of keeping your system in OP is that you would be warned if something out of nominal happened.

If you are for one or other reason not able to keep the PDO data running for some time on your master then it is advisable to go back to safe-OP. The slave remains in standby, all outputs are switched to safe (as defined by the slave), and PDO exchange is no longer necessary. Although when using DC and SYNC there could be some trouble. Because the slave remains "hot" the return to OP is very quick.

If the expected time in non operational state is long (whatever your definition) then you could as well go back to init. This has the advantage that the slaves are all left in a know state, and there could be possible power savings both on master and slaves. Wake up and reconfig is however much longer than recovering from safe-op.

julius280 commented 4 years ago

Thank you very much! I'm excited to try this out tomorrow!

mwh-newtec commented 3 years ago

@ArthurKetels Do you have a documentation snippet backing up the following statement:

The Ecat state machine does not allow OP->pre-OP transition

According to ETG1000.6 (and ETG2200 v.3.1.0) OP->PRE-OP is perfectly accepted. OP->BOOT however is NOT accepted. The only way to transition to BOOT is from INIT.

Please correct me if I'm wrong.

Best regards Mathias

ArthurKetels commented 3 years ago

Yes, you are right about the accepted state transitions. I had to look it up too in the ETG documents. A slave must be able to go from OP to pre-OP. In a real world application this is quite useless, but rules are rules. I guess the slave does not like it because it can not handle the tear down from OP to pre-OP in one go. Some internal state remains active and causes a time-out.

nakarlsson commented 3 years ago

@julius280 , can we close this issue?

nakarlsson commented 3 years ago

close due to inactivity