Hello, For a project I'm working on we're using CANopen on a linux platform configured with buildroot. Conveniently, canfestival 3.0 is in it (listed as "canfestival-7740ac6fdedc23e1ed6908d3d7db54833c88572b"). I've been running it for some time now and like the ease of use to get canfestival running in both server/client modes. Thus, first of all thank you very much for the effort spent on this project!
However, there seems to be some sort of race condition for segmented SDO's that generate abort conditions. This example shows the problem: If I use a 6byte (TimeOfDay) object with read-only permissions, and try to write it with SDO from the server side (both ends are using canfestival). The following behavior can be observed: 1. Server: Init download request (0x1) 2. Client: Init download response (0x3) 3. Server: Download segment request (0x0) 4. Client: Download segment response (0x1) 5. Client: Abort response (0x4 --> 0X6010002) Step 4 causes the callback on the server to trigger. Then when one attempts to get the result from canfestival with "getWriteResultNetworkDict" there is a small window in which it return success rather than the abort code. The problem seems to be caused by this code section: sdo.c (line 895): MSG_WAR(0x3A73, "SDO. Send response to download request defined at index 0x1200 + ", CliServNbr); sendSDO(d, whoami, CliServNbr, data); /* Inverting the toggle for the next segment. */ d->transfers[line].toggle = ! d->transfers[line].toggle & 1; /* If it was the last segment, */ if (getSDOc(m->data[0])) { /* Transfering line data to object dictionary. */ /* The code does not use the "d" of initiate frame. So it is safe if e=s=0 */ errorCode = SDOlineToObjdict(d, line); if (errorCode) { MSG_ERR(0x1A54, "SDO error : Unable to copy the data in the object dictionary", 0); failedSDO(d, CliServNbr, whoami, index, subIndex, errorCode); return 0xFF; } /* Release of the line */ resetSDOline(d, line); MSG_WAR(0x3A74, "SDO. End of download defined at index 0x1200 + ", CliServNbr); } I think the sendSDO() should not be called if the failedSDO() is bound to occur. If we look at how expedited SDO transfers are handled (sdo.c line 900-910), there the object dictionary is called first, and if it doesn't fail the sendSDO is performed. Therefore, it seems that moving the 3 lines under the MSG_WAR to after the if (getSDOc(m->data[0])) statement solves the issue. This, as the failedSDO is followed by a return statement, thus preventing both messges from appearing. I've included a patch with a possible fix. What do you think of this approach? Met vriendelijke groet / Kind regards, Bas van de Ven Designer [Prodrive B.V.]<http://www.prodrive-technologies.com/> Mobile +31 63 17 76 396 Phone +31 40 26 76 200 www.prodrive-technologies.com<http://www.prodrive-technologies.com> [cid:image002.png@01D1A78C.994597F0] Disclaimer: The content of this e-mail is intended solely for the use of the Individual or entity to whom it is addressed. If you have received this communication in error, be aware that forwarding it, copying it, or in any way disclosing its content to any other person, is strictly prohibited. If you have received this communication in error, please notify the author by replying to this e-mail immediately.
sdo.c.patch
Description: sdo.c.patch
------------------------------------------------------------------------------ Find and fix application performance issues faster with Applications Manager Applications Manager provides deep performance insights into multiple tiers of your business applications. It resolves application problems quickly and reduces your MTTR. Get your free trial! https://ad.doubleclick.net/ddm/clk/302982198;130105516;z
_______________________________________________ Canfestival-devel mailing list Canfestival-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/canfestival-devel