27 #ifndef LELY_NO_CO_DCF 33 #ifndef LELY_NO_CO_TPDO 70 #ifndef LELY_NO_CO_TPDO 78 static void co_obj_set_id(
79 co_obj_t *obj, co_unsigned8_t new_id, co_unsigned8_t old_id);
80 static void co_sub_set_id(
81 co_sub_t *sub, co_unsigned8_t new_id, co_unsigned8_t old_id);
82 static void co_val_set_id(co_unsigned16_t type,
void *val,
83 co_unsigned8_t new_id, co_unsigned8_t old_id);
88 void *ptr = malloc(
sizeof(
struct __co_dev));
95 __co_dev_free(
void *ptr)
101 __co_dev_init(
struct __co_dev *dev, co_unsigned8_t
id)
157 goto error_alloc_dev;
160 if (!__co_dev_init(dev,
id)) {
234 co_unsigned16_t *idx)
243 for (
size_t i = 0; node && i < maxidx;
257 if (obj->
dev && obj->
dev != dev)
336 if (!name || !*name) {
342 void *ptr = realloc(dev->
name, strlen(name) + 1);
348 strcpy(dev->
name, name);
366 if (!vendor_name || !*vendor_name) {
372 void *ptr = realloc(dev->
vendor_name, strlen(vendor_name) + 1);
412 if (!product_name || !*product_name) {
418 void *ptr = realloc(dev->
product_name, strlen(product_name) + 1);
474 if (!order_code || !*order_code) {
480 void *ptr = realloc(dev->
order_code, strlen(order_code) + 1);
564 const void *ptr,
size_t n)
577 #define LELY_CO_DEFINE_TYPE(a, b, c, d) \ 578 co_##b##_t co_dev_get_val_##c(const co_dev_t *dev, \ 579 co_unsigned16_t idx, co_unsigned8_t subidx) \ 582 co_sub_t *sub = dev \ 583 ? co_dev_find_sub(dev, idx, subidx) \ 586 return co_sub_get_val_##c(sub); \ 589 size_t co_dev_set_val_##c(co_dev_t *dev, co_unsigned16_t idx, \ 590 co_unsigned8_t subidx, co_##b##_t c) \ 594 co_sub_t *sub = co_dev_find_sub(dev, idx, subidx); \ 596 set_errnum(ERRNUM_INVAL); \ 600 return co_sub_set_val_##c(sub, c); \ 602 #include <lely/co/def/basic.def> 603 #undef LELY_CO_DEFINE_TYPE 607 const uint_least8_t *begin,
const uint_least8_t *end)
609 if (!begin || !end || end - begin < 2 + 1 + 4)
618 co_unsigned8_t subidx;
623 co_unsigned32_t size;
628 if (end - begin < (ptrdiff_t)size)
637 if (
co_val_read(type, &val, begin, begin + size) == size)
648 return 2 + 1 + 4 + size;
653 co_unsigned8_t subidx, uint_least8_t *begin, uint_least8_t *end)
661 co_unsigned32_t size =
co_val_write(type, val, NULL, NULL);
665 if (begin && (!end || end - begin >= (ptrdiff_t)(2 + 1 + 4 + size))) {
684 return 2 + 1 + 4 + size;
698 const uint_least8_t *begin = *ptr;
699 const uint_least8_t *end = begin + size;
708 for (
size_t i = 0; i < n; i++) {
729 #ifndef LELY_NO_CO_DCF 732 co_unsigned16_t *pmax,
const char *filename)
739 goto error_create_buf;
790 co_unsigned32_t n = 0;
813 uint_least8_t *begin = *ptr;
814 uint_least8_t *end = begin + size;
837 #ifndef LELY_NO_CO_DCF 840 co_unsigned16_t max,
const char *filename)
847 goto error_write_dcf;
853 goto error_create_buf;
857 if (
fwbuf_write(buf, dom, nbyte) != (ssize_t)nbyte) {
884 #ifndef LELY_NO_CO_TPDO 920 for (co_unsigned16_t i = 0; i < 512 && !obj_1800; i++)
922 for (; obj_1800; obj_1800 =
co_obj_next(obj_1800)) {
940 for (
size_t j = 0; j < map->
n; j++) {
941 if (((map->
map[j] >> 16) & 0xffff) != idx)
943 if (((map->
map[j] >> 8) & 0xff) != subidx)
954 #endif // !LELY_NO_CO_TPDO 957 co_obj_set_id(
co_obj_t *obj, co_unsigned8_t new_id, co_unsigned8_t old_id)
966 co_sub_set_id(
co_sub_t *sub, co_unsigned8_t new_id, co_unsigned8_t old_id)
972 #ifndef LELY_NO_CO_OBJ_LIMITS 974 co_val_set_id(type, &sub->
min, new_id, old_id);
976 co_val_set_id(type, &sub->
max, new_id, old_id);
978 #ifndef LELY_NO_CO_OBJ_DEFAULT 980 co_val_set_id(type, &sub->
def, new_id, old_id);
983 co_val_set_id(type, sub->
val, new_id, old_id);
987 co_val_set_id(co_unsigned16_t type,
void *val, co_unsigned8_t new_id,
988 co_unsigned8_t old_id)
994 #define LELY_CO_DEFINE_TYPE(a, b, c, d) \ 995 case CO_DEFTYPE_##a: \ 996 u->c += new_id - old_id; \ 998 #include <lely/co/def/basic.def> 999 #undef LELY_CO_DEFINE_TYPE int lss
A flag specifying whether LSS is supported (1) or not (0).
int co_dev_set_id(co_dev_t *dev, co_unsigned8_t id)
Sets the node-ID 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.
A PDO mapping parameter record.
void co_dev_set_rate(co_dev_t *dev, co_unsigned16_t rate)
Sets the (pending) baudrate of a CANopen device.
#define CO_NUM_NODES
The maximum number of nodes in a CANopen network.
const void * key
A pointer to the key for this node.
size_t co_dev_write_sub(const co_dev_t *dev, co_unsigned16_t idx, co_unsigned8_t subidx, uint_least8_t *begin, uint_least8_t *end)
Loads the value of a sub-object from the object dictionary of a CANopen device, and writes it to a me...
void * tpdo_event_data
A pointer to user-specified data for tpdo_event_ind.
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_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.
#define CO_UNSIGNED16_MAX
The maximum value of a 16-bit unsigned integer.
co_obj_t * co_obj_next(const co_obj_t *obj)
Finds the next object in the object dictionary of a CANopen device.
co_obj_t * co_dev_last_obj(const co_dev_t *dev)
Finds the last object (with the highest index) in the object dictionary of a CANopen device...
#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.
co_sub_t * co_obj_first_sub(const co_obj_t *obj)
Finds the first sub-object (with the lowest sub-index) in a CANopen object.
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.
void diag(enum diag_severity severity, int errc, const char *format,...)
Emits a diagnostic message.
co_unsigned8_t n
Number of mapped objects in PDO.
A union of the CANopen static data types.
A PDO communication parameter record.
void co_dev_tpdo_event(co_dev_t *dev, co_unsigned16_t idx, co_unsigned8_t subidx)
Checks if the specified sub-object in the object dictionary of a CANopen device can be mapped into a ...
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.
#define CO_NUM_NETWORKS
The maximum number of CANopen networks.
#define MIN(a, b)
Returns the minimum of a and b.
#define CO_UNSIGNED16_MIN
The minimum value of a 16-bit unsigned integer.
co_unsigned32_t cobid
COB-ID.
co_unsigned8_t co_dev_get_id(const co_dev_t *dev)
Returns the node-ID of a CANopen device.
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.
int co_sub_get_pdo_mapping(const co_sub_t *sub)
Returns 1 if it is possible to map the specified CANopen sub-object into a PDO, and 0 if not...
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.
union co_val def
The default value.
int co_dev_set_vendor_name(co_dev_t *dev, const char *vendor_name)
Sets the vendor name 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.
#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.
struct rbnode * rbtree_last(const struct rbtree *tree)
Returns a pointer to the last (rightmost) node in a red-black tree.
void * val
A pointer to the sub-object value.
co_obj_t * co_dev_first_obj(const co_dev_t *dev)
Finds the first object (with the lowest index) in the object dictionary of a CANopen device...
#define rbtree_foreach(tree, node)
Iterates over each node in a red-black tree in ascending order.
co_unsigned32_t co_dev_get_revision(const co_dev_t *dev)
Returns the revision number of a CANopen device.
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...
int co_dev_get_lss(const co_dev_t *dev)
Returns 1 if LSS is supported and 0 if not.
struct rbnode node
The node of this object in the tree of objects.
size_t co_val_read(co_unsigned16_t type, void *val, const uint_least8_t *begin, const uint_least8_t *end)
Reads a value of the specified data type from a memory buffer.
#define CO_DEFTYPE_UNSIGNED16
The data type (and object index) of a 16-bit unsigned integer.
size_t co_val_write(co_unsigned16_t type, const void *val, uint_least8_t *begin, uint_least8_t *end)
Writes a value of the specified data type to a memory buffer.
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.
This is the internal header file of the CANopen library.
fwbuf_t * fwbuf_create(const char *filename)
Creates a new (atomic) write file buffer.
#define CO_PDO_COBID_VALID
The bit in the PDO COB-ID specifying whether the PDO exists and is valid.
co_unsigned8_t n
Highest sub-index supported.
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.
void co_dev_set_baud(co_dev_t *dev, unsigned int baud)
Sets the supported bit rates of a CANopen device.
int get_errc(void)
Returns the last (thread-specific) native error code set by a system call or library function...
const char * co_dev_get_vendor_name(const co_dev_t *dev)
Returns a pointer to the vendor name of a CANopen device.
#define MAX(a, b)
Returns the maximum of a and b.
const char * co_dev_get_name(const co_dev_t *dev)
Returns the name of a CANopen device.
#define CO_DEFTYPE_UNSIGNED8
The data type (and object index) of an 8-bit unsigned integer.
An read file buffer struct.
struct rbnode * rbtree_find(const struct rbtree *tree, const void *key)
Finds a node in a red-black tree.
co_sub_t * co_sub_next(const co_sub_t *sub)
Finds the next sub-object in a CANopen object.
void frbuf_destroy(frbuf_t *buf)
Destroys a read file buffer.
co_unsigned32_t dummy
The data types supported for mapping dummy entries in PDOs.
void rbtree_remove(struct rbtree *tree, struct rbnode *node)
Removes a node from a red-black tree.
int co_dev_set_netid(co_dev_t *dev, co_unsigned8_t id)
Sets the network-ID 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.
const char * co_dev_get_order_code(const co_dev_t *dev)
Returns a pointer to the order code of a CANopen device.
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).
unsigned int co_sub_get_flags(const co_sub_t *sub)
Returns the object flags of a CANopen sub-object.
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_set_lss(co_dev_t *dev, int lss)
Sets the LSS support flag.
co_unsigned8_t co_dev_get_netid(const co_dev_t *dev)
Returns the network-ID of a CANopen device.
int errno2c(int errnum)
Transforms a standard C error number to a native error code.
void co_dev_destroy(co_dev_t *dev)
Destroys a CANopen device, including all objects in its object dictionary.
This header file is part of the utilities library; it contains the diagnostic declarations.
#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.
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.
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_insert_obj(co_dev_t *dev, co_obj_t *obj)
Inserts an object into the object dictionary of a CANopen device.
An (atomic) write file buffer struct.
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.
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_dev_read_sub(co_dev_t *dev, co_unsigned16_t *pidx, co_unsigned8_t *psubidx, const uint_least8_t *begin, const uint_least8_t *end)
Reads a value from a memory buffer, in the concise DCF format, and stores it in a sub-object in the o...
void co_dev_set_tpdo_event_ind(co_dev_t *dev, co_dev_tpdo_event_ind_t *ind, void *data)
Sets the indication function invoked by co_dev_tpdo_event() when an event is indicated for (a sub-obj...
void co_obj_destroy(co_obj_t *obj)
Destroys a CANopen object, including its sub-objects.
#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.
int co_dev_set_name(co_dev_t *dev, const char *name)
Sets the name of a CANopen device.
void co_val_fini(co_unsigned16_t type, void *val)
Finalizes a value of the specified data type.
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.
co_unsigned16_t co_dev_get_rate(const co_dev_t *dev)
Returns the (pending) baudrate of a CANopen device (in kbit/s).
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...
This header file is part of the CANopen library; it contains the device description declarations...
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 }.
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.
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.
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 co_dev_get_tpdo_event_ind(const co_dev_t *dev, co_dev_tpdo_event_ind_t **pind, void **pdata)
Retrieves the indication function invoked by co_dev_tpdo_event() when an event is indicated for (a su...
void rbtree_insert(struct rbtree *tree, struct rbnode *node)
Inserts a node into a red-black tree.
co_unsigned32_t map[0x40]
An array of objects to be mapped.
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 utilities library; it contains the (atomic) write file buffer declara...
co_unsigned8_t co_sub_get_subidx(const co_sub_t *sub)
Returns the sub-index of a CANopen sub-object.
This header file is part of the C11 and POSIX compatibility library; it includes <stdlib.h> and defines any missing functionality.
co_unsigned32_t co_dev_get_vendor_id(const co_dev_t *dev)
Returns the vendor ID 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_tpdo_event_ind_t * tpdo_event_ind
A pointer to the Transmit-PDO event indication function.
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.
void co_dev_tpdo_event_ind_t(co_unsigned16_t num, void *data)
The type of a CANopen Transmit-PDO event indication function, invoked by co_dev_tpdo_event() when an ...
co_unsigned16_t co_obj_get_idx(const co_obj_t *obj)
Returns the index of a CANopen object.
#define CO_OBJ_FLAGS_MAX_NODEID
The upper limit of the object value is of the form $NODEID { "+" number }.
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_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.
#define CO_OBJ_FLAGS_MIN_NODEID
The lower limit of the object value is of the form $NODEID { "+" number }.
co_unsigned8_t trans
Transmission type.
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.
co_unsigned16_t rate
The (pending) baudrate (in kbit/s).
void * co_obj_addressof_val(const co_obj_t *obj)
Returns the address of the value of a CANopen object.
struct rbnode * rbtree_first(const struct rbtree *tree)
Returns a pointer to the first (leftmost) node in a red-black tree.
co_dev_t * co_dev_create(co_unsigned8_t id)
Creates a new CANopen device.
co_unsigned32_t co_dev_get_product_code(const co_dev_t *dev)
Returns the product code of a CANopen device.
A node in a red-black tree.
This header file is part of the CANopen library; it contains the Process Data Object (PDO) declaratio...