コード例 #1
0
ファイル: hal_memory.c プロジェクト: ArcEye/machinekit
// part of public API
void *halg_malloc(const int use_hal_mutex, size_t size)
{
    PCHECK_NULL(hal_data);
    {
        WITH_HAL_MUTEX_IF(use_hal_mutex);

	void *retval = shmalloc_rt(size);
	if (retval == NULL)
	    HALERR("out of rt memory - allocating %zu bytes", size);

	hal_data->hal_malloced += size; // beancounting
	return retval;
    }
}
コード例 #2
0
ファイル: hal_comp.c プロジェクト: 13788593535/machinekit
// use only for owner_ids of pins, params or functs
// may return NULL if buggy using code
hal_comp_t *halpr_find_owning_comp(const int owner_id)
{
    hal_comp_t *comp = halpr_find_comp_by_id(owner_id);
    if (comp != NULL)
	return comp;  // legacy case: the owner_id refers to a comp

    // nope, so it better be an instance
    hal_inst_t *inst = halpr_find_inst_by_id(owner_id);
    if (inst == NULL) {
	HALERR("BUG: owner_id %d refers neither to a hal_comp_t nor an hal_inst_t",
	       owner_id);
	return NULL;
    }

    // found the instance. Retrieve its owning comp:
    comp =  halpr_find_comp_by_id(inst->comp_id);
    if (comp == NULL) {
	// really bad. an instance which has no owning comp?
	HALERR("BUG: instance %s/%d's comp_id %d refers to a non-existant comp",
	       inst->name, inst->inst_id, inst->comp_id);
    }
    return comp;
}
コード例 #3
0
ファイル: hal_comp.c プロジェクト: 13788593535/machinekit
// instantiation handlers
static int create_instance(const hal_funct_args_t *fa)
{
    const int argc = fa_argc(fa);
    const char **argv = fa_argv(fa);

#if 0
    HALDBG("'%s' called, arg=%p argc=%d",
	   fa_funct_name(fa), fa_arg(fa), argc);
    int i;
    for (i = 0; i < argc; i++)
	HALDBG("    argv[%d] = \"%s\"", i,argv[i]);
#endif

    if (argc < 2) {
	HALERR("need component name and instance name");
	return -EINVAL;
    }
    const char *cname = argv[0];
    const char *iname = argv[1];

    hal_comp_t *comp = halpr_find_comp_by_name(cname);
    if (!comp) {
	HALERR("no such component '%s'", cname);
	return -EINVAL;
    }
    if (!comp->ctor) {
	HALERR("component '%s' not instantiable", cname);
	return -EINVAL;
    }
    hal_inst_t *inst = halpr_find_inst_by_name(iname);
    if (inst) {
	HALERR("instance '%s' already exists", iname);
	return -EBUSY;
    }
    return comp->ctor(iname, argc - 2, &argv[2]);
}
コード例 #4
0
ファイル: hal_comp.c プロジェクト: 13788593535/machinekit
static int delete_instance(const hal_funct_args_t *fa)
{
    const int argc = fa_argc(fa);
    const char **argv = fa_argv(fa);

    HALDBG("'%s' called, arg=%p argc=%d",
	   fa_funct_name(fa), fa_arg(fa), argc);
    int i;
    for (i = 0; i < argc; i++)
	HALDBG("    argv[%d] = \"%s\"", i, argv[i]);
    if (argc < 1) {
	HALERR("no instance name given");
	return -EINVAL;
    }
    return hal_inst_delete(argv[0]);
}
コード例 #5
0
ファイル: hal_memory.c プロジェクト: ArcEye/machinekit
int hal_heap_addmem(size_t click)
{
    size_t actual = RTAPI_ALIGN(click, RTAPI_CACHELINE);

    HALDBG("extending arena by %zu bytes", actual);

    if (hal_freemem() < HAL_HEAP_MINFREE) {
	HALERR("can't extend arena - below minfree: %zu", hal_freemem());
	return 0;
    }

    if (rtapi_heap_addmem(&hal_data->heap,
			  SHMPTR(hal_data->shmem_bot),
			  actual)) {
	HALFAIL_RC(ENOMEM, "rtapi_heap_addmem(%zu) failed", actual);
    }
    hal_data->shmem_bot += actual;
    return 0;
}
コード例 #6
0
int hal_inst_delete(const char *name)
{
    CHECK_HALDATA();
    CHECK_STR(name);

    {
	hal_inst_t *inst  __attribute__((cleanup(halpr_autorelease_mutex)));
	rtapi_mutex_get(&(hal_data->mutex));

	// inst must exist
	if ((inst = halpr_find_inst_by_name(name)) == NULL) {
	    HALERR("instance '%s' does not exist", name);
	    return -ENOENT;
	}
	// this does most of the heavy lifting
	free_inst_struct(inst);
    }
    return 0;
}
コード例 #7
0
ファイル: hal_comp.c プロジェクト: 13788593535/machinekit
int hal_xinitf(const int type,
	       const int userarg1,
	       const int userarg2,
	       const hal_constructor_t ctor,
	       const hal_destructor_t dtor,
	       const char *fmt, ...)
{
    va_list ap;
    char hal_name[HAL_NAME_LEN + 1];

    CHECK_NULL(fmt);
    va_start(ap, fmt);
    int sz = rtapi_vsnprintf(hal_name, sizeof(hal_name), fmt, ap);
    if(sz == -1 || sz > HAL_NAME_LEN) {
        HALERR("invalid length %d for name starting with '%s'",
	       sz, hal_name);
        return -EINVAL;
    }
    return hal_xinit(type, userarg1, userarg2, ctor, dtor, hal_name);
}
コード例 #8
0
ファイル: hal_memory.c プロジェクト: ArcEye/machinekit-arceye
// part of public API
void *hal_malloc(long int size)
{
    void *retval;

    if (hal_data == 0) {
        HALERR("hal_malloc called before init");
        return 0;
    }
    /* get the mutex */
    rtapi_mutex_get(&(hal_data->mutex));
    /* allocate memory */
    retval = shmalloc_up(size);
    /* release the mutex */
    rtapi_mutex_give(&(hal_data->mutex));
    /* check return value */
    if (retval == 0) {
        HALDBG("hal_malloc() can't allocate %ld bytes", size);
    }
    return retval;
}
コード例 #9
0
ファイル: icomp.c プロジェクト: ArcEye/MK-Qt5
// 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;
}
コード例 #10
0
ファイル: hal_comp.c プロジェクト: 13788593535/machinekit
int hal_xinit(const int type,
	      const int userarg1,
	      const int userarg2,
	      const hal_constructor_t ctor,
	      const hal_destructor_t dtor,
	      const char *name)
{
    int comp_id, retval;

    rtapi_set_logtag("hal_lib");
    CHECK_STRLEN(name, HAL_NAME_LEN);

    // sanity: these must have been inited before by the
    // respective rtapi.so/.ko module
    CHECK_NULL(rtapi_switch);

    if ((dtor != NULL) && (ctor == NULL)) {
	HALERR("component '%s': NULL constructor doesnt make"
	       " sense with non-NULL destructor", name);
	return -EINVAL;
    }

    // RTAPI initialisation already done
    HALDBG("initializing component '%s' type=%d arg1=%d arg2=%d/0x%x",
	   name, type, userarg1, userarg2, userarg2);

    if ((lib_module_id < 0) && (type != TYPE_HALLIB)) {
	// if hal_lib not inited yet, do so now - recurse
#ifdef RTAPI
	retval = hal_xinit(TYPE_HALLIB, 0, 0, NULL, NULL, "hal_lib");
#else
	retval = hal_xinitf(TYPE_HALLIB, 0, 0, NULL, NULL, "hal_lib%ld",
			    (long) getpid());
#endif
	if (retval < 0)
	    return retval;
    }

    // tag message origin field since ulapi autoload re-tagged them temporarily
    rtapi_set_logtag("hal_lib");

    /* copy name to local vars, truncating if needed */
    char rtapi_name[RTAPI_NAME_LEN + 1];
    char hal_name[HAL_NAME_LEN + 1];

    rtapi_snprintf(hal_name, sizeof(hal_name), "%s", name);
    rtapi_snprintf(rtapi_name, RTAPI_NAME_LEN, "HAL_%s", hal_name);

    /* do RTAPI init */
    comp_id = rtapi_init(rtapi_name);
    if (comp_id < 0) {
	HALERR("rtapi init(%s) failed", rtapi_name);
	return -EINVAL;
    }

    // recursing? init HAL shm
    if ((lib_module_id < 0) && (type == TYPE_HALLIB)) {
	// recursion case, we're initing hal_lib

	// get HAL shared memory from RTAPI
	int shm_id = rtapi_shmem_new(HAL_KEY,
				     comp_id,
				     global_data->hal_size);
	if (shm_id < 0) {
	    HALERR("hal_lib:%d failed to allocate HAL shm %x, rc=%d",
		   comp_id, HAL_KEY, shm_id);
	    rtapi_exit(comp_id);
	    return -EINVAL;
	}
	// retrieve address of HAL shared memory segment
	void *mem;
	retval = rtapi_shmem_getptr(shm_id, &mem, 0);
	if (retval < 0) {
	    HALERR("hal_lib:%d failed to acquire HAL shm %x, id=%d rc=%d",
		   comp_id, HAL_KEY, shm_id, retval);
	    rtapi_exit(comp_id);
	    return -EINVAL;
	}
	// set up internal pointers to shared mem and data structure
	hal_shmem_base = (char *) mem;
	hal_data = (hal_data_t *) mem;

#ifdef RTAPI
	// only on RTAPI hal_lib initialization:
	// initialize up the HAL shm segment
	retval = init_hal_data();
	if (retval) {
	    HALERR("could not init HAL shared memory rc=%d", retval);
	    rtapi_exit(lib_module_id);
	    lib_module_id = -1;
	    return -EINVAL;
	}
	retval = hal_proc_init();
	if (retval) {
	    HALERR("could not init /proc files");
	    rtapi_exit(lib_module_id);
	    lib_module_id = -1;
	    return -EINVAL;
	}
#endif
	// record hal_lib comp_id
	lib_module_id = comp_id;
	// and the HAL shm segmed id
	lib_mem_id = shm_id;

    }
    // global_data MUST be at hand now:
    HAL_ASSERT(global_data != NULL);

    // paranoia
    HAL_ASSERT(hal_shmem_base != NULL);
    HAL_ASSERT(hal_data != NULL);
    HAL_ASSERT(lib_module_id > -1);
    HAL_ASSERT(lib_mem_id > -1);
    if (lib_module_id < 0) {
	HALERR("giving up");
	return -EINVAL;
    }

    {
	hal_comp_t *comp  __attribute__((cleanup(halpr_autorelease_mutex)));

	/* get mutex before manipulating the shared data */
	rtapi_mutex_get(&(hal_data->mutex));
	/* make sure name is unique in the system */
	if (halpr_find_comp_by_name(hal_name) != 0) {
	    /* a component with this name already exists */
	    HALERR("duplicate component name '%s'", hal_name);
	    rtapi_exit(comp_id);
	    return -EINVAL;
	}
	/* allocate a new component structure */
	comp = halpr_alloc_comp_struct();
	if (comp == 0) {
	    HALERR("insufficient memory for component '%s'", hal_name);
	    rtapi_exit(comp_id);
	    return -ENOMEM;
	}

	/* initialize the comp structure */
	comp->userarg1 = userarg1;
	comp->userarg2 = userarg2;
	comp->comp_id = comp_id;
	comp->type = type;
	comp->ctor = ctor;
	comp->dtor = dtor;
#ifdef RTAPI
	comp->pid = 0;
#else /* ULAPI */
	// a remote component starts out disowned
	comp->pid = comp->type == TYPE_REMOTE ? 0 : getpid();
#endif
	comp->state = COMP_INITIALIZING;
	comp->last_update = 0;
	comp->last_bound = 0;
	comp->last_unbound = 0;
	comp->shmem_base = hal_shmem_base;
	comp->insmod_args = 0;
	rtapi_snprintf(comp->name, sizeof(comp->name), "%s", hal_name);
	/* insert new structure at head of list */
	comp->next_ptr = hal_data->comp_list_ptr;
	hal_data->comp_list_ptr = SHMOFF(comp);

    }
    // scope exited - mutex released

    // finish hal_lib initialisation
    // in ULAPI this will happen after the recursion on hal_lib%d unwinds

    if (type == TYPE_HALLIB) {
#ifdef RTAPI
	// only on RTAPI hal_lib initialization:
	// export the instantiation support userfuncts
	hal_export_xfunct_args_t ni = {
	    .type = FS_USERLAND,
	    .funct.u = create_instance,
	    .arg = NULL,
	    .owner_id = lib_module_id
	};
	if ((retval = hal_export_xfunctf( &ni, "newinst")) < 0)
	    return retval;

	hal_export_xfunct_args_t di = {
	    .type = FS_USERLAND,
	    .funct.u = delete_instance,
	    .arg = NULL,
	    .owner_id = lib_module_id
	};
	if ((retval = hal_export_xfunctf( &di, "delinst")) < 0)
	    return retval;
#endif
	retval = hal_ready(lib_module_id);
	if (retval)
	    HALERR("hal_ready(%d) failed rc=%d", lib_module_id, retval);
	else
	    HALDBG("%s initialization complete", hal_name);
	return retval;
    }

    HALDBG("%s component '%s' id=%d initialized%s",
	   (ctor != NULL) ? "instantiable" : "legacy",
	   hal_name, comp_id,
	   (dtor != NULL) ? ", has destructor" : "");
    return comp_id;
}


int hal_exit(int comp_id)
{
    int *prev, next, comptype;
    char name[HAL_NAME_LEN + 1];

    CHECK_HALDATA();

    HALDBG("removing component %d", comp_id);

    {
	hal_comp_t *comp  __attribute__((cleanup(halpr_autorelease_mutex)));

	/* grab mutex before manipulating list */
	rtapi_mutex_get(&(hal_data->mutex));
	/* search component list for 'comp_id' */
	prev = &(hal_data->comp_list_ptr);
	next = *prev;
	if (next == 0) {
	    /* list is empty - should never happen, but... */
	    HALERR("no components defined");
	    return -EINVAL;
	}
	comp = SHMPTR(next);
	while (comp->comp_id != comp_id) {
	    /* not a match, try the next one */
	    prev = &(comp->next_ptr);
	    next = *prev;
	    if (next == 0) {
		/* reached end of list without finding component */
		HALERR("no such component with id %d", comp_id);
		return -EINVAL;
	    }
	    comp = SHMPTR(next);
	}

	// record type, since we're about to zap the comp in free_comp_struct()
	comptype = comp->type;

	/* save component name for later */
	rtapi_snprintf(name, sizeof(name), "%s", comp->name);
	/* get rid of the component */
	free_comp_struct(comp);

	// unlink the comp only now as free_comp_struct() must
	// determine ownership of pins/params/functs and this
	// requires access to the current comp, too
	// since this is all under lock it should not matter
	*prev = comp->next_ptr;

	// add it to free list
	comp->next_ptr = hal_data->comp_free_ptr;
	hal_data->comp_free_ptr = SHMOFF(comp);

	// scope exit - mutex released
    }

    // if unloading the hal_lib component, destroy HAL shm
    if (comptype == TYPE_HALLIB) {
	int retval;

	/* release RTAPI resources */
	retval = rtapi_shmem_delete(lib_mem_id, comp_id);
	if (retval) {
	    HALERR("rtapi_shmem_delete(%d,%d) failed: %d",
		   lib_mem_id, comp_id, retval);
	}
	// HAL shm is history, take note ASAP
	lib_mem_id = -1;
	hal_shmem_base = NULL;
	hal_data = NULL;;

	retval = rtapi_exit(comp_id);
	if (retval) {
	    HALERR("rtapi_exit(%d) failed: %d",
		   lib_module_id, retval);
	}
	// the hal_lib RTAPI module is history, too
	// in theory we'd be back to square 1
	lib_module_id = -1;

    } else {
	// the standard case
	rtapi_exit(comp_id);
    }

    //HALDBG("component '%s' id=%d removed", name, comp_id);
    return 0;
}
コード例 #11
0
ファイル: hal_ring.c プロジェクト: 13788593535/machinekit
int hal_ring_delete(const char *name)
{
    int retval;

    CHECK_HALDATA();
    CHECK_STRLEN(name, HAL_NAME_LEN);
    CHECK_LOCK(HAL_LOCK_LOAD);

    {
	hal_ring_t *hrptr __attribute__((cleanup(halpr_autorelease_mutex)));
	rtapi_mutex_get(&(hal_data->mutex));

	// ring must exist
	if ((hrptr = halpr_find_ring_by_name(name)) == NULL) {
	    HALERR("ring '%s' not found", name);
	    return -ENOENT;
	}

	ringheader_t *rhptr;
	int shmid = -1;

	if (hrptr->flags & ALLOC_HALMEM) {
	    // ring exists as HAL memory.
	    rhptr = SHMPTR(hrptr->ring_offset);
	} else {
	    // ring exists as shm segment. Retrieve shared memory address.
	    if ((shmid = rtapi_shmem_new_inst(hrptr->ring_shmkey,
					      rtapi_instance, lib_module_id,
					      0 )) < 0) {
		if (shmid != -EEXIST)  {
		    HALERR("ring '%s': rtapi_shmem_new_inst() failed %d",
			   name, shmid);
		    return shmid;
		}
	    }
	    if ((retval = rtapi_shmem_getptr(shmid, (void **)&rhptr, 0))) {
		HALERR("ring '%s': rtapi_shmem_getptr %d failed %d",
		       name, shmid, retval);
		return -ENOMEM;
	    }
	}
	// assure attach/detach balance is zero:
	if (rhptr->refcount) {
	    HALERR("ring '%s' still attached - refcount=%d",
		   name, rhptr->refcount);
	    return -EBUSY;
	}

	HALDBG("deleting ring '%s'", name);
	if (hrptr->flags & ALLOC_HALMEM) {
	    ; // if there were a HAL memory free function, call it here
	} else {
	    if ((retval = rtapi_shmem_delete(shmid, lib_module_id)) < 0)  {
		HALERR("ring '%s': rtapi_shmem_delete(%d,%d) failed: %d",
		       name, shmid, lib_module_id, retval);
		return retval;
	    }
	}
	// search for the ring (again..)
	int *prev = &(hal_data->ring_list_ptr);
	int next = *prev;
	while (next != 0) {
	    hrptr = SHMPTR(next);
	    if (strcmp(hrptr->name, name) == 0) {
		// this is the right ring
		// unlink from list
		*prev = hrptr->next_ptr;
		// and delete it, linking it on the free list
		free_ring_struct(hrptr);
		return 0;
	    }
	    // no match, try the next one
	    prev = &(hrptr->next_ptr);
	    next = *prev;
	}

	HALERR("BUG: deleting ring '%s'; not found in ring_list?",
	       name);
	return -ENOENT;
    }

}
コード例 #12
0
ファイル: interpolate.c プロジェクト: ftkalcevic/machinekit
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;
}
コード例 #13
0
ファイル: hal_funct.c プロジェクト: ArcEye/MK-Qt5
static int hal_export_xfunctfv(const hal_export_xfunct_args_t *xf, const char *fmt, va_list ap)
{
    int *prev, next, cmp, sz;
    hal_funct_t *nf, *fptr;
    char name[HAL_NAME_LEN + 1];

    CHECK_HALDATA();
    CHECK_LOCK(HAL_LOCK_LOAD);

    sz = rtapi_vsnprintf(name, sizeof(name), fmt, ap);
    if(sz == -1 || sz > HAL_NAME_LEN) {
        HALERR("length %d invalid for name starting '%s'", sz, name);
        return -ENOMEM;
    }

    HALDBG("exporting function '%s' type %d", name, xf->type);
    {
	hal_comp_t *comp  __attribute__((cleanup(halpr_autorelease_mutex)));

	/* get mutex before accessing shared data */
	rtapi_mutex_get(&(hal_data->mutex));

	comp = halpr_find_owning_comp(xf->owner_id);
	if (comp == 0) {
	    /* bad comp_id */
	    HALERR("funct '%s': owning component %d not found",
		   name, xf->owner_id);
	    return -EINVAL;
	}

	if (comp->type == TYPE_USER) {
	    /* not a realtime component */
	    HALERR("funct '%s': component %s/%d is not realtime (%d)",
		   name, comp->name, comp->comp_id, comp->type);
	    return -EINVAL;
	}

	bool legacy = (halpr_find_inst_by_id(xf->owner_id) == NULL);

	// instances may export functs post hal_ready
	if (legacy && (comp->state > COMP_INITIALIZING)) {
	    HALERR("funct '%s': called after hal_ready", name);
	    return -EINVAL;
	}
	/* allocate a new function structure */
	nf = alloc_funct_struct();
	if (nf == 0)
	    NOMEM("function '%s'", name);

	/* initialize the structure */
	nf->uses_fp = xf->uses_fp;
	nf->owner_id = xf->owner_id;
	nf->reentrant = xf->reentrant;
	nf->users = 0;
	nf->handle = rtapi_next_handle();
	nf->arg = xf->arg;
	nf->type = xf->type;
	nf->funct.l = xf->funct.l; // a bit of a cheat really
	rtapi_snprintf(nf->name, sizeof(nf->name), "%s", name);
	/* search list for 'name' and insert new structure */
	prev = &(hal_data->funct_list_ptr);
	next = *prev;
	while (1) {
	    if (next == 0) {
		/* reached end of list, insert here */
		nf->next_ptr = next;
		*prev = SHMOFF(nf);
		/* break out of loop and init the new function */
		break;
	    }
	    fptr = SHMPTR(next);
	    cmp = strcmp(fptr->name, nf->name);
	    if (cmp > 0) {
		/* found the right place for it, insert here */
		nf->next_ptr = next;
		*prev = SHMOFF(nf);
		/* break out of loop and init the new function */
		break;
	    }
	    if (cmp == 0) {
		/* name already in list, can't insert */
		free_funct_struct(nf);
		HALERR("duplicate function '%s'", name);
		return -EINVAL;
	    }
	    /* didn't find it yet, look at next one */
	    prev = &(fptr->next_ptr);
	    next = *prev;
	}
	// at this point we have a new function and can
	// yield the mutex by scope exit

    }
    /* init time logging variables */
    nf->runtime = 0;
    nf->maxtime = 0;
    nf->maxtime_increased = 0;

    /* at this point we have a new function and can yield the mutex */
    rtapi_mutex_give(&(hal_data->mutex));

    switch (xf->type) {
    case FS_LEGACY_THREADFUNC:
    case FS_XTHREADFUNC:
	/* create a pin with the function's runtime in it */
	if (hal_pin_s32_newf(HAL_OUT, &(nf->runtime), xf->owner_id, "%s.time",name)) {
	    HALERR("failed to create pin '%s.time'", name);
	    return -EINVAL;
	}
	*(nf->runtime) = 0;

	/* note that failure to successfully create the following params
	   does not cause the "export_funct()" call to fail - they are
	   for debugging and testing use only */
	/* create a parameter with the function's maximum runtime in it */
	nf->maxtime = 0;
	hal_param_s32_newf(HAL_RW,  &(nf->maxtime), xf->owner_id, "%s.tmax", name);

	/* create a parameter with the function's maximum runtime in it */
	nf->maxtime_increased = 0;
	hal_param_bit_newf(HAL_RO, &(nf->maxtime_increased), xf->owner_id,
			    "%s.tmax-inc", name);
	break;
    case FS_USERLAND: // no timing pins/params
	;
    }

    return 0;
}
コード例 #14
0
int hal_inst_create(const char *name, const int comp_id, const int size,
		    void **inst_data)
{
    CHECK_HALDATA();
    CHECK_STR(name);

    {
	hal_inst_t *inst  __attribute__((cleanup(halpr_autorelease_mutex)));
	hal_comp_t *comp;
	void *m = NULL;
	rtapi_mutex_get(&(hal_data->mutex));

	// comp must exist
	if ((comp = halpr_find_comp_by_id(comp_id)) == 0) {
	    HALERR("comp %d not found", comp_id);
	    return -ENOENT;
	}

	// inst may not exist
	if ((inst = halpr_find_inst_by_name(name)) != NULL) {
	    HALERR("instance '%s' already exists", name);
	    return -EEXIST;
	}

	if (size > 0) {
	    m = shmalloc_up(size);
	    if (m == NULL)
		NOMEM(" instance %s: cant allocate %d bytes", name, size);
	}
	memset(m, 0, size);

	// allocate instance descriptor
	if ((inst = alloc_inst_struct()) == NULL)
	    NOMEM("instance '%s'", name);

	inst->comp_id = comp->comp_id;
	inst->inst_id = rtapi_next_handle();
	inst->inst_data_ptr = SHMOFF(m);

	inst->inst_size = size;
	rtapi_snprintf(inst->name, sizeof(inst->name), "%s", name);


	HALDBG("%s: creating instance '%s' size %d at ^ %d/%p base=%p",
#ifdef RTAPI
	       "rtapi",
#else
	       "ulapi",
#endif
	       name, size, inst->inst_data_ptr, m,  hal_shmem_base);

	// if not NULL, pass pointer to blob
	if (inst_data)
	    *(inst_data) = m;

	// make it visible
	inst->next_ptr = hal_data->inst_list_ptr;
	hal_data->inst_list_ptr = SHMOFF(inst);

	return inst->inst_id;
  }
}
コード例 #15
0
ファイル: hal_ring.c プロジェクト: 13788593535/machinekit
int hal_ring_attach(const char *name, ringbuffer_t *rbptr,unsigned *flags)
{
    hal_ring_t *rbdesc;
    ringheader_t *rhptr;

    CHECK_HALDATA();
    CHECK_STRLEN(name, HAL_NAME_LEN);

    // no mutex(es) held up to here
    {
	int retval  __attribute__((cleanup(halpr_autorelease_mutex)));
	rtapi_mutex_get(&(hal_data->mutex));

	if ((rbdesc = halpr_find_ring_by_name(name)) == NULL) {
	    HALERR("no such ring '%s'", name);
	    return -ENOENT;
	}

	// calling hal_ring_attach(name, NULL, NULL) is a way to determine
	// if a given ring exists.
	// hal_ring_attach(name, NULL, &flags) is a way to inspect the flags
	// of an existing ring without actually attaching it.
	if (rbptr == NULL) {
	    if (flags)
		*flags = rbdesc->flags;
	    return 0;
	}

	if (rbdesc->flags & ALLOC_HALMEM) {
	    rhptr = SHMPTR(rbdesc->ring_offset);
	} else {
	    int shmid;

	    // map in the shm segment - size 0 means 'must exist'
	    if ((retval = rtapi_shmem_new_inst(rbdesc->ring_shmkey,
					       rtapi_instance, lib_module_id,
					   0 )) < 0) {
		if (retval != -EEXIST)  {
		    HALERR("ring '%s': rtapi_shmem_new_inst() failed %d",
			   name, retval);
		    return retval;
		}
		// tried to map shm again. May happen in halcmd_commands:print_ring_info().
		// harmless.
	    }
	    shmid = retval;

	    // make it accessible
	    if ((retval = rtapi_shmem_getptr(shmid, (void **)&rhptr, 0))) {
		HALERR("ring '%s': rtapi_shmem_getptr %d failed %d",
		       name, shmid, retval);
		return -ENOMEM;
	    }
	}
	// record usage in ringheader
	rhptr->refcount++;
	// fill in ringbuffer_t
	ringbuffer_init(rhptr, rbptr);

	if (flags)
	    *flags = rbdesc->flags;
	// hal mutex unlock happens automatically on scope exit
    }
    return 0;
}
コード例 #16
0
ファイル: hal_ring.c プロジェクト: 13788593535/machinekit
int hal_ring_new(const char *name, int size, int sp_size, int mode)
{
    hal_ring_t *rbdesc;
    int *prev, next, cmp, retval;
    int ring_id;
    ringheader_t *rhptr;

    CHECK_HALDATA();
    CHECK_STRLEN(name, HAL_NAME_LEN);
    CHECK_LOCK(HAL_LOCK_LOAD);

    {
	hal_ring_t *ptr __attribute__((cleanup(halpr_autorelease_mutex)));

	rtapi_mutex_get(&(hal_data->mutex));

	// make sure no such ring name already exists
	if ((ptr = halpr_find_ring_by_name(name)) != 0) {
	    HALERR("ring '%s' already exists", name);
	    return -EEXIST;
	}
	// allocate a new ring id - needed since we dont track ring shm
	// segments in RTAPI
	if ((ring_id = next_ring_id()) < 0) {
	    HALERR("cant allocate new ring id for '%s'", name);
	    return -ENOMEM;
	}

	// allocate a new ring descriptor
	if ((rbdesc = alloc_ring_struct()) == 0)
	    NOMEM("ring '%s'", name);

	rbdesc->handle = rtapi_next_handle();
	rbdesc->flags = mode;
	rbdesc->ring_id = ring_id;

	// make total allocation fit ringheader, ringbuffer and scratchpad
	rbdesc->total_size = ring_memsize( rbdesc->flags, size, sp_size);

	if (rbdesc->flags & ALLOC_HALMEM) {
	    void *ringmem = shmalloc_up(rbdesc->total_size);
	    if (ringmem == NULL)
		NOMEM("ring '%s' size %d - insufficient HAL memory for ring",
		      name,rbdesc->total_size);

	    rbdesc->ring_offset = SHMOFF(ringmem);
	    rhptr = ringmem;
	} else {
	    // allocate shared memory segment for ring and init
	    rbdesc->ring_shmkey = OS_KEY((RTAPI_RING_SHM_KEY + ring_id), rtapi_instance);

	    int shmid;

	    // allocate an RTAPI shm segment owned by HAL_LIB_xxx
	    if ((shmid = rtapi_shmem_new(rbdesc->ring_shmkey, lib_module_id,
					 rbdesc->total_size)) < 0)
		NOMEM("rtapi_shmem_new(0x%8.8x,%d) failed: %d",
		       rbdesc->ring_shmkey, lib_module_id,
		       rbdesc->total_size);

	    // map the segment now so we can fill in the ringheader details
	    if ((retval = rtapi_shmem_getptr(shmid,
					     (void **)&rhptr, 0)) < 0)
		NOMEM("rtapi_shmem_getptr for %d failed %d",
		       shmid, retval);
	}

	HALDBG("created ring '%s' in %s, total_size=%d",
	       name, (rbdesc->flags & ALLOC_HALMEM) ? "halmem" : "shm",
	       rbdesc->total_size);

	ringheader_init(rhptr, rbdesc->flags, size, sp_size);
	rhptr->refcount = 0; // on hal_ring_attach: increase; on hal_ring_detach: decrease
	rtapi_snprintf(rbdesc->name, sizeof(rbdesc->name), "%s", name);
	rbdesc->next_ptr = 0;

	// search list for 'name' and insert new structure
	prev = &(hal_data->ring_list_ptr);
	next = *prev;
	while (1) {
	    if (next == 0) {
		/* reached end of list, insert here */
		rbdesc->next_ptr = next;
		*prev = SHMOFF(rbdesc);
		return 0;
	    }
	    ptr = SHMPTR(next);
	    cmp = strcmp(ptr->name, rbdesc->name);
	    if (cmp > 0) {
		/* found the right place for it, insert here */
		rbdesc->next_ptr = next;
		*prev = SHMOFF(rbdesc);
		return 0;
	    }
	    /* didn't find it yet, look at next one */
	    prev = &(ptr->next_ptr);
	    next = *prev;
	}
	// automatic unlock by scope exit
    }
}
コード例 #17
0
ファイル: hal_rcomp.c プロジェクト: BarneyLiuAKL/machinekit
int hal_ccomp_match(hal_compiled_comp_t *cc)
{
    int i, nchanged = 0;
    hal_bit_t halbit;
    hal_s32_t hals32;
    hal_s32_t halu32;
    hal_float_t halfloat,delta;
    hal_pin_t *pin;
    hal_sig_t *sig;
    void *data_ptr;

    assert(cc->magic ==  CCOMP_MAGIC);
    RTAPI_ZERO_BITMAP(cc->changed, cc->n_pins);

    for (i = 0; i < cc->n_pins; i++) {
	pin = cc->pin[i];
	if (pin->signal != 0) {
	    sig = SHMPTR(pin->signal);
	    data_ptr = SHMPTR(sig->data_ptr);
	} else {
	    data_ptr = hal_shmem_base + SHMOFF(&(pin->dummysig));
	}

	switch (pin->type) {
	case HAL_BIT:
	    halbit = *((char *) data_ptr);
	    if (cc->tracking[i].b != halbit) {
		nchanged++;
		RTAPI_BIT_SET(cc->changed, i);
		cc->tracking[i].b = halbit;
	    }
	    break;
	case HAL_FLOAT:
	    halfloat = *((hal_float_t *) data_ptr);
	    delta = HAL_FABS(halfloat - cc->tracking[i].f);
	    if (delta > hal_data->epsilon[pin->eps_index]) {
		nchanged++;
		RTAPI_BIT_SET(cc->changed, i);
		cc->tracking[i].f = halfloat;
	    }
	    break;
	case HAL_S32:
	    hals32 =  *((hal_s32_t *) data_ptr);
	    if (cc->tracking[i].s != hals32) {
		nchanged++;
		RTAPI_BIT_SET(cc->changed, i);
		cc->tracking[i].s = hals32;
	    }
	    break;
	case HAL_U32:
	    halu32 =  *((hal_u32_t *) data_ptr);
	    if (cc->tracking[i].u != halu32) {
		nchanged++;
		RTAPI_BIT_SET(cc->changed, i);
		cc->tracking[i].u = halu32;
	    }
	    break;
	default:
	    HALERR("BUG: hal_ccomp_match(%s): invalid type for pin %s: %d",
		   cc->comp->name, pin->name, pin->type);
	    return -EINVAL;
	}
    }
    return nchanged;
}
コード例 #18
0
ファイル: hal_rcomp.c プロジェクト: BarneyLiuAKL/machinekit
int hal_compile_comp(const char *name, hal_compiled_comp_t **ccomp)
{
   hal_compiled_comp_t *tc;
   int pincount = 0;

   CHECK_HALDATA();
   CHECK_STRLEN(name, HAL_NAME_LEN);
   {
       hal_comp_t *comp __attribute__((cleanup(halpr_autorelease_mutex)));
       int next, n;
       hal_comp_t *owner;
       hal_pin_t *pin;

       rtapi_mutex_get(&(hal_data->mutex));

       if ((comp = halpr_find_comp_by_name(name)) == NULL) {
	    HALERR("no such component '%s'", name);
	   return -EINVAL;
       }

       // array sizing: count pins owned by this component
       next = hal_data->pin_list_ptr;
       n = 0;
       while (next != 0) {
	    pin = SHMPTR(next);
	    owner = halpr_find_owning_comp(pin->owner_id);
	    if (owner->comp_id == comp->comp_id) {
		if (!(pin->flags & PIN_DO_NOT_TRACK))
		    n++;
		pincount++;
	    }
	    next = pin->next_ptr;
       }
       if (n == 0) {
	   HALERR("component %s has no pins to watch for changes",
		  name);
	   return -EINVAL;
       }
       // a compiled comp is a userland/per process memory object
       if ((tc = malloc(sizeof(hal_compiled_comp_t))) == NULL)
	   return -ENOMEM;

       memset(tc, 0, sizeof(hal_compiled_comp_t));
       tc->comp = comp;
       tc->n_pins = n;

       // alloc pin array
       if ((tc->pin = malloc(sizeof(hal_pin_t *) * tc->n_pins)) == NULL)
	   return -ENOMEM;
       // alloc tracking value array
       if ((tc->tracking =
	    malloc(sizeof(hal_data_u) * tc->n_pins )) == NULL)
	   return -ENOMEM;
       // alloc change bitmap
       if ((tc->changed =
	    malloc(RTAPI_BITMAP_BYTES(tc->n_pins))) == NULL)
	    return -ENOMEM;

       memset(tc->pin, 0, sizeof(hal_pin_t *) * tc->n_pins);
       memset(tc->tracking, 0, sizeof(hal_data_u) * tc->n_pins);
       RTAPI_ZERO_BITMAP(tc->changed,tc->n_pins);

       // fill in pin array
       n = 0;
       next = hal_data->pin_list_ptr;
       while (next != 0) {
	   pin = SHMPTR(next);
	   owner = halpr_find_owning_comp(pin->owner_id);
	   if ((owner->comp_id == comp->comp_id) &&
	       !(pin->flags & PIN_DO_NOT_TRACK))
	       tc->pin[n++] = pin;
	   next = pin->next_ptr;
       }
       assert(n == tc->n_pins);
       tc->magic = CCOMP_MAGIC;
       *ccomp = tc;
   }
   HALDBG("ccomp '%s': %d pins, %d tracked", name, pincount, tc->n_pins);
   return 0;
}
コード例 #19
0
ファイル: hal_rcomp.c プロジェクト: BarneyLiuAKL/machinekit
int hal_retrieve_pinstate(const char *comp_name,
			  hal_retrieve_pins_callback_t callback,
			  void *cb_data)
{
    int next;
    int nvisited = 0;
    int result;
    hal_comp_t *comp = NULL;
    hal_comp_t *owner;
    hal_pinstate_t pinstate;

    CHECK_HALDATA();
    CHECK_STRLEN(comp_name, HAL_NAME_LEN);

    {
	hal_pin_t *pin __attribute__((cleanup(halpr_autorelease_mutex)));

	/* get mutex before accessing shared data */
	rtapi_mutex_get(&(hal_data->mutex));

	if (comp_name != NULL) {
	    comp = halpr_find_comp_by_name(comp_name);
	    if (comp == NULL) {
		HALERR("no such component '%s'", comp_name);
		return -EINVAL;
	    }
	}
	// either comp == NULL, so visit all pins
	// or comp != NULL, in which case visit only this
	// component's pins

	// walk the pinlist
	next = hal_data->pin_list_ptr;
	while (next != 0) {
	    pin = SHMPTR(next);
	    owner = halpr_find_owning_comp(pin->owner_id);
	    if (!comp_name || (owner->comp_id == comp->comp_id)) {
		nvisited++;
		/* this is the right comp */
		if (callback) {
		    // fill in the details:
		    // NB: cover remote link case!
		    pinstate.value = SHMPTR(pin->data_ptr_addr);
		    pinstate.type = pin->type;
		    pinstate.dir = pin->dir;
		    pinstate.epsilon = hal_data->epsilon[pin->eps_index];
		    pinstate.flags = pin->flags;
		    strncpy(pinstate.name, pin->name, sizeof(pin->name));
		    strncpy(pinstate.owner_name, owner->name, sizeof(owner->name));

		    result = callback(&pinstate, cb_data);
		    if (result < 0) {
			// callback signaled an error, pass that back up.
			return result;
		    } else if (result > 0) {
			// callback signaled 'stop iterating'.
			// pass back the number of visited pins so far.
			return nvisited;
		    } else {
			// callback signaled 'OK to continue'
			// fall through
		    }
		} else {
		    // null callback passed in,
		    // just count pins
		    // nvisited already bumped above.
		}
	    }
	    /* no match, try the next one */
	    next = pin->next_ptr;
	}
	HALDBG("hal_retrieve_pinstate: visited %d pins", nvisited);
	/* if we get here, we ran through all the pins, so return count */
	return nvisited;
    }
}
コード例 #20
0
ファイル: hal_comp.c プロジェクト: 13788593535/machinekit
/** init_hal_data() initializes the entire HAL data structure,
    by the RT hal_lib component
*/
int init_hal_data(void)
{

    /* has the block already been initialized? */
    if (hal_data->version != 0) {
	/* yes, verify version code */
	if (hal_data->version == HAL_VER) {
	    return 0;
	} else {
	    HALERR("version code mismatch");
	    return -1;
	}
    }
    /* no, we need to init it, grab the mutex unconditionally */
    rtapi_mutex_try(&(hal_data->mutex));

    // some heaps contain garbage, like xenomai
    memset(hal_data, 0, global_data->hal_size);

    /* set version code so nobody else init's the block */
    hal_data->version = HAL_VER;

    /* initialize everything */
    hal_data->comp_list_ptr = 0;
    hal_data->pin_list_ptr = 0;
    hal_data->sig_list_ptr = 0;
    hal_data->param_list_ptr = 0;
    hal_data->funct_list_ptr = 0;
    hal_data->thread_list_ptr = 0;
    hal_data->vtable_list_ptr = 0;
    hal_data->base_period = 0;
    hal_data->threads_running = 0;
    hal_data->oldname_free_ptr = 0;
    hal_data->comp_free_ptr = 0;
    hal_data->pin_free_ptr = 0;
    hal_data->sig_free_ptr = 0;
    hal_data->param_free_ptr = 0;
    hal_data->funct_free_ptr = 0;
    hal_data->vtable_free_ptr = 0;

    list_init_entry(&(hal_data->funct_entry_free));
    hal_data->thread_free_ptr = 0;
    hal_data->exact_base_period = 0;

    hal_data->group_list_ptr = 0;
    hal_data->member_list_ptr = 0;
    hal_data->ring_list_ptr = 0;
    hal_data->inst_list_ptr = 0;

    hal_data->group_free_ptr = 0;
    hal_data->member_free_ptr = 0;
    hal_data->ring_free_ptr = 0;
    hal_data->inst_free_ptr = 0;

    RTAPI_ZERO_BITMAP(&hal_data->rings, HAL_MAX_RINGS);
    // silly 1-based shm segment id allocation FIXED
    // yeah, 'user friendly', how could one possibly think zero might be a valid id
    RTAPI_BIT_SET(hal_data->rings,0);

    /* set up for shmalloc_xx() */
    hal_data->shmem_bot = sizeof(hal_data_t);
    hal_data->shmem_top = global_data->hal_size;
    hal_data->lock = HAL_LOCK_NONE;

    int i;
    for (i = 0; i < MAX_EPSILON; i++)
	hal_data->epsilon[i] = 0.0;
    hal_data->epsilon[0] = DEFAULT_EPSILON;

    /* done, release mutex */
    rtapi_mutex_give(&(hal_data->mutex));
    return 0;
}
コード例 #21
0
ファイル: hal_funct.c プロジェクト: ArcEye/MK-Qt5
int hal_add_funct_to_thread(const char *funct_name,
			    const char *thread_name, int position)
{
    hal_funct_t *funct;
    hal_list_t *list_root, *list_entry;
    int n;
    hal_funct_entry_t *funct_entry;

    CHECK_HALDATA();
    CHECK_LOCK(HAL_LOCK_CONFIG);
    CHECK_STR(funct_name);
    CHECK_STR(thread_name);

    HALDBG("adding function '%s' to thread '%s'", funct_name, thread_name);
    {
	hal_thread_t *thread __attribute__((cleanup(halpr_autorelease_mutex)));

	/* get mutex before accessing data structures */
	rtapi_mutex_get(&(hal_data->mutex));

	/* make sure position is valid */
	if (position == 0) {
	    /* zero is not allowed */
	    HALERR("bad position: 0");
	    return -EINVAL;
	}

	/* search function list for the function */
	funct = halpr_find_funct_by_name(funct_name);
	if (funct == 0) {
	    HALERR("function '%s' not found", funct_name);
	    return -EINVAL;
	}
	// type-check the functions which go onto threads
	switch (funct->type) {
	case FS_LEGACY_THREADFUNC:
	case FS_XTHREADFUNC:
	    break;
	default:
	    HALERR("cant add type %d function '%s' "
		   "to a thread", funct->type, funct_name);
	    return -EINVAL;
	}
	/* found the function, is it available? */
	if ((funct->users > 0) && (funct->reentrant == 0)) {
	    HALERR("function '%s' may only be added "
		   "to one thread", funct_name);
	    return -EINVAL;
	}
	/* search thread list for thread_name */
	thread = halpr_find_thread_by_name(thread_name);
	if (thread == 0) {
	    /* thread not found */
	    HALERR("thread '%s' not found", thread_name);
	    return -EINVAL;
	}
#if 0
	/* ok, we have thread and function, are they compatible? */
	if ((funct->uses_fp) && (!thread->uses_fp)) {
	    HALERR("function '%s' needs FP", funct_name);
	    return -EINVAL;
	}
#endif
	/* find insertion point */
	list_root = &(thread->funct_list);
	list_entry = list_root;
	n = 0;
	if (position > 0) {
	    /* insertion is relative to start of list */
	    while (++n < position) {
		/* move further into list */
		list_entry = list_next(list_entry);
		if (list_entry == list_root) {
		    /* reached end of list */
		    HALERR("position '%d' is too high", position);
		    return -EINVAL;
		}
	    }
	} else {
	    /* insertion is relative to end of list */
	    while (--n > position) {
		/* move further into list */
		list_entry = list_prev(list_entry);
		if (list_entry == list_root) {
		    /* reached end of list */
		    HALERR("position '%d' is too low", position);
		    return -EINVAL;
		}
	    }
	    /* want to insert before list_entry, so back up one more step */
	    list_entry = list_prev(list_entry);
	}
	/* allocate a funct entry structure */
	funct_entry = alloc_funct_entry_struct();
	if (funct_entry == 0)
	    NOMEM("thread->function link");

	/* init struct contents */
	funct_entry->funct_ptr = SHMOFF(funct);
	funct_entry->arg = funct->arg;
	funct_entry->funct.l = funct->funct.l;
	funct_entry->type = funct->type;
	/* add the entry to the list */
	list_add_after((hal_list_t *) funct_entry, list_entry);
	/* update the function usage count */
	funct->users++;
    }
    return 0;
}