Exemple #1
0
int hal_unbind(const char *comp_name)
{
    CHECK_HALDATA();
    CHECK_STRLEN(comp_name, HAL_NAME_LEN);
    {
	hal_comp_t *comp __attribute__((cleanup(halpr_autorelease_mutex)));

	rtapi_mutex_get(&(hal_data->mutex));

	comp = halpr_find_comp_by_name(comp_name);
	if (comp == NULL) {
	    HALERR("no such component '%s'", comp_name);
	    return -EINVAL;
	}
	if (comp->type != TYPE_REMOTE) {
	    HALERR("component '%s' not a remote component (%d)",
		   comp_name, comp->type);
	    return -EINVAL;
	}
	if (comp->state != COMP_BOUND) {
	    HALERR("component '%s': state not bound (%d)",
		   comp_name, comp->state);
	    return -EINVAL;
	}
	comp->state = COMP_UNBOUND;
	comp->last_unbound = (long int) time(NULL);
    }
    return 0;
}
Exemple #2
0
int hal_release(const char *comp_name)
{
    CHECK_HALDATA();
    CHECK_STRLEN(comp_name, HAL_NAME_LEN);
    {
	hal_comp_t *comp __attribute__((cleanup(halpr_autorelease_mutex)));

	rtapi_mutex_get(&(hal_data->mutex));
	comp = halpr_find_comp_by_name(comp_name);

	if (comp == NULL) {
	    HALERR("no such component '%s'", comp_name);
	    return -EINVAL;
	}
	if (comp->type != TYPE_REMOTE) {
	    HALERR("component '%s' not a remote component (%d)",
		   comp_name, comp->type);
	    return -EINVAL;
	}
	if (comp->pid == 0) {
	    HALERR("component '%s': component already disowned",
			    comp_name);
	    return -EINVAL;
	}

	if (comp->pid != getpid()) {
	    HALERR("component '%s': component owned by pid %d",
			    comp_name, comp->pid);
	    // return -EINVAL;
	}
	comp->pid = 0;
    }
    return 0;
}
Exemple #3
0
int hal_bind(const char *comp_name)
{
    if (hal_data == 0) {
	hal_print_msg(RTAPI_MSG_ERR,
			"HAL: ERROR: hal_bind called before hal_init\n");
	return -EINVAL;
    }
    {
	hal_comp_t *comp __attribute__((cleanup(halpr_autorelease_mutex)));

	rtapi_mutex_get(&(hal_data->mutex));
	comp = halpr_find_comp_by_name(comp_name);

	if (comp == NULL) {
	    hal_print_msg(RTAPI_MSG_ERR,
			    "HAL: hal_bind(): no such component '%s'\n", comp_name);
	    return -EINVAL;
	}
	if (comp->type != TYPE_REMOTE) {
	    hal_print_msg(RTAPI_MSG_ERR,
			    "HAL: hal_bind(%s): not a remote componet (%d)\n",
			    comp_name, comp->type);
	    return -EINVAL;
	}
	if (comp->state != COMP_UNBOUND) {
	    hal_print_msg(RTAPI_MSG_ERR,
			    "HAL: hal_bind(%s): state not unbound (%d)\n",
			    comp_name, comp->state);
	    return -EINVAL;
	}
	comp->state = COMP_BOUND;
	comp->last_bound = (long int) time(NULL);; // XXX ugly
    }
    return 0;
}
Exemple #4
0
int
hal_comp_state_by_name(const char *name)
{
    hal_comp_t *comp __attribute__((cleanup(halpr_autorelease_mutex)));
    rtapi_mutex_get(&(hal_data->mutex));

    comp = halpr_find_comp_by_name(name);
    if (comp == NULL)
	return -ENOENT;
    return comp->state;
}
Exemple #5
0
int hal_acquire(const char *comp_name, int pid)
{
    if (hal_data == 0) {
	hal_print_msg(RTAPI_MSG_ERR,
			"HAL: ERROR: hal_acquire called before hal_init\n");
	return -EINVAL;
    }
    {
	hal_comp_t *comp __attribute__((cleanup(halpr_autorelease_mutex)));

	rtapi_mutex_get(&(hal_data->mutex));
	comp = halpr_find_comp_by_name(comp_name);

	if (comp == NULL) {
	    hal_print_msg(RTAPI_MSG_ERR,
			    "HAL: hal_acquire(): no such component '%s'\n",
			    comp_name);
	    return -EINVAL;
	}
	if (comp->type != TYPE_REMOTE) {
	    hal_print_msg(RTAPI_MSG_ERR,
			    "HAL: hal_acquire(%s): not a remote component (%d)\n",
			    comp_name, comp->type);
	    return -EINVAL;
	}
	if (comp->state == COMP_BOUND) {
	    hal_print_msg(RTAPI_MSG_ERR,
			    "HAL: hal_acquire(%s): cant reown a bound component (%d)\n",
			    comp_name, comp->state);
	    return -EINVAL;
	}
	// let a comp be 'adopted away' from the RT environment
	// this is a tad hacky, should separate owner pid from RT/user distinction
	if ((comp->pid !=0) &&
	    (comp->pid != global_data->rtapi_app_pid))

	    {
		hal_print_msg(RTAPI_MSG_ERR,
				"HAL: hal_acquire(%s): component already owned by pid %d\n",
				comp_name, comp->pid);
		return -EINVAL;
	    }
	comp->pid = pid;
	return comp->comp_id;
    }
}
Exemple #6
0
int hal_release(const char *comp_name)
{
    if (hal_data == 0) {
	hal_print_msg(RTAPI_MSG_ERR,
			"HAL: ERROR: hal_release called before hal_init\n");
	return -EINVAL;
    }
    {
	hal_comp_t *comp __attribute__((cleanup(halpr_autorelease_mutex)));

	rtapi_mutex_get(&(hal_data->mutex));
	comp = halpr_find_comp_by_name(comp_name);

	if (comp == NULL) {
	    hal_print_msg(RTAPI_MSG_ERR,
			    "HAL: hal_release(): no such component '%s'\n",
			    comp_name);
	    return -EINVAL;
	}
	if (comp->type != TYPE_REMOTE) {
	    hal_print_msg(RTAPI_MSG_ERR,
			    "HAL: hal_release(%s): not a remote componet (%d)\n",
			    comp_name, comp->type);
	    return -EINVAL;
	}
	if (comp->pid == 0) {
	    hal_print_msg(RTAPI_MSG_ERR,
			    "HAL: hal_release(%s): component already disowned\n",
			    comp_name);
	    return -EINVAL;
	}

	if (comp->pid != getpid()) {
	    hal_print_msg(RTAPI_MSG_WARN,
			    "HAL: hal_release(%s): component owned by pid %d\n",
			    comp_name, comp->pid);
	    // return -EINVAL;
	}
	comp->pid = 0;
    }
    return 0;
}
Exemple #7
0
// return number of params in a component
int
halpr_param_count(const char *name)
{
    hal_comp_t *comp;
    hal_comp_t *owner;
    int count = 0;

    comp = halpr_find_comp_by_name(name);
    if (comp == 0)
	return -ENOENT;

    int next = hal_data->param_list_ptr;
    while (next != 0) {
	hal_param_t *param = (hal_param_t *)SHMPTR(next);
	owner = halpr_find_owning_comp(param->owner_id);
	if (owner->comp_id == comp->comp_id)
	    count++;
	next = param->next_ptr;
    }
    return count;
}
Exemple #8
0
int hal_acquire(const char *comp_name, int pid)
{
    CHECK_HALDATA();
    CHECK_STRLEN(comp_name, HAL_NAME_LEN);
    {
	hal_comp_t *comp __attribute__((cleanup(halpr_autorelease_mutex)));

	rtapi_mutex_get(&(hal_data->mutex));
	comp = halpr_find_comp_by_name(comp_name);

	if (comp == NULL) {
	    HALERR("no such component '%s'", comp_name);
	    return -EINVAL;
	}
	if (comp->type != TYPE_REMOTE) {
	    HALERR("component '%s' not a remote component (%d)",
		   comp_name, comp->type);
	    return -EINVAL;
	}
	if (comp->state == COMP_BOUND) {
	    HALERR("component '%s': cant reown a bound component (%d)",
		   comp_name, comp->state);
	    return -EINVAL;
	}
	// let a comp be 'adopted away' from the RT environment
	// this is a tad hacky, should separate owner pid from RT/user distinction
	if ((comp->pid !=0) &&
	    (comp->pid != global_data->rtapi_app_pid))

	    {
		HALERR("component '%s': already owned by pid %d",
		       comp_name, comp->pid);
		return -EINVAL;
	    }
	comp->pid = pid;
	return comp->comp_id;
    }
}
Exemple #9
0
// 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]);
}
Exemple #10
0
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;
}
Exemple #11
0
int hal_init_mode(const char *name, int type, int userarg1, int userarg2)
{
    int comp_id;
    char rtapi_name[RTAPI_NAME_LEN + 1];
    char hal_name[HAL_NAME_LEN + 1];

    // tag message origin field
    rtapi_set_logtag("hal_lib");

    if (name == 0) {
	hal_print_msg(RTAPI_MSG_ERR, "HAL: ERROR: no component name\n");
	return -EINVAL;
    }
    if (strlen(name) > HAL_NAME_LEN) {
	hal_print_msg(RTAPI_MSG_ERR,
			"HAL: ERROR: component name '%s' is too long\n", name);
	return -EINVAL;
    }
    // rtapi initialisation already done
    // since this happens through the constructor
    hal_print_msg(RTAPI_MSG_DBG,
		    "HAL: initializing component '%s' type=%d arg1=%d arg2=%d/0x%x\n",
		    name, type, userarg1, userarg2, userarg2);
    /* copy name to local vars, truncating if needed */
    rtapi_snprintf(rtapi_name, RTAPI_NAME_LEN, "HAL_%s", name);
    rtapi_snprintf(hal_name, sizeof(hal_name), "%s", name);

    /* do RTAPI init */
    comp_id = rtapi_init(rtapi_name);
    if (comp_id < 0) {
	hal_print_msg(RTAPI_MSG_ERR, "HAL: ERROR: rtapi init failed\n");
	return -EINVAL;
    }
    // tag message origin field since ulapi autoload re-tagged them
    rtapi_set_logtag("hal_lib");
#ifdef ULAPI
    hal_rtapi_attach();
#endif
    {
	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 */
	    hal_print_msg(RTAPI_MSG_ERR,
			    "HAL: ERROR: duplicate component name '%s'\n", hal_name);
	    rtapi_exit(comp_id);
	    return -EINVAL;
	}
	/* allocate a new component structure */
	comp = halpr_alloc_comp_struct();
	if (comp == 0) {
	    /* couldn't allocate structure */
	    hal_print_msg(RTAPI_MSG_ERR,
			    "HAL: ERROR: insufficient memory for component '%s'\n", 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;
#ifdef RTAPI
	comp->pid = 0;   //FIXME revisit this
#else /* ULAPI */
	// a remote component starts out disowned
	comp->pid = comp->type == TYPE_REMOTE ? 0 : getpid(); //FIXME revisit this
#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
    /* done */
    hal_print_msg(RTAPI_MSG_DBG,
		    "HAL: component '%s' initialized, ID = %02d\n", hal_name, comp_id);
    return comp_id;
}
Exemple #12
0
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;
}
Exemple #13
0
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;
    }
}
Exemple #14
0
int hal_compile_comp(const char *name, hal_compiled_comp_t **ccomp)
{
   hal_compiled_comp_t *tc;
   int pincount = 0;

   if (!name) {
       hal_print_msg(RTAPI_MSG_ERR,
		       "HAL:%d ERROR: hal_compile_comp() called with NULL name\n",
		       rtapi_instance);
	return -EINVAL;
   }
   {
       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) {
	   hal_print_msg(RTAPI_MSG_ERR,
		       "HAL:%d ERROR: hal_comp_compile(%s): no such comp\n",
			   rtapi_instance, 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 = SHMPTR(pin->owner_ptr);
	    if (owner->comp_id == comp->comp_id) {
		if (!(pin->flags & PIN_DO_NOT_TRACK))
		    n++;
		pincount++;
	    }
	    next = pin->next_ptr;
       }
       if (n == 0) {
	   hal_print_msg(RTAPI_MSG_ERR,
			   "ERROR: component %s has no pins to watch for changes\n",
			   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 = SHMPTR(pin->owner_ptr);
	   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;
   }
   hal_print_msg(RTAPI_MSG_DBG, "hal_compile_comp(%s): %d pins, %d tracked",
		   name, pincount, tc->n_pins);
   return 0;
}