55 void *ptr = malloc(
sizeof(
struct __co_obj));
62 __co_obj_free(
void *ptr)
68 __co_obj_init(
struct __co_obj *obj, co_unsigned16_t
idx)
78 #ifndef LELY_NO_CO_OBJ_NAME
100 #ifndef LELY_NO_CO_OBJ_NAME
108 trace(
"creating object %04X",
idx);
114 return __co_obj_init(obj,
idx);
121 trace(
"destroying object %04X", obj->
idx);
163 co_unsigned8_t *subidx)
172 for (
size_t i = 0; node && i < maxidx;
187 if (sub->
obj && sub->
obj != obj)
251 #ifndef LELY_NO_CO_OBJ_NAME
266 if (!name || !*name) {
272 void *ptr = realloc(obj->
name, strlen(name) + 1);
278 strcpy(obj->
name, name);
313 return obj ? obj->
val : NULL;
319 return obj ? obj->
size : 0;
343 #define LELY_CO_DEFINE_TYPE(a, b, c, d) \
344 co_##b##_t co_obj_get_val_##c( \
345 const co_obj_t *obj, co_unsigned8_t subidx) \
348 co_sub_t *sub = obj \
349 ? co_obj_find_sub(obj, subidx) \
352 return co_sub_get_val_##c(sub); \
355 size_t co_obj_set_val_##c( \
356 co_obj_t *obj, co_unsigned8_t subidx, co_##b##_t c) \
360 co_sub_t *sub = co_obj_find_sub(obj, subidx); \
362 set_errnum(ERRNUM_INVAL); \
366 return co_sub_set_val_##c(sub, c); \
368 #include <lely/co/def/basic.def>
369 #undef LELY_CO_DEFINE_TYPE
380 #ifndef LELY_NO_CO_OBJ_UPLOAD
394 void *ptr = malloc(
sizeof(
struct __co_sub));
401 __co_sub_free(
void *ptr)
415 #ifndef LELY_NO_CO_OBJ_NAME
420 #ifndef LELY_NO_CO_OBJ_LIMITS
426 #ifndef LELY_NO_CO_OBJ_DEFAULT
438 #ifndef LELY_NO_CO_OBJ_UPLOAD
454 #ifndef LELY_NO_CO_OBJ_DEFAULT
457 #ifndef LELY_NO_CO_OBJ_LIMITS
462 #ifndef LELY_NO_CO_OBJ_NAME
475 goto error_alloc_sub;
535 #ifndef LELY_NO_CO_OBJ_NAME
550 if (!name || !*name) {
556 void *ptr = realloc(sub->
name, strlen(name) + 1);
562 strcpy(sub->
name, name);
577 #ifndef LELY_NO_CO_OBJ_LIMITS
594 return sub ? &sub->
min : NULL;
621 return sub ? &sub->
max : NULL;
635 #ifndef LELY_NO_CO_OBJ_DEFAULT
652 return sub ? &sub->
def : NULL;
681 return sub ? sub->
val : NULL;
693 #define LELY_CO_DEFINE_TYPE(a, b, c, d) \
694 co_##b##_t co_sub_get_val_##c(const co_sub_t *sub) \
696 static const co_##b##_t val; \
698 if (!sub || sub->type != CO_DEFTYPE_##a || !sub->val) \
700 return ((union co_val *)sub->val)->c; \
703 size_t co_sub_set_val_##c(co_sub_t *sub, co_##b##_t c) \
707 if (sub->type != CO_DEFTYPE_##a) { \
708 set_errnum(ERRNUM_INVAL); \
712 return co_sub_set_val(sub, &c, sizeof(c)); \
714 #include <lely/co/def/basic.def>
715 #undef LELY_CO_DEFINE_TYPE
717 #ifndef LELY_NO_CO_OBJ_LIMITS
727 if (sub->
type != type)
800 #ifndef LELY_NO_CO_OBJ_FILE
826 return co_sub_set_val(sub, filename, strlen(filename) + 1) ? 0 : -1;
853 return co_sub_set_val(sub, filename, strlen(filename) + 1) ? 0 : -1;
875 sub->
dn_data = ind ? data : NULL;
884 #ifndef LELY_NO_CO_OBJ_FILE
898 #ifndef LELY_NO_CO_OBJ_LIMITS
938 co_unsigned32_t ac = 0;
967 #ifndef LELY_NO_CO_OBJ_UPLOAD
986 sub->
up_data = ind ? data : NULL;
997 #ifndef LELY_NO_CO_OBJ_FILE
1002 if (!filename || !*filename)
1030 #ifdef LELY_NO_CO_OBJ_UPLOAD
1054 val = calloc(1,
size);
1069 void *src = sub->
val;
1070 sub->
val = (
char *)val +
size;
1093 static co_unsigned32_t
1098 co_unsigned32_t ac = 0;
1103 static co_unsigned32_t
1108 co_unsigned32_t ac = 0;
This header file is part of the utilities library; it contains the comparison function definitions.
This header file is part of the CANopen library; it contains the device description declarations.
int co_dev_remove_obj(co_dev_t *dev, co_obj_t *obj)
Removes an object from the object dictionary a CANopen device.
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 CO_ACCESS_READ
The object can be read.
#define CO_OBJ_FLAGS_WRITE
Refuse write on download.
#define CO_ACCESS_WO
Write-only access.
#define CO_ACCESS_RO
Read-only access.
#define CO_OBJECT_DEFSTRUCT
A record type definition.
#define CO_OBJECT_ARRAY
A multiple data field object where each data field is a simple variable of the same basic data type.
#define CO_OBJECT_RECORD
A multiple data field object where the data fields may be any combination of simple variables.
#define CO_OBJECT_DEFTYPE
A type definitions.
#define CO_OBJECT_DOMAIN
A large variable amount of data.
#define CO_ACCESS_RW
Read or write access.
co_unsigned32_t co_sub_up_ind_t(const co_sub_t *sub, struct co_sdo_req *req, void *data)
The type of a CANopen sub-object upload indication function, invoked by an SDO upload request or Tran...
co_unsigned32_t co_sub_dn_ind_t(co_sub_t *sub, struct co_sdo_req *req, void *data)
The type of a CANopen sub-object download indication function, invoked by an SDO download request or ...
#define CO_OBJECT_VAR
A single value.
#define CO_ACCESS_RWR
Read or write on process input.
#define CO_OBJ_FLAGS_DOWNLOAD_FILE
If a write access is performed for the object, the data is stored in a file.
#define CO_OBJECT_NULL
An object with no data fields.
#define CO_OBJ_FLAGS_UPLOAD_FILE
If a read access is performed for the object, the data is stored in a file.
#define CO_ACCESS_WRITE
The object can be written.
#define CO_ACCESS_RWW
Read or write on process output.
#define CO_ACCESS_CONST
Constant value.
This header file is part of the CANopen library; it contains the Service Data Object (SDO) declaratio...
#define CO_SDO_AC_PARAM_LO
SDO abort code: Value of parameter written too low (download only).
#define CO_SDO_AC_NO_READ
SDO abort code: Attempt to read a write only object.
int co_sdo_req_dn_val(struct co_sdo_req *req, co_unsigned16_t type, void *val, co_unsigned32_t *pac)
Copies the next segment of the specified CANopen SDO download request to the internal buffer and,...
#define CO_SDO_REQ_INIT
The static initializer for struct co_sdo_req.
int co_sdo_req_up_val(struct co_sdo_req *req, co_unsigned16_t type, const void *val, co_unsigned32_t *pac)
Writes the specified value to a buffer and constructs a CANopen SDO upload request.
void co_sdo_req_fini(struct co_sdo_req *req)
Finalizes a CANopen SDO upload/download request.
#define CO_SDO_AC_TYPE_LEN
SDO abort code: Data type does not match, length of service parameter does not match.
#define CO_SDO_AC_ERROR
SDO abort code: General error.
int co_sdo_req_dn_file(struct co_sdo_req *req, const char *filename, co_unsigned32_t *pac)
Copies the next segment of the specified CANopen SDO download request to the internal buffer and,...
int co_sdo_req_up_file(struct co_sdo_req *req, const char *filename, co_unsigned32_t *pac)
Loads the specified file into a buffer and constructs a CANopen SDO upload request.
#define CO_SDO_AC_PARAM_HI
SDO abort code: Value of parameter written too high (download only).
#define CO_SDO_AC_NO_DATA
SDO abort code: No data available.
#define CO_SDO_AC_NO_SUB
SDO abort code: Sub-index does not exist.
#define CO_SDO_AC_NO_WRITE
SDO abort code: Attempt to write a read only object.
#define CO_SDO_AC_PARAM_RANGE
SDO abort code: Maximum value is less than minimum value (download only).
#define structof(ptr, type, member)
Obtains the address of a structure from the address of one of its members.
#define ALIGN(x, a)
Rounds x up to the nearest multiple of a.
int co_sub_set_access(co_sub_t *sub, unsigned int access)
Sets the access type of a CANopen sub-object.
int co_sub_set_name(co_sub_t *sub, const char *name)
Sets the name of a CANopen sub-object.
co_obj_t * co_obj_prev(const co_obj_t *obj)
Finds the previous object in the object dictionary of a CANopen device.
co_unsigned8_t co_sub_get_subidx(const co_sub_t *sub)
Returns the sub-index of a CANopen sub-object.
void co_sub_destroy(co_sub_t *sub)
Destroys a CANopen sub-object.
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 co_sub_set_def(co_sub_t *sub, const void *ptr, size_t n)
Sets the default value of a CANopen sub-object.
const void * co_sub_get_val(const co_sub_t *sub)
Returns a pointer to the current value of a CANopen sub-object.
int co_sub_set_download_file(co_sub_t *sub, const char *filename)
Sets the value of the DownloadFile attribute of a CANopen sub-object.
co_unsigned32_t co_sub_dn_ind(co_sub_t *sub, struct co_sdo_req *req)
Invokes the download indication function of a CANopen sub-object, registered with co_sub_set_dn_ind()...
co_sub_t * co_sub_next(const co_sub_t *sub)
Finds the next sub-object in a CANopen object.
void co_sub_set_up_ind(co_sub_t *sub, co_sub_up_ind_t *ind, void *data)
Sets the upload indication function for a CANopen sub-object.
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_sub_t * co_sub_create(co_unsigned8_t subidx, co_unsigned16_t type)
Creates a CANopen sub-object.
co_unsigned16_t co_obj_get_idx(const co_obj_t *obj)
Returns the index of a CANopen object.
static co_unsigned32_t default_sub_dn_ind(co_sub_t *sub, struct co_sdo_req *req, void *data)
The default download indication function.
static co_unsigned32_t default_sub_up_ind(const co_sub_t *sub, struct co_sdo_req *req, void *data)
The default upload indication function.
const void * co_sub_get_max(const co_sub_t *sub)
Returns a pointer to the upper limit of the value of a CANopen sub-object.
const void * co_sub_addressof_def(const co_sub_t *sub)
Returns the address of the default value of a CANopen sub-object.
void co_sub_set_dn_ind(co_sub_t *sub, co_sub_dn_ind_t *ind, void *data)
Sets the download indication function for a CANopen sub-object.
const char * co_sub_get_name(const co_sub_t *sub)
Returns the name of 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.
const char * co_obj_get_name(const co_obj_t *obj)
Returns the name of a CANopen object.
int co_obj_set_code(co_obj_t *obj, co_unsigned8_t code)
Sets the code (type) of a CANopen object.
int co_sub_set_upload_file(co_sub_t *sub, const char *filename)
Sets the value of the UploadFile attribute of a CANopen sub-object.
co_unsigned32_t co_sub_up_ind(const co_sub_t *sub, struct co_sdo_req *req)
Invokes the upload indication function of a CANopen sub-object, registered with co_sub_set_up_ind().
static void co_obj_clear(co_obj_t *obj)
Destroys all sub-objects.
const void * co_sub_get_def(const co_sub_t *sub)
Returns a pointer to the default value of a CANopen sub-object.
void co_sub_set_flags(co_sub_t *sub, unsigned int flags)
Sets the object flags of a CANopen sub-object.
co_unsigned32_t co_sub_dn_ind_val(co_sub_t *sub, co_unsigned16_t type, const void *val)
Invokes the download indication function of a CANopen sub-object, registered with co_sub_set_dn_ind()...
void co_sub_get_dn_ind(const co_sub_t *sub, co_sub_dn_ind_t **pind, void **pdata)
Retrieves the download indication function for a CANopen sub-object.
co_sub_t * co_obj_last_sub(const co_obj_t *obj)
Finds the last sub-object (with the highest sub-index) in a CANopen object.
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.
const void * co_sub_addressof_val(const co_sub_t *sub)
Returns the address of the current value of a CANopen sub-object.
size_t co_sub_sizeof_max(const co_sub_t *sub)
Returns size (in bytes) of the upper limit of the value of a CANopen sub-object.
void * co_obj_addressof_val(const co_obj_t *obj)
Returns the address of the value of a CANopen object.
size_t co_sub_sizeof_def(const co_sub_t *sub)
Returns size (in bytes) of the default value of a CANopen sub-object.
void co_sub_get_up_ind(const co_sub_t *sub, co_sub_up_ind_t **pind, void **pdata)
Retrieves the upload indication function for a CANopen sub-object.
co_sub_t * co_sub_prev(const co_sub_t *sub)
Finds the previous 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.
int co_sub_dn(co_sub_t *sub, void *val)
Downloads (moves) a value into a CANopen sub-object if the refuse-write-on-download flag (CO_OBJ_FLAG...
co_unsigned8_t co_obj_get_code(const co_obj_t *obj)
Returns the object code of a CANopen object.
size_t co_sub_set_max(co_sub_t *sub, const void *ptr, size_t n)
Sets the upper limit of a value of a CANopen sub-object.
unsigned int co_sub_get_flags(const co_sub_t *sub)
Returns the object flags of a CANopen sub-object.
co_obj_t * co_obj_next(const co_obj_t *obj)
Finds the next object in the object dictionary of a CANopen device.
co_sub_t * co_obj_find_sub(const co_obj_t *obj, co_unsigned8_t subidx)
Finds a sub-object in a CANopen object.
int co_obj_set_name(co_obj_t *obj, const char *name)
Sets the name of a CANopen object.
size_t co_sub_set_min(co_sub_t *sub, const void *ptr, size_t n)
Sets the lower limit of a value of a CANopen sub-object.
size_t co_sub_sizeof_val(const co_sub_t *sub)
Returns size (in bytes) of the current value of a CANopen sub-object.
static void co_obj_update(co_obj_t *obj)
Updates an object by allocating a new memory region containing the members and moving the old values.
int co_obj_remove_sub(co_obj_t *obj, co_sub_t *sub)
Removes a sub-object from a CANopen object.
int co_sub_on_dn(co_sub_t *sub, struct co_sdo_req *req, co_unsigned32_t *pac)
Implements the default behavior when a download indication is received by a CANopen sub-object.
const void * co_obj_get_val(const co_obj_t *obj, co_unsigned8_t subidx)
Returns a pointer to the current value of a CANopen sub-object.
void co_sub_set_pdo_mapping(co_sub_t *sub, int pdo_mapping)
Enables or disables PDO mapping a CANopen sub-object.
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 co_obj_destroy(co_obj_t *obj)
Destroys a CANopen object, including its sub-objects.
void co_obj_set_dn_ind(co_obj_t *obj, co_sub_dn_ind_t *ind, void *data)
Sets the download indication function for a CANopen object.
int co_obj_insert_sub(co_obj_t *obj, co_sub_t *sub)
Inserts a sub-object into a CANopen object.
const char * co_sub_get_download_file(const co_sub_t *sub)
Returns a pointer to the value of the DownloadFile attribute of a CANopen sub-object,...
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.
co_obj_t * co_obj_create(co_unsigned16_t idx)
Creates a CANopen object.
const char * co_sub_get_upload_file(const co_sub_t *sub)
Returns a pointer to the value of the UploadFile attribute of a CANopen sub-object,...
void co_obj_set_up_ind(co_obj_t *obj, co_sub_up_ind_t *ind, void *data)
Sets the upload indication function for a CANopen object.
const void * co_sub_get_min(const co_sub_t *sub)
Returns a pointer to the lower limit of the value of a CANopen sub-object.
size_t co_obj_sizeof_val(const co_obj_t *obj)
Returns size (in bytes) of the value of a CANopen object.
int co_sub_on_up(const co_sub_t *sub, struct co_sdo_req *req, co_unsigned32_t *pac)
Implements the default behavior when an upload indication is received by a CANopen sub-object.
unsigned int co_sub_get_access(const co_sub_t *sub)
Returns the access type of a CANopen sub-object.
size_t co_obj_set_val(co_obj_t *obj, co_unsigned8_t subidx, const void *ptr, size_t n)
Sets the current value of a CANopen sub-object.
co_unsigned8_t co_obj_get_subidx(const co_obj_t *obj, co_unsigned8_t maxidx, co_unsigned8_t *subidx)
Retrieves a list of sub-indices in a CANopen object.
co_unsigned32_t co_sub_chk_val(const co_sub_t *sub, co_unsigned16_t type, const void *val)
Checks if the specifed value would be a valid value for a CANopen sub-object.
size_t co_sub_sizeof_min(const co_sub_t *sub)
Returns size (in bytes) of the lower limit of the value of a CANopen sub-object.
co_unsigned16_t co_sub_get_type(const co_sub_t *sub)
Returns the data type of a CANopen sub-object.
struct rbnode * rbnode_prev(const struct rbnode *node)
Returns a pointer to the previous (in-order) node in a red-black tree with respect to node.
void rbtree_insert(struct rbtree *tree, struct rbnode *node)
Inserts a node into a red-black tree.
struct rbnode * rbtree_last(const struct rbtree *tree)
Returns a pointer to the last (rightmost) node in a red-black tree.
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.
struct rbnode * rbtree_first(const struct rbtree *tree)
Returns a pointer to the first (leftmost) node in a red-black tree.
#define rbtree_foreach(tree, node)
Iterates over each node in a red-black tree in ascending order.
struct rbnode * rbtree_find(const struct rbtree *tree, const void *key)
Finds a 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.
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....
This header file is part of the C11 and POSIX compatibility library; it includes <string....
co_unsigned16_t idx
The object index.
co_unsigned8_t code
The object code.
size_t size
The size (in bytes) of the value at val.
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.
char * name
A pointer to the name of the object.
void * val
A pointer to the object value.
unsigned long flags
The object flags.
co_sub_dn_ind_t * dn_ind
A pointer to the download indication function.
co_unsigned8_t subidx
The object sub-index.
struct rbnode node
The node of this sub-object in the tree of sub-objects.
co_obj_t * obj
A pointer to the CANopen object containing this sub-object.
union co_val def
The default value.
unsigned long access
The access type.
union co_val min
The lower limit of the object value.
co_sub_up_ind_t * up_ind
A pointer to the upload indication function.
union co_val max
The upper limit of the object value.
char * name
A pointer to the name of the sub-object.
co_unsigned16_t type
The data type.
void * val
A pointer to the sub-object value.
void * dn_data
A pointer to user-specified data for dn_ind.
void * up_data
A pointer to user-specified data for up_ind.
unsigned long pdo_mapping
A flag indicating if it is possible to map this object into a PDO.
A CANopen SDO upload/download request.
size_t size
The total size (in bytes) of the value to be uploaded/downloaded.
A node in a red-black tree.
const void * key
A pointer to the key for this node.
#define CO_DEFTYPE_DOMAIN
The data type (and object index) of an arbitrary large block of data.
size_t co_type_alignof(co_unsigned16_t type)
Returns the alignment requirements (in bytes) of a value of the specified data type,...
size_t co_type_sizeof(co_unsigned16_t type)
Returns the native size (in bytes) of a value of the specified data type, or 0 if it is not a static ...
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.
A union of the CANopen static data types.
int co_val_init(co_unsigned16_t type, void *val)
Initializes a value of the specified data type to zero.
size_t co_val_move(co_unsigned16_t type, void *dst, void *src)
Moves one value to another.
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_val_sizeof(co_unsigned16_t type, const void *val)
Returns the size (in bytes) of 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.
int co_val_init_min(co_unsigned16_t type, void *val)
Initializes a value of the specified data type with its lower limit.
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_val_fini(co_unsigned16_t type, void *val)
Finalizes a value of the specified data type.
int co_val_init_max(co_unsigned16_t type, void *val)
Initializes a value of the specified data type with its upper limit.