GithubHelp home page GithubHelp logo

rscada / libcanopen Goto Github PK

View Code? Open in Web Editor NEW
62.0 62.0 30.0 415 KB

Open-source library for CANopen. This library is designed to be used together with the SocketCAN Linux framework for CAN.

License: BSD 3-Clause "New" or "Revised" License

C 22.60% Shell 60.66% Python 2.06% Makefile 14.46% M4 0.22%

libcanopen's People

Contributors

amrbekhit avatar rscada avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

libcanopen's Issues

Use blocking socket in `rs-canopen-dump` to avoid "Resource temporarily unavailable" error (or handle it)

When using rs-canopen-dump I frequently encountered these errors and the tool would exit:

read: can raw socket read: Resource temporarily unavailable

This is because a non-blocking socket is opened when using can_socket_open():

/* Create the socket */
if ((sock = can_socket_open(argv[1])) < 0)

An alternate approach is to use can_socket_open_timeout() with a timeout of 0 instead:

diff --git a/bin/rs-canopen-dump.c b/bin/rs-canopen-dump.c
index 7b68661..7439799 100644
--- a/bin/rs-canopen-dump.c
+++ b/bin/rs-canopen-dump.c
@@ -47,7 +47,7 @@ main(int argc, char **argv)
     }
 
     /* Create the socket */
-    if ((sock = can_socket_open(argv[1])) < 0)
+    if ((sock = can_socket_open_timeout(argv[1], 0)) < 0)
     {
         fprintf(stderr, "Error: Failed to create socket.\n");
         return -1;

This is consistent with how rs-canopen-monitor operates:

/* Create the socket */
if ((sock = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0)
{
fprintf(stderr, "Error: Failed to create socket.\n");
return -1;
}
/* Locate the interface you wish to use */
strcpy(ifr.ifr_name, argv[1]);
ioctl(sock, SIOCGIFINDEX, &ifr); /* ifr.ifr_ifindex gets filled
* with that device's index */
// XXX add check
/* Select that CAN interface, and bind the socket to it. */
addr.can_family = AF_CAN;
addr.can_ifindex = ifr.ifr_ifindex;
bind(sock, (struct sockaddr*)&addr, sizeof(addr)); // XXX Add check

Thanks for your work on libcanopen.

Need to document that `SEG` mode argument is available for SDO upload tool.

The "SEG" argument here:

if (argc == 6 && strcmp(argv[5], "SEG") == 0)

Is not documented as available here:

fprintf(stderr, "usage: %s can-interface NODE INDEX SUBINDEX\n", argv[0]);

The existence of the equivalent argument is (somewhat) documented here for the download tool:

fprintf(stderr, "usage: %s can-interface NODE INDEX SUBINDEX DATA [MODE]\n", argv[0]);

Effect

Without the SEG argument documented it's not clear that e.g. visible strings longer than an expedited transfer can handle are still able to be viewed, e.g.:

$ rs-canopen-sdo-upload can0 30 0x1008 0
0000000b
$ rs-canopen-sdo-upload can0 30 0x1008 0 SEG
43414e6f70656e4e6f6465 // 'C', 'A', 'N', 'o', 'p', 'e', 'n', 'N', 'o', 'd', 'e'

error while make

after ./configure i have given make. it is produced below error

siva@siva-Vostro-3268:~/Downloads/libcanopen-master$ make
make all-recursive
make[1]: Entering directory '/home/siva/Downloads/libcanopen-master'
Making all in canopen
make[2]: Entering directory '/home/siva/Downloads/libcanopen-master/canopen'
source='canopen.c' object='canopen.lo' libtool=yes
DEPDIR=.deps depmode=none /bin/bash ../depcomp
/bin/bash ../libtool --tag=CC --mode=compile gcc -DHAVE_CONFIG_H -I. -I.. -I.. -I.. -g -O2 -c -o canopen.lo canopen.c
/bin/bash: ../depcomp: No such file or directory
Makefile:325: recipe for target 'canopen.lo' failed
make[2]: *** [canopen.lo] Error 127
make[2]: Leaving directory '/home/siva/Downloads/libcanopen-master/canopen'
Makefile:359: recipe for target 'all-recursive' failed
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory '/home/siva/Downloads/libcanopen-master'
Makefile:270: recipe for target 'all' failed
make: *** [all] Error 2

Document/improve how data argument length/size is calculated

It wasn't at all obvious to me how the size of data is calculated from supplied arguments and it turns out it's IMO non-obvious/non-intuitive. In some scenarios it also appears to work but causes CANopen errors which are not easily diagnose-able.

How data argument length/size is currently calculated

Specifically, the data length is calculated based on the length of the supplied string argument:

data = strtol(argv[5], NULL, 16);
len = strlen(argv[5])/2;

len = strlen(argv[5])/2;
if (argc == 7 && strcmp(argv[6], "SEG") == 0)
{
char *data_str = argv[5];

That is, it expects the data to be expressed as two ASCII characters per byte being the hexadecimal value of the byte without any 0x prefix. e.g.: 00 or 03e8

Issues with this method of size calculation

The approach currently used leads to issues in a number of situations, including when the value is 0 or is prefixed with 0x.

This is significant because there are a number of situations where a data value of 0 is required (e.g. TPDO/RPDO remapping).

If one naively uses 0 as the argument value it results in CANopen errors such as 0x06070010 "Data type does not match". (Or, rather it should result in this error number but the value is currently incorrect, see #7.)

Alternate approaches

Ideally, a more robust size calculation would be implemented but in the interim hopefully documenting this will clarify the situation.

Current correct approach for supplying data arguments

The correct format to use is two ASCII characters per byte being the hexadecimal value of the byte without any 0x prefix.

Here is a working example (remapping a TPDO for Node ID 0x30 a.k.a 48 & modifying the event timer) to clarify how the data should be specified:

rs-canopen-sdo-download can0 30 0x1800 1 800001b0
rs-canopen-sdo-download can0 30 0x1A00 0 00
rs-canopen-sdo-download can0 30 0x1A00 1 64010110
rs-canopen-sdo-download can0 30 0x1A00 0 02
rs-canopen-sdo-download can0 30 0x1800 1 000001b0
rs-canopen-sdo-download can0 30 0x1800 5 03e8

Document (and/or fix) the different ways tools parse numeric arguments

There are a number of issues related to the parsing of numeric arguments which would benefit from fixing and/or documenting:

  • Incorrect documentation
  • Inconsistent parsing
  • Lack of documentation

Incorrect documentation

The rs-canopen-ds401 tool has useful documentation here and it would be helpful to replicate for the other tools:

fprintf(stderr, "usage: rs-canopen-ds401 INTERFACE NODE COMMAND DEVICE ADDRESS [VALUE]\n");
fprintf(stderr, "\tINTERFACE = can0 | can1 | ...\n");
fprintf(stderr, "\tNODE\t = 0 .. 127\n");
fprintf(stderr, "\tCOMMAND\t = read | write\n");
fprintf(stderr, "\tDEVICE\t = di | do\n");
fprintf(stderr, "\tADDRESS\t = 0 .. 3\n");
fprintf(stderr, "\tVALUE\t = 0 | 1 [only for COMMAND = write]\n");

Except that it gives the NODE ID range as 0 .. 127 (implied to be a decimal/base 10 number) when the argument is actually parsed as hexadecimal:

node = strtol(argv[2], NULL, 16);
address = atoi(argv[5]);

Inconsistent parsing

The rs-canopen-nmt tool uses atoi() to parse the Node ID argument as a decimal/base 10 number:

node = atoi(argv[3]);

But all the other tools use strol() to parse the Node ID (and other numeric arguments) as a hexadecimal/base 16 number:

node = strtol(argv[2], NULL, 16);

node = strtol(argv[2], NULL, 16);
index = strtol(argv[3], NULL, 16);
subindex = strtol(argv[4], NULL, 16);
data = strtol(argv[5], NULL, 16);
len = strlen(argv[5])/2;

node = strtol(argv[2], NULL, 16);
index = strtol(argv[3], NULL, 16);
subindex = strtol(argv[4], NULL, 16);

node = strtol(argv[2], NULL, 16);
index = strtol(argv[3], NULL, 16);
subindex = strtol(argv[4], NULL, 16);
len = strlen(argv[5])/2;

node = strtol(argv[2], NULL, 16);
index = strtol(argv[3], NULL, 16);
subindex = strtol(argv[4], NULL, 16);

Lack of documentation

With the exception of rs-canopen-ds401 all the other tools don't document the format/range of their numeric arguments in their usage message. It would be helpful to document this.

Related:

In part I've created this issue to document these details for people until any changes are added to the code base.

Document that SDO Block Upload is not implemented

While a function named canopen_sdo_upload_block() exists, it has no implementation:

int
canopen_sdo_upload_block(int sock, uint8_t node, uint16_t index, uint8_t subindex,
uint8_t *data, uint32_t data_len)
{
return -1;
}

A Python wrapper function does exist but uses the unimplemented C function:

def SDOUploadBlock(self, node, index, subindex, size):
"""
Block SDO upload.
"""
data = create_string_buffer(int(size))
ret = libcanopen.canopen_sdo_upload_block(self.sock, c_uint8(node), c_uint16(index), c_uint8(subindex), data, c_uint16(size));
if ret != 0:
raise Exception("CANopen Block SDO upload error")
return binascii.hexlify(data)

The Python wrapper function used to mention that the function was unimplemented but the note was removed here.

Incorrect values for Data Type related SDO abort codes

These SDO abort code values are incorrect as they have the prefix 0x0606 instead of 0x0607 (e.g. see):

{ 0x06060010, "Data type does not match, lengh of service parameter does not match"},
{ 0x06060012, "Data type does not match, lengh of service parameter is too high"},
{ 0x06060013, "Data type does not match, lengh of service parameter is too low"},

Presumably this is a copy/paste error.

Quick patch:

diff --git a/canopen/canopen.c b/canopen/canopen.c
index b02fdda..b2d2b7a 100644
--- a/canopen/canopen.c
+++ b/canopen/canopen.c
@@ -46,9 +46,9 @@ static SDO_abort_code_t SDO_abort_codes[] = {
     { 0x06040043, "General parameter incompatibility reason"},
     { 0x06040047, "General internal incompatibility in the device"},
     { 0x06060000, "Object access failed due to a hardware error"},
-    { 0x06060010, "Data type does not match, lengh of service parameter does not match"},
-    { 0x06060012, "Data type does not match, lengh of service parameter is too high"},
-    { 0x06060013, "Data type does not match, lengh of service parameter is too low"},
+    { 0x06070010, "Data type does not match, lengh of service parameter does not match"},
+    { 0x06070012, "Data type does not match, lengh of service parameter is too high"},
+    { 0x06070013, "Data type does not match, lengh of service parameter is too low"},
     { 0x06090011, "Sub-index does not exist"},
     { 0x06090030, "Value range of parameter exceeded (only for write access)"},
     { 0x06090031, "Value of parameter written too high"},

Note: "length" is also misspelled.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.