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);
283 #endif // !LELY_NO_CO_OBJ_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;
478 if (!__co_sub_init(sub, subidx, type)) {
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);
567 #endif // !LELY_NO_CO_OBJ_NAME 577 #ifndef LELY_NO_CO_OBJ_LIMITS 594 return sub ? &sub->
min : NULL;
621 return sub ? &sub->
max : NULL;
633 #endif // !LELY_NO_CO_OBJ_LIMITS 635 #ifndef LELY_NO_CO_OBJ_DEFAULT 652 return sub ? &sub->
def : NULL;
664 #endif // !LELY_NO_CO_OBJ_DEFAULT 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;
856 #endif // !LELY_NO_CO_OBJ_FILE 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;
989 #endif // !LELY_NO_CO_OBJ_UPLOAD 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;
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...
unsigned int co_sub_get_flags(const co_sub_t *sub)
Returns the object flags of a CANopen sub-object.
A CANopen SDO upload/download request.
#define CO_ACCESS_RWW
Read or write on process output.
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, or NULL if the attribute does not exist.
#define CO_SDO_AC_NO_READ
SDO abort code: Attempt to read a write only object.
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.
#define CO_OBJ_FLAGS_UPLOAD_FILE
If a read access is performed for the object, the data is stored in a file.
const void * key
A pointer to the key for this node.
#define CO_SDO_AC_PARAM_HI
SDO abort code: Value of parameter written too high (download only).
co_sub_t * co_sub_create(co_unsigned8_t subidx, co_unsigned16_t type)
Creates 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...
size_t co_type_alignof(co_unsigned16_t type)
Returns the alignment requirements (in bytes) of a value of the specified data type, or 0 if it is not a static 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 ...
unsigned long pdo_mapping
A flag indicating if it is possible to map this object into a PDO.
#define CO_OBJECT_DOMAIN
A large variable amount of data.
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.
size_t size
The total size (in bytes) of the value to be uploaded/downloaded.
void co_obj_destroy(co_obj_t *obj)
Destroys a CANopen object, including its sub-objects.
#define CO_ACCESS_WRITE
The object can be written.
void * dn_data
A pointer to user-specified data for dn_ind.
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.
co_obj_t * obj
A pointer to the CANopen object containing this sub-object.
co_unsigned8_t co_obj_get_code(const co_obj_t *obj)
Returns the object code of a CANopen object.
#define CO_SDO_AC_NO_DATA
SDO abort code: No data available.
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.
co_unsigned16_t type
The data type.
void * co_obj_addressof_val(const co_obj_t *obj)
Returns the address of the value of a CANopen object.
#define CO_DEFTYPE_DOMAIN
The data type (and object index) of an arbitrary large block of data.
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.
This header file is part of the utilities library; it contains the comparison function definitions...
size_t rbtree_size(const struct rbtree *tree)
Returns the size (in number of nodes) of a red-black tree.
#define CO_OBJ_FLAGS_DOWNLOAD_FILE
If a write access is performed for the object, the data is stored in a file.
co_unsigned16_t co_sub_get_type(const co_sub_t *sub)
Returns the data type of a CANopen sub-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.
#define CO_ACCESS_RWR
Read or write on process input.
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_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.
co_sub_up_ind_t * up_ind
A pointer to the upload indication function.
A union of the CANopen static data types.
co_sub_dn_ind_t * dn_ind
A pointer to the download indication function.
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.
unsigned long flags
The object flags.
#define CO_SDO_AC_ERROR
SDO abort code: General error.
co_obj_t * co_obj_next(const co_obj_t *obj)
Finds the next object in the object dictionary of a CANopen device.
#define CO_OBJECT_DEFTYPE
A type definitions.
char * name
A pointer to the name of the sub-object.
#define CO_OBJ_FLAGS_WRITE
Refuse write on download.
co_unsigned8_t code
The object code.
const char * co_obj_get_name(const co_obj_t *obj)
Returns the name of a CANopen object.
union co_val max
The upper limit of the object value.
int co_val_init_min(co_unsigned16_t type, void *val)
Initializes a value of the specified data type with its lower limit.
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.
int co_obj_remove_sub(co_obj_t *obj, co_sub_t *sub)
Removes a sub-object from a CANopen object.
int co_obj_set_name(co_obj_t *obj, const char *name)
Sets the name of a CANopen 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.
struct rbtree tree
The tree containing all the sub-objects.
union co_val min
The lower limit of the object value.
This header file is part of the CANopen library; it contains the Service Data Object (SDO) declaratio...
This is the internal header file of the object dictionary.
co_dev_t * co_obj_get_dev(const co_obj_t *obj)
Returns a pointer to the CANopen device containing the specified 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.
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_sub_addressof_min(const co_sub_t *sub)
Returns the address of the lower limit of the value of a CANopen sub-object.
void set_errc(int errc)
Sets the current (thread-specific) native error code to errc.
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...
const void * co_sub_get_def(const co_sub_t *sub)
Returns a pointer to the default value 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.
#define CO_OBJECT_RECORD
A multiple data field object where the data fields may be any combination of simple variables...
union co_val def
The default value.
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.
#define CO_ACCESS_READ
The object can be read.
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_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.
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.
int co_sub_set_access(co_sub_t *sub, unsigned int access)
Sets the access type of a CANopen sub-object.
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.
This header file is part of the utilities library; it contains the native and platform-independent er...
#define CO_ACCESS_RO
Read-only access.
#define rbtree_foreach(tree, node)
Iterates over each node in a red-black tree in ascending order.
int co_obj_insert_sub(co_obj_t *obj, co_sub_t *sub)
Inserts a sub-object into 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_SDO_AC_PARAM_RANGE
SDO abort code: Maximum value is less than minimum value (download only).
struct rbnode node
The node of this object in the tree of objects.
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...
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.
#define CO_ACCESS_CONST
Constant value.
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.
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.
int co_val_init_max(co_unsigned16_t type, void *val)
Initializes a value of the specified data type with its upper limit.
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...
size_t co_sub_sizeof_def(const co_sub_t *sub)
Returns size (in bytes) of the default value of a CANopen sub-object.
#define CO_ACCESS_RW
Read or write access.
const void * co_sub_addressof_def(const co_sub_t *sub)
Returns the address of the default value of a CANopen sub-object.
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 get_errc(void)
Returns the last (thread-specific) native error code set by a system call or library function...
int co_sub_set_name(co_sub_t *sub, const char *name)
Sets the name 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.
const void * co_sub_get_val(const co_sub_t *sub)
Returns a pointer to the current value of a CANopen sub-object.
struct rbnode * rbtree_find(const struct rbtree *tree, const void *key)
Finds a node in a red-black tree.
const char * co_sub_get_name(const co_sub_t *sub)
Returns the name of a CANopen sub-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, or NULL if the attribute does not exist.
struct rbnode node
The node of this sub-object in the tree of sub-objects.
co_unsigned8_t co_sub_get_subidx(const co_sub_t *sub)
Returns the sub-index of a CANopen sub-object.
co_unsigned16_t idx
The object index.
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.
void rbtree_remove(struct rbtree *tree, struct rbnode *node)
Removes a node from a red-black tree.
void * val
A pointer to the object value.
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.
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.
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.
#define CO_OBJECT_VAR
A single value.
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.
#define ALIGN(x, a)
Rounds x up to the nearest multiple of a.
static void co_obj_clear(co_obj_t *obj)
Destroys all sub-objects.
size_t co_obj_sizeof_val(const co_obj_t *obj)
Returns size (in bytes) of the value of a CANopen object.
int errno2c(int errnum)
Transforms a standard C error number to a native error code.
#define CO_SDO_AC_NO_WRITE
SDO abort code: Attempt to write a read only object.
unsigned long access
The access type.
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.
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.
int co_val_cmp(co_unsigned16_t type, const void *v1, const void *v2)
Compares two values of the specified data type.
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().
#define CO_OBJECT_NULL
An object with no data fields.
#define CO_SDO_AC_PARAM_LO
SDO abort code: Value of parameter written too low (download only).
co_unsigned8_t subidx
The object sub-index.
unsigned int co_sub_get_access(const co_sub_t *sub)
Returns the access 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 CO_OBJECT_DEFSTRUCT
A record type definition.
co_sub_t * co_sub_next(const co_sub_t *sub)
Finds the next sub-object in a CANopen object.
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.
size_t co_sub_sizeof_val(const co_sub_t *sub)
Returns size (in bytes) of the current value of a CANopen sub-object.
void co_sub_destroy(co_sub_t *sub)
Destroys a CANopen sub-object.
#define CO_SDO_AC_NO_SUB
SDO abort code: Sub-index does not exist.
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()...
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...
size_t co_val_move(co_unsigned16_t type, void *dst, void *src)
Moves one value to another.
co_obj_t * co_obj_create(co_unsigned16_t idx)
Creates a CANopen object.
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.
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 * up_data
A pointer to user-specified data for up_ind.
char * name
A pointer to the name of the object.
int co_obj_set_code(co_obj_t *obj, co_unsigned8_t code)
Sets the code (type) of a CANopen object.
void rbtree_insert(struct rbtree *tree, struct rbnode *node)
Inserts a node into a red-black tree.
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.
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.
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...
This header file is part of the C11 and POSIX compatibility library; it includes <stdlib.h> and defines any missing functionality.
void co_sdo_req_fini(struct co_sdo_req *req)
Finalizes a CANopen SDO upload/download request.
void co_sub_set_flags(co_sub_t *sub, unsigned int flags)
Sets the object flags of a CANopen sub-object.
co_unsigned16_t co_obj_get_idx(const co_obj_t *obj)
Returns the index of a CANopen 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()...
const void * co_sub_addressof_val(const co_sub_t *sub)
Returns the address of the current value of a CANopen sub-object.
co_sub_t * co_sub_prev(const co_sub_t *sub)
Finds the previous sub-object in a CANopen object.
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...
#define CO_SDO_AC_TYPE_LEN
SDO abort code: Data type does not match, length of service parameter does not match.
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.
size_t size
The size (in bytes) of the value at val.
#define CO_SDO_REQ_INIT
The static initializer for struct co_sdo_req.
#define CO_OBJECT_ARRAY
A multiple data field object where each data field is a simple variable of the same basic data type...
struct rbnode * rbtree_first(const struct rbtree *tree)
Returns a pointer to the first (leftmost) node in a red-black tree.
int co_dev_remove_obj(co_dev_t *dev, co_obj_t *obj)
Removes an object from the object dictionary a CANopen device.
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.
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 ...
A node in a red-black tree.
void co_sub_set_pdo_mapping(co_sub_t *sub, int pdo_mapping)
Enables or disables PDO mapping a CANopen sub-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.