Commit 87b88706 authored by Anders Blomdell's avatar Anders Blomdell
Browse files

Start and stop actions implemented

parent a5def94f
......@@ -31,7 +31,6 @@ static struct deferred_action {
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);
......@@ -288,6 +287,7 @@ enum moberg_status moberg_start(
struct moberg *moberg,
FILE *f)
{
return moberg_config_start(moberg->config, f);
return moberg_OK;
}
......@@ -296,6 +296,7 @@ enum moberg_status moberg_stop(
struct moberg *moberg,
FILE *f)
{
return moberg_config_stop(moberg->config, f);
return moberg_OK;
}
......@@ -305,7 +306,6 @@ void moberg_deferred_action(
{
struct deferred_action *deferred = malloc(sizeof(*deferred));
if (deferred) {
fprintf(stderr, "DEFERRED %p %p\n", action, param);
deferred->next = deferred_action;
deferred->action = action;
deferred->param = param;
......
......@@ -94,4 +94,21 @@ int moberg_config_install_channels(struct moberg_config *config,
return result;
}
int moberg_config_start(struct moberg_config *config,
FILE *f)
{
for (struct device_entry *d = config->device_head ; d ; d = d->next) {
moberg_device_start(d->device, f);
}
return 1;
}
int moberg_config_stop(struct moberg_config *config,
FILE *f)
{
for (struct device_entry *d = config->device_head ; d ; d = d->next) {
moberg_device_stop(d->device, f);
}
return 1;
}
......@@ -17,4 +17,10 @@ int moberg_config_add_device(struct moberg_config *config,
int moberg_config_install_channels(struct moberg_config *config,
struct moberg_channel_install *install);
int moberg_config_start(struct moberg_config *config,
FILE *f);
int moberg_config_stop(struct moberg_config *config,
FILE *f);
#endif
......@@ -228,13 +228,6 @@ int moberg_device_parse_map(struct moberg_device* device,
};
struct moberg_channel_map map_channel = {
.device=device,
#if 0
.analog_in=moberg_device_add_analog_in,
.analog_out=moberg_device_add_analog_out,
.digital_in=moberg_device_add_digital_in,
.digital_out= moberg_device_add_digital_out,
.encoder_in= moberg_device_add_encoder_in,
#endif
.map=map
};
......@@ -259,50 +252,19 @@ int moberg_device_install_channels(struct moberg_device *device,
channel->index,
device,
channel->u.channel);
switch (channel->kind) {
case chan_ANALOGIN: {
/*
install->analog_in(install->context,
channel->index,
device,
channel->u.analog_in);
*/
} break;
case chan_ANALOGOUT: {
/*
install->analog_out(install->context,
channel->index,
device,
channel->u.analog_out);
*/
} break;
case chan_DIGITALIN: {
/*
install->digital_in(install->context,
channel->index,
device,
channel->u.digital_in);
*/
} break;
case chan_DIGITALOUT: {
/*
install->digital_out(install->context,
channel->index,
device,
channel->u.digital_out);
*/
} break;
case chan_ENCODERIN: {
/*
install->encoder_in(install->context,
channel->index,
device,
channel->u.encoder_in);
*/
} break;
}
channel = next;
}
return 1;
}
int moberg_device_start(struct moberg_device *device,
FILE *f)
{
return device->driver.start(device->device_context, f);
}
int moberg_device_stop(struct moberg_device *device,
FILE *f)
{
return device->driver.stop(device->device_context, f);
}
......@@ -18,6 +18,7 @@ struct moberg_device_driver {
/* Use-count of device, when it reaches zero, device will be free'd */
int (*up)(struct moberg_device_context *context);
int (*down)(struct moberg_device_context *context);
/* Parse driver dependent parts of config file */
int (*parse_config)(
struct moberg_device_context *device,
......@@ -27,6 +28,15 @@ struct moberg_device_driver {
struct moberg_parser_context *parser,
enum moberg_channel_kind kind,
struct moberg_channel_map *map);
/* Shell commands for starting and stopping */
int (*start)(
struct moberg_device_context *device,
FILE *f);
int (*stop)(
struct moberg_device_context *device,
FILE *f);
};
struct moberg_device;
......@@ -49,5 +59,13 @@ int moberg_device_parse_map(struct moberg_device* device,
int moberg_device_install_channels(struct moberg_device *device,
struct moberg_channel_install *install);
int moberg_device_start(struct moberg_device *device,
FILE *f);
int moberg_device_stop(struct moberg_device *device,
FILE *f);
#endif
......@@ -36,8 +36,7 @@ struct moberg_parser_integer {
struct moberg_parser_token {
enum moberg_parser_token_kind kind;
union {
struct moberg_parser_ident ident;
struct moberg_parser_ident string;
struct moberg_parser_ident idstr;
struct moberg_parser_integer integer;
} u;
};
......
......@@ -44,8 +44,8 @@ static inline int acceptkeyword(context_t *c,
static const void nextsym_ident(context_t *c)
{
c->token.kind = tok_IDENT;
c->token.u.ident.length = 1;
c->token.u.ident.value = c->p;
c->token.u.idstr.length = 1;
c->token.u.idstr.value = c->p;
c->p++;
while (*c->p) {
switch (*c->p) {
......@@ -54,7 +54,7 @@ static const void nextsym_ident(context_t *c)
case '0'...'9':
case '_':
c->p++;
c->token.u.ident.length++;
c->token.u.idstr.length++;
break;
default:
return;
......@@ -77,15 +77,15 @@ static const void nextsym_string(context_t *c)
{
c->token.kind = tok_STRING;
c->p++;
c->token.u.string.value = c->p;
c->token.u.string.length = 0;
c->token.u.idstr.value = c->p;
c->token.u.idstr.length = 0;
while (*c->p && *c->p != '"') {
if (*c->p == '\\') {
c->token.u.string.length++;
c->token.u.idstr.length++;
c->p++;
}
if (*c->p) {
c->token.u.string.length++;
c->token.u.idstr.length++;
c->p++;
}
}
......@@ -235,7 +235,7 @@ int moberg_parser_acceptkeyword(context_t *c,
{
token_t t;
if (peeksym(c, tok_IDENT, &t) &&
strncmp(keyword, t.u.ident.value, t.u.ident.length) == 0) {
strncmp(keyword, t.u.idstr.value, t.u.idstr.length) == 0) {
nextsym(c);
c->expected.n = 0;
return 1;
......@@ -277,11 +277,11 @@ void moberg_parser_failed(
break;
case tok_IDENT:
fprintf(f, "%.*s (<IDENT>)",
c->token.u.ident.length, c->token.u.ident.value);
c->token.u.idstr.length, c->token.u.idstr.value);
break;
case tok_STRING:
fprintf(f, "\"%.*s'\" (<STRING>)",
c->token.u.string.length, c->token.u.string.value);
c->token.u.idstr.length, c->token.u.idstr.value);
break;
}
fprintf(f, "\n%s\n", c->p);
......@@ -375,10 +375,10 @@ static int parse(context_t *c)
if (! acceptsym(c, tok_IDENT, &t)) { goto syntax_err; }
if (! acceptsym(c, tok_RPAREN, NULL)) { goto syntax_err; }
char *name = strndup(t.u.ident.value, t.u.ident.length);
char *name = strndup(t.u.idstr.value, t.u.idstr.length);
if (! name) {
fprintf(stderr, "Failed to allocate driver name '%.*s'\n",
t.u.ident.length, t.u.ident.value);
t.u.idstr.length, t.u.idstr.value);
goto err;
}
device = moberg_device_new(name);
......
......@@ -15,7 +15,13 @@ struct moberg_device_context {
int (*dlclose)(void *dlhandle);
void *dlhandle;
int use_count;
char *device;
char *name;
struct idstr {
struct idstr *next;
struct idstr *prev;
kind_t kind;
char *value;
} modprobe_list, config_list;
};
struct moberg_channel_context {
......@@ -58,6 +64,10 @@ static struct moberg_device_context *new_context(
memset(result, 0, sizeof(*result));
result->dlclose = dlclose;
result->dlhandle = dlhandle;
result->modprobe_list.next = &result->modprobe_list;
result->modprobe_list.prev = &result->modprobe_list;
result->config_list.next = &result->config_list;
result->config_list.prev = &result->config_list;
}
return result;
}
......@@ -74,7 +84,23 @@ static int device_down(struct moberg_device_context *context)
int result = context->use_count;
if (context->use_count <= 0) {
moberg_deferred_action(context->dlclose, context->dlhandle);
free(context->device);
free(context->name);
struct idstr *e;
e = context->modprobe_list.next;
while (e != &context->modprobe_list) {
struct idstr *next = e->next;
free(e->value);
free(e);
e = next;
}
e = context->config_list.next;
while (e != &context->config_list) {
struct idstr *next = e->next;
free(e->value);
free(e);
e = next;
}
free(context);
return 0;
}
......@@ -99,13 +125,12 @@ static int channel_down(struct moberg_channel *channel)
return channel->context->use_count;
}
static void init_channel(
struct moberg_channel *channel,
void *to_free,
struct moberg_channel_context *context,
struct moberg_device_context *device,
enum moberg_channel_kind kind,
union moberg_channel_action action)
static void init_channel(struct moberg_channel *channel,
void *to_free,
struct moberg_channel_context *context,
struct moberg_device_context *device,
enum moberg_channel_kind kind,
union moberg_channel_action action)
{
context->to_free = to_free;
context->device = device;
......@@ -132,10 +157,45 @@ static inline int acceptkeyword(context_t *c,
{
return moberg_parser_acceptkeyword(c, keyword);
}
static int append_modprobe(struct moberg_device_context *device,
token_t token)
{
struct idstr *modprobe = malloc(sizeof(*modprobe));
if (! modprobe) { goto err; }
modprobe->value = strndup(token.u.idstr.value, token.u.idstr.length);
if (! modprobe->value) { goto free_modprobe; }
modprobe->prev = device->modprobe_list.prev;
modprobe->next = modprobe->prev->next;
modprobe->prev->next = modprobe;
modprobe->next->prev = modprobe;
return 1;
free_modprobe:
free(modprobe);
err:
return 0;
}
static int append_config(struct moberg_device_context *device,
token_t token)
{
struct idstr *config = malloc(sizeof(*config));
if (! config) { goto err; }
config->value = strndup(token.u.idstr.value, token.u.idstr.length);
if (! config->value) { goto free_config; }
config->prev = device->config_list.prev;
config->next = config->prev->next;
config->prev->next = config;
config->next->prev = config;
return 1;
free_config:
free(config);
err:
return 0;
}
static int parse_config(
struct moberg_device_context *device,
struct moberg_parser_context *c)
static int parse_config(struct moberg_device_context *device,
struct moberg_parser_context *c)
{
if (! acceptsym(c, tok_LBRACE, NULL)) { goto syntax_err; }
for (;;) {
......@@ -146,15 +206,17 @@ static int parse_config(
if (! acceptsym(c, tok_EQUAL, NULL)) { goto syntax_err; }
if (! acceptsym(c, tok_STRING, &name)) { goto syntax_err; }
if (! acceptsym(c, tok_SEMICOLON, NULL)) { goto syntax_err; }
device->device = strndup(name.u.string.value, name.u.string.length);
device->name = strndup(name.u.idstr.value, name.u.idstr.length);
} else if (acceptkeyword(c, "config")) {
if (! acceptsym(c, tok_EQUAL, NULL)) { goto syntax_err; }
if (! acceptsym(c, tok_LBRACKET, NULL)) { goto syntax_err; }
for (;;) {
token_t config;
if (acceptsym(c, tok_RBRACKET, NULL)) {
break;
} else if (acceptsym(c, tok_IDENT, NULL) ||
acceptsym(c, tok_STRING, NULL)) {
} else if (acceptsym(c, tok_IDENT, &config) ||
acceptsym(c, tok_STRING, &config)) {
append_config(device, config);
} else {
goto syntax_err;
}
......@@ -164,10 +226,12 @@ static int parse_config(
if (! acceptsym(c, tok_EQUAL, NULL)) { goto syntax_err; }
if (! acceptsym(c, tok_LBRACKET, NULL)) { goto syntax_err; }
for (;;) {
token_t modprobe;
if (acceptsym(c, tok_RBRACKET, NULL)) {
break;
} else if (acceptsym(c, tok_IDENT, NULL) ||
acceptsym(c, tok_STRING, NULL)) {
} else if (acceptsym(c, tok_IDENT, &modprobe) ||
acceptsym(c, tok_STRING, &modprobe)) {
append_modprobe(device, modprobe);
} else {
goto syntax_err;
}
......@@ -183,11 +247,10 @@ syntax_err:
return 0;
}
static int parse_map(
struct moberg_device_context *device,
struct moberg_parser_context *c,
enum moberg_channel_kind kind,
struct moberg_channel_map *map)
static int parse_map(struct moberg_device_context *device,
struct moberg_parser_context *c,
enum moberg_channel_kind kind,
struct moberg_channel_map *map)
{
token_t min, max;
......@@ -304,10 +367,49 @@ err:
return 0;
}
static int start(struct moberg_device_context *device,
FILE *f)
{
for (struct idstr *e = device->modprobe_list.next ;
e != &device->modprobe_list ;
e = e->next) {
fprintf(f, "modprobe %s\n", e->value);
}
fprintf(f, "comedi_config %s ", device->name);
int i = 0;
for (struct idstr *e = device->config_list.next ;
e != &device->config_list ;
e = e->next) {
switch (i) {
case 0: fprintf(f, "%s", e->value); break;
case 1: fprintf(f, " %s", e->value); break;
default: fprintf(f, ",%s", e->value); break;
}
i++;
}
fprintf(f, "\n");
return 1;
}
static int stop(struct moberg_device_context *device,
FILE *f)
{
fprintf(f, "comedi_config --remove %s\n", device->name);
for (struct idstr *e = device->modprobe_list.prev ;
e != &device->modprobe_list ;
e = e->prev) {
fprintf(f, "rmmod %s\n", e->value);
}
return 1;
}
struct moberg_device_driver moberg_device_driver = {
.new=new_context,
.up=device_up,
.down=device_down,
.parse_config=parse_config,
.parse_map=parse_map,
.start=start,
.stop=stop
};
......@@ -145,7 +145,7 @@ static int parse_config(
if (! acceptsym(c, tok_EQUAL, NULL)) { goto syntax_err; }
if (! acceptsym(c, tok_STRING, &name)) { goto syntax_err; }
if (! acceptsym(c, tok_SEMICOLON, NULL)) { goto syntax_err; }
device->name = strndup(name.u.string.value, name.u.string.length);
device->name = strndup(name.u.idstr.value, name.u.idstr.length);
} else if (acceptkeyword(c, "baud")) {
token_t baud;
if (! acceptsym(c, tok_EQUAL, NULL)) { goto syntax_err; }
......@@ -275,10 +275,24 @@ syntax_err:
return 0;
}
static int start(struct moberg_device_context *device,
FILE *f)
{
return 1;
}
static int stop(struct moberg_device_context *device,
FILE *f)
{
return 1;
}
struct moberg_device_driver moberg_device_driver = {
.new=new_context,
.up=device_up,
.down=device_down,
.parse_config=parse_config,
.parse_map=parse_map,
.start=start,
.stop=stop
};
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment