Esempio n. 1
0
// constructor - init all HAL pins, params, funct etc here
static int instantiate(const char *name, const int argc, const char**argv)
{
    struct inst_data *ip;

    // allocate a named instance, and some HAL memory for the instance data
    int inst_id = hal_inst_create(name, comp_id,
				  sizeof(struct inst_data),
				  (void **)&ip);
    if (inst_id < 0)
	return -1;

    // here ip is guaranteed to point to a blob of HAL memory of size sizeof(struct inst_data).
    HALERR("inst=%s argc=%d\n", name, argc);
    HALERR("instance parms: repeat=%d prefix='%s'", repeat, prefix);
    HALERR("module parms: answer=%d text='%s'", answer, text);

    // these pins/params/functs will be owned by the instance, and can be separately exited
    int retval = export_halobjs(ip, inst_id, name);

    // unittest: echo instance parameters into observer pins
    if (!retval) {
	*(ip->repeat_value) = repeat;
	*(ip->prefix_len) = strlen(prefix);
    }
    return retval;
}
Esempio n. 2
0
static int instantiate_lutn(const char *name,
			    const int argc,
			    const char**argv)
{
    struct inst_data *ip;
    int i, inst_id;



    if ((inputs < 1) || (inputs > 5)) {
	hal_print_msg(RTAPI_MSG_ERR,
		      "%s: invalid parameter inputs=%d, valid range=1..5",
		      name, inputs);
	return -1;
    }
    if ((function == 0) || (function == -1)) {
	hal_print_msg(RTAPI_MSG_ERR,
		      "%s: function=0x%x does not make sense",
		      name, function);
	return -1;
    }

    if ((inst_id = hal_inst_create(name, comp_id,
				  sizeof(struct inst_data) + inputs * sizeof(hal_bit_t *),
				   (void **)&ip)) < 0)
	return -1;

    hal_print_msg(RTAPI_MSG_DBG,
		  "%s: name='%s' inputs=%d function=0x%x ip=%p",
		  __FUNCTION__, name, inputs, function, ip);
    // record instance params
    ip->inputs = inputs;
    ip->function = function;

    // export per-instance HAL objects
    for (i = 0; i < ip->inputs; i++)
	if (hal_pin_bit_newf(HAL_IN, &(ip->in[i]), inst_id, "%s.in%d", name, i))
	    return -1;
    if (hal_pin_bit_newf(HAL_OUT, &(ip->out), inst_id, "%s.out", name))
	return -1;
   if (hal_export_functf(lutn, ip, 0, 0, inst_id, "%s.funct", name))
	return -1;
    return 0;
}
Esempio n. 3
0
// init HAL objects
static int export_halobjs(struct inst_data *ip, int owner_id, const char *name)
{
    if (rring) {
	// if given, the ring MUST be a stream type
	plug_args_t rargs = {
	    .type = PLUG_READER,
	    .flags = RINGTYPE_STREAM,
	    .ring_name = rring,
	    .owner_name = name
	};
	ip->rplug = halg_plug_new(1, &rargs);
	if (ip->rplug == NULL)
	    return _halerrno;
    }
    if (wring) {
	// this plug accepts any ring type
	plug_args_t wargs = {
	    .type = PLUG_WRITER,
	    .flags = RINGTYPE_ANY,
	    .ring_name = wring,
	    .owner_name = name
	};
	ip->wplug = halg_plug_new(1, &wargs);
	if (ip->wplug == NULL)
	    return _halerrno;
    }

    // exporting '<instname>.funct' as an extended thread function
    // see lutn.c for a discussion of advantages
    hal_export_xfunct_args_t xfunct_args = {
        .type = FS_XTHREADFUNC,
        .funct.x = funct,
        .arg = ip,  // the instance's HAL memory blob
        .uses_fp = 1,
        .reentrant = 0,
        .owner_id = owner_id
    };
    return hal_export_xfunctf(&xfunct_args, "%s.funct", name);
}

// constructor - init all HAL pins, params, funct etc here
static int instantiate(const int argc, const char**argv)
{
    // argv[0]: component name
    const char *name = argv[1]; // instance name
    struct inst_data *ip;

    // allocate a named instance, and some HAL memory for the instance data
    int inst_id = hal_inst_create(name, comp_id,
				  sizeof(struct inst_data),
				  (void **)&ip);
    if (inst_id < 0)
	return -1;

    // here ip is guaranteed to point to a blob of HAL memory
    // of size sizeof(struct inst_data).
    HALDBG("inst=%s argc=%d\n", name, argc);
    HALDBG("instance parms: rring=%s wring=%s", rring, wring);

    // these pins/params/functs will be owned by the instance,
    // and can be separately exited 'halcmd delinst <instancename>'
    int retval = export_halobjs(ip, inst_id, name);
    return retval;
}

// custom destructor
// pins, params, and functs are automatically deallocated by hal_exit(comp_id)
// regardless if a destructor is used or not (see below), so usually it is not
// needed
//
// however, some objects like vtables, rings, threads, signals are not owned by
// a component, hence cannot be automatically exited by hal_exit() even if desired
//
// interaction with such objects may require a custom destructor like below for
// cleanup actions

// NB: if a customer destructor is used, it is called
// - after the instance's functs have been removed from their respective threads
//   (so a thread funct call cannot interact with the destructor any more)
// - any pins,  params and plugs of this instance are still intact when the destructor is
//   called, and they are automatically destroyed by the HAL library once the
//   destructor returns
static int delete(const char *name, void *inst, const int inst_size)
{

    HALDBG("inst=%s size=%d %p\n", name, inst_size, inst);
    return 0;
}

int rtapi_app_main(void)
{
    comp_id = hal_xinit(TYPE_RT, 0, 0, instantiate, delete, compname);
    if (comp_id < 0)
	return comp_id;
    hal_ready(comp_id);
    return 0;
}
Esempio n. 4
0
int rtapi_app_main(void)
{
    int retval;
    dlist_init_entry(&head);

    if ((comp_id = hal_xinit(TYPE_RT, 0, 0,
			     instantiate_encoder_pair,
			     delete_encoder_pair,
			     compname)) < 0)
	return comp_id;

    hal_export_xfunct_args_t u = {
        .type = FS_XTHREADFUNC,
        .funct.x = update,
        .arg = &head,
        .uses_fp = 1,
        .reentrant = 0,
        .owner_id = comp_id
    };
    if ((retval = hal_export_xfunctf(&u, "%s.update",
				     prefix)) < 0)
	return retval;

    hal_export_xfunct_args_t mp = {
        .type = FS_XTHREADFUNC,
        .funct.x = sample,
        .arg = &head,
        .uses_fp = 0,
        .reentrant = 0,
        .owner_id = comp_id
    };
    if ((retval = hal_export_xfunctf(&mp, "%s.sample",
				     prefix)) < 0)
	return retval;
    hal_ready(comp_id);
    return 0;
}


void rtapi_app_exit(void)
{
    hal_exit(comp_id);
}

static int instantiate_encoder_pair(const int argc, const char**argv)
{
    encoder_pair_t *p;
    int retval;
    int msg;
    const char* name;
    
    if(argc >= 2)
        name = argv[1];
    else
        HALFAIL_RC(EINVAL, "ERROR: insufficient args in argv");
    
    /* This function exports a lot of stuff, which results in a lot of
       logging if msg_level is at INFO or ALL. So we save the current value
       of msg_level and restore it later. */
    msg = rtapi_get_msg_level();

#ifndef  VERBOSE_SETUP
    rtapi_set_msg_level(RTAPI_MSG_WARN);
#endif

    if ((retval = hal_inst_create(name, comp_id, sizeof(encoder_pair_t), (void **)&p)) < 0)
	return retval;

    p->inst_id = retval;
    if ((retval = export_encoder_pair(name, p->inst_id, p)) != 0)
	HALFAIL_RC(retval, "%s: ERROR: export(%s) failed", compname, name);

    // append to instance list
    dlist_init_entry(&p->list);
    dlist_add_after(&p->list, &head);

    /* restore saved message level */
    rtapi_set_msg_level(msg);
    return 0;
}
Esempio n. 5
0
static int instantiate_interpolate(const int argc, const char **argv)
{
    const char *name = argv[1];
    struct inst_data *ip;
    int inst_id, i;

    if ((inst_id = hal_inst_create(name, comp_id,
				   sizeof(struct inst_data) +
				   count * sizeof(struct joint),
				   (void **)&ip)) < 0)
	return -1;

    // instance-level values
    ip->count = count;

    // attach the command ringbuffer '<instancename>.traj' if it exists
    // must be record mode
    unsigned flags;
    if (!hal_ring_attachf(&(ip->traj), &flags,  "%s.traj", name)) {
		if ((flags & RINGTYPE_MASK) != RINGTYPE_RECORD) {
		    HALERR("ring %s.traj not a record mode ring: mode=%d",name, flags & RINGTYPE_MASK);
		    return -EINVAL;
		}
		ip->traj.header->reader = inst_id; // we're the reader - advisory
    } else {
		HALERR("ring %s.traj does not exist", name);
		return -EINVAL;
    }

    // per-instance objects
    if (hal_pin_s32_newf(HAL_OUT, &(ip->serial), inst_id, "%s.serial", name) ||
		hal_pin_u32_newf(HAL_IN, &(ip->degree), inst_id, "%s.degree", name) ||
		hal_pin_bit_newf(HAL_IN, &(ip->jitter_correct), inst_id, "%s.jitter-correct", name) ||
		hal_pin_float_newf(HAL_IN, &(ip->epsilon), inst_id, "%s.epsilon", name) ||
		hal_pin_float_newf(HAL_OUT, &(ip->duration), inst_id, "%s.duration", name) ||
		hal_pin_float_newf(HAL_OUT, &(ip->progress), inst_id, "%s.progress", name))
		return -1;
    *(ip->serial) = 0;
    *(ip->degree) = 1;
    *(ip->jitter_correct) = 0;
    *(ip->epsilon) = 0;
    *(ip->duration) = 0;
    *(ip->progress) = 0;
    ip->time_from_start = 0;
    // per-joint objects
    for (i = 0; i < ip->count; i++) {
		struct joint *jp = &ip->joints[i];
		if (hal_pin_float_newf(HAL_OUT, &(jp->end_pos), inst_id, "%s.%d.end-pos", name, i) ||
		    hal_pin_float_newf(HAL_OUT, &(jp->end_vel), inst_id, "%s.%d.end-vel", name, i) ||
		    hal_pin_float_newf(HAL_OUT, &(jp->end_acc), inst_id, "%s.%d.end-acc", name, i) ||
		    hal_pin_float_newf(HAL_OUT, &(jp->curr_pos), inst_id, "%s.%d.curr-pos", name, i) ||
		    hal_pin_float_newf(HAL_OUT, &(jp->curr_vel), inst_id, "%s.%d.curr-vel", name, i) ||
		    hal_pin_float_newf(HAL_OUT, &(jp->curr_acc), inst_id, "%s.%d.curr-acc", name, i) ||
			hal_pin_bit_newf(HAL_OUT, &(jp->traj_busy), inst_id, "%s.%d.traj-busy", name, i))
		    return -1;
        // set all pin values to zero
        *(jp->end_pos) = 0;
        *(jp->end_vel) = 0;
        *(jp->end_acc) = 0;
        *(jp->curr_pos) = 0;
        *(jp->curr_vel) = 0;
        *(jp->curr_acc) = 0;
		*(jp->traj_busy) = false;
    }
    hal_export_xfunct_args_t xfunct_args = {
        .type = FS_XTHREADFUNC,
        .funct.x = update,
        .arg = ip,
        .uses_fp = 0,
        .reentrant = 0,
        .owner_id = inst_id
    };
    return hal_export_xfunctf(&xfunct_args, "%s.update", name);
}

static int delete_interpolate(const char *name, void *inst, const int inst_size)
{

    struct inst_data *ip = (struct inst_data *) inst;
    int retval;

    if (ringbuffer_attached(&ip->traj)) {
	if ((retval = hal_ring_detach(&ip->traj)) < 0) {
	    rtapi_print_msg(RTAPI_MSG_ERR,
			    "%s: hal_ring_detach(%s.traj) failed: %d\n",
			    compname, name, retval);
	    return retval;
	}
	ip->traj.header->reader = 0;
    }
    return 0;
}

int rtapi_app_main(void)
{
    comp_id = hal_xinit(TYPE_RT, 0, 0,
			(hal_constructor_t)instantiate_interpolate,
			delete_interpolate,
			compname);
    if (comp_id < 0)
	return comp_id;
    hal_ready(comp_id);
    return 0;
}
Esempio n. 6
0
// init HAL objects
static int export_halobjs(struct inst_data *ip, int owner_id, const char *name)
{
    if (hal_pin_float_newf(HAL_OUT, &ip->out, owner_id, "%s.out", name))
        return -1;
    if (hal_pin_float_newf(HAL_IN,  &ip->in,  owner_id, "%s.in", name))
        return -1;
    if (hal_param_s32_newf(HAL_RO,  &ip->iter,owner_id, "%s.iter", name))
        return -1;

    // unittest observer pins, per instance
    if (hal_pin_s32_newf(HAL_OUT, &ip->repeat_value, owner_id, "%s.repeat_value", name))
        return -1;
    if (hal_pin_s32_newf(HAL_OUT, &ip->prefix_len, owner_id, "%s.prefix_len", name))
        return -1;

    // exporting '<instname>.funct' as an extended thread function
    // see lutn.c for a discussion of advantages
    hal_export_xfunct_args_t xfunct_args = {
        .type = FS_XTHREADFUNC,
        .funct.x = funct,
        .arg = ip,  // the instance's HAL memory blob
        .uses_fp = 1,
        .reentrant = 0,
        .owner_id = owner_id
    };
    return hal_export_xfunctf(&xfunct_args, "%s.funct", name);
}

// constructor - init all HAL pins, params, funct etc here
static int instantiate(const int argc, const char**argv)
{
    // argv[0]: component name
    const char *name = argv[1]; // instance name
    struct inst_data *ip;

    // allocate a named instance, and some HAL memory for the instance data
    int inst_id = hal_inst_create(name, comp_id,
                                  sizeof(struct inst_data),
                                  (void **)&ip);
    if (inst_id < 0)
        return -1;

    // here ip is guaranteed to point to a blob of HAL memory
    // of size sizeof(struct inst_data).
    HALINFO("inst=%s argc=%d\n", name, argc);
    HALINFO("instance parms: repeat=%d prefix='%s'", repeat, prefix);
    HALINFO("module parms: answer=%d text='%s'", answer, text);

    // example - parse newinst arguments getopt-style:
    // straight from: http://www.informit.com/articles/article.aspx?p=175771&seqNum=3

    int do_all, do_help, do_verbose;    /* flag variables */
    char *myfile;
    struct option longopts[] = {
        { "all",     no_argument,       & do_all,     1   },
        { "file",    required_argument, NULL,         'f' },
        { "help",    no_argument,       & do_help,    1   },
        { "verbose", no_argument,       & do_verbose, 1   },
        { 0, 0, 0, 0 }
    };
    int c;
    while ((c = getopt_long(argc, argv, ":f:", longopts, NULL)) != -1) {
        switch (c) {
        case 'f':
            myfile = optarg;
            break;
        case 0:     // getopt_long() set a variable, just keep going
            break;
        case ':':   // missing option argument
            HALERR("%s: option `-%c' requires an argument\n",
                   argv[1], optopt);
            break;
        case '?':
        default:    // invalid option
            HALERR("%s: option `-%c' is invalid, ignored",
                   argv[1], optopt);
            break;
        }
    }
    HALINFO("do_all=%d do_help=%d do_verbose=%d myfile=%s",
            do_all, do_help, do_verbose, myfile);

    // these pins/params/functs will be owned by the instance,
    // and can be separately exited via 'halcmd delinst <instancename>'
    int retval = export_halobjs(ip, inst_id, name);

    // unittest: echo instance parameters into observer pins
    if (!retval) {
        *(ip->repeat_value) = repeat;
        *(ip->prefix_len) = strlen(prefix);
    }
    return retval;
}

// custom destructor
// pins, params, and functs are automatically deallocated by hal_exit(comp_id)
// regardless if a destructor is used or not (see below), so usually it is not
// needed
//
// however, some objects like vtables, rings, threads, signals are not owned by
// a component, hence cannot be automatically exited by hal_exit() even if desired
//
// interaction with such objects may require a custom destructor like below for
// cleanup actions

// NB: if a customer destructor is used, it is called
// - after the instance's functs have been removed from their respective threads
//   (so a thread funct call cannot interact with the destructor any more)
// - any pins and params of this instance are still intact when the destructor is
//   called, and they are automatically destroyed by the HAL library once the
//   destructor returns
static int delete(const char *name, void *inst, const int inst_size)
{

    HALERR("inst=%s size=%d %p\n", name, inst_size, inst);
    HALERR("instance parms: repeat=%d prefix='%s'", repeat, prefix);
    HALERR("module parms: answer=%d text='%s'", answer, text);

    return 0;
}

int rtapi_app_main(void)
{

    HALERR("instance parms: repeat=%d prefix='%s'", repeat, prefix);
    HALERR("module parms: answer=%d text='%s'", answer, text);

    // to use default destructor, use NULL instead of delete
    comp_id = hal_xinit(TYPE_RT, 0, 0, instantiate, delete, compname);
    if (comp_id < 0)
        return comp_id;
#if 0
    // this is how an 'instance' would have been done in the legacy way
    struct inst_data *ip = hal_malloc(sizeof(struct inst_data));
    // these pins/params/functs will be owned by the component
    // NB: this 'instance' cannot be exited, and no new one created on the fly
    if (export_halobjs(ip, comp_id, "foo"))
        return -1;
#endif
    // unittest only, see nosetests/unittest_instbindings.py and
    //    nosetests/unittest_icomp.py
    // purpose: echo module params into observer pins
    // (cant set pins to strings, so just echo the string length)
    if ((cd = export_observer_pins(comp_id, compname)) == NULL)
        return -1;
    *(cd->answer_value) = answer;
    *(cd->text_len) = strlen(text);

    hal_ready(comp_id);
    return 0;
}