[etherlab-users] Knowing when the packet has finished cycle

+BigNose bignose at bluewin.ch
Wed Dec 14 10:05:13 CET 2011

Hallo Shahbaz,

I encountered the exact same problem. So I'm happy, this topic get's

The problem is, that in a realtime control application, it is common,
that you wanna have the sensor values as fresh as possible. And as
Ethercat is very fast, this yields a good starting point.

But just like you, I also encountered the problem, of how can you get
ASAP the data from the master.

IMHO the main problem here is, that the interrupt capability of the
driver has been dropped. So that now it has to be polled.

BTW: Why exactly has the interrupt capability been dropped? What is
the advantage of this?

To always poll, if the master has received, is IMHO a bit ressource
hungry, and as you said, I wouldn't know how to implement this
anyway, as you push the Master into an error, if you do it.
A maybe workable solution would be, as you said, if one can surely
determine, after how much time, one can surely 100% read the master.

So I'm really very interested in this topic.

Thank you

SY> Hello Jun,

SY> Thanks for not giving up on this matter. You got it all right, and your
SY> suggested solution is more or less what we had come with also. There is no
SY> necessity in splitting the PDOs in multiple domains and indeed EtherCAT
SY> proves to be fast enough to handle them. The problem, which was our
SY> original question, is *How do you implement this line:

SY>     if (answer_is_there)*

SY> (Note: I would like to remind you that as of the current version, if you *
SY> ecrt_master_receive* too soon, the master decides that something has gone
SY> horribly wrong, output some log and threat the situation as an error. So in
SY> your algorithm, if none of the answers *are there* (that is, you received
SY> too soon), then the master decides it's an error)

SY> Emanuele can give you more precise numbers if you were interested, but for
SY> our case, it would take EtherCAT about 5ms to gather data from all those
SY> PDOs. Now, the thing is, with the EtherCAT master, there comes no facility
SY> that implements the aforementioned *if*. So the only way to realize it,
SY> would be to make sure enough time has passed since the packet asking for
SY> data of this domain was sent. How would you know this time? That is our
SY> question.

SY> I saw in *master.c*, in *ec_master_idle_thread*, an amount of *
SY> sent_bytes*EC_BYTE_TRANSMISSION_TIME_NS* sleep. This suggests that we could
SY> follow the same formula and guess our delay. We are however not sure if
SY> that is a really well-tested always-correct formula, or just something that
SY> has worked for you and has been found by trial and error.

SY> Emanuele has done some latency calculations and have indeed come to the
SY> conclusion that, all considered, the better estimate is indeed higher (I'm
SY> not sure, but say by around 10%).

SY> So as you can see, knowing how much to wait is also not trivial. If
SY> you *do*have a good formula for estimation of this time, we would be
SY> happy to hear
SY> about it. A better way to do it, although I am not sure of the complexities
SY> of its implementation, would be for the EtherCAT master to keep a flag for
SY> each domain that indicates whether the last packet that has been sent
SY> (containing this domain) has arrived yet or not. That is of course, updated
SY> after a call to *ecrt_master_receive*.

SY> So in the end the code would look something like this:

SY> while (1)
SY> {
SY>     ecrt_domain_queue(domain);
SY>     ecrt_master_send(master);

SY>     sleep(a lower bound);
SY>     ecrt_master_receive(master);
SY>     while (!domain->*has_returned*)
SY>     {
SY>         sleep(a little);
SY>         ecrt_master_receive(master);   // try receiving again
SY>     }

SY>     ecrt_domain_process(domain);

SY>     // process the data
SY>     wait_period();
SY> }

SY> Do you think you could implement such a thing? If so, we would most
SY> certainly appreciate this feature. We will even send you a delicious
SY> chocolate cake as a thank you.

SY> Emanuele can fill you in with more precise numbers if you were interested,
SY> Thank you,
SY> Shahbaz

SY> On Tue, Dec 13, 2011 at 2:32 AM, Jun Yuan <j.yuan at rtleaders.com> wrote:

>> Hello Shahbaz, Hello Emanuele,
>> so there are 30000 pdos, 100 slaves on the bus, WOW. If I understand
>> it rightly, those slaves have different updating rates, all the pdos
>> were putted into one domain, and the bus cycle was in 40ms only
>> because some slaves (sensors) need 37ms to update its data. Having
>> those data with a nearly 40ms delay for the processing is
>> unacceptable, so we need to improve it.
>> I've got an idea. I am not sure if it actually works, but this is my
>> suggestion:
>> The first thing I want to point out, is that the bus cycle and the
>> slave's internal updating cycle are two different things. The bus
>> cycle should not be limited to the slaves' internal cycle. The bus
>> cycle is only limited by two things: the processing time in the while
>> loop of the EtherCAT, and the datagram transmission time. Please
>> correct me if I am wrong.
>> As the 40ms delay is a concern here, I think we should have the bus
>> running faster. Let's say 1ms cycle time, if it allows. So the data
>> would only have a max. 1ms delay for processing.
>> Those pdos would be splitted into different domains, according to
>> their updating frequency. There shall be one EtherCAT thread dealing
>> only with the bus. And if the data processing may cost more time than
>> 1 ms(bus cycle), each domains can have one data processing thread.
>> There shall be two list, one for those domain to be sent, the other
>> one for those domains that have been sent and waits for receiving the
>> answer. The while loop of the EtherCAT thread shall be like this:
>> while(true) {
>>   ecrt_master_receive(master_ptr);
>>   for (each domain in receiving list) {
>>     ecrt_domain_process(domain_ptr);
>>    if (answer_is_there) {
>>        notify_its_data_process_thread();
>>        delete_itself_from_receiving_list();
>>    }
>>   }
>>  for (each domain in sending list) {
>>    ecrt_domain_queue(domain_ptr);
>>   add_itself_to_receving_list();
>>  }
>>  ecrt_master_send(master_ptr);
>>  wait_for_bus_cycle();
>> }
>> The data processing thread while loop:
>> while(true) {
>>  add_domain_to_sending_list();
>>  wait_for_the_answer();
>>  data_processing();
>>  wait_for_domain_cycle();
>> }
>> The worst case for datagram transmission is that when all the domains
>> require data update.  I don't known how long does it take to transmit
>> all the 30000 pdos in all that different domains. You'll need to find
>> it out for deciding the bus cycle time. And if it too takes too long,
>> well, try to not let that "all domain requiring data" happens.
>> Hope this can help you.
>> Best Regards,
>> Jun YUAN

More information about the Etherlab-users mailing list