/* fieldbus device driver interface */ /* #include "lldi.h" */ typedef void *LL_INTERFACE; /* result codes */ #define RESOK 0 #define RESERR_INTERFACE_ALREADY_REGISTERD 1 #define RESERR_LLINTERFACE_ALREADY_IN_USE 2 #define RESERR_LLINTERFACE_HAS_WRONG_TYPE 3 #define RESERR_OUT_OF_MEM 4 #define RESERR_TIMEOUT 5 #define RESERR_NO_ACCESS 6 #define RESERR_BUFFER_TO_SMALL 7 #define RESERR_WRONGTPUTYPE 8 /* io-interface */ struct _io_interface { char* name; /* name of the interface */ unsigned long version; /* version of the interface */ int (*_fptr_bind_io_interface)(char* name, LL_INTERFACE llitf, struct _io_interface_inst **result); /* function pointer of the bind_io_interface method (see bind_io_interface for further information) */ int (*_fptr_configure_io_interface_inst)(struct _io_interface_inst *itfinst, struct _io_device *root); /* function pointer of the configure_io_interface_inst method (see configure_io_interface for further information) */ int (*_fptr_scan_io_interface_inst)(struct _io_interface_inst *itfinst, struct _io_device **root); /* function pointer of the scan_io_interface_inst method (see scan_io_interface_inst for further information) */ }; typedef struct _io_interface *IO_INTERFACE; /* instance of io-interface */ struct _io_interface_inst { char* name; /* name of the io-interface-instance */ IO_INTERFACE ioitf; /* the type of the io-interface */ LL_INTERFACE llitf; /* the low level interface, to which the io-interface is bound to */ struct _io_device *root; /* root device, set during configuration */ int num_tpus; /* number of io-transport units (set after configuration) */ struct _io_transport_units *tpus; /* list of io-transport units (set after configuration) */ void* inst_data; /* type specific management data */ }; typedef struct _io_interface_inst *IO_INTERFACE_INST; /* io-device */ enum _io_device_state { DEVSTATE_VOID, /* the device is not configured */ DEVSTATE_MISSING, /* the configuration of the device failed, because it is missing */ DEVSTATE_CONFIG_ERROR, /* the configuration of the device failed, because of wrong config data */ DEVSTATE_PREOPERATIONAL, /* the device is configured, but not working */ DEVSTATE_OPERATIONAL, /* the device is working */ DEVSTATE_OPERATION_ERROR /* the device encountered an error, while it is working */ }; typedef enum _io_device_state IO_DEVICE_STATE; enum _io_device_command { DEVCMD_START, /* start the device */ DEVCMD_STOP, /* stop the device */ DEVCMD_RESET, /* reset the device */ DEVCMD_IDENTIFY, /* let the device do something to identify itself (like blinking with a LED) */ DEVCMD_QUITERR /* quit an error of the device, to return to normal operation */ }; typedef enum _io_device_command IO_DEVICE_COMMAND; /* use this datatype with the function cmd_iodevice */ struct _io_device_param { unsigned long key; unsigned long value; unsigned short flags; }; #define PARAMFLAG_PTR 0 /* value contains a pointer to a struct (frist word of the struct is size) */ #define PARAMFLAG_BYTE 1 /* value contais a byte */ #define PARAMFLAG_WORD 2 /* value contains a word */ #define PARAMFLAG_LONG 3 /* value contains a double word */ #define PARAMFLAG_TYPEMASK 3 /* value contains a double word */ #define PARAMFLAG_DEFAULT 4 /* value contains a device default parameter. the parameter is used to set up the configuration, * but need not to be sent to the device */ typedef struct _io_device_param IO_DEVICE_PARAM; struct _io_device { IO_INTERFACE_INST itfinst; /* reference to owning io-interface instance (set by fddi) */ unsigned long physical_id; /* physical id of the device */ unsigned long logical_id; /* logical id of the device */ unsigned long type_id; /* type id of the device */ char* name; /* optional name of the device (from configuration) */ int num_params; /* number of parameters */ IO_DEVICE_PARAM* params; /* pointer to list of parameters */ struct _io_device* parent; /* parent device */ struct _io_device* first_child; /* first child device of this device */ struct _io_device* next_child;/* next child of the same parent */ IO_DEVICE_STATE state; /* state of the device */ }; typedef struct _io_device *IO_DEVICE; /* io-transport unit */ struct _io_transport_unit { IO_INTERFACE_INST itfinst; /* reference to owning io-interface instance (set by fddi) */ unsigned long id; unsigned long time_stamp; unsigned long flags; unsigned long size; unsigned char* buf_read; unsigned char* buf_write; }; #define TPUFLAG_IN 1 /* application reads from this transport unit */ #define TPUFLAG_OUT 2 /* application writes to this transport unit */ #define TPUFLAG_SYNC 4 /* this transport unit synchronizes a group of io-devices */ #define TPUFLAG_EXTMEM 8 /* the memory of this transport unit is not maintained by the fddi */ #define TPUFLAG_CONSIST 16 /* the memory of this transport unit is kept consistent by the fddi (cannot be used with TPUFLAG_EXTMEM) */ typedef struct _io_transport_unit *IO_TRANSPORT_UNIT; /* io-variable */ struct _io_variable { char* name; /* optional name of the variable */ unsigned long size; /* size of the variable */ unsigned long offset; /* offset of the variable in io-transport unit */ IO_TRANSPORT_UNIT iotpu;/* reference to io-transport unit */ IO_DEVICE iodev; /* reference to io-device */ }; typedef struct _io_variable *IO_VARIABLE; /* functions of the fddi */ int register_io_interface(IO_INTERFACE ioitf); /* registers a new io-interface to the fddi layer (for example a CANopen stack) * * ioitf: [in] the definition of the new interface * * result: RESOK, RESERR_INTERFACE_ALREADY_REGISTERD, RESERR_OUT_OF_MEM * * remarks: this function is only called by the module which implements his own driver * it need not to be called by users of an existiong driver */ int bind_io_interface(IO_INTERFACE ioitf, char* name, LL_INTERFACE llitf, IO_INTERFACE_INST* res); /* binds a io-interface to a hardware interface (for example a CANopen stack to CAN interface 1) * * name: [in] name of the interface instance (for example "CANopen on can1") * The name can be used to open the instance * llitf: [in] handle of the low level interface, to which the io_interface should be bound to * res: [out] pointer to resulting interface instace * * result: RESOK, RESERR_LLINTERFACE_ALREADY_IN_USE, RESERR_LLINTERFACE_HAS_WRONG_TYPE, RESERR_OUT_OF_MEM */ int enum_io_interfaces(IO_INTERFACE** ioitfs); /* enumerates all registered io-interfaces * * ioitfs: [out] pointer to pointer to an array of io_interfaces * * result: Because this function can never fail, the number of io_interfaces is returned */ int enum_io_interface_instances(IO_INTERFACE_INST** ioitfinsts); /* enumerates all io-interface instances * * ioitfinsts: [out] pointer to pointer to an array of io-interfaces-instances * * result: Because this function can never fail, the number of io interfaces instances is returned */ IO_INTERFACE get_io_interface(char* name); /* retrieves a io-interface by its name * * name: [in] name of the io-interface to retrieved * * result: the io-interface with the given name or null if the name was not found */ IO_INTERFACE_INST get_io_interface_inst(char* name); /* retrieves a io-interface instance by its name * * name: [in] name of the io-interface instance to retrieved * * result: the io-interface instance with the given name or null if the name was not found */ int enum_io_transport_units(IO_INTERFACE_INST ioitfinst, IO_TRANSPORT_UNIT** iotpus); /* enumerates all configured io-transport-units of an io-interface instances * * ioitfinst: [in] interface instance, which content should be enumerated * iotpus: [out] pointer to pointer to an array of io-transport-units * * result: Because this function can never fail, the number of io-transport-units is returned */ int enum_io_devices(IO_INTERFACE_INST ioitfinst, IO_DEVICE** iodevices); /* enumerates all configured io-devices of an io-interface instances as a flat list * * ioitfinst: [in] interface instance, which content should be enumerated * iodevices: [out] pointer to pointer to an array of io-devices * * result: Because this function can never fail, the number of io-devices is returned */ int enum_io_variables(IO_INTERFACE_INST ioitfinst, IO_VARIABLE** iovars); /* enumerates all configured io-variables of an io-interface instances * * ioitfinst: [in] interface instance, which content should be enumerated * iovars: [out] pointer to pointer to an array of io-variables * * result: Because this function can never fail, the number of io-variables is returned */ int configure_io_interface_inst(IO_INTERFACE_INST ioitfinst, IO_DEVICE root); /* configures a io-interface instance * * ioitfinst: [in] the interface to be configured * root: [in] root node, which contains the configured child nodes. * Typically the root node contains the interface hardware and the childs are the fieldbus slaves. * The following members of IO_DEVICE are expected to be set correctly in each node: * * logical_id; * type_id; * name; (optional) * * num_params; * params; * * parent; * first_child; * next_child; * * result: RESOK, RESERR_OUT_OF_MEM * remarks: all previous configurations are disgarded. * configuration can take some time. it can be useful to do process it in a extra thread with a timeout. */ int scan_io_interface_inst(IO_INTERFACE_INST itfinst, IO_DEVICE *root); /* scans a io-interface instance for all connected devices * * ioitfinst: [in] the interface to be scanned * root: [out] root node, which contains the connected child nodes. The following members of IO_DEVICE * are set: * * pysical_id * logical_id; * type_id; * name; (optional) * * parent; * first_child; * next_child; * * result: RESOK, RESERR_OUT_OF_MEM * remarks: a previous configurations is not disgarded. * scan can take some time. it can be useful to do process it in a extra thread with a timeout. */ int read_iodevice_async(IO_DEVICE iodev, unsigned long address, unsigned char* buf, unsigned long buf_size, unsigned long* read_size); /* performs an asynchronous read (for example CANopen SDO, Profibus DPV1 etc.) on an io-device * * iodev: [in] device on which the read operation is done * address: [in] address in the device * buf: [out] buffer to receive the result * buf_size:[in] size of the buffer / size of the data to read * read_size:[out] size of the data, which was actually read * * result: RESOK, RESERR_TIMEOUT, RESERR_NO_ACCESS, RESERR_BUFFER_TO_SMALL * remarks: async read can take some time. it can be useful to do process it in a extra thread with a timeout. */ int write_iodevice_async(IO_DEVICE iodev, unsigned long address, unsigned char* buf, unsigned long size); /* performs an asynchronous write (for example CANopen SDO, Profibus DPV1 etc.) on an io-device * * iodev: [in] device on which the write operation is done * address: [in] address in the device * buf: [in] buffer with the data to write * buf_size:[in] size of the data to write * * result: RESOK, RESERR_TIMEOUT, RESERR_NO_ACCESS * remarks: async write can take some time. it can be useful to do process it in a extra thread with a timeout. */ int cmd_iodevice(IO_DEVICE iodev, IO_DEVICE_COMMAND cmd); /* performs a command like start, stop, reset on an io-device * * iodev: [in] device on which the command should be done * cmd: [in] the command (see definition of IO_DEVICE_COMMAND) * * result: RESOK, RESERR_TIMEOUT, RESERR_NO_ACCESS * remarks: cmd_iodevice can take some time. it can be useful to do process it in a extra thread with a timeout. * a command done on the root device typically, executes the command for all devices (start, stop) */ int enum_io_variables_of_iodevice(IO_DEVICE iodev, IO_VARIABLE** iovars); /* enumerates all configured io-variables of an io-device * * iodev: [in] device, which content should be enumerated * iovars: [out] pointer to pointer to an array of io-variables * * result: Because this function can never fail, the number of io-variables is returned */ unsigned char* address_to_read(IO_TRANSPORT_UNIT iotpu); /* Get the adress of the process data of a io-transport unit to read on it * * iotpu: [in] transport unit of which the address is retrieved * * result: the address * remarks: only read operations should be done on the memory area. * use release_address after finishing read operations. */ unsigned char* address_to_write(IO_TRANSPORT_UNIT iotpu); /* Get the address of the process data of a io-transport unit to write (modify) it * * iotpu: [in] transport unit of which the address is retrieved * * result: the adress * remarks: if the complete memory of the io-transport unit is written, use address_to_replace, because it may be faster. * use release_adress after finishing write operations. */ unsigned char* address_to_replace(IO_TRANSPORT_UNIT iotpu); /* Get the address of the process data of a io-transport unit to write the complete process data * * iotpu: [in] transport unit of which the address is retrieved * * result: the adress * remarks: this function is faster on consistent transport units than address_to_write * use release_adress after finishing write operations. */ int release_adress(IO_TRANSPORT_UNIT iotpu, unsigned char* address); /* Releases an address, previously retrieved by address_to_read, address_to_write, address_to_replace * * iotpu: [in] transport unit of which the address is released * address: [in] address to release * * result: the adress */ int send_iotransport_unit(IO_TRANSPORT_UNIT iotpu); /* Explcitly send an io-transport unit, to do I/O syncronously, application triggered * * iotpu: [in] transport unit which is to be sent * * result: RESOK, RESERR_WRONGTPUTYPE */ int register_callback_to_iotransport_unit(IO_TRANSPORT_UNIT iotpu, void (*callback)(IO_TRANSPORT_UNIT iotpu)); /* Registers a callback function to a io-transport unit, to do I/O synchronously, IO-system triggered * * iotpu: [in] transport unit which should trigger the callback * callback:[in] callback function, which supplies a reference to the io-transport unit as parameter * * result: RESOK, RESERR_WRONGTPUTYPE * remarks: the callback is called after a write operation is finished (release_address) on the given transport unit */ int enum_io_variables_of_iotransport_unit(IO_TRANSPORT_UNIT iotpu, IO_VARIABLE** iovars); /* enumerates all configured io-variables of an io-transport-unit * * iotpu: [in] transport unit, which content should be enumerated * iovars: [out] pointer to pointer to an array of io-variables * * result: Because this function can never fail, the number of io-variables is returned */