69static void co_obj_set_id(
70 co_obj_t *obj, co_unsigned8_t new_id, co_unsigned8_t old_id);
71static void co_sub_set_id(
72 co_sub_t *sub, co_unsigned8_t new_id, co_unsigned8_t old_id);
73static void co_val_set_id(co_unsigned16_t type,
void *val,
74 co_unsigned8_t new_id, co_unsigned8_t old_id);
79 void *ptr = malloc(
sizeof(
struct __co_dev));
86__co_dev_free(
void *ptr)
92__co_dev_init(
struct __co_dev *dev, co_unsigned8_t
id)
148 goto error_alloc_dev;
225 co_unsigned16_t *idx)
234 for (
size_t i = 0; node && i < maxidx;
309 if (!name || !*name) {
315 void *ptr = realloc(dev->
name, strlen(name) + 1);
321 strcpy(dev->
name, name);
339 if (!vendor_name || !*vendor_name) {
345 void *ptr = realloc(dev->
vendor_name, strlen(vendor_name) + 1);
385 if (!product_name || !*product_name) {
391 void *ptr = realloc(dev->
product_name, strlen(product_name) + 1);
447 if (!order_code || !*order_code) {
453 void *ptr = realloc(dev->
order_code, strlen(order_code) + 1);
540 const void *ptr,
size_t n)
553#define LELY_CO_DEFINE_TYPE(a, b, c, d) \
554 co_##b##_t co_dev_get_val_##c(const co_dev_t *dev, \
555 co_unsigned16_t idx, co_unsigned8_t subidx) \
557 co_sub_t *sub = __likely(dev) \
558 ? co_dev_find_sub(dev, idx, subidx) \
560 return co_sub_get_val_##c(sub); \
563 size_t co_dev_set_val_##c(co_dev_t *dev, co_unsigned16_t idx, \
564 co_unsigned8_t subidx, co_##b##_t c) \
568 co_sub_t *sub = co_dev_find_sub(dev, idx, subidx); \
569 if (__unlikely(!sub)) { \
570 set_errnum(ERRNUM_INVAL); \
574 return co_sub_set_val_##c(sub, c); \
576#include <lely/co/def/basic.def>
577#undef LELY_CO_DEFINE_TYPE
581 const uint8_t *begin,
const uint8_t *end)
583 if (
__unlikely(!begin || !end || end - begin < 2 + 1 + 4))
595 co_unsigned8_t subidx;
603 co_unsigned32_t size;
611 if (
__unlikely(end - begin < (ptrdiff_t)size))
634 return 2 + 1 + 4 + size;
639 co_unsigned8_t subidx, uint8_t *begin, uint8_t *end)
647 co_unsigned32_t size =
co_val_write(type, val, NULL, NULL);
651 if (begin && (!end || end - begin >= (ptrdiff_t)(2 + 1 + 4 + size))) {
678 return 2 + 1 + 4 + size;
692 const uint8_t *begin = *ptr;
693 const uint8_t *end = begin + size;
702 for (
size_t i = 0; i < n; i++) {
723#ifndef LELY_NO_CO_DCF
726 co_unsigned16_t *pmax,
const char *filename)
733 goto error_create_buf;
786 co_unsigned16_t *idx = calloc(maxidx,
sizeof(co_unsigned16_t));
789 goto error_malloc_idx;
794 co_unsigned32_t n = 0;
796 for (
size_t i = 0; i < maxidx; i++) {
797 if (idx[i] < min || idx[i] > max)
802 co_unsigned8_t subidx[0xff];
807 for (
size_t j = 0; j < maxsubidx; j++, n++)
809 dev, idx[i], subidx[j], NULL, NULL);
817 uint8_t *begin = *ptr;
818 uint8_t *end = begin + size;
823 for (
size_t i = 0; i < maxidx; i++) {
824 if (idx[i] < min || idx[i] > max)
829 co_unsigned8_t subidx[0xff];
833 for (
size_t j = 0; j < maxsubidx; j++, n++)
835 dev, idx[i], subidx[j], begin, end);
849#ifndef LELY_NO_CO_DCF
852 co_unsigned16_t max,
const char *filename)
859 goto error_write_dcf;
865 goto error_create_buf;
896co_obj_set_id(
co_obj_t *obj, co_unsigned8_t new_id, co_unsigned8_t old_id)
905co_sub_set_id(
co_sub_t *sub, co_unsigned8_t new_id, co_unsigned8_t old_id)
911#ifndef LELY_NO_CO_OBJ_LIMITS
913 co_val_set_id(type, &sub->
min, new_id, old_id);
915 co_val_set_id(type, &sub->
max, new_id, old_id);
918 co_val_set_id(type, &sub->
def, new_id, old_id);
920 co_val_set_id(type, sub->
val, new_id, old_id);
924co_val_set_id(co_unsigned16_t type,
void *val, co_unsigned8_t new_id,
925 co_unsigned8_t old_id)
931#define LELY_CO_DEFINE_TYPE(a, b, c, d) \
932 case CO_DEFTYPE_##a: \
933 u->c += new_id - old_id; \
935#include <lely/co/def/basic.def>
936#undef LELY_CO_DEFINE_TYPE
This header file is part of the utilities library; it contains the comparison function definitions.
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_dev_get_idx(const co_dev_t *dev, co_unsigned16_t maxidx, co_unsigned16_t *idx)
Retrieves a list of object indices in the object dictionary of a CANopen device.
int co_dev_read_dcf(co_dev_t *dev, co_unsigned16_t *pmin, co_unsigned16_t *pmax, void *const *ptr)
Reads the values of a range of objects from a memory buffer, in the concise DCF format,...
co_unsigned8_t co_dev_get_id(const co_dev_t *dev)
Returns the node-ID 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_product_code(co_dev_t *dev, co_unsigned32_t product_code)
Sets the product code of a CANopen device.
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.
int co_dev_insert_obj(co_dev_t *dev, co_obj_t *obj)
Inserts an object into the object dictionary of a CANopen device.
const char * co_dev_get_product_name(const co_dev_t *dev)
Returns a pointer to the product 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.
size_t co_dev_read_sub(co_dev_t *dev, co_unsigned16_t *pidx, co_unsigned8_t *psubidx, const uint8_t *begin, const uint8_t *end)
Reads a value from a memory buffer, in the concise DCF format, and stores it in a sub-object in the o...
int co_dev_set_id(co_dev_t *dev, co_unsigned8_t id)
Sets the node-ID of a CANopen device.
int co_dev_set_netid(co_dev_t *dev, co_unsigned8_t id)
Sets the network-ID of a CANopen device.
const char * co_dev_get_vendor_name(const co_dev_t *dev)
Returns a pointer to the vendor name of a CANopen device.
void co_dev_set_revision(co_dev_t *dev, co_unsigned32_t revision)
Sets the revision number of a CANopen device.
co_sub_t * co_dev_find_sub(const co_dev_t *dev, co_unsigned16_t idx, co_unsigned8_t subidx)
Finds a sub-object in the object dictionary of a CANopen device.
co_unsigned16_t co_dev_get_rate(const co_dev_t *dev)
Returns the (pending) baudrate of a CANopen device (in kbit/s).
size_t co_dev_write_sub(const co_dev_t *dev, co_unsigned16_t idx, co_unsigned8_t subidx, uint8_t *begin, uint8_t *end)
Loads the value of a sub-object from the object dictionary of a CANopen device, and writes it to a me...
int co_dev_write_dcf(const co_dev_t *dev, co_unsigned16_t min, co_unsigned16_t max, void **ptr)
Loads the values of a range of objects in the object dictionary of a CANopen device,...
int co_dev_remove_obj(co_dev_t *dev, co_obj_t *obj)
Removes an object from the object dictionary a CANopen device.
int co_dev_get_lss(const co_dev_t *dev)
Returns 1 if LSS is supported and 0 if not.
co_unsigned8_t co_dev_get_netid(const co_dev_t *dev)
Returns the network-ID of a CANopen device.
co_unsigned32_t co_dev_get_vendor_id(const co_dev_t *dev)
Returns the vendor ID of a CANopen device.
void co_dev_set_lss(co_dev_t *dev, int lss)
Sets the LSS support flag.
int co_dev_set_order_code(co_dev_t *dev, const char *order_code)
Sets the order code of a CANopen device.
co_unsigned32_t co_dev_get_dummy(const co_dev_t *dev)
Returns the data types supported by a CANopen device for mapping dummy entries in PDOs (one bit for e...
const char * co_dev_get_name(const co_dev_t *dev)
Returns the name of a CANopen device.
int co_dev_write_dcf_file(const co_dev_t *dev, co_unsigned16_t min, co_unsigned16_t max, const char *filename)
Loads the values of a range of objects in the object dictionary of a CANopen device,...
void co_dev_destroy(co_dev_t *dev)
Destroys a CANopen device, including all objects in its object dictionary.
void co_dev_set_rate(co_dev_t *dev, co_unsigned16_t rate)
Sets the (pending) baudrate of a CANopen device.
size_t co_dev_set_val(co_dev_t *dev, co_unsigned16_t idx, co_unsigned8_t subidx, const void *ptr, size_t n)
Sets the current value of a CANopen sub-object.
unsigned int co_dev_get_baud(const co_dev_t *dev)
Returns the supported bit rates of a CANopen device (any combination of CO_BAUD_1000,...
co_unsigned32_t co_dev_get_product_code(const co_dev_t *dev)
Returns the product code of a CANopen device.
const void * co_dev_get_val(const co_dev_t *dev, co_unsigned16_t idx, co_unsigned8_t subidx)
Returns a pointer to the current value of 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.
void co_dev_set_baud(co_dev_t *dev, unsigned int baud)
Sets the supported bit rates of a CANopen device.
int co_dev_read_dcf_file(co_dev_t *dev, co_unsigned16_t *pmin, co_unsigned16_t *pmax, const char *filename)
Reads the values of a range of objects from a file, in the concise DCF format, and stores them in the...
co_dev_t * co_dev_create(co_unsigned8_t id)
Creates a new CANopen device.
const char * co_dev_get_order_code(const co_dev_t *dev)
Returns a pointer to the order code of a CANopen device.
int co_dev_set_name(co_dev_t *dev, const char *name)
Sets the name of a CANopen device.
co_unsigned32_t co_dev_get_revision(const co_dev_t *dev)
Returns the revision number of a CANopen device.
This header file is part of the CANopen library; it contains the device description declarations.
#define CO_NUM_NODES
The maximum number of nodes in a CANopen network.
#define CO_NUM_NETWORKS
The maximum number of CANopen networks.
This header file is part of the utilities library; it contains the native and platform-independent er...
@ ERRNUM_INVAL
Invalid argument.
int get_errc(void)
Returns the last (thread-specific) native error code set by a system call or library function.
void set_errc(int errc)
Sets the current (thread-specific) native error code to errc.
int errno2c(int errnum)
Transforms a standard C error number to a native error code.
void set_errnum(errnum_t errnum)
Sets the current (thread-specific) platform-independent error number to errnum.
#define __unlikely(x)
Indicates to the compiler that the expression is most-likely false.
#define __likely(x)
Indicates to the compiler that the expression is most-likely true.
This header file is part of the utilities library; it contains the read file buffer declarations.
intmax_t frbuf_get_size(frbuf_t *buf)
Returns the size (in bytes) of the a read file buffer, or -1 on error.
void frbuf_destroy(frbuf_t *buf)
Destroys a read file buffer.
frbuf_t * frbuf_create(const char *filename)
Creates a new read file buffer.
ssize_t frbuf_read(frbuf_t *buf, void *ptr, size_t size)
Reads bytes from the current position in a read file buffer.
This header file is part of the utilities library; it contains the (atomic) write file buffer declara...
ssize_t fwbuf_write(fwbuf_t *buf, const void *ptr, size_t size)
Writes bytes to the current position in a write file buffer.
void fwbuf_destroy(fwbuf_t *buf)
Destroys a write file buffer.
int fwbuf_commit(fwbuf_t *buf)
Commits all changes to a write file buffer to disk if all previous file operations were successful,...
fwbuf_t * fwbuf_create(const char *filename)
Creates a new (atomic) write file buffer.
co_unsigned8_t co_obj_get_subidx(const co_obj_t *obj, co_unsigned8_t maxsubidx, co_unsigned8_t *subidx)
Retrieves a list of sub-indices in a CANopen object.
#define CO_OBJ_FLAGS_MAX_NODEID
The upper limit of the object value is of the form $NODEID { "+" number }.
co_unsigned16_t co_obj_get_idx(const co_obj_t *obj)
Returns the index of a CANopen object.
const void * co_sub_get_val(const co_sub_t *sub)
Returns a pointer to the current value 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.
size_t co_sub_set_val(co_sub_t *sub, const void *ptr, size_t n)
Sets the current value of a CANopen sub-object.
#define CO_OBJ_FLAGS_DEF_NODEID
The default object value is of the form $NODEID { "+" number }.
unsigned int co_sub_get_flags(const co_sub_t *sub)
Returns the object flags of a CANopen sub-object.
#define CO_OBJ_FLAGS_MIN_NODEID
The lower limit of the object value is of the form $NODEID { "+" number }.
#define CO_OBJ_FLAGS_VAL_NODEID
The current object value is of the form $NODEID { "+" number }.
void co_obj_destroy(co_obj_t *obj)
Destroys a CANopen object, including its sub-objects.
co_unsigned16_t co_sub_get_type(const co_sub_t *sub)
Returns the data type of a CANopen sub-object.
#define structof(ptr, type, member)
Obtains the address of a structure from the address of one of its members.
#define MIN(a, b)
Returns the minimum of a and b.
#define MAX(a, b)
Returns the maximum of a and b.
void rbtree_insert(struct rbtree *tree, struct rbnode *node)
Inserts a node into a red-black tree.
struct rbnode * rbtree_find(const struct rbtree *tree, const void *key)
Finds a node in a red-black tree.
struct rbnode * rbtree_first(const struct rbtree *tree)
Returns a pointer to the first (leftmost) node in a red-black tree.
struct rbnode * rbnode_next(const struct rbnode *node)
Returns a pointer to the next (in-order) node in a red-black tree with respect to node.
void rbtree_init(struct rbtree *tree, rbtree_cmp_t *cmp)
Initializes a red-black tree.
size_t rbtree_size(const struct rbtree *tree)
Returns the size (in number of nodes) of a red-black tree.
void rbtree_remove(struct rbtree *tree, struct rbnode *node)
Removes a node from a red-black tree.
#define rbtree_foreach(tree, node)
Iterates over each node in a red-black tree in ascending order.
This is the internal header file of the CANopen library.
This is the internal header file of the object dictionary.
This header file is part of the C11 and POSIX compatibility library; it includes <stdlib....
struct rbtree tree
The tree containing the object dictionary.
co_unsigned32_t product_code
The product code.
char * product_name
A pointer to the product name.
co_unsigned16_t rate
The (pending) baudrate (in kbit/s).
char * vendor_name
A pointer to the vendor name.
char * order_code
A pointer to the order code.
co_unsigned8_t netid
The network-ID.
co_unsigned8_t id
The node-ID.
unsigned baud
The supported bit rates.
int lss
A flag specifying whether LSS is supported (1) or not (0).
co_unsigned32_t vendor_id
The vendor ID.
co_unsigned32_t revision
The revision number.
co_unsigned32_t dummy
The data types supported for mapping dummy entries in PDOs.
char * name
A pointer to the name of the device.
struct rbtree tree
The tree containing all the sub-objects.
struct rbnode node
The node of this object in the tree of objects.
co_dev_t * dev
A pointer to the CANopen device containing this object.
union co_val def
The default value.
union co_val min
The lower limit of the object value.
union co_val max
The upper limit of the object value.
void * val
A pointer to the sub-object value.
An read file buffer struct.
An (atomic) write file buffer struct.
A node in a red-black tree.
const void * key
A pointer to the key for this node.
#define CO_DEFTYPE_UNSIGNED16
The data type (and object index) of a 16-bit unsigned integer.
#define CO_DEFTYPE_DOMAIN
The data type (and object index) of an arbitrary large block of data.
#define CO_DEFTYPE_UNSIGNED8
The data type (and object index) of an 8-bit unsigned integer.
#define CO_DEFTYPE_UNSIGNED32
The data type (and object index) of a 32-bit unsigned integer.
ptrdiff_t ssize_t
Used for a count of bytes or an error indication.
A union of the CANopen static data types.
size_t co_val_write(co_unsigned16_t type, const void *val, uint8_t *begin, uint8_t *end)
Writes a value of the specified data type to a memory buffer.
int co_val_init(co_unsigned16_t type, void *val)
Initializes a value of the specified data type to zero.
const void * co_val_addressof(co_unsigned16_t type, const void *val)
Returns the address of the first byte in a value of the specified data type.
#define CO_UNSIGNED16_MIN
The minimum value of a 16-bit unsigned integer.
int co_val_init_dom(void **val, const void *dom, size_t n)
Initializes an arbitrary large block of data (CO_DEFTYPE_DOMAIN).
size_t co_val_read(co_unsigned16_t type, void *val, const uint8_t *begin, const uint8_t *end)
Reads a value of the specified data type from a memory buffer.
size_t co_val_sizeof(co_unsigned16_t type, const void *val)
Returns the size (in bytes) of a value of the specified data type.
void co_val_fini(co_unsigned16_t type, void *val)
Finalizes a value of the specified data type.
#define CO_UNSIGNED16_MAX
The maximum value of a 16-bit unsigned integer.