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 size_t co_val_lex_dcf(co_unsigned16_t type,
void *val,
const char *begin,
64 const char *end,
struct floc *at);
65 static size_t co_val_lex_id(
66 const char *begin,
const char *end,
struct floc *at);
67 static void co_val_set_id(co_unsigned16_t type,
void *val, co_unsigned8_t
id);
69 static co_unsigned16_t config_get_idx(
const config_t *cfg,
const char *section,
70 co_unsigned16_t maxidx, co_unsigned16_t *idx);
73 __co_dev_init_from_dcf_file(
struct __co_dev *dev,
const char *filename)
78 "unable to create configuration struct");
79 goto error_create_cfg;
83 goto error_parse_ini_file;
85 if (!__co_dev_init_from_dcf_cfg(dev, cfg))
107 goto error_alloc_dev;
110 if (!__co_dev_init_from_dcf_file(dev, filename)) {
125 __co_dev_init_from_dcf_text(
struct __co_dev *dev,
const char *begin,
126 const char *end,
struct floc *at)
131 "unable to create configuration struct");
132 goto error_create_cfg;
136 goto error_parse_ini_text;
138 if (!__co_dev_init_from_dcf_cfg(dev, cfg))
146 error_parse_ini_text:
160 goto error_alloc_dev;
163 if (!__co_dev_init_from_dcf_text(dev, begin, end, at)) {
183 if (!__co_dev_init(dev, 0xff)) {
185 "unable to initialize device description");
189 if (co_dev_parse_cfg(dev, cfg) == -1)
190 goto error_parse_cfg;
210 config_get(cfg,
"DeviceInfo",
"VendorName")) == -1) {
213 goto error_parse_dev;
216 val =
config_get(cfg,
"DeviceInfo",
"VendorNumber");
222 config_get(cfg,
"DeviceInfo",
"ProductName")) == -1) {
225 goto error_parse_dev;
228 val =
config_get(cfg,
"DeviceInfo",
"ProductNumber");
232 val =
config_get(cfg,
"DeviceInfo",
"RevisionNumber");
238 config_get(cfg,
"DeviceInfo",
"OrderCode")) == -1) {
240 goto error_parse_dev;
244 unsigned int baud = 0;
245 val =
config_get(cfg,
"DeviceInfo",
"BaudRate_10");
246 if (val && *val && strtoul(val, NULL, 0))
248 val =
config_get(cfg,
"DeviceInfo",
"BaudRate_20");
249 if (val && *val && strtoul(val, NULL, 0))
251 val =
config_get(cfg,
"DeviceInfo",
"BaudRate_50");
252 if (val && *val && strtoul(val, NULL, 0))
254 val =
config_get(cfg,
"DeviceInfo",
"BaudRate_125");
255 if (val && *val && strtoul(val, NULL, 0))
257 val =
config_get(cfg,
"DeviceInfo",
"BaudRate_250");
258 if (val && *val && strtoul(val, NULL, 0))
260 val =
config_get(cfg,
"DeviceInfo",
"BaudRate_500");
261 if (val && *val && strtoul(val, NULL, 0))
263 val =
config_get(cfg,
"DeviceInfo",
"BaudRate_800");
264 if (val && *val && strtoul(val, NULL, 0))
266 val =
config_get(cfg,
"DeviceInfo",
"BaudRate_1000");
267 if (val && *val && strtoul(val, NULL, 0))
271 val =
config_get(cfg,
"DeviceInfo",
"LSS_Supported");
277 co_unsigned32_t
dummy = 0;
278 for (
int i = 0; i < 0x20; i++) {
281 snprintf(key,
sizeof(key),
"Dummy%04X", (co_unsigned16_t)i);
284 if (val && *val && strtoul(val, NULL, 0))
290 co_unsigned16_t n = 0;
291 n += config_get_idx(cfg,
"MandatoryObjects", 0, NULL);
292 n += config_get_idx(cfg,
"OptionalObjects", 0, NULL);
293 n += config_get_idx(cfg,
"ManufacturerObjects", 0, NULL);
296 co_unsigned16_t *idx = malloc(n *
sizeof(co_unsigned16_t));
299 "unable to create object list");
300 goto error_parse_idx;
302 co_unsigned16_t i = 0;
303 i += config_get_idx(cfg,
"MandatoryObjects", n - i, idx + i);
304 i += config_get_idx(cfg,
"OptionalObjects", n - i, idx + i);
305 config_get_idx(cfg,
"ManufacturerObjects", n - i, idx + i);
307 for (i = 0; i < n; i++) {
311 goto error_parse_obj;
316 snprintf(section,
sizeof(section),
"%X", idx[i]);
319 co_obj_t *obj = co_obj_build(dev, idx[i]);
321 goto error_parse_obj;
324 if (co_obj_parse_cfg(obj, cfg, section) == -1)
325 goto error_parse_obj;
337 val =
config_get(cfg,
"DeviceInfo",
"CompactPDO");
338 unsigned int mask = val && *val ? strtoul(val, NULL, 0) : 0;
340 co_unsigned16_t nrpdo = 0;
341 val =
config_get(cfg,
"DeviceInfo",
"NrOfRxPDO");
343 nrpdo = (co_unsigned16_t)strtoul(val, NULL, 0);
345 for (co_unsigned16_t i = 0; i < 512 && nrpdo; i++) {
350 for (co_unsigned16_t i = 0; i < 512; i++) {
358 if (co_rpdo_build(dev, i + 1, mask) == -1)
359 goto error_parse_pdo;
362 co_unsigned16_t ntpdo = 0;
363 val =
config_get(cfg,
"DeviceInfo",
"NrOfTxPDO");
365 ntpdo = (co_unsigned16_t)strtoul(val, NULL, 0);
367 for (co_unsigned16_t i = 0; i < 512 && ntpdo; i++) {
372 for (co_unsigned16_t i = 0; i < 512; i++) {
380 if (co_tpdo_build(dev, i + 1, mask) == -1)
381 goto error_parse_pdo;
385 val =
config_get(cfg,
"DeviceComissioning",
"NodeID");
388 (co_unsigned8_t)strtoul(val, NULL, 0)) == -1) {
392 goto error_parse_dcf;
395 val =
config_get(cfg,
"DeviceComissioning",
"NetNumber");
398 (co_unsigned32_t)strtoul(val, NULL, 0)) == -1) {
401 "invalid network-ID (%s) specified", val);
402 goto error_parse_dcf;
407 config_get(cfg,
"DeviceComissioning",
"NodeName"))
411 goto error_parse_dcf;
414 val =
config_get(cfg,
"DeviceComissioning",
"Baudrate");
418 val =
config_get(cfg,
"DeviceComissioning",
"LSS_SerialNumber");
420 if (val && *val && !co_dev_set_val_u32(dev, 0x1018, 0x04,
421 strtoul(val, NULL, 0))) {
424 goto error_parse_dcf;
447 struct floc at = { section, 0, 0 };
451 const char *name =
config_get(cfg, section,
"ParameterName");
454 "ParameterName not specified for object 0x%04X",
458 #ifndef LELY_NO_CO_OBJ_NAME 464 "unable to set name of object 0x%04X", idx);
472 code = (co_unsigned8_t)strtoul(val, NULL, 0);
475 "ObjectType = 0x%x for object 0x%04X",
483 co_unsigned8_t subnum = 0;
486 subnum = (co_unsigned8_t)strtoul(val, NULL, 0);
487 co_unsigned8_t subobj = 0;
488 val =
config_get(cfg, section,
"CompactSubObj");
490 subobj = (co_unsigned8_t)strtoul(val, NULL, 0);
491 if (!subnum && !subobj) {
493 "neither SubNumber nor CompactSubObj specified for object 0x%04X",
497 if (subnum && subobj) {
499 "both SubNumber and CompactSubObj specified for object 0x%04X",
505 for (
size_t subidx = 0; subnum && subidx < 0xff; subidx++) {
508 snprintf(section,
sizeof(section),
"%Xsub%X",
509 (co_unsigned16_t)idx,
510 (co_unsigned8_t)subidx);
515 cfg, section,
"ParameterName");
530 "DataType not specified");
533 co_unsigned16_t type =
534 (co_unsigned16_t)strtoul(val, NULL, 0);
538 (co_unsigned8_t)subidx, type, name);
543 if (co_sub_parse_cfg(sub, cfg, section) == -1)
549 co_sub_t *sub = co_sub_build(obj, 0,
555 #ifndef LELY_NO_CO_OBJ_DEFAULT 560 name =
config_get(cfg, section,
"ParameterName");
566 "DataType not specified");
569 co_unsigned16_t type =
570 (co_unsigned16_t)strtoul(val, NULL, 0);
573 for (
size_t subidx = 1; subidx <= subobj; subidx++) {
575 char *subname = NULL;
577 if (
asprintf(&subname,
"%s%u", name,
578 (co_unsigned8_t)subidx) < 0)
583 sub = co_sub_build(obj, (co_unsigned8_t)subidx,
591 if (co_sub_parse_cfg(sub, cfg, section) == -1)
595 #ifndef LELY_NO_CO_OBJ_NAME 597 if (co_obj_parse_names(obj, cfg) == -1)
602 if (co_obj_parse_values(obj, cfg) == -1)
609 "object 0x%04X does not provide the highest sub-index implemented",
621 type = (co_unsigned16_t)strtoul(val, NULL, 0);
628 co_sub_t *sub = co_sub_build(obj, 0, type, name);
633 if (co_sub_parse_cfg(sub, cfg, section) == -1)
640 #ifndef LELY_NO_CO_OBJ_NAME 651 snprintf(section,
sizeof(section),
"%XName", idx);
653 const char *val =
config_get(cfg, section,
"NrOfEntries");
657 co_unsigned8_t n = (co_unsigned8_t)strtoul(val, NULL, 0);
658 for (
size_t subidx = 1; n && subidx < 0xff; subidx++) {
660 snprintf(key,
sizeof(key),
"%u", (co_unsigned8_t)subidx);
666 obj, (co_unsigned8_t)subidx);
669 "unable to set name of sub-object %Xsub%X",
670 (co_unsigned16_t)idx,
671 (co_unsigned8_t)subidx);
679 #endif // LELY_NO_CO_OBJ_NAME 692 snprintf(section,
sizeof(section),
"%XValue", (co_unsigned16_t)idx);
693 struct floc at = { section, 0, 0 };
695 const char *val =
config_get(cfg, section,
"NrOfEntries");
699 co_unsigned8_t n = (co_unsigned8_t)strtoul(val, NULL, 0);
700 for (
size_t subidx = 1; n && subidx < 0xff; subidx++) {
702 snprintf(key,
sizeof(key),
"%u", (co_unsigned8_t)subidx);
708 obj, (co_unsigned8_t)subidx);
711 size_t chars = co_val_lex_id(val, NULL, &at);
716 if (!co_val_lex_dcf(type, sub->
val, val, NULL, &at)) {
718 "unable to set value of sub-object %Xsub%X",
719 (co_unsigned16_t)idx,
720 (co_unsigned8_t)subidx);
724 co_val_set_id(type, sub->
val,
id);
732 co_obj_build(
co_dev_t *dev, co_unsigned16_t idx)
745 "unable to insert object 0x%04X into the object dictionary",
763 struct floc at = { section, 0, 0 };
768 #ifdef LELY_NO_CO_OBJ_DEFAULT 773 #ifndef LELY_NO_CO_OBJ_LIMITS 776 size_t chars = co_val_lex_id(val, NULL, &at);
781 if (!co_val_lex_dcf(type, &sub->
min, val, NULL, &at)) {
783 "unable to parse LowLimit");
787 co_val_set_id(type, &sub->
min,
id);
792 size_t chars = co_val_lex_id(val, NULL, &at);
797 if (!co_val_lex_dcf(type, &sub->
max, val, NULL, &at)) {
799 "unable to parse HighLimit");
803 co_val_set_id(type, &sub->
max,
id);
805 #endif // LELY_NO_CO_OBJ_LIMITS 810 if (!strcasecmp(val,
"ro")) {
812 }
else if (!strcasecmp(val,
"wo")) {
814 }
else if (!strcasecmp(val,
"rw")) {
816 }
else if (!strcasecmp(val,
"rwr")) {
818 }
else if (!strcasecmp(val,
"rww")) {
820 }
else if (!strcasecmp(val,
"const")) {
832 val =
config_get(cfg, section,
"DefaultValue");
834 size_t chars = co_val_lex_id(val, NULL, &at);
839 #ifdef LELY_NO_CO_OBJ_DEFAULT 840 if (!co_val_lex_dcf(type, &def, val, NULL, &at)) {
842 if (!co_val_lex_dcf(type, &sub->
def, val, NULL, &at)) {
845 "unable to parse DefaultValue");
849 #ifdef LELY_NO_CO_OBJ_DEFAULT 850 co_val_set_id(type, &def,
id);
852 co_val_set_id(type, &sub->
def,
id);
862 sub->
flags |= strtoul(val, NULL, 0);
864 val =
config_get(cfg, section,
"ParameterValue");
866 size_t chars = co_val_lex_id(val, NULL, &at);
871 if (!co_val_lex_dcf(type, sub->
val, val, NULL, &at)) {
873 "unable to parse ParameterValue");
877 co_val_set_id(type, sub->
val,
id);
878 #ifndef LELY_NO_CO_OBJ_FILE 880 && (val =
config_get(cfg, section,
"UploadFile"))
884 "AccessType must be 'ro' or 'const' when using UploadFile");
886 access &= ~CO_ACCESS_WRITE;
895 "unable to parse UploadFile");
899 && (val =
config_get(cfg, section,
"DownloadFile"))
903 "AccessType must be 'wo' when using DownloadFile");
904 access &= ~CO_ACCESS_READ;
913 "unable to parse DownloadFile");
920 #ifdef LELY_NO_CO_OBJ_DEFAULT 927 #ifndef LELY_NO_CO_OBJ_LIMITS 931 #ifndef LELY_NO_CO_OBJ_DEFAULT 937 "LowLimit exceeds HighLimit");
938 #ifndef LELY_NO_CO_OBJ_DEFAULT 946 "ParameterValue underflow");
949 "ParameterValue overflow");
956 #ifdef LELY_NO_CO_OBJ_DEFAULT 963 co_sub_build(
co_obj_t *obj, co_unsigned8_t subidx, co_unsigned16_t type,
973 "unable to create sub-object %Xsub%X", idx,
980 "unable to insert sub-object %Xsub%X into the object dictionary",
985 #ifndef LELY_NO_CO_OBJ_NAME 988 "unable to set name of sub-object %Xsub%X", idx,
1004 co_rpdo_build(
co_dev_t *dev, co_unsigned16_t num,
int mask)
1007 assert(num && num <= 512);
1011 co_unsigned8_t n = 0;
1012 for (
int i = 0; i < 6; i++) {
1013 if (mask & (1 << i))
1019 co_obj_t *obj = co_obj_build(dev, 0x1400 + num - 1);
1022 #ifndef LELY_NO_CO_OBJ_NAME 1033 "Highest sub-index supported");
1037 #ifndef LELY_NO_CO_OBJ_DEFAULT 1044 "COB-ID used by RPDO");
1049 cobid = num * 0x100 + 0x100 + 0xff;
1054 #ifndef LELY_NO_CO_OBJ_DEFAULT 1062 "Transmission type");
1078 "Compatibility entry");
1094 "SYNC start value");
1103 co_obj_t *obj = co_obj_build(dev, 0x1600 + num - 1);
1106 #ifndef LELY_NO_CO_OBJ_NAME 1116 "Highest sub-index supported");
1121 for (co_unsigned8_t i = 1; i <= 0x40; i++) {
1123 snprintf(name,
sizeof(name),
"Application object %u",
1138 co_tpdo_build(
co_dev_t *dev, co_unsigned16_t num,
int mask)
1141 assert(num && num <= 512);
1145 co_unsigned8_t n = 0;
1146 for (
int i = 0; i < 6; i++) {
1147 if (mask & (1 << i))
1153 co_obj_t *obj = co_obj_build(dev, 0x1800 + num - 1);
1156 #ifndef LELY_NO_CO_OBJ_NAME 1167 "Highest sub-index supported");
1171 #ifndef LELY_NO_CO_OBJ_DEFAULT 1178 "COB-ID used by TPDO");
1183 cobid = num * 0x100 + 0x80 + 0xff;
1188 #ifndef LELY_NO_CO_OBJ_DEFAULT 1196 "Transmission type");
1228 "SYNC start value");
1237 co_obj_t *obj = co_obj_build(dev, 0x1a00 + num - 1);
1240 #ifndef LELY_NO_CO_OBJ_NAME 1250 "Highest sub-index supported");
1255 for (co_unsigned8_t i = 1; i <= 0x40; i++) {
1257 snprintf(name,
sizeof(name),
"Application object %u",
1272 co_val_lex_dcf(co_unsigned16_t type,
void *val,
const char *begin,
1273 const char *end,
struct floc *at)
1276 assert(!end || end >= begin);
1281 size_t chars =
lex_hex(begin, end, NULL, NULL, &n);
1285 "unable to create value of type OCTET_STRING");
1288 uint_least8_t *os = *(
void **)val;
1290 lex_hex(begin, end, NULL, os, &n);
1292 return floc_lex(at, begin, begin + chars);
1298 for (cp = begin; (!end || cp < end) && *cp;) {
1300 cp +=
lex_utf8(cp, end, NULL, &c32);
1301 assert(c32 < 0xd800 || c32 > 0xdfff);
1302 n += c32 <= 0xffff ? 1 : 2;
1307 "unable to create value of type UNICODE_STRING");
1311 char16_t *us = *(
void **)val;
1313 for (cp = begin; (!end || cp < end) && *cp;) {
1315 cp +=
lex_utf8(cp, end, NULL, &c32);
1316 assert(c32 < 0xd800 || c32 > 0xdfff);
1318 if (c32 <= 0xffff) {
1322 *us++ = 0xd800 + ((c32 >> 10) & 0x3ff);
1323 *us++ = 0xdc00 + (c32 & 0x3ff);
1331 size_t chars =
lex_hex(begin, end, NULL, NULL, &n);
1335 "unable to create value of type DOMAIN");
1338 void *dom = *(
void **)val;
1340 lex_hex(begin, end, NULL, dom, &n);
1342 return floc_lex(at, begin, begin + chars);
1344 default:
return co_val_lex(type, val, begin, end, at);
1349 co_val_lex_id(
const char *begin,
const char *end,
struct floc *at)
1353 const char *cp = begin;
1355 if ((end && cp - end < 7) || strncasecmp(begin,
"$NODEID", 7))
1369 co_val_set_id(co_unsigned16_t type,
void *val, co_unsigned8_t
id)
1375 #define LELY_CO_DEFINE_TYPE(a, b, c, d) \ 1376 case CO_DEFTYPE_##a: \ 1379 #include <lely/co/def/basic.def> 1380 #undef LELY_CO_DEFINE_TYPE 1384 static co_unsigned16_t
1385 config_get_idx(
const config_t *cfg,
const char *section, co_unsigned16_t maxidx,
1386 co_unsigned16_t *idx)
1393 const char *val =
config_get(cfg, section,
"SupportedObjects");
1397 co_unsigned16_t n = (co_unsigned16_t)strtoul(val, NULL, 0);
1398 for (
size_t i = 0; i < (size_t)
MIN(n, maxidx); i++) {
1400 snprintf(key,
sizeof(key),
"%u", (co_unsigned16_t)(i + 1));
1404 idx[i] = val && *val
1405 ? (co_unsigned16_t)strtoul(val, NULL, 0) : 0;
1412 #endif // !LELY_NO_CO_DCF int co_dev_set_netid(co_dev_t *dev, co_unsigned8_t id)
Sets the network-ID of a CANopen device.
#define CO_ACCESS_RWW
Read or write on process output.
#define CO_BAUD_800
A bit rate of 800 kbit/s.
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.
#define CO_OBJECT_DOMAIN
A large variable amount of data.
void co_dev_set_rate(co_dev_t *dev, co_unsigned16_t rate)
Sets the (pending) baudrate of a CANopen device.
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.
co_unsigned16_t type
The data type.
#define CO_DEFTYPE_DOMAIN
The data type (and object index) of an arbitrary large block of data.
void co_dev_set_product_code(co_dev_t *dev, co_unsigned32_t product_code)
Sets the product code of a CANopen device.
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.
#define CO_BAUD_50
A bit rate of 50 kbit/s.
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.
#define CO_ACCESS_RWR
Read or write on process input.
A union of the CANopen static data types.
#define CO_BAUD_10
A bit rate of 10 kbit/s.
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.
unsigned long flags
The object flags.
#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.
union co_val min
The lower limit of the object value.
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.
int co_val_init_us_n(char16_t **val, const char16_t *us, size_t n)
Initializes an array of (16-bit) Unicode characters (CO_DEFTYPE_UNICODE_STRING).
#define CO_BAUD_250
A bit rate of 250 kbit/s.
#define CO_OBJECT_RECORD
A multiple data field object where the data fields may be any combination of simple variables...
size_t lex_ctype(int(*ctype)(int), const char *begin, const char *end, struct floc *at)
Greedily lexes a sequence of characters of the specified class from a memory buffer.
union co_val def
The default value.
#define CO_ACCESS_READ
The object can be read.
void co_dev_set_lss(co_dev_t *dev, int lss)
Sets the LSS support flag.
#define CO_DEFTYPE_UNSIGNED32
The data type (and object index) of a 32-bit unsigned integer.
size_t lex_char(int c, const char *begin, const char *end, struct floc *at)
Lexes the specified character from a memory buffer.
void config_destroy(config_t *config)
Destroys a configuration struct.
void * val
A pointer to the sub-object value.
co_unsigned8_t co_dev_get_id(const co_dev_t *dev)
Returns the node-ID of a CANopen device.
size_t lex_utf8(const char *begin, const char *end, struct floc *at, char32_t *pc32)
Lexes a UTF-8 encoded Unicode character from a memory buffer.
#define CO_ACCESS_RO
Read-only access.
#define CO_BAUD_125
A bit rate of 125 kbit/s.
int co_val_init_os(uint_least8_t **val, const uint_least8_t *os, size_t n)
Initializes an array of octets (CO_DEFTYPE_OCTET_STRING).
#define CO_DEFTYPE_UNSIGNED16
The data type (and object index) of a 16-bit unsigned integer.
#define CO_ACCESS_CONST
Constant value.
void co_dev_set_revision(co_dev_t *dev, co_unsigned32_t revision)
Sets the revision number of a CANopen device.
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.
void diag_if(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.
#define CO_DEFTYPE_UNICODE_STRING
The data type (and object index) of an array of (16-bit) Unicode characters.
int column
The column number (starting from 1).
#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 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.
size_t floc_lex(struct floc *at, const char *begin, const char *end)
Increments a file location by reading characters from a memory buffer.
#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.
int co_dev_set_product_name(co_dev_t *dev, const char *product_name)
Sets the product name of a CANopen device.
size_t co_val_copy(co_unsigned16_t type, void *dst, const void *src)
Copies one value to another.
co_unsigned32_t dummy
The data types supported for mapping dummy entries in PDOs.
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.
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.
void co_dev_set_baud(co_dev_t *dev, unsigned int baud)
Sets the supported bit rates of a CANopen device.
int co_val_cmp(co_unsigned16_t type, const void *v1, const void *v2)
Compares two values of the specified data type.
#define CO_DEFTYPE_OCTET_STRING
The data type (and object index) of an array of octets.
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.
size_t lex_hex(const char *begin, const char *end, struct floc *at, void *ptr, size_t *pn)
Lexes and decodes the hexadecimal representation of binary data from a memory buffer.
int co_dev_set_name(co_dev_t *dev, const char *name)
Sets the name of a CANopen device.
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.
#define CO_BAUD_1000
A bit rate of 1 Mbit/s.
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.
#define CO_BAUD_500
A bit rate of 500 kbit/s.
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.
int co_val_init(co_unsigned16_t type, void *val)
Initializes a value of the specified data type to zero.
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_order_code(co_dev_t *dev, const char *order_code)
Sets the order 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.
void co_dev_set_vendor_id(co_dev_t *dev, co_unsigned32_t vendor_id)
Sets the vendor ID of a CANopen device.
int co_dev_insert_obj(co_dev_t *dev, co_obj_t *obj)
Inserts an object into the object dictionary of a CANopen device.
Section and key names are case-insensitive.
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 }.
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.
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.
int co_dev_set_id(co_dev_t *dev, co_unsigned8_t id)
Sets the node-ID 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.
#define CO_BAUD_20
A bit rate of 20 kbit/s.
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 }.
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.
#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...
This header file is part of the CANopen library; it contains the Process Data Object (PDO) declaratio...