[OSADL-svn-commits] r2 - documentation fddi-20070502-1 fddi-20070502-1/doc fddi-20070502-1/src fddi-20070529-1 fddi-20070529-1/doc fddi-20070529-1/src fddi-20070618-1 fddi-20070618-1/doc fddi-20070618-1/src protocols src

OSADL repository commits osadl-svn-commits at lists.osadl.org
Tue Oct 2 11:41:08 CEST 2007


Author: robert
Date: Mon Jun 18 19:44:22 2007
New Revision: 2

Log:
added dhe's versions from the mailing list

Added:
   fddi-20070502-1/
   fddi-20070502-1/doc/
   fddi-20070502-1/doc/Fieldbus-Device-Driver-Interface.pdf   (contents, props changed)
   fddi-20070502-1/src/
   fddi-20070529-1/
   fddi-20070529-1/doc/
   fddi-20070529-1/doc/Fieldbus-Device-Driver-Interface.odt   (contents, props changed)
   fddi-20070529-1/src/
   fddi-20070529-1/src/fddi.h
   fddi-20070618-1/
   fddi-20070618-1/doc/
   fddi-20070618-1/doc/Fieldbus-Device-Driver-Interface.odt   (contents, props changed)
   fddi-20070618-1/src/
   fddi-20070618-1/src/fddi.c
   fddi-20070618-1/src/fddi.h
Removed:
   documentation/
   protocols/
   src/

Added: fddi-20070502-1/doc/Fieldbus-Device-Driver-Interface.pdf
==============================================================================
Binary file. No diff available.

Added: fddi-20070529-1/doc/Fieldbus-Device-Driver-Interface.odt
==============================================================================
Binary file. No diff available.

Added: fddi-20070529-1/src/fddi.h
==============================================================================
--- (empty file)
+++ fddi-20070529-1/src/fddi.h	Mon Jun 18 19:44:22 2007
@@ -0,0 +1,392 @@
+/* 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
+	*/
+

Added: fddi-20070618-1/doc/Fieldbus-Device-Driver-Interface.odt
==============================================================================
Binary file. No diff available.

Added: fddi-20070618-1/src/fddi.c
==============================================================================
--- (empty file)
+++ fddi-20070618-1/src/fddi.c	Mon Jun 18 19:44:22 2007
@@ -0,0 +1,286 @@
+#include <string.h>
+#include <memory.h>
+#include <stdlib.h>
+#include "fddi.h"
+
+#define MAX_IO_INTERFACES	16
+#define MAX_IO_INTERFACE_INSTS	64
+
+/* managment of io-interfaces */
+static int num_of_interfaces = 0;
+static IO_INTERFACE io_interfaces[MAX_IO_INTERFACES];
+
+
+static int num_of_interface_instances = 0;
+static IO_INTERFACE_INST io_interface_instances[MAX_IO_INTERFACE_INSTS];
+
+int register_io_interface(IO_INTERFACE ioitf)
+{
+	if (num_of_interfaces >= MAX_IO_INTERFACES)
+		return RESERR_OUT_OF_MEM;
+	io_interfaces[num_of_interfaces++] = ioitf;
+	return RESOK;
+}
+
+int bind_io_interface(IO_INTERFACE ioitf, char* name, LL_INTERFACE llitf, IO_INTERFACE_INST* res)
+{
+	int ret;
+	if (num_of_interface_instances >= MAX_IO_INTERFACE_INSTS)
+		return RESERR_OUT_OF_MEM;
+	/* call to function pointer from registered io-interface */
+	ret = (*ioitf->_fptr_bind_io_interface)(name, llitf, res);
+	if (ret == RESOK)
+		io_interface_instances[num_of_interface_instances++] = *res;
+	return ret;
+}
+
+int enum_io_interfaces(IO_INTERFACE** ioitfs)
+{
+	*ioitfs = io_interfaces;
+	return num_of_interfaces;
+}
+
+int enum_io_interface_instances(IO_INTERFACE_INST** ioitfinsts)
+{
+	*ioitfinsts = io_interface_instances;
+	return num_of_interface_instances;
+}
+
+IO_INTERFACE get_io_interface(char* name)
+{
+	int i;
+	for (i = 0; i < num_of_interfaces; i++)
+		if (strcmp(name, io_interfaces[i]->name) == 0)
+			return io_interfaces[i];
+	return NULL;
+}
+
+IO_INTERFACE_INST get_io_interface_inst(char* name)
+{
+	int i;
+	for (i = 0; i < num_of_interface_instances; i++)
+		if (strcmp(name, io_interface_instances[i]->name) == 0)
+			return io_interface_instances[i];
+	return NULL;
+}
+
+int enum_io_transport_units(IO_INTERFACE_INST ioitfinst, IO_TRANSPORT_UNIT** iotpus)
+{
+	*iotpus = ioitfinst->tpus;
+	return ioitfinst->num_tpus;
+}
+
+int enum_io_devices(IO_INTERFACE_INST ioitfinst, IO_DEVICE** iodevices)
+{
+	*iodevices = ioitfinst->devlist;
+	return ioitfinst->num_dev;
+}
+
+int enum_io_variables(IO_INTERFACE_INST ioitfinst, IO_VARIABLE** iovars)
+{
+	*iovars = ioitfinst->varlist;
+	return ioitfinst->num_var;
+}
+
+static int count_devices(IO_DEVICE io_device)
+{
+	int n_dev;
+	IO_DEVICE dev_child;
+
+	if (io_device == NULL)
+		return 0;
+
+	n_dev = 1; // the device itself
+	dev_child = io_device->first_child;
+
+	while (dev_child != NULL)
+	{
+		n_dev += count_devices(dev_child);
+		dev_child = dev_child->next_child;
+	}
+	return n_dev;
+}
+
+static IO_DEVICE* fill_devices(IO_DEVICE dev, IO_DEVICE* devlist)
+/* return adress to continue. devlist must be large enough */
+{
+	IO_DEVICE* list = devlist;
+	IO_DEVICE dev_child;
+
+	*list = dev;
+	list++;
+
+	dev_child = dev->first_child;
+
+	while (dev_child != NULL)
+	{
+		list = fill_devices(dev_child, list);
+		dev_child = dev_child->next_child;
+	}
+	return list;
+}
+
+int configure_io_interface_inst(IO_INTERFACE_INST ioitfinst, IO_DEVICE root)
+{
+	int ret;
+	/* call to function pointer from registered io-interface */
+	ret = (*ioitfinst->ioitf->_fptr_configure_io_interface_inst)(ioitfinst, root);
+	if (ret == RESOK)
+	{
+		int i;
+		IO_VARIABLE* list;
+
+		/* the configure method fills the tpu-list */
+		/* the other lists are filled by the fddi interface in this function */
+
+		/* fill device list */
+		ioitfinst->num_dev = count_devices(root);
+		ioitfinst->devlist = malloc(ioitfinst->num_dev * sizeof(IO_DEVICE));
+		fill_devices(root, ioitfinst->devlist);
+
+		/* fill variable list */
+		ioitfinst->num_var = 0;
+		for (i = 0; i < ioitfinst->num_tpus; i++)
+			ioitfinst->num_var += ioitfinst->tpus[i]->num_var;
+
+		ioitfinst->varlist = malloc(ioitfinst->num_var * sizeof(IO_VARIABLE));
+		list = ioitfinst->varlist;
+		for (i = 0; i < ioitfinst->num_tpus; i++)
+		{
+			memcpy(list, ioitfinst->tpus[i]->varlist, ioitfinst->tpus[i]->num_var * sizeof(IO_VARIABLE));
+			list += ioitfinst->tpus[i]->num_var;
+		}
+	}
+	return ret;
+}
+
+int scan_io_interface_inst(IO_INTERFACE_INST ioitfinst, IO_DEVICE *root)
+{
+	int ret;
+	/* call to function pointer from registered io-interface */
+	ret = (*ioitfinst->ioitf->_fptr_scan_io_interface_inst)(ioitfinst, root);
+	return ret;
+}
+
+int read_iodevice_async(IO_DEVICE iodev, unsigned long address, unsigned char* buf, unsigned long buf_size, unsigned long* read_size)
+{
+	int ret;
+	/* call to function pointer from registered io-interface */
+	ret = (*iodev->itfinst->ioitf->_fptr_read_device_async)(iodev, address, buf, buf_size, read_size);
+	return ret;
+}
+
+int write_iodevice_async(IO_DEVICE iodev, unsigned long address, unsigned char* buf, unsigned long size)
+{
+	int ret;
+	/* call to function pointer from registered io-interface */
+	ret = (*iodev->itfinst->ioitf->_fptr_write_device_async)(iodev, address, buf, size);
+	return ret;
+}
+
+int cmd_iodevice(IO_DEVICE iodev, IO_DEVICE_COMMAND cmd)
+{
+	int ret;
+	/* call to function pointer from registered io-interface */
+	ret = (*iodev->itfinst->ioitf->_fptr_cmd_device)(iodev, cmd);
+	return ret;
+}
+
+int enum_io_variables_of_iodevice(IO_DEVICE iodev, IO_VARIABLE** iovars)
+{
+	// todo
+	return 0;
+}
+
+/* A very simple implementation of transport units with a lot of improvement possibilities */
+/* While anyone is reading the buffer all write operations are done in a extra buffer to keep the read buffer consistent */
+
+unsigned char* address_to_read(IO_TRANSPORT_UNIT iotpu)
+{
+	iotpu->read_count++;
+	return iotpu->buf_read;
+}
+
+unsigned char* address_to_write(IO_TRANSPORT_UNIT iotpu)
+{
+	if (iotpu->write_count != 0)
+		return NULL;
+	
+	iotpu->write_count++;
+	if (iotpu->buf_read == iotpu->buf_write)
+	{
+		iotpu->buf_write = malloc(iotpu->size);
+		memcpy(iotpu->buf_write, iotpu->buf_read, iotpu->size);
+	}
+	return iotpu->buf_write;
+}
+
+unsigned char* address_to_replace(IO_TRANSPORT_UNIT iotpu)
+{
+	if (iotpu->write_count != 0)
+		return NULL;
+
+	iotpu->write_count++;
+	if (iotpu->buf_read == iotpu->buf_write)
+		iotpu->buf_write = malloc(iotpu->size);
+	return iotpu->buf_write;
+}
+
+int release_adress(IO_TRANSPORT_UNIT iotpu, unsigned char* address)
+{
+	if (address == iotpu->buf_read)
+	{
+		iotpu->read_count--;
+		/* assert iotpu->read_count >= 0 */
+		if (iotpu->read_count == 0 && iotpu->write_count == 0 && iotpu->buf_read != iotpu->buf_write)
+		{
+			free(iotpu->buf_read);
+			iotpu->buf_read = iotpu->buf_write;
+		}
+		return RESOK;
+	}
+	else if (address == iotpu->buf_write)
+	{
+		int i;
+		iotpu->write_count--;
+		/* assert iotpu->write_count >= 0 */
+		if (iotpu->read_count == 0 && iotpu->write_count == 0 && iotpu->buf_read != iotpu->buf_write)
+		{
+			free(iotpu->buf_read);
+			iotpu->buf_read = iotpu->buf_write;
+		}
+
+		/* trigger callbacks */
+		for (i = 0; i < iotpu->num_callbacks; i++)
+			(*iotpu->callback[i])(iotpu);
+
+		return RESOK;
+	}
+	return RESERR_UNKOWNADDRESS;
+}
+
+int send_iotransport_unit(IO_TRANSPORT_UNIT iotpu)
+{
+	int res = 0;
+	/* pseudo code, because low level interface is not ready */
+	/* may be redirected trough stack */
+	/*
+	res = iotpu->itfinst->llitf->Send(iotpu->id, iotpu->buf_write, iotpu->size);
+	*/
+	return 0;
+}
+
+int register_callback_to_iotransport_unit(IO_TRANSPORT_UNIT iotpu, void (*callback)(IO_TRANSPORT_UNIT iotpu))
+{
+	if (iotpu->num_callbacks >= MAXCALLBACKS)
+		return RESERR_OUT_OF_MEM;
+	iotpu->callback[iotpu->num_callbacks] = callback;
+	iotpu->num_callbacks++;
+	return RESOK;
+}
+
+int enum_io_variables_of_iotransport_unit(IO_TRANSPORT_UNIT iotpu, IO_VARIABLE** iovars)
+{
+	*iovars = iotpu->varlist;
+	return iotpu->num_var;
+}

Added: fddi-20070618-1/src/fddi.h
==============================================================================
--- (empty file)
+++ fddi-20070618-1/src/fddi.h	Mon Jun 18 19:44:22 2007
@@ -0,0 +1,414 @@
+/* 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
+#define RESERR_UNKOWNADDRESS 9
+
+/* 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) */
+	int (*_fptr_read_device_async)(struct _io_device *dev, unsigned long address, unsigned char* buf, unsigned long buf_size, unsigned long* read_size);
+	/* function pointer of the read_iodevice_async method (see scan_io_interface_inst for further information) */
+	int (*_fptr_write_device_async)(struct _io_device *dev, unsigned long address, unsigned char* buf, unsigned long size);
+	/* function pointer of the write_iodevice_async method (see scan_io_interface_inst for further information) */
+	int (*_fptr_cmd_device)(struct _io_device *dev, enum _io_device_command cmd);
+	/* function pointer of the cmd_iodevice 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_unit **tpus; /* list of io-transport units (set after configuration by fddi-driver) */
+
+	int num_dev;		/* number of devices */
+	struct _io_device **devlist; /* linear list of all devices (set automatically after configuration by fddi) */
+
+	int num_var;		/* number of variables */
+	struct _io_variable **varlist; /* linear list of all variables (set after configuration by fddi-driver) */
+
+	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;
+
+#define MAXCALLBACKS 3
+
+/* 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;
+
+	int num_callbacks;
+	void (*callback[MAXCALLBACKS])(struct _io_transport_unit *iotpu);
+
+	int read_count;
+	int write_count;
+
+	int num_var;		/* number of variables */
+	struct _io_variable **varlist; /* linear list of all variables (set after configuration by fddi-driver) */
+};
+
+#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:	RESOK, RESERR_UNKOWNADDRESS
+	*/
+
+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
+	*/


More information about the OSADL-svn-commits mailing list