Ejemplo 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;
}
Ejemplo n.º 2
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;
}
Ejemplo n.º 3
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;
}