27 #ifndef LELY_NO_CO_DCF 69 static void co_obj_set_id(
70 co_obj_t *obj, co_unsigned8_t new_id, co_unsigned8_t old_id);
71 static void co_sub_set_id(
72 co_sub_t *sub, co_unsigned8_t new_id, co_unsigned8_t old_id);
73 static 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;
896 co_obj_set_id(
co_obj_t *obj, co_unsigned8_t new_id, co_unsigned8_t old_id)
905 co_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);
924 co_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 int lss
A flag specifying whether LSS is supported (1) or not (0).
const char * co_dev_get_product_name(const co_dev_t *dev)
Returns a pointer to the product name 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.
#define CO_NUM_NETWORKS
The maximum number of CANopen networks.
const void * key
A pointer to the key for this node.
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...
int co_dev_insert_obj(co_dev_t *dev, co_obj_t *obj)
Inserts an object into the object dictionary of a CANopen device.
#define CO_UNSIGNED16_MAX
The maximum value of a 16-bit unsigned integer.
#define CO_DEFTYPE_DOMAIN
The data type (and object index) of an arbitrary large block of data.
int co_val_init_dom(void **val, const void *dom, size_t n)
Initializes an arbitrary large block of data (CO_DEFTYPE_DOMAIN).
char * order_code
A pointer to the order code.
This header file is part of the utilities library; it contains the comparison function definitions...
co_unsigned32_t revision
The revision number.
size_t rbtree_size(const struct rbtree *tree)
Returns the size (in number of nodes) of a red-black tree.
void set_errnum(errnum_t errnum)
Sets the current (thread-specific) platform-independent error number to errnum.
co_dev_t * dev
A pointer to the CANopen device containing this object.
int co_dev_set_product_name(co_dev_t *dev, const char *product_name)
Sets the product name 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.
A union of the CANopen static data types.
int co_dev_set_id(co_dev_t *dev, co_unsigned8_t id)
Sets the node-ID of a CANopen device.
#define MIN(a, b)
Returns the minimum of a and b.
void co_dev_set_lss(co_dev_t *dev, int lss)
Sets the LSS support flag.
#define CO_UNSIGNED16_MIN
The minimum value of a 16-bit unsigned integer.
union co_val max
The upper limit of the object value.
struct rbtree tree
The tree containing all the sub-objects.
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.
const char * co_dev_get_order_code(const co_dev_t *dev)
Returns a pointer to the order code of a CANopen device.
char * name
A pointer to the name of the device.
struct rbtree tree
The tree containing the object dictionary.
void set_errc(int errc)
Sets the current (thread-specific) native error code to errc.
const char * co_dev_get_vendor_name(const co_dev_t *dev)
Returns a pointer to the vendor name of a CANopen device.
union co_val def
The default value.
#define CO_DEFTYPE_UNSIGNED32
The data type (and object index) of a 32-bit unsigned integer.
co_unsigned8_t netid
The network-ID.
co_unsigned32_t vendor_id
The vendor ID.
void * val
A pointer to the sub-object value.
This header file is part of the utilities library; it contains the native and platform-independent er...
#define __likely(x)
Indicates to the compiler that the expression is most-likely true.
#define rbtree_foreach(tree, node)
Iterates over each node in a red-black tree in ascending order.
void co_dev_set_revision(co_dev_t *dev, co_unsigned32_t revision)
Sets the revision number of a CANopen device.
void fwbuf_destroy(fwbuf_t *buf)
Destroys a write file buffer.
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_BAUD_800, CO_BAUD_500, CO_BAUD_250, CO_BAUD_125, CO_BAUD_50, CO_BAUD_20, CO_BAUD_10 and CO_BAUD_AUTO).
void co_dev_set_baud(co_dev_t *dev, unsigned int baud)
Sets the supported bit rates of a CANopen device.
int fwbuf_commit(fwbuf_t *buf)
Commits all changes to a write file buffer to disk if all previous file operations were successful...
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.
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.
struct rbnode node
The node of this object in the tree of objects.
#define CO_DEFTYPE_UNSIGNED16
The data type (and object index) of a 16-bit unsigned integer.
const void * co_sub_get_val(const co_sub_t *sub)
Returns a pointer to the current value of a CANopen sub-object.
frbuf_t * frbuf_create(const char *filename)
Creates a new read file buffer.
const char * co_dev_get_name(const co_dev_t *dev)
Returns the name of a CANopen device.
This is the internal header file of the CANopen library.
fwbuf_t * fwbuf_create(const char *filename)
Creates a new (atomic) write file buffer.
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, and writes them to a memory buffer, in the concise DCF format.
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...
void co_dev_destroy(co_dev_t *dev)
Destroys a CANopen device, including all objects in its object dictionary.
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.
char * product_name
A pointer to the product name.
int co_dev_get_lss(const co_dev_t *dev)
Returns 1 if LSS is supported and 0 if not.
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 get_errc(void)
Returns the last (thread-specific) native error code set by a system call or library function...
void co_dev_set_product_code(co_dev_t *dev, co_unsigned32_t product_code)
Sets the product code of a CANopen device.
#define MAX(a, b)
Returns the maximum of a and b.
#define CO_DEFTYPE_UNSIGNED8
The data type (and object index) of an 8-bit unsigned integer.
co_dev_t * co_dev_create(co_unsigned8_t id)
Creates a new CANopen device.
An read file buffer struct.
#define CO_NUM_NODES
The maximum number of nodes in a CANopen network.
struct rbnode * rbtree_find(const struct rbtree *tree, const void *key)
Finds a node in a red-black tree.
void frbuf_destroy(frbuf_t *buf)
Destroys a read file buffer.
co_unsigned16_t co_dev_get_rate(const co_dev_t *dev)
Returns the (pending) baudrate of a CANopen device (in kbit/s).
co_unsigned32_t co_dev_get_product_code(const co_dev_t *dev)
Returns the product code of a CANopen device.
co_unsigned32_t dummy
The data types supported for mapping dummy entries in PDOs.
int co_dev_remove_obj(co_dev_t *dev, co_obj_t *obj)
Removes an object from the object dictionary a CANopen device.
void rbtree_remove(struct rbtree *tree, struct rbnode *node)
Removes a node from a red-black tree.
unsigned int co_sub_get_flags(const co_sub_t *sub)
Returns the object flags of a CANopen sub-object.
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.
int errno2c(int errnum)
Transforms a standard C error number to a native error code.
#define __unlikely(x)
Indicates to the compiler that the expression is most-likely false.
#define CO_OBJ_FLAGS_VAL_NODEID
The current object value is of the form $NODEID { "+" number }.
ssize_t frbuf_read(frbuf_t *buf, void *ptr, size_t size)
Reads bytes from the current position in a read file buffer.
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.
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.
intmax_t frbuf_get_size(frbuf_t *buf)
Returns the size (in bytes) of the a read file buffer, or -1 on error.
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, and writes them to a file, in the concise DCF format.
An (atomic) write file buffer struct.
int co_dev_set_name(co_dev_t *dev, const char *name)
Sets the name 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, and stores them in the object dictionary of a CANopen device.
void co_obj_destroy(co_obj_t *obj)
Destroys a CANopen object, including its sub-objects.
This header file is part of the CANopen library; it contains the device description declarations...
#define structof(ptr, type, member)
Obtains the address of a structure from the address of one of its members.
co_unsigned8_t id
The node-ID.
co_unsigned32_t product_code
The product code.
int co_val_init(co_unsigned16_t type, void *val)
Initializes a value of the specified data type to zero.
void co_dev_set_vendor_id(co_dev_t *dev, co_unsigned32_t vendor_id)
Sets the vendor ID of a CANopen device.
void co_val_fini(co_unsigned16_t type, void *val)
Finalizes a value of the specified data type.
char * vendor_name
A pointer to the vendor name.
This header file is part of the utilities library; it contains the read file buffer declarations...
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_revision(const co_dev_t *dev)
Returns the revision number of a CANopen device.
void rbtree_init(struct rbtree *tree, rbtree_cmp_t *cmp)
Initializes a red-black tree.
#define CO_OBJ_FLAGS_DEF_NODEID
The default object value is of the form $NODEID { "+" number }.
void co_dev_set_rate(co_dev_t *dev, co_unsigned16_t rate)
Sets the (pending) baudrate of a CANopen device.
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...
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 rbtree_insert(struct rbtree *tree, struct rbnode *node)
Inserts a node into a red-black tree.
This header file is part of the utilities library; it contains the (atomic) write file buffer declara...
co_unsigned8_t co_dev_get_id(const co_dev_t *dev)
Returns the node-ID of a CANopen device.
This header file is part of the C11 and POSIX compatibility library; it includes <stdlib.h> and defines any missing functionality.
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.
int co_dev_set_vendor_name(co_dev_t *dev, const char *vendor_name)
Sets the vendor name of a CANopen device.
#define CO_OBJ_FLAGS_MAX_NODEID
The upper limit of the object value is of the form $NODEID { "+" number }.
co_unsigned32_t co_dev_get_vendor_id(const co_dev_t *dev)
Returns the vendor ID 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.
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.
#define CO_OBJ_FLAGS_MIN_NODEID
The lower limit of the object value is of the form $NODEID { "+" number }.
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.
int co_dev_set_order_code(co_dev_t *dev, const char *order_code)
Sets the order code of a CANopen device.
co_unsigned16_t rate
The (pending) baudrate (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...
struct rbnode * rbtree_first(const struct rbtree *tree)
Returns a pointer to the first (leftmost) node in a red-black tree.
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.
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.
A node in a red-black tree.