<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40"><head><meta http-equiv=Content-Type content="text/html; charset=us-ascii"><meta name=Generator content="Microsoft Word 15 (filtered medium)"><style><!--
/* Font Definitions */
@font-face
        {font-family:Wingdings;
        panose-1:5 0 0 0 0 0 0 0 0 0;}
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0cm;
        margin-bottom:.0001pt;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;
        mso-fareast-language:EN-US;}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:#0563C1;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:#954F72;
        text-decoration:underline;}
p.MsoPlainText, li.MsoPlainText, div.MsoPlainText
        {mso-style-priority:99;
        mso-style-link:"Plain Text Char";
        margin:0cm;
        margin-bottom:.0001pt;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;
        mso-fareast-language:EN-US;}
p.MsoListParagraph, li.MsoListParagraph, div.MsoListParagraph
        {mso-style-priority:34;
        margin-top:0cm;
        margin-right:0cm;
        margin-bottom:0cm;
        margin-left:36.0pt;
        margin-bottom:.0001pt;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;
        mso-fareast-language:EN-US;}
span.PlainTextChar
        {mso-style-name:"Plain Text Char";
        mso-style-priority:99;
        mso-style-link:"Plain Text";
        font-family:"Calibri",sans-serif;}
span.EmailStyle20
        {mso-style-type:personal;
        font-family:"Calibri",sans-serif;
        color:windowtext;}
span.EmailStyle21
        {mso-style-type:personal-compose;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-size:10.0pt;
        font-family:"Calibri",sans-serif;
        mso-fareast-language:EN-US;}
@page WordSection1
        {size:612.0pt 792.0pt;
        margin:72.0pt 72.0pt 72.0pt 72.0pt;}
div.WordSection1
        {page:WordSection1;}
/* List Definitions */
@list l0
        {mso-list-id:880478917;
        mso-list-type:hybrid;
        mso-list-template-ids:1401192168 336134145 336134147 336134149 336134145 336134147 336134149 336134145 336134147 336134149;}
@list l0:level1
        {mso-level-number-format:bullet;
        mso-level-text:\F0B7;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;
        font-family:Symbol;}
@list l0:level2
        {mso-level-number-format:bullet;
        mso-level-text:o;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;
        font-family:"Courier New";}
@list l0:level3
        {mso-level-number-format:bullet;
        mso-level-text:\F0A7;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;
        font-family:Wingdings;}
@list l0:level4
        {mso-level-number-format:bullet;
        mso-level-text:\F0B7;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;
        font-family:Symbol;}
@list l0:level5
        {mso-level-number-format:bullet;
        mso-level-text:o;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;
        font-family:"Courier New";}
@list l0:level6
        {mso-level-number-format:bullet;
        mso-level-text:\F0A7;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;
        font-family:Wingdings;}
@list l0:level7
        {mso-level-number-format:bullet;
        mso-level-text:\F0B7;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;
        font-family:Symbol;}
@list l0:level8
        {mso-level-number-format:bullet;
        mso-level-text:o;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;
        font-family:"Courier New";}
@list l0:level9
        {mso-level-number-format:bullet;
        mso-level-text:\F0A7;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;
        font-family:Wingdings;}
@list l1
        {mso-list-id:1996184846;
        mso-list-type:hybrid;
        mso-list-template-ids:-1022216572 -1359712834 336134147 336134149 336134145 336134147 336134149 336134145 336134147 336134149;}
@list l1:level1
        {mso-level-start-at:0;
        mso-level-number-format:bullet;
        mso-level-text:\F0B7;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;
        font-family:Symbol;
        mso-fareast-font-family:Calibri;
        mso-bidi-font-family:"Times New Roman";}
@list l1:level2
        {mso-level-number-format:bullet;
        mso-level-text:o;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;
        font-family:"Courier New";}
@list l1:level3
        {mso-level-number-format:bullet;
        mso-level-text:\F0A7;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;
        font-family:Wingdings;}
@list l1:level4
        {mso-level-number-format:bullet;
        mso-level-text:\F0B7;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;
        font-family:Symbol;}
@list l1:level5
        {mso-level-number-format:bullet;
        mso-level-text:o;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;
        font-family:"Courier New";}
@list l1:level6
        {mso-level-number-format:bullet;
        mso-level-text:\F0A7;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;
        font-family:Wingdings;}
@list l1:level7
        {mso-level-number-format:bullet;
        mso-level-text:\F0B7;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;
        font-family:Symbol;}
@list l1:level8
        {mso-level-number-format:bullet;
        mso-level-text:o;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;
        font-family:"Courier New";}
@list l1:level9
        {mso-level-number-format:bullet;
        mso-level-text:\F0A7;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;
        font-family:Wingdings;}
ol
        {margin-bottom:0cm;}
ul
        {margin-bottom:0cm;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]--></head><body lang=EN-NZ link="#0563C1" vlink="#954F72"><div class=WordSection1><p class=MsoPlainText>I might be on a bit of a roll now.  I've had some of these changes planned for a while, and some of them are pretty major (though I think it's worth it).<o:p></o:p></p><p class=MsoPlainText><o:p> </o:p></p><p class=MsoPlainText style='margin-left:36.0pt;text-indent:-18.0pt;mso-list:l1 level1 lfo2'><![if !supportLists]><span style='font-family:Symbol'><span style='mso-list:Ignore'>·<span style='font:7.0pt "Times New Roman"'>         </span></span></span><![endif]><b>0026-Add-register-read-write-support.patch</b>:<br>Renamed the ethercat tool command from reg_readwrite to reg_rdwr, as the prefix matching was interfering with reg_read.<o:p></o:p></p><p class=MsoPlainText><o:p> </o:p></p><p class=MsoPlainText style='margin-left:36.0pt;text-indent:-18.0pt;mso-list:l1 level1 lfo2'><![if !supportLists]><span style='font-family:Symbol'><span style='mso-list:Ignore'>·<span style='font:7.0pt "Times New Roman"'>         </span></span></span><![endif]><b>0029-Disable-DC-SYNC-before-updating-a-running-slave-s-sy.patch</b>:<br>Dropped.<br><br><o:p></o:p></p><p class=MsoPlainText style='margin-left:36.0pt;text-indent:-18.0pt;mso-list:l1 level1 lfo2'><![if !supportLists]><span style='font-family:Symbol'><span style='mso-list:Ignore'>·<span style='font:7.0pt "Times New Roman"'>         </span></span></span><![endif]><b>0029-Avoid-changing-running-slaves-DC-offset.patch</b>:<br>Added as a replacement for the above.  It does the following:<o:p></o:p></p><p class=MsoPlainText style='margin-left:72.0pt;text-indent:-18.0pt;mso-list:l1 level2 lfo2'><![if !supportLists]><span style='font-family:"Courier New"'><span style='mso-list:Ignore'>o<span style='font:7.0pt "Times New Roman"'>   </span></span></span><![endif]>If the System Time Offset and Delay registers for a given slave are already correct, it will not write to them at all.<o:p></o:p></p><p class=MsoPlainText style='margin-left:72.0pt;text-indent:-18.0pt;mso-list:l1 level2 lfo2'><![if !supportLists]><span style='font-family:"Courier New"'><span style='mso-list:Ignore'>o<span style='font:7.0pt "Times New Roman"'>   </span></span></span><![endif]>If it wants to change the System Time Offset register but the slave is already in SAFEOP or OP, then it won’t change it (but will still update the System Time Delay with the transmission delay).<o:p></o:p></p><p class=MsoPlainText style='margin-left:108.0pt;text-indent:-18.0pt;mso-list:l1 level3 lfo2'><![if !supportLists]><span style='font-family:Wingdings'><span style='mso-list:Ignore'>§<span style='font:7.0pt "Times New Roman"'>  </span></span></span><![endif]>Modifying the System Time Offset register (0x0920) causes a step change in the System Time of the slave, which can cause it to miss the next sync time (for a 32-bit slave, it can take 4 seconds to recover, and for a 64-bit slave, it might never sync again).<o:p></o:p></p><p class=MsoPlainText style='margin-left:108.0pt;text-indent:-18.0pt;mso-list:l1 level3 lfo2'><![if !supportLists]><span style='font-family:Wingdings'><span style='mso-list:Ignore'>§<span style='font:7.0pt "Times New Roman"'>  </span></span></span><![endif]>Modifying the System Time Delay register (0x0928) just alters the value it uses when the normal time sync datagram circulates (as far as I can tell); this is drift compensated so it will gradually drift to the correct time instead of stepping straight to it, so shouldn't cause the above problem.<o:p></o:p></p><p class=MsoPlainText style='margin-left:108.0pt;text-indent:-18.0pt;mso-list:l1 level3 lfo2'><![if !supportLists]><span style='font-family:Wingdings'><span style='mso-list:Ignore'>§<span style='font:7.0pt "Times New Roman"'>  </span></span></span><![endif]>Patches 0001 and 0002 both make it more likely for the master to want to update the System Time Offset (though they do improve other things, and this is good for the initial startup case – just less so for the reconfigure-during-OP case).<o:p></o:p></p><p class=MsoPlainText style='margin-left:72.0pt;text-indent:-18.0pt;mso-list:l1 level2 lfo2'><![if !supportLists]><span style='font-family:"Courier New"'><span style='mso-list:Ignore'>o<span style='font:7.0pt "Times New Roman"'>   </span></span></span><![endif]>If it updated either the offset or the delay it will also write register 0x0930 to reset the drift filter (this is recommended in the datasheets).<o:p></o:p></p><p class=MsoPlainText style='margin-left:36.0pt'><br>This should now be cleaner and safer than the previous patch (which disabled and re-enabled sync outputs, which only works if the slave supports and enables AssignActivate 0x2000 and might miss some pulses), and better for general use, since this allows running slaves to always use drift compensation to adjust their clocks gradually rather than stepping instantly (while slaves being configured from PREOP can still step immediately).<br><br>The patch now applies to all DC-capable slaves – previously it only affected slaves that use sync pulse generation (AssignActivate 0x0100), but step changes can be a problem for slaves that perform DC timestamping or other things too.<br><br>It should also avoid DC timing shifts during operation, especially if you are using a slave as the reference clock and syncing the master clock to it rather than the reverse.  (Note that the dc_user example code does do the reverse and actually uses the master clock as the real reference.  If you’re not sure which is which, using ecrt_master_reference_clock_time to get the slave refclock time and use it in the master code is the former, while using ecrt_master_sync_reference_clock to send the master clock to the slave refclock is the latter.  Both approaches should be safe but the latter is subject to higher jitter and drift.)<br><br>However bear in mind that the way I’m using DC I’m not going to notice small timing errors.  So I’d appreciate it if someone who is using DC more extensively (especially with motor slaves, which tend to be picky) could verify it.<br><br>(Just to repeat the background from the original patch: if the network rescans while the master app is running [eg. due to a change in the number of responding slaves], then without any patch the reconfig process is likely to update the System Time Offset register, which causes an immediate step change in the slave’s DC clock and can in turn sometimes result in it missing pulses and possibly stopping altogether, as mentioned above.)<br><br><o:p></o:p></p><p class=MsoPlainText style='margin-left:36.0pt'>FWIW, the datasheets also recommend sending a flood of resync datagrams (about 15,000) after changing the clocks, to make it drift in more quickly.  I haven’t done this as at the default update rate this would take quite a while (about a minute, in fact).  But master app code might want to consider detecting a change to the number of slaves during operation and calling ecrt_master_sync_slave_clocks more frequently afterwards (if a change to the number of slaves isn’t fatal to your application anyway).  Another possibility might be to temporarily increase the speed of the drift adjustment.<o:p></o:p></p><p class=MsoPlainText style='margin-left:36.0pt'><o:p> </o:p></p><p class=MsoPlainText style='margin-left:36.0pt;text-indent:-18.0pt;mso-list:l0 level1 lfo4'><![if !supportLists]><span style='font-family:Symbol'><span style='mso-list:Ignore'>·<span style='font:7.0pt "Times New Roman"'>         </span></span></span><![endif]><b>0042-print-sync-signed.patch</b>:<br>Corrects the DC sync log message to use signed format, since it can be given negative values.<o:p></o:p></p><p class=MsoPlainText><o:p> </o:p></p><p class=MsoPlainText>And now here’s the major bundle (I skipped some numbers to show grouping):<o:p></o:p></p><p class=MsoPlainText><o:p> </o:p></p><p class=MsoPlainText style='margin-left:36.0pt;text-indent:-18.0pt;mso-list:l0 level1 lfo4'><![if !supportLists]><span style='font-family:Symbol'><span style='mso-list:Ignore'>·<span style='font:7.0pt "Times New Roman"'>         </span></span></span><![endif]><b>0050-fsm_sii_external-datagram.patch</b>:<o:p></o:p></p><p class=MsoPlainText style='margin-left:36.0pt;text-indent:-18.0pt;mso-list:l0 level1 lfo4'><![if !supportLists]><span style='font-family:Symbol'><span style='mso-list:Ignore'>·<span style='font:7.0pt "Times New Roman"'>         </span></span></span><![endif]><b>0051-fsm_change-external-datagram.patch</b>:<o:p></o:p></p><p class=MsoPlainText style='margin-left:36.0pt;text-indent:-18.0pt;mso-list:l0 level1 lfo4'><![if !supportLists]><span style='font-family:Symbol'><span style='mso-list:Ignore'>·<span style='font:7.0pt "Times New Roman"'>         </span></span></span><![endif]><b>0052-fsm_slave_config-external-datagram.patch</b>:<o:p></o:p></p><p class=MsoPlainText style='margin-left:36.0pt;text-indent:-18.0pt;mso-list:l0 level1 lfo4'><![if !supportLists]><span style='font-family:Symbol'><span style='mso-list:Ignore'>·<span style='font:7.0pt "Times New Roman"'>         </span></span></span><![endif]><b>0053-fsm_slave_scan-external-datagram.patch</b>:<br>These are prep work for the following patches.  They each take one state machine and convert it from using a single fixed datagram object provided at init time for all operations (as is the style of fsm_master), to using a different one provided each time to the exec function (as is the style of fsm_slave and several low-level FSMs).<br><br><o:p></o:p></p><p class=MsoPlainText style='margin-left:36.0pt;text-indent:-18.0pt;mso-list:l0 level1 lfo4'><![if !supportLists]><span style='font-family:Symbol'><span style='mso-list:Ignore'>·<span style='font:7.0pt "Times New Roman"'>         </span></span></span><![endif]><b>0054-fsm_slave-handles-all-sdos.patch</b>:<br>This moves the internal SDO requests and SDO dictionary requests (if you disable EC_SKIP_SDO_DICT from patch 0010; otherwise dictionary requests already were effectively moved) from fsm_master into fsm_slave.<br><br>This does two important things: firstly it removes the fighting over the CoE mailbox between the internal and external SDO requests (making the busy-checking on each side unnecessary).  And secondly it allows both of these to occur in the background and in parallel between multiple slaves.<br><br><o:p></o:p></p><p class=MsoPlainText style='margin-left:36.0pt;text-indent:-18.0pt;mso-list:l0 level1 lfo4'><![if !supportLists]><span style='font-family:Symbol'><span style='mso-list:Ignore'>·<span style='font:7.0pt "Times New Roman"'>         </span></span></span><![endif]><b>0055-fsm_slave_config_scan-to-fsm_slave.patch</b>:<br>This is a big patch (though not the largest in the set; but I couldn’t see a way to split it up any more without making intermediate states that wouldn’t compile or run), and it’s a doozy.<br><br>Similar to the previous patch, this moves fsm_slave_scan and fsm_slave_config from fsm_master to fsm_slave.  This allows slave scanning and configuration to occur in parallel for multiple slaves.  (Note that scanning all slaves must complete before configuring any slave can begin.)<br><br>This also adds scan_required to ec_slave_info_t; when true the other fields are unreliable (and should be ignored) as scanning has not yet started or is still in progress.<br><br>The motivating case was a network of about 100 slave devices; while scanning is fast (under a second, after prior SII patches), the configuration process to bring the slaves from PREOP to OP took about 80 seconds (and you could see the lights coming on each slave in sequence).  After the patch it takes about 20 seconds.<br><br>I actually originally intended to only move fsm_slave_config, but the structure of the code required moving fsm_slave_scan as well.  Logically they do both belong in the slave FSM anyway.<br><br>Note that in this case “parallel” does not mean separate threads – all the FSMs (master and all slaves) still execute on a single thread.  But it can now include datagrams for multiple slaves in the same frame.  The existing throttling mechanism for fsm_slave is used, so it will configure slaves in chunks, not all at once (so the network won’t get overloaded if you have a large number of slaves, though network usage will be higher than it previously was).<br><br><o:p></o:p></p><p class=MsoPlainText style='margin-left:36.0pt;text-indent:-18.0pt;mso-list:l0 level1 lfo4'><![if !supportLists]><span style='font-family:Symbol'><span style='mso-list:Ignore'>·<span style='font:7.0pt "Times New Roman"'>         </span></span></span><![endif]><b>0056-fsm-exec-simplify.patch</b>:<br>Now that most of the FSMs execute from fsm_slave, it’s not necessary for them to check the datagram state, as master.c’s ec_master_exec_slave_fsms does this in advance.  This simplifies the FSM exec functions.<o:p></o:p></p><p class=MsoPlainText><o:p> </o:p></p><p class=MsoPlainText>These have been tested and appear to work as expected, at least with my networks.  However there are a few caveats:<o:p></o:p></p><p class=MsoPlainText><o:p> </o:p></p><p class=MsoPlainText style='margin-left:36.0pt;text-indent:-18.0pt;mso-list:l0 level1 lfo4'><![if !supportLists]><span style='font-family:Symbol'><span style='mso-list:Ignore'>·<span style='font:7.0pt "Times New Roman"'>         </span></span></span><![endif]>The “ready” state exposed in ec_slave_config_state_t and ec_slave_info_t by one of my earlier patches (integrated into default) is less useful than it used to be; it now turns on earlier when the slave is still awaiting scanning and configuration (in fact it will rarely be false unless you’re hammering the slave with requests).  Since this is relatively new I doubt it will bother anyone, but I’m open to suggestions.<br><br><o:p></o:p></p><p class=MsoPlainText style='margin-left:36.0pt;text-indent:-18.0pt;mso-list:l0 level1 lfo4'><![if !supportLists]><span style='font-family:Symbol'><span style='mso-list:Ignore'>·<span style='font:7.0pt "Times New Roman"'>         </span></span></span><![endif]>Previously since slaves were scanned and configured in order, you could check whether the last slave was ready and use this to decide that the network as a whole has finished configuration (and consequently that things like SDO requests would be acted on quickly).  Similarly since the last slave was the last brought to OP, you could have external equipment detect the network is ready by having an output on this slave (that turns off when not at OP).<br><br>While the last slave should still be among the last slaves to be configured, it may no longer be the actual last slave configured, especially if some slaves are faster to configure than others.  Having said that, you can still assume that requests will be acted on quickly for an individual slave if that slave claims to be ready (unless it hasn’t been configured yet) – it’s only making inferences about other slaves that’s more problematic now.<br><br><o:p></o:p></p><p class=MsoPlainText style='margin-left:36.0pt;text-indent:-18.0pt;mso-list:l0 level1 lfo4'><![if !supportLists]><span style='font-family:Symbol'><span style='mso-list:Ignore'>·<span style='font:7.0pt "Times New Roman"'>         </span></span></span><![endif]>Network usage will be higher when scanning/configuring than it previously was (though it’s capped, as mentioned above).  The price for talking to more slaves at once is that frame sizes are larger (or it might send multiple frames).  There is a chance that this might overflow your cycle times if you’re running at a very high rate.  Up to EC_EXT_RING_SIZE/2 slave FSMs (default 16) can be running in parallel; you may need to tune this lower in that case.  (Or you can tune it higher, if you have spare time and you want it to configure more slaves at once.)  Testing was done at 1ms cycle times on PREEMPT_RT.<o:p></o:p></p><p class=MsoPlainText><o:p> </o:p></p><p class=MsoPlainText>Also note that as the numbering implies, they assume that all prior patches have been applied.  Some of the prior patches have effectively been “baked in” as this moves their changes from one file to another, so they can’t be trivially reordered.  Each successive patch will compile and run correctly before the next in the sequence is applied, however.<o:p></o:p></p><p class=MsoPlainText><o:p> </o:p></p></div></body></html>