OpenEtherCATsociety / SOEM

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

SDO communication problem #410

Closed AlexCorrado closed 3 years ago

AlexCorrado commented 4 years ago

Goodmorning to all, I'm using a Pc with Ubuntu as Ethercat master and an ethercat slave which uses a LAN9252. The slave is connected to a pc with window which is used to load the SOES program and once the software has been loaded, it remains connected in debug mode for checking the variables. I have a problem with the SDO communication. When i run, on my master, the slaveinfo.c from command window with the optional parameter -sdo i obtain the following results:

SOEM (Simple Open EtherCAT Master) Slaveinfo Starting slaveinfo ec_init on enp2s0 succeeded. 1 slaves found and configured. Calculated workcounter 3

Slave:1 Name: SSC_Device Output size: 1024bits Input size: 1024bits State: 4 Delay: 0[ns] Has DC: 1 DCParentport:0 Activeports:1.0.0.0 Configured address: 1001 Man: 00000afc ID: 00010000 Rev: 00000001 SM0 A:1000 L: 128 F:00010026 Type:1 SM1 A:1200 L: 128 F:00010022 Type:2 SM2 A:1400 L: 128 F:00010064 Type:3 SM3 A:1600 L: 128 F:00010020 Type:4 FMMU0 Ls:00000000 Ll: 128 Lsb:0 Leb:7 Ps:1400 Psb:0 Ty:02 Act:01 FMMU1 Ls:00000080 Ll: 128 Lsb:0 Leb:7 Ps:1600 Psb:0 Ty:01 Act:01 FMMUfunc 0:1 1:2 2:0 3:0 MBX length wr: 128 rd: 128 MBX protocols : 04 CoE details: 0d FoE details: 00 EoE details: 00 SoE details: 00 Ebus current: 0[mA] only LRD/LWR:0 ec_slave[cnt].mbx_proto: 04 printSDO: 1 End slaveinfo, close socket End program

The problem is that i don't see the CoE object dictionary. I checked the exchange of packages between master and slave, i saw that the master sent a request to obtain the informations but my slave don't receive them. From the slave debugger I checked the SM_status (Sync manager status SM1 0x080d) that is the register that indicate if the mailmox is full and can be read and i saw that this register doesn't change value and then my slave doesn't pass into read SDO mode. Someone know what is the problem? the eeprom memory need to have a particular structure to allow a correct SDO comunication? Or maybe is only a slave software problem?

Thanks.

nakarlsson commented 4 years ago

Post a wireshark , it might help to see what happens.

Just to check, is it as expected that the SOES slave use the same EEPROM as the "SSC_Device"? What SOES source do you run? Any of the samples?

AlexCorrado commented 4 years ago

Hello, I'm using the last version of Ethercat SOES. I attach the file "TEST.csv" which contains the data registered by Wireshark. In this file at rows 328-329 the "COE SDO request" is sent by the master, but the slave doesn't answer. For us, it's correct that the SOES slave uses the same EEPROM as the "SSC_Device". On the SOEM master we run the file "slaveinfo.c" trought a roscpp node (on Ubuntu 16.04 Ros Kinetic).

TEST.txt

Please let me know, thank you

nakarlsson commented 4 years ago

please send the capture in native wireshark format

AlexCorrado commented 4 years ago

I can't upload the native file because it is not supported by this chat box. How can i do it? Have you got an e-mail address? I can send you the original file.

Thank you

AlexCorrado commented 4 years ago

Here the zip file that contain the native wireshark file.

TEST.zip

Thank you

nakarlsson commented 4 years ago

It is a slave issue, can you explain the slave setup? You use the LAN9252 as ESC, what CPU run SOES and what LAN9252 driver do you use? Have you verifyed that it starts OK?

Ex, in the wireshark you can see ALStatus beeing 0x11, Init + E flag set, yet ALStatusCode is 0x0000.

AlexCorrado commented 4 years ago

@nakarlsson sorry for the 2 posts, in the last implementation I used a PDO with size 128 Byte and there was no problems but now, before proceeding with SDO management, I need to increase the size of the PDO. My priority has momentarily changed. The SOES run on a STM32 F4 and we have done a personalized driver for the LAN9252, but it start ok.

AlexCorrado commented 4 years ago

@nakarlsson I followed you advice and I built a standard slave, with my hardware but I used all the slave SOES functions. I changed only the functions for read/write PDO, read/write SDO and read/write a register, in particular I rewrite the two functions ESC_read() and ESC_write() to adapt it. The PDO trasmission work perfectly but I have again problems with the SDO communication. There are some things on the code that I don't understand:

1) where is the SDO structure described, or rather its content, if I wanted to edit it manually from code? surely there is a function that reads the content of the next SDO to be written, what is it?

2) what does the MBXBUFFER variable mean? Should SDO only have a buffer or am I wrong? I used MBXBUFFER=2.

3) what is the function ESC_ackmbxread for? I don't understand its usefulness

I enclose the wireshark files when I run the slaveInfo.c program with -sdo and with -map with CoE active and respectively the screens of the results on the command windows.

WSs.zip

-sdo ↓ Cattura-sdo

-map ↓ Cattura-map

Please let me know, thank you

nakarlsson commented 4 years ago
  1. Check the samples in https://github.com/OpenEtherCATsociety/SOES/tree/master/applications, the SDO structure is in _objectlist.c

  2. It is number of mailbox buffers, 2 for TX and 1 for RX. Again, check the samples, the defines are in ecat_options.h.

  3. I Can’t find the spec text right now, but it is part of the mailbox protocol. Basically when the slave write the first byte it becomes in use and claimed by PDI. I think if you find some flowchart of the mailbox protocol, it might be mentioned there.

AlexCorrado commented 4 years ago

@nakarlsson thank you for the last response, it was very useful for us. I solved all the problems and now the PDO/SDO communications works very well. Now I'm facing another problem, I want to use the SDO communication because we need to exchange some data without using PDO. For example from a roscpp node (which use SOEM) we want to read some entries of the OD through the command ec_SDOread. Using this function, only the field "value" of the selected OD entry is returned. I would like to get the "data" field of the entry instead of the "value". Is it possible? I tried to use this function on the program slaveInfo.cpp but it seems that "data" field is NULL and consequently "value" field is returned. Could you help me?

Please let me know, thank you.

nakarlsson commented 4 years ago

You need to connect a variable to the SDO, making ”data” != NULL.

Check for example object 0x1C32 https://github.com/OpenEtherCATsociety/SOES/blob/master/applications/rtl_xmc4_dynpdo/slave_objectlist.c

If you want to write to it, you also need to change the permission to RW.

AlexCorrado commented 4 years ago

@nakarlsson thank you for the answear, I have done as you said but if I connect a variable to the SDO, making "data"="&variable" (the SDO will be a structure and also the varible ) and I define this "variable" with casual values, the SOEM see always null fields and take the value fields. But if I make the same procedure and always in SOES before the SDO reading I initialize the "variable" with casual values then it works only for the first ec_SDOread. It seems that the reading process is destructive, namely, the data fields are set to null after each reading. Is it correct?

Please let me know, thank you.

nakarlsson commented 4 years ago

No, it should not set ”data” to NULL if it is set to a variable address.

SOEM don’t know of ”data” or ”value” fields, it just try to read a SDO. SOES use ”data” or ”value” depending of the nature of the SDO, read-only or read-write, simple or complex data type, and so on.

So, the issue is on the slave/SOES side. Can you post the objectlist C source?

AlexCorrado commented 4 years ago

I set the "data" SDO fields always read-write and equals to a variable address as follow:

const _objectlist SDOobjects[] = { {0x1000, OTYPE_VAR, 0, 0, &acName1000[0], &SDO1000[0]}, {0x1008, OTYPE_VAR, 0, 0, &acName1008[0], &SDO1008[0]}, {0x1009, OTYPE_VAR, 0, 0, &acName1009[0], &SDO1009[0]}, {0x100A, OTYPE_VAR, 0, 0, &acName100A[0], &SDO100A[0]}, {0x1018, OTYPE_RECORD, 4, 0, &acName1018[0], &SDO1018[0]}, {0x1600, OTYPE_RECORD, 0x80, 0, &acName1600[0], &SDO1600[0]}, {0x1A00, OTYPE_RECORD, 0x80, 0, &acName1A00[0], &SDO1A00[0]}, {0x1C00, OTYPE_ARRAY, 0x04, 0, &acName1C00[0], &SDO1C00[0]}, {0x1C10, OTYPE_ARRAY, 0, 0, &acName1C10[0], &SDO1C10[0]}, {0x1C11, OTYPE_ARRAY, 0, 0, &acName1C11[0], &SDO1C11[0]}, {0x1C12, OTYPE_ARRAY, 1, 0, &acName1C12[0], &SDO1C12[0]}, {0x1C13, OTYPE_ARRAY, 1, 0, &acName1C13[0], &SDO1C13[0]}, {0x6000, OTYPE_ARRAY, 0x80, 0, &acName6000[0], &SDO6000[0]}, {0x7000, OTYPE_ARRAY, 0x80, 0, &acName7000[0], &SDO7000[0]}, {0x7100, OTYPE_ARRAY, 0x02, 0, &acName7100[0], &SDO7100[0]}, {0x8001, OTYPE_ARRAY, 0x0C, 0, &acName8001[0], &SDO8001[0]}, {0xffff, 0xff, 0xff, 0xff, NULL, NULL} };

const _objd SDO8001[] = { {0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, &acNameNOE[0], 0x0C, NULL}, {0x01, DTYPE_UNSIGNED8, 8, ATYPE_RW, &acName8001_01[0], 0x00, &j_size}, {0x02, DTYPE_UNSIGNED16, 16, ATYPE_RW, &acName8001_02[0], 0x00, &j_hw_v}, {0x03, DTYPE_INTEGER32, 32, ATYPE_RW, &acName8001_03[0], 0x00, &kt}, {0x04, DTYPE_UNSIGNED8, 8, ATYPE_RW, &acName8001_04[0], 0x00, &kr}, {0x05, DTYPE_INTEGER32, 32, ATYPE_RW, &acName8001_05[0], 0x00, &jeq}, {0x06, DTYPE_INTEGER32, 32, ATYPE_RW, &acName8001_06[0], 0x00, &beta_v}, {0x07, DTYPE_INTEGER32, 32, ATYPE_RW, &acName8001_07[0], 0x00, &beta_c}, {0x08, DTYPE_UNSIGNED16, 16, ATYPE_RW, &acName8001_08[0], 0x00, &fw_v}, {0x09, DTYPE_UNSIGNED8, 8, ATYPE_RW, &acName8001_09[0], 0x00, &j_pos}, {0x0A, DTYPE_INTEGER16, 16, ATYPE_RW, &acName8001_10[0], 0x00, &j_phase}, {0x0B, DTYPE_UNSIGNED16, 16, ATYPE_RW, &acName8001_11[0], 0x00, &j_id}, {0x0C, DTYPE_UNSIGNED8, 8, ATYPE_RW, &acName8001_12[0], 0x00, &dev_type} };

The objects at index 8001 are my SDO parameters. The SDO parameters used here are constant but their values are contained in the EEPROM of our STM32 F4 (and not the EEPROM of the IAN9252) hence I must read them from the memory, copy the values on variables and obviously use these variables as SDO parameters. I solved the problem initializing the above SDO variables at each SDO read request.

nakarlsson commented 4 years ago

The above seems to be OK, just did a quick check. It should also work as ATYPE_RO as long as you have a variable connected to ”data”. The RO will only block the master from writing, checked in the SOES stack, from the slave/PDI side you can do what you want.

If ”data” become NULL, your memory get corruption for some reason. The SDO is const and is protected from beeing written, but that is for you to dig in to.

nakarlsson commented 4 years ago

@AlexCorrado , Can this be closed?