diff --git a/moberg.c b/moberg.c index f66eac786437ad2640b5fa2774b80e11d6adcdfe..bc9e52905c7b3a2fea511b2e1772878e53c767c4 100644 --- a/moberg.c +++ b/moberg.c @@ -14,12 +14,6 @@ #include <moberg_config.h> #include <moberg_parser.h> -static struct deferred_action { - struct deferred_action *next; - int (*action)(void *param); - void *param; -} *deferred_action = NULL; - struct moberg { struct moberg_config *config; struct channel_list { @@ -28,6 +22,23 @@ struct moberg { } analog_in, analog_out, digital_in, digital_out, encoder_in; }; +static struct deferred_action { + struct deferred_action *next; + int (*action)(void *param); + void *param; +} *deferred_action = NULL; + +static void run_deferred_actions() +{ + while (deferred_action) { + fprintf(stderr, "RUNNING deferred\n"); + struct deferred_action *deferred = deferred_action; + deferred_action = deferred_action->next; + deferred->action(deferred->param); + free(deferred); + } +} + static int channel_list_set(struct channel_list *list, int index, struct moberg_channel *value) @@ -253,6 +264,7 @@ struct moberg *moberg_new( /* Parse environment overrides */ } install_config(result); + run_deferred_actions(); err: return result; @@ -269,13 +281,7 @@ void moberg_free(struct moberg *moberg) channel_list_free(&moberg->encoder_in); free(moberg); } - while (deferred_action) { - fprintf(stderr, "RUNNING deferred\n"); - struct deferred_action *deferred = deferred_action; - deferred_action = deferred_action->next; - deferred->action(deferred->param); - free(deferred); - } + run_deferred_actions(); } enum moberg_status moberg_start( diff --git a/moberg_channel.h b/moberg_channel.h new file mode 100644 index 0000000000000000000000000000000000000000..2045b215a97f7421256b14d6a8c70d26b1025d6d --- /dev/null +++ b/moberg_channel.h @@ -0,0 +1,67 @@ +#ifndef __MOBERG_CHANNEL_H__ +#define __MOBERG_CHANNEL_H__ + +#include <moberg.h> + +enum moberg_channel_kind { + chan_ANALOGIN, + chan_ANALOGOUT, + chan_DIGITALIN, + chan_DIGITALOUT, + chan_ENCODERIN +}; + +struct moberg_channel { + struct moberg_channel_context *context; + + /* Use-count of channel, when it reaches zero, channel will be free'd */ + int (*up)(struct moberg_channel *channel); + int (*down)(struct moberg_channel *channel); + + /* Channel open and close */ + int (*open)(struct moberg_channel *channel); + int (*close)(struct moberg_channel *channel); + + /* I/O operations */ + enum moberg_channel_kind kind; + union moberg_channel_action { + struct { + struct moberg_channel_analog_in *context; + int (*read)(struct moberg_channel_analog_in *, double *value); + } analog_in; + struct { + struct moberg_channel_analog_out *context; + int (*write)(struct moberg_channel_context *, double value); + } analog_out; + struct { + struct moberg_channel_digital_in *context; + int (*read)(struct moberg_channel_context *, int *value); + } digital_in; + struct { + struct moberg_channel_digital_out *context; + int (*write)(struct moberg_channel_context *, int value); + } digital_out; + struct { + struct moberg_channel_encoder_in *context; + int (*read)(struct moberg_channel_context *, long *value); + } encoder_in; + } action; +}; + +struct moberg_channel_map { + struct moberg_device *device; + int (*map)(struct moberg_device* device, + struct moberg_channel *channel); +}; + +struct moberg_channel_install { + struct moberg *context; + int (*channel)(struct moberg *context, + int index, + struct moberg_device* device, + struct moberg_channel *channel); +}; + + + +#endif diff --git a/moberg_config.c b/moberg_config.c index aac3855000b642f256850d527f04b534a2e5fa05..6f7e6e4497fc3b33167e93b2d6a844a7550cb974 100644 --- a/moberg_config.c +++ b/moberg_config.c @@ -76,6 +76,21 @@ int moberg_config_install_channels(struct moberg_config *config, for (struct device_entry *d = config->device_head ; d ; d = d->next) { result &= moberg_device_install_channels(d->device, install); } + struct device_entry *device = config->device_head; + struct device_entry **previous = &config->device_head; + while (device) { + struct device_entry *next = device->next; + if (moberg_device_in_use(device->device)) { + previous = &device->next; + } else { + fprintf(stderr, "FREE\n"); + moberg_device_free(device->device); + free(device); + *previous = next; + } + device = next; + } + return result; } diff --git a/moberg_device.c b/moberg_device.c index a6e6d8649a6ab915552e01e74c165d62e5417c0d..b2daf2ff5a48640496f708aa8d2ddbd546742975 100644 --- a/moberg_device.c +++ b/moberg_device.c @@ -90,6 +90,14 @@ void moberg_device_free(struct moberg_device *device) free(device); } +int moberg_device_in_use(struct moberg_device *device) +{ + device->driver.up(device->device_context); + int use = device->driver.down(device->device_context); + fprintf(stderr, "IN_USE: %d\n", use); + return use > 1; +} + int moberg_device_parse_config(struct moberg_device *device, struct moberg_parser_context *parser) { diff --git a/moberg_device.h b/moberg_device.h index 6a5085eefed7c20bacb59aa89ab320cfe63475e0..de4a90d62f5345ca3eb0f33d9f35429731f98355 100644 --- a/moberg_device.h +++ b/moberg_device.h @@ -35,6 +35,8 @@ struct moberg_device *moberg_device_new(const char *driver); void moberg_device_free(struct moberg_device *device); +int moberg_device_in_use(struct moberg_device *device); + int moberg_device_parse_config(struct moberg_device* device, struct moberg_parser_context *context);