27 #ifndef LELY_NO_CO_DCF 42 static struct __co_dev *__co_dev_init_from_dcf_cfg(
47 static int co_obj_parse_cfg(
49 #ifndef LELY_NO_CO_OBJ_NAME 55 static int co_sub_parse_cfg(
58 co_unsigned16_t type,
const char *
name);
60 static int co_rpdo_build(
co_dev_t *dev, co_unsigned16_t num,
int mask);
61 static int co_tpdo_build(
co_dev_t *dev, co_unsigned16_t num,
int mask);
63 static void co_val_set_id(co_unsigned16_t type,
void *val, co_unsigned8_t
id);
65 static co_unsigned16_t config_get_idx(
const config_t *cfg,
const char *section,
66 co_unsigned16_t maxidx, co_unsigned16_t *idx);
69 __co_dev_init_from_dcf_file(
struct __co_dev *dev,
const char *filename)
74 "unable to create configuration struct");
75 goto error_create_cfg;
79 goto error_parse_ini_file;
81 if (
__unlikely(!__co_dev_init_from_dcf_cfg(dev, cfg)))
103 goto error_alloc_dev;
106 if (
__unlikely(!__co_dev_init_from_dcf_file(dev, filename))) {
121 __co_dev_init_from_dcf_text(
struct __co_dev *dev,
const char *begin,
122 const char *end,
struct floc *at)
127 "unable to create configuration struct");
128 goto error_create_cfg;
132 goto error_parse_ini_text;
134 if (
__unlikely(!__co_dev_init_from_dcf_cfg(dev, cfg)))
142 error_parse_ini_text:
156 goto error_alloc_dev;
159 if (
__unlikely(!__co_dev_init_from_dcf_text(dev, begin, end, at))) {
181 "unable to initialize device description");
185 if (
__unlikely(co_dev_parse_cfg(dev, cfg) == -1))
186 goto error_parse_cfg;
206 config_get(cfg,
"DeviceInfo",
"VendorName")) == -1)) {
209 goto error_parse_dev;
212 val =
config_get(cfg,
"DeviceInfo",
"VendorNumber");
218 config_get(cfg,
"DeviceInfo",
"ProductName")) == -1)) {
221 goto error_parse_dev;
224 val =
config_get(cfg,
"DeviceInfo",
"ProductNumber");
228 val =
config_get(cfg,
"DeviceInfo",
"RevisionNumber");
234 config_get(cfg,
"DeviceInfo",
"OrderCode")) == -1)) {
236 goto error_parse_dev;
240 unsigned int baud = 0;
241 val =
config_get(cfg,
"DeviceInfo",
"BaudRate_10");
242 if (val && *val && strtoul(val, NULL, 0))
244 val =
config_get(cfg,
"DeviceInfo",
"BaudRate_20");
245 if (val && *val && strtoul(val, NULL, 0))
247 val =
config_get(cfg,
"DeviceInfo",
"BaudRate_50");
248 if (val && *val && strtoul(val, NULL, 0))
250 val =
config_get(cfg,
"DeviceInfo",
"BaudRate_125");
251 if (val && *val && strtoul(val, NULL, 0))
253 val =
config_get(cfg,
"DeviceInfo",
"BaudRate_250");
254 if (val && *val && strtoul(val, NULL, 0))
256 val =
config_get(cfg,
"DeviceInfo",
"BaudRate_500");
257 if (val && *val && strtoul(val, NULL, 0))
259 val =
config_get(cfg,
"DeviceInfo",
"BaudRate_800");
260 if (val && *val && strtoul(val, NULL, 0))
262 val =
config_get(cfg,
"DeviceInfo",
"BaudRate_1000");
263 if (val && *val && strtoul(val, NULL, 0))
267 val =
config_get(cfg,
"DeviceInfo",
"LSS_Supported");
273 co_unsigned32_t
dummy = 0;
274 for (
int i = 0; i < 0x20; i++) {
277 sprintf(key,
"Dummy%04X", (co_unsigned16_t)i);
280 if (val && *val && strtoul(val, NULL, 0))
286 co_unsigned16_t n = 0;
287 n += config_get_idx(cfg,
"MandatoryObjects", 0, NULL);
288 n += config_get_idx(cfg,
"OptionalObjects", 0, NULL);
289 n += config_get_idx(cfg,
"ManufacturerObjects", 0, NULL);
292 co_unsigned16_t *idx = malloc(n *
sizeof(co_unsigned16_t));
295 "unable to create object list");
296 goto error_parse_idx;
298 co_unsigned16_t i = 0;
299 i += config_get_idx(cfg,
"MandatoryObjects", n - i, idx + i);
300 i += config_get_idx(cfg,
"OptionalObjects", n - i, idx + i);
301 config_get_idx(cfg,
"ManufacturerObjects", n - i, idx + i);
303 for (i = 0; i < n; i++) {
307 goto error_parse_obj;
312 sprintf(section,
"%X", idx[i]);
315 co_obj_t *obj = co_obj_build(dev, idx[i]);
317 goto error_parse_obj;
320 if (
__unlikely(co_obj_parse_cfg(obj, cfg, section) == -1))
321 goto error_parse_obj;
333 val =
config_get(cfg,
"DeviceInfo",
"CompactPDO");
335 unsigned int mask = strtoul(val, NULL, 0);
337 co_unsigned16_t nrpdo = 0;
338 val =
config_get(cfg,
"DeviceInfo",
"NrOfRxPDO");
340 nrpdo = (co_unsigned16_t)strtoul(val, NULL, 0);
341 for (co_unsigned16_t num = 1; num <= nrpdo; num++) {
342 if (
__unlikely(co_rpdo_build(dev, num, mask) == -1))
343 goto error_parse_pdo;
346 co_unsigned16_t ntpdo = 0;
347 val =
config_get(cfg,
"DeviceInfo",
"NrOfTxPDO");
349 ntpdo = (co_unsigned16_t)strtoul(val, NULL, 0);
350 for (co_unsigned16_t num = 1; num <= ntpdo; num++) {
351 if (
__unlikely(co_tpdo_build(dev, num, mask) == -1))
352 goto error_parse_pdo;
356 val =
config_get(cfg,
"DeviceComissioning",
"NodeID");
359 (co_unsigned8_t)strtoul(val, NULL, 0)) == -1) {
363 goto error_parse_dcf;
366 val =
config_get(cfg,
"DeviceComissioning",
"NetNumber");
369 (co_unsigned32_t)strtoul(val, NULL, 0)) == -1) {
372 "invalid network-ID (%s) specified", val);
373 goto error_parse_dcf;
378 config_get(cfg,
"DeviceComissioning",
"NodeName"))
382 goto error_parse_dcf;
385 val =
config_get(cfg,
"DeviceComissioning",
"Baudrate");
389 val =
config_get(cfg,
"DeviceComissioning",
"LSS_SerialNumber");
391 if (val && *val && !co_dev_set_val_u32(dev, 0x1018, 0x04,
392 strtoul(val, NULL, 0))) {
395 goto error_parse_dcf;
418 struct floc at = { section, 0, 0 };
422 const char *name =
config_get(cfg, section,
"ParameterName");
425 "ParameterName not specified for object 0x%04X",
429 #ifndef LELY_NO_CO_OBJ_NAME 435 "unable to set name of object 0x%04X", idx);
443 code = (co_unsigned8_t)strtoul(val, NULL, 0);
446 "ObjectType = 0x%x for object 0x%04X",
454 co_unsigned8_t subnum = 0;
457 subnum = (co_unsigned8_t)strtoul(val, NULL, 0);
458 co_unsigned8_t subobj = 0;
459 val =
config_get(cfg, section,
"CompactSubObj");
461 subobj = (co_unsigned8_t)strtoul(val, NULL, 0);
464 "neither SubNumber nor CompactSubObj specified for object 0x%04X",
470 "both SubNumber and CompactSubObj specified for object 0x%04X",
476 for (
size_t subidx = 0; subnum && subidx < 0xff; subidx++) {
479 sprintf(section,
"%Xsub%X", (co_unsigned16_t)idx,
480 (co_unsigned8_t)subidx);
485 cfg, section,
"ParameterName");
500 "DataType not specified");
503 co_unsigned16_t type =
504 (co_unsigned16_t)strtoul(val, NULL, 0);
508 (co_unsigned8_t)subidx, type, name);
514 if (
__unlikely(co_sub_parse_cfg(sub, cfg, section)
522 co_sub_t *sub = co_sub_build(obj, 0,
531 name =
config_get(cfg, section,
"ParameterName");
537 "DataType not specified");
540 co_unsigned16_t type =
541 (co_unsigned16_t)strtoul(val, NULL, 0);
544 for (
size_t subidx = 1; subidx <= subobj; subidx++) {
546 char *subname = NULL;
549 (co_unsigned8_t)subidx) < 0))
554 sub = co_sub_build(obj, (co_unsigned8_t)subidx,
569 #ifndef LELY_NO_CO_OBJ_NAME 571 if (
__unlikely(co_obj_parse_names(obj, cfg) == -1))
576 if (
__unlikely(co_obj_parse_values(obj, cfg) == -1))
586 "object 0x%04X does not provide the highest sub-index implemented",
598 type = (co_unsigned16_t)strtoul(val, NULL, 0);
605 co_sub_t *sub = co_sub_build(obj, 0, type, name);
610 if (
__unlikely(co_sub_parse_cfg(sub, cfg, section) == -1))
617 #ifndef LELY_NO_CO_OBJ_NAME 628 sprintf(section,
"%XName", idx);
630 const char *val =
config_get(cfg, section,
"NrOfEntries");
634 co_unsigned8_t n = (co_unsigned8_t)strtoul(val, NULL, 0);
635 for (
size_t subidx = 1; n && subidx < 0xff; subidx++) {
637 sprintf(key,
"%u", (co_unsigned8_t)subidx);
643 obj, (co_unsigned8_t)subidx);
649 "unable to set name of sub-object %Xsub%X",
650 (co_unsigned16_t)idx,
651 (co_unsigned8_t)subidx);
659 #endif // LELY_NO_CO_OBJ_NAME 672 sprintf(section,
"%XValue", (co_unsigned16_t)idx);
673 struct floc at = { section, 0, 0 };
675 const char *val =
config_get(cfg, section,
"NrOfEntries");
679 co_unsigned8_t n = (co_unsigned8_t)strtoul(val, NULL, 0);
680 for (
size_t subidx = 1; n && subidx < 0xff; subidx++) {
682 sprintf(key,
"%u", (co_unsigned8_t)subidx);
688 obj, (co_unsigned8_t)subidx);
691 if (!strncmp(val,
"$NODEID", 7)) {
697 type, sub->
val, val, NULL, &at))) {
700 "unable to set value of sub-object %Xsub%X",
701 (co_unsigned16_t)idx,
702 (co_unsigned8_t)subidx);
706 co_val_set_id(type, sub->
val,
id);
714 co_obj_build(
co_dev_t *dev, co_unsigned16_t idx)
727 "unable to insert object 0x%04X into the object dictionary",
743 struct floc at = { section, 0, 0 };
748 #ifndef LELY_NO_CO_OBJ_LIMITS 751 if (!strncmp(val,
"$NODEID", 7)) {
757 "unable to parse LowLimit");
761 co_val_set_id(type, &sub->
min,
id);
766 if (!strncmp(val,
"$NODEID", 7)) {
772 "unable to parse HighLimit");
776 co_val_set_id(type, &sub->
max,
id);
778 #endif // LELY_NO_CO_OBJ_LIMITS 783 if (!strcasecmp(val,
"ro")) {
785 }
else if (!strcasecmp(val,
"wo")) {
787 }
else if (!strcasecmp(val,
"rw")) {
789 }
else if (!strcasecmp(val,
"rwr")) {
791 }
else if (!strcasecmp(val,
"rww")) {
793 }
else if (!strcasecmp(val,
"const")) {
805 val =
config_get(cfg, section,
"DefaultValue");
807 if (!strncmp(val,
"$NODEID", 7)) {
813 "unable to parse DefaultValue");
817 co_val_set_id(type, &sub->
def,
id);
826 sub->
flags |= strtoul(val, NULL, 0);
828 val =
config_get(cfg, section,
"ParameterValue");
830 if (!strncmp(val,
"$NODEID", 7)) {
836 "unable to parse ParameterValue");
840 co_val_set_id(type, sub->
val,
id);
841 #ifndef LELY_NO_CO_OBJ_FILE 843 && (val =
config_get(cfg, section,
"UploadFile"))
847 "AccessType must be 'ro' or 'const' when using UploadFile");
861 "unable to parse UploadFile");
865 && (val =
config_get(cfg, section,
"DownloadFile"))
869 "AccessType must be 'wo' when using DownloadFile");
882 "unable to parse DownloadFile");
892 #ifndef LELY_NO_CO_OBJ_LIMITS 900 "LowLimit exceeds HighLimit");
908 "ParameterValue underflow");
912 "ParameterValue overflow");
920 co_sub_build(
co_obj_t *obj, co_unsigned8_t subidx, co_unsigned16_t type,
930 "unable to create sub-object %Xsub%X", idx,
937 "unable to insert sub-object %Xsub%X into the object dictionary",
942 #ifndef LELY_NO_CO_OBJ_NAME 945 "unable to set name of sub-object %Xsub%X", idx,
961 co_rpdo_build(
co_dev_t *dev, co_unsigned16_t num,
int mask)
964 assert(num && num <= 512);
968 co_unsigned8_t n = 0;
969 for (
int i = 0; i < 6; i++) {
976 co_obj_t *obj = co_obj_build(dev, 0x1400 + num - 1);
979 #ifndef LELY_NO_CO_OBJ_NAME 982 "RPDO communication parameter") == -1)) {
992 "Highest sub-index supported");
1001 "COB-ID used by RPDO");
1006 cobid = num * 0x100 + 0x100 + 0xff;
1018 "Transmission type");
1034 "Compatibility entry");
1050 "SYNC start value");
1059 co_obj_t *obj = co_obj_build(dev, 0x1600 + num - 1);
1062 #ifndef LELY_NO_CO_OBJ_NAME 1075 "Highest sub-index supported");
1080 for (co_unsigned8_t i = 1; i <= 0x40; i++) {
1082 sprintf(name,
"Application object %u", i);
1096 co_tpdo_build(
co_dev_t *dev, co_unsigned16_t num,
int mask)
1099 assert(num && num <= 512);
1103 co_unsigned8_t n = 0;
1104 for (
int i = 0; i < 6; i++) {
1105 if (mask & (1 << i))
1111 co_obj_t *obj = co_obj_build(dev, 0x1800 + num - 1);
1114 #ifndef LELY_NO_CO_OBJ_NAME 1117 "TPDO communication parameter") == -1)) {
1127 "Highest sub-index supported");
1136 "COB-ID used by TPDO");
1141 cobid = num * 0x100 + 0x80 + 0xff;
1153 "Transmission type");
1185 "SYNC start value");
1194 co_obj_t *obj = co_obj_build(dev, 0x1a00 + num - 1);
1197 #ifndef LELY_NO_CO_OBJ_NAME 1210 "Highest sub-index supported");
1215 for (co_unsigned8_t i = 1; i <= 0x40; i++) {
1217 sprintf(name,
"Application object %u", i);
1231 co_val_set_id(co_unsigned16_t type,
void *val, co_unsigned8_t
id)
1237 #define LELY_CO_DEFINE_TYPE(a, b, c, d) \ 1238 case CO_DEFTYPE_##a: \ 1241 #include <lely/co/def/basic.def> 1242 #undef LELY_CO_DEFINE_TYPE 1246 static co_unsigned16_t
1247 config_get_idx(
const config_t *cfg,
const char *section, co_unsigned16_t maxidx,
1248 co_unsigned16_t *idx)
1255 const char *val =
config_get(cfg, section,
"SupportedObjects");
1259 co_unsigned16_t n = (co_unsigned16_t)strtoul(val, NULL, 0);
1260 for (
size_t i = 0; i < (size_t)
MIN(n, maxidx); i++) {
1262 sprintf(key,
"%u", (co_unsigned16_t)(i + 1));
1266 idx[i] = val && *val
1267 ? (co_unsigned16_t)strtoul(val, NULL, 0) : 0;
1274 #endif // !LELY_NO_CO_DCF #define CO_ACCESS_RWW
Read or write on process output.
void co_dev_set_revision(co_dev_t *dev, co_unsigned32_t revision)
Sets the revision number of a CANopen device.
int co_obj_insert_sub(co_obj_t *obj, co_sub_t *sub)
Inserts a sub-object into a CANopen object.
#define CO_OBJ_FLAGS_UPLOAD_FILE
If a read access is performed for the object, the data is stored in a file.
void co_dev_set_lss(co_dev_t *dev, int lss)
Sets the LSS support flag.
#define CO_BAUD_20
A bit rate of 20 kbit/s.
void co_dev_set_dummy(co_dev_t *dev, co_unsigned32_t dummy)
Sets the data types supported by a CANopen device for mapping dummy entries in PDOs.
#define CO_OBJECT_DOMAIN
A large variable amount of data.
#define CO_BAUD_10
A bit rate of 10 kbit/s.
This header file is part of the C11 and POSIX compatibility library; it includes <strings.h>, if it exists, and defines any missing functionality.
size_t config_parse_ini_text(config_t *config, const char *begin, const char *end, struct floc *at)
Parses a string in INI-format and adds the keys to a configuration struct.
#define CO_ACCESS_WRITE
The object can be written.
This header file is part of the C11 and POSIX compatibility library; it includes <string.h> and defines any missing functionality.
#define CO_ACCESS_WO
Write-only access.
const void * co_sub_addressof_max(const co_sub_t *sub)
Returns the address of the upper limit of the value of a CANopen sub-object.
#define CO_BAUD_500
A bit rate of 500 kbit/s.
co_unsigned16_t type
The data type.
#define CO_DEFTYPE_DOMAIN
The data type (and object index) of an arbitrary large block of data.
A location in a text file.
int co_sub_set_name(co_sub_t *sub, const char *name)
Sets the name of a CANopen sub-object.
int asprintf(char **strp, const char *fmt,...)
Equivalent to sprintf(), except that it allocates a string large enough to hold the output...
int co_val_init_dom(void **val, const void *dom, size_t n)
Initializes an arbitrary large block of data (CO_DEFTYPE_DOMAIN).
int co_obj_set_code(co_obj_t *obj, co_unsigned8_t code)
Sets the code (type) of a CANopen object.
#define CO_OBJ_FLAGS_DOWNLOAD_FILE
If a write access is performed for the object, the data is stored in a file.
co_dev_t * co_dev_create_from_dcf_file(const char *filename)
Creates a CANopen device from an EDS or DCF file.
void diag(enum diag_severity severity, int errc, const char *format,...)
Emits a diagnostic message.
Section and key names are case-insensitive.
unsigned flags
The object flags.
#define CO_ACCESS_RWR
Read or write on process input.
A union of the CANopen static data types.
co_obj_t * co_obj_create(co_unsigned16_t idx)
Creates a CANopen object.
This header file is part of the utilities library; it contains the configuration functions.
co_unsigned8_t co_dev_get_id(const co_dev_t *dev)
Returns the node-ID of a CANopen device.
#define MIN(a, b)
Returns the minimum of a and b.
union co_val max
The upper limit of the object value.
co_unsigned8_t co_obj_get_code(const co_obj_t *obj)
Returns the object code of a CANopen object.
#define CO_BAUD_50
A bit rate of 50 kbit/s.
union co_val min
The lower limit of the object value.
void co_dev_set_product_code(co_dev_t *dev, co_unsigned32_t product_code)
Sets the product code of a CANopen device.
int co_dev_set_vendor_name(co_dev_t *dev, const char *vendor_name)
Sets the vendor name of a CANopen device.
This is the internal header file of the object dictionary.
unsigned baud
The supported bit rates.
void co_sub_destroy(co_sub_t *sub)
Destroys a CANopen sub-object.
const void * co_sub_addressof_min(const co_sub_t *sub)
Returns the address of the lower limit of the value of a CANopen sub-object.
char * name
A pointer to the name of the device.
void set_errc(int errc)
Sets the current (thread-specific) native error code to errc.
const void * co_sub_addressof_def(const co_sub_t *sub)
Returns the address of the default value of a CANopen sub-object.
unsigned int co_sub_get_access(const co_sub_t *sub)
Returns the access type of a CANopen sub-object.
#define CO_OBJECT_RECORD
A multiple data field object where the data fields may be any combination of simple variables...
union co_val def
The default value.
#define CO_ACCESS_READ
The object can be read.
#define CO_DEFTYPE_UNSIGNED32
The data type (and object index) of a 32-bit unsigned integer.
void config_destroy(config_t *config)
Destroys a configuration struct.
void * val
A pointer to the sub-object value.
int co_dev_set_netid(co_dev_t *dev, co_unsigned8_t id)
Sets the network-ID of a CANopen device.
#define CO_ACCESS_RO
Read-only access.
#define CO_BAUD_125
A bit rate of 125 kbit/s.
#define CO_DEFTYPE_UNSIGNED16
The data type (and object index) of a 16-bit unsigned integer.
#define CO_ACCESS_CONST
Constant value.
int co_type_is_basic(co_unsigned16_t type)
Returns 1 if the specified (static) data type is a basic type, and 0 if not.
This is the internal header file of the CANopen library.
void co_sub_set_pdo_mapping(co_sub_t *sub, int pdo_mapping)
Enables or disables PDO mapping a CANopen sub-object.
#define CO_ACCESS_RW
Read or write access.
This header file is part of the utilities library; it contains the lexer function declarations...
#define CO_PDO_COBID_VALID
The bit in the PDO COB-ID specifying whether the PDO exists and is valid.
int co_dev_insert_obj(co_dev_t *dev, co_obj_t *obj)
Inserts an object into the object dictionary of a CANopen device.
int get_errc(void)
Returns the last (thread-specific) native error code set by a system call or library function...
co_dev_t * co_obj_get_dev(const co_obj_t *obj)
Returns a pointer to the CANopen device containing the specified object.
int co_dev_set_order_code(co_dev_t *dev, const char *order_code)
Sets the order code of a CANopen device.
#define CO_DEFTYPE_UNSIGNED8
The data type (and object index) of an 8-bit unsigned integer.
co_dev_t * co_dev_create_from_dcf_text(const char *begin, const char *end, struct floc *at)
Creates a CANopen device from an EDS or DCF text string.
size_t co_val_copy(co_unsigned16_t type, void *dst, const void *src)
Copies one value to another.
void co_dev_set_rate(co_dev_t *dev, co_unsigned16_t rate)
Sets the (pending) baudrate of a CANopen device.
co_unsigned32_t dummy
The data types supported for mapping dummy entries in PDOs.
#define CO_BAUD_250
A bit rate of 250 kbit/s.
int errno2c(int errnum)
Transforms a standard C error number to a native error code.
This header file is part of the utilities library; it contains the diagnostic declarations.
#define __unlikely(x)
Indicates to the compiler that the expression is most-likely false.
const char * config_get(const config_t *config, const char *section, const char *key)
Retrieves a key from a configuration struct.
#define CO_OBJ_FLAGS_VAL_NODEID
The current object value is of the form $NODEID { "+" number }.
size_t co_val_make(co_unsigned16_t type, void *val, const void *ptr, size_t n)
Constructs a value of the specified data type.
int co_val_cmp(co_unsigned16_t type, const void *v1, const void *v2)
Compares two values of the specified data type.
void diag_at(enum diag_severity severity, int errc, const struct floc *at, const char *format,...)
Emits a diagnostic message occurring at a location in a text file.
co_obj_t * co_sub_get_obj(const co_sub_t *sub)
Returns the a pointer to the CANopen object containing the specified sub-object.
size_t co_val_lex(co_unsigned16_t type, void *val, const char *begin, const char *end, struct floc *at)
Lexes a value of the specified data type from a memory buffer.
This header file is part of the C11 and POSIX compatibility library; it includes <stdio.h> and defines any missing functionality.
const void * co_sub_addressof_val(const co_sub_t *sub)
Returns the address of the current value of a CANopen sub-object.
void co_obj_destroy(co_obj_t *obj)
Destroys a CANopen object, including its sub-objects.
#define CO_OBJECT_DEFSTRUCT
A record type definition.
void co_val_fini(co_unsigned16_t type, void *val)
Finalizes a value of the specified data type.
int co_sub_set_access(co_sub_t *sub, unsigned int access)
Sets the access type of a CANopen sub-object.
co_sub_t * co_sub_create(co_unsigned8_t subidx, co_unsigned16_t type)
Creates a CANopen sub-object.
int co_dev_set_product_name(co_dev_t *dev, const char *product_name)
Sets the product name of a CANopen device.
int co_obj_set_name(co_obj_t *obj, const char *name)
Sets the name of a CANopen object.
#define CO_OBJ_FLAGS_DEF_NODEID
The default object value is of the form $NODEID { "+" number }.
int co_dev_set_id(co_dev_t *dev, co_unsigned8_t id)
Sets the node-ID of a CANopen device.
void co_dev_set_baud(co_dev_t *dev, unsigned int baud)
Sets the supported bit rates of a CANopen device.
#define CO_BAUD_800
A bit rate of 800 kbit/s.
size_t config_parse_ini_file(config_t *config, const char *filename)
Parses an INI file and adds the keys to a configuration struct.
This header file is part of the C11 and POSIX compatibility library; it includes <stdlib.h> and defines any missing functionality.
#define CO_BAUD_1000
A bit rate of 1 Mbit/s.
co_obj_t * co_dev_find_obj(const co_dev_t *dev, co_unsigned16_t idx)
Finds an object in the object dictionary of a CANopen device.
co_unsigned16_t co_sub_get_type(const co_sub_t *sub)
Returns the data type of a CANopen sub-object.
co_sub_t * co_obj_find_sub(const co_obj_t *obj, co_unsigned8_t subidx)
Finds a sub-object in a CANopen object.
co_unsigned16_t co_obj_get_idx(const co_obj_t *obj)
Returns the index of a CANopen object.
config_t * config_create(int flags)
Creates a new configuration struct with an unnamed empty root section.
#define CO_OBJ_FLAGS_MAX_NODEID
The upper limit of the object value is of the form $NODEID { "+" number }.
int co_dev_set_name(co_dev_t *dev, const char *name)
Sets the name of a CANopen device.
#define CO_OBJ_FLAGS_MIN_NODEID
The lower limit of the object value is of the form $NODEID { "+" number }.
This header file is part of the CANopen library; it contains the Electronic Data Sheet (EDS) and Devi...
#define CO_OBJECT_ARRAY
A multiple data field object where each data field is a simple variable of the same basic data type...
void co_dev_set_vendor_id(co_dev_t *dev, co_unsigned32_t vendor_id)
Sets the vendor ID of a CANopen device.
This header file is part of the CANopen library; it contains the Process Data Object (PDO) declaratio...