Пример #1
0
void rtapi_app_exit(void)
{
    int retval;

    rtapi_set_msg_handler(old_handler);

    rtapi_print_msg(RTAPI_MSG_INFO, "MOTION: cleanup_module() started.\n");

    retval = hal_stop_threads();
    if (retval < 0) {
	rtapi_print_msg(RTAPI_MSG_ERR,
	    _("MOTION: hal_stop_threads() failed, returned %d\n"), retval);
    }
    /* free shared memory */
    retval = rtapi_shmem_delete(emc_shmem_id, mot_comp_id);
    if (retval < 0) {
	rtapi_print_msg(RTAPI_MSG_ERR,
	    _("MOTION: rtapi_shmem_delete() failed, returned %d\n"), retval);
    }
    /* disconnect from HAL and RTAPI */
    retval = hal_exit(mot_comp_id);
    if (retval < 0) {
	rtapi_print_msg(RTAPI_MSG_ERR,
	    _("MOTION: hal_exit() failed, returned %d\n"), retval);
    }
    rtapi_print_msg(RTAPI_MSG_INFO, "MOTION: cleanup_module() finished.\n");
}
Пример #2
0
/* part of the Linux kernel module that stops the shmem task */
void rtapi_app_exit(void)
{
    int retval;

    if (0 != shmem_struct) {
	rtapi_print("shmemtask exit: heartbeat is %u\n",
	    shmem_struct->heartbeat);
    }

    retval = rtapi_task_pause(shmem_task);
    if (retval < 0) {
	rtapi_print("shmemtask exit: rtapi_task_stop returned %d\n", retval);
    }
    retval = rtapi_task_delete(shmem_task);
    if (retval < 0) {
	rtapi_print("shmemtask exit: rtapi_task_delete returned %d\n",
	    retval);
    }
    retval = rtapi_shmem_delete(shmem_mem, module);
    if (retval < 0) {
	rtapi_print("shmemtask exit: rtapi_shmem_delete returned %d\n",
	    retval);
    }
    /* Clean up and exit */
    rtapi_exit(module);
}
Пример #3
0
void rtapi_app_exit(void)
{
    /* is sample function linked to a thread? */
    if (ctrl_shm->thread_name[0] != '\0') {
	/* need to unlink it before we release the scope shared memory */
	hal_del_funct_from_thread("scope.sample", ctrl_shm->thread_name);
    }
    rtapi_shmem_delete(shm_id, comp_id);
    hal_exit(comp_id);
}
Пример #4
0
void rtapi_app_exit(void)
{
    int n;

    /* free any shmem blocks */
    for ( n = 0 ; n < MAX_SAMPLERS ; n++ ) {
	if ( shmem_id[n] > 0 ) {
	    rtapi_shmem_delete(shmem_id[n], comp_id);
	}
    }
    hal_exit(comp_id);
}
/* signal handler */
static void quit(int sig)
{
    if ( ignore_sig ) {
	return;
    }
    if ( shmem_id >= 0 ) {
	rtapi_shmem_delete(shmem_id, comp_id);
    }
    if ( comp_id >= 0 ) {
	hal_exit(comp_id);
    }
    exit(exitval);
}
Пример #6
0
void ClassicLadder_FreeAll(char CleanAndRemoveTmpDir)
{
#ifdef GTK_INTERFACE
	if (EditArithmExpr)
		free(EditArithmExpr);
#endif
#ifndef RTAPI // there is no directory in realtime!
if ( CleanAndRemoveTmpDir )
		CleanTmpLadderDirectory( TRUE/*RemoveTmpDirAtEnd*/ );
#endif
#ifdef HAL_SUPPORT
	rtapi_shmem_delete(ShmemId,compId);
#endif	
}
Пример #7
0
int rtapi_app_main(void)
{
    int retval;
    void *shm_base;
    long skip;
    /* connect to the HAL */
    comp_id = hal_init("scope_rt");
    if (comp_id < 0) {
	rtapi_print_msg(RTAPI_MSG_ERR, "SCOPE: ERROR: hal_init() failed\n");
	return -1;
    }
    /* connect to scope shared memory block */
    skip = (sizeof(scope_shm_control_t) + 3) & ~3;
    shm_size = skip + num_samples * sizeof(scope_data_t);
    shm_id = rtapi_shmem_new(SCOPE_SHM_KEY, comp_id, shm_size);
    if (shm_id < 0) {
	rtapi_print_msg(RTAPI_MSG_ERR,
	    "SCOPE RT: ERROR: failed to get shared memory (key=0x%x, size=%lu)\n",
            SCOPE_SHM_KEY,
            shm_size
        );
	hal_exit(comp_id);
	return -1;
    }
    retval = rtapi_shmem_getptr(shm_id, &shm_base);
    if (retval < 0) {
	rtapi_print_msg(RTAPI_MSG_ERR,
	    "SCOPE: ERROR: failed to map shared memory\n");
	rtapi_shmem_delete(shm_id, comp_id);
	hal_exit(comp_id);
	return -1;
    }

    /* init control structure */
    ctrl_rt = &ctrl_struct;
    init_rt_control_struct(shm_base);

    /* export scope data sampling function */
    retval = hal_export_funct("scope.sample", sample, NULL, 0, 0, comp_id);
    if (retval != 0) {
	rtapi_print_msg(RTAPI_MSG_ERR,
	    "SCOPE_RT: ERROR: sample funct export failed\n");
	hal_exit(comp_id);
	return -1;
    }
    rtapi_print_msg(RTAPI_MSG_DBG, "SCOPE_RT: installed sample function\n");
    hal_ready(comp_id);
    return 0;
}
Пример #8
0
int hal_rtapi_detach()
{
    /* release RTAPI resources */
    if (lib_mem_id > -1) {
	// if they were actually initialized
	rtapi_shmem_delete(lib_mem_id, lib_module_id);
	rtapi_exit(lib_module_id);

	lib_mem_id = 0;
	lib_module_id = -1;
	hal_shmem_base = NULL;
	hal_data = NULL;
    }
    return 0;
}
Пример #9
0
int main()
{
    int retval;

    module = rtapi_init("SHMEM_USR");
    if (module < 1) {
	rtapi_print_msg(RTAPI_MSG_ERR,
	    "shmemusr main: rtapi_init returned %d\n", module);
	return -1;
    }

    /* allocate the shared memory structure */
    shmem_id = rtapi_shmem_new(key, module, sizeof(SHMEM_STRUCT));
    if (shmem_id < 0) {
	rtapi_print_msg(RTAPI_MSG_ERR,
	    "shmemusr main: rtapi_shmem_new returned %d\n", shmem_id);
	rtapi_exit(module);
	return -1;
    }
    retval = rtapi_shmem_getptr(shmem_id, (void **) &shmem_struct);
    if (retval < 0) {
	rtapi_print_msg(RTAPI_MSG_ERR,
	    "shmemusr main: rtapi_shmem_getptr returned %d\n", retval);
	rtapi_exit(module);
	return -1;
    }

    signal(SIGINT, quit);
    while (!done) {
	rtapi_print("%lu\n", shmem_struct->heartbeat);
	sleep(1);
    }

    retval = rtapi_shmem_delete(shmem_id, module);
    if (retval < 0) {
	rtapi_print_msg(RTAPI_MSG_ERR,
	    "shmemusr main: rtapi_free_shmem returned %d\n", retval);
	rtapi_exit(module);
	return -1;
    }

    return rtapi_exit(module);
}
Пример #10
0
void rtapi_app_exit(void)
{
    int retval;

    hal_print_msg(RTAPI_MSG_DBG,
		    "HAL_LIB:%d removing RT support\n",rtapi_instance);
    hal_proc_clean();

    {
	hal_thread_t *thread __attribute__((cleanup(halpr_autorelease_mutex)));

	/* grab mutex before manipulating list */
	rtapi_mutex_get(&(hal_data->mutex));
	/* must remove all threads before unloading this module */
	while (hal_data->thread_list_ptr != 0) {
	    /* point to a thread */
	    thread = SHMPTR(hal_data->thread_list_ptr);
	    /* unlink from list */
	    hal_data->thread_list_ptr = thread->next_ptr;
	    /* and delete it */
	    free_thread_struct(thread);
	}
    }

    /* release RTAPI resources */
    retval = rtapi_shmem_delete(lib_mem_id, lib_module_id);
    if (retval) {
	hal_print_msg(RTAPI_MSG_ERR,
			"HAL_LIB:%d rtapi_shmem_delete(%d,%d) failed: %d\n",
			rtapi_instance, lib_mem_id, lib_module_id, retval);
    }

    retval = rtapi_exit(lib_module_id);
    if (retval) {
	hal_print_msg(RTAPI_MSG_ERR,
			"HAL_LIB:%d rtapi_exit(%d) failed: %d\n",
			rtapi_instance, lib_module_id, retval);
    }
    /* done */
    hal_print_msg(RTAPI_MSG_DBG,
		    "HAL_LIB:%d RT support removed successfully\n",
		    rtapi_instance);
}
Пример #11
0
/* release_HAL_mutex() unconditionally releases the hal_mutex
   very useful after a program segfaults while holding the mutex
*/
static int release_HAL_mutex(void)
{
    int comp_id, mem_id, retval;
    void *mem;
    hal_data_t *hal_data;

    /* do RTAPI init */
    comp_id = rtapi_init("hal_unlocker");
    if (comp_id < 0) {
        rtapi_print_msg(RTAPI_MSG_ERR, "ERROR: rtapi init failed\n");
        return -EINVAL;
    }
    /* get HAL shared memory block from RTAPI */
    mem_id = rtapi_shmem_new(HAL_KEY, comp_id, global_data->hal_size);
    if (mem_id < 0) {
        rtapi_print_msg(RTAPI_MSG_ERR,
                        "ERROR: could not open shared memory\n");
        rtapi_exit(comp_id);
        return -EINVAL;
    }
    /* get address of shared memory area */
    retval = rtapi_shmem_getptr(mem_id, &mem);
    if (retval < 0) {
        rtapi_print_msg(RTAPI_MSG_ERR,
                        "ERROR: could not access shared memory\n");
        rtapi_exit(comp_id);
        return -EINVAL;
    }
    /* set up internal pointers to shared mem and data structure */
    hal_data = (hal_data_t *) mem;
    /* release mutex  */
    rtapi_mutex_give(&(hal_data->mutex));
    /* release RTAPI resources */
    rtapi_shmem_delete(mem_id, comp_id);
    rtapi_exit(comp_id);
    /* done */
    return 0;

}
int main(int argc, char **argv)
{
    int n, channel, retval, size, line;
    char *cp, *cp2;
    void *shmem_ptr;
    fifo_t *fifo;
    shmem_data_t *data, *dptr;
    char buf[BUF_SIZE];
	const char *errmsg;
    int tmpin, newin;
    struct timespec delay;

    /* set return code to "fail", clear it later if all goes well */
    exitval = 1;
    channel = 0;
    for ( n = 1 ; n < argc ; n++ ) {
	cp = argv[n];
	if ( *cp != '-' ) {
	    break;
	}
	switch ( *(++cp) ) {
	case 'c':
	    if (( *(++cp) == '\0' ) && ( ++n < argc )) { 
		cp = argv[n];
	    }
	    channel = strtol(cp, &cp2, 10);
	    if (( *cp2 ) || ( channel < 0 ) || ( channel >= MAX_STREAMERS )) {
		fprintf(stderr,"ERROR: invalid channel number '%s'\n", cp );
		exit(1);
	    }
	    break;
	default:
	    fprintf(stderr,"ERROR: unknown option '%s'\n", cp );
	    exit(1);
	    break;
	}
    }
    if(n < argc) {
	int fd;
	if(argc > n+1) {
	    fprintf(stderr, "ERROR: At most one filename may be specified\n");
	    exit(1);
	}
	// make stdin be the named file
	fd = open(argv[n], O_RDONLY);
	close(0);
	dup2(fd, 0);
    }
    /* register signal handlers - if the process is killed
       we need to call hal_exit() to free the shared memory */
    signal(SIGINT, quit);
    signal(SIGTERM, quit);
    signal(SIGPIPE, SIG_IGN);
    /* connect to HAL */
    /* create a unique module name, to allow for multiple streamers */
    snprintf(comp_name, sizeof(comp_name), "halstreamer%d", getpid());
    /* connect to the HAL */
    ignore_sig = 1;
    comp_id = hal_init(comp_name);
    ignore_sig = 0;
    /* check result */
    if (comp_id < 0) {
	fprintf(stderr, "ERROR: hal_init() failed: %d\n", comp_id );
	goto out;
    }
    hal_ready(comp_id);
    /* open shmem for user/RT comms (fifo) */
    /* initial size is unknown, assume only the fifo structure */
    shmem_id = rtapi_shmem_new(STREAMER_SHMEM_KEY+channel, comp_id, sizeof(fifo_t));
    if ( shmem_id < 0 ) {
	fprintf(stderr, "ERROR: couldn't allocate user/RT shared memory\n");
	goto out;
    }
    retval = rtapi_shmem_getptr(shmem_id, &shmem_ptr);
    if ( retval < 0 ) {
	fprintf(stderr, "ERROR: couldn't map user/RT shared memory\n");
	goto out;
    }
    fifo = shmem_ptr;
    if ( fifo->magic != FIFO_MAGIC_NUM ) {
	fprintf(stderr, "ERROR: channel %d realtime part is not loaded\n", channel );
	goto out;
    }
    /* now use data in fifo structure to calculate proper shmem size */
    size = sizeof(fifo_t) + fifo->num_pins * fifo->depth * sizeof(shmem_data_t);
    /* close shmem, re-open with proper size */
    rtapi_shmem_delete(shmem_id, comp_id);
    shmem_id = rtapi_shmem_new(STREAMER_SHMEM_KEY+channel, comp_id, size);
    if ( shmem_id < 0 ) {
	fprintf(stderr, "ERROR: couldn't re-allocate user/RT shared memory\n");
	goto out;
    }
    retval = rtapi_shmem_getptr(shmem_id, &shmem_ptr);
    if ( retval < 0 ) {
	fprintf(stderr, "ERROR: couldn't re-map user/RT shared memory\n");
	goto out;
    }
    line = 1;
    fifo = shmem_ptr;
    data = fifo->data;
    while ( fgets(buf, BUF_SIZE, stdin) ) {
	/* calculate _next_ value for in */
	tmpin = fifo->in;
	newin = tmpin + 1;
	if ( newin >= fifo->depth ) {
	    newin = 0;
	}
	/* wait until there is space in the buffer */
	while ( newin == fifo->out ) {
            /* fifo full, sleep for 10mS */
	    delay.tv_sec = 0;
	    delay.tv_nsec = 10000000;
	    nanosleep(&delay,NULL);
	}
	/* make pointer fifo entry */
	dptr = &data[tmpin*fifo->num_pins];
	/* parse input line, write results to fifo */
	cp = buf;
	errmsg = NULL;
	for ( n = 0 ; n < fifo->num_pins ; n++ ) {
	    /* strip leading whitespace */
	    while ( isspace(*cp) ) {
		cp++;
	    }
	    switch ( fifo->type[n] ) {
	    case HAL_FLOAT:
		dptr->f = strtod(cp, &cp2);
		break;
	    case HAL_BIT:
		if ( *cp == '0' ) {
		    dptr->b = 0;
		    cp2 = cp + 1;
		} else if ( *cp == '1' ) {
		    dptr->b = 1;
		    cp2 = cp + 1;
		} else {
		    errmsg = "bit value not 0 or 1";
		    cp2 = cp;
		}
		break;
	    case HAL_U32:
		dptr->u = strtoul(cp, &cp2, 10);
		break;
	    case HAL_S32:
		dptr->s = strtol(cp, &cp2, 10);
		break;
	    default:
		/* better not happen */
		goto out;
	    }
	    if ( errmsg == NULL ) {
		/* no error yet, check for other possibilties */
		/* whitespace separates fields, and there is a newline
		   at the end... so if there is not space or newline at
		   the end of a field, something is wrong. */
		if ( *cp2 == '\0' ) {
		    errmsg = "premature end of line";
		} else if ( ! isspace(*cp2) ) {
		    errmsg = "bad character";
		}
	    }
	    /* test for any error */
	    if ( errmsg != NULL ) {
		/* abort loop on error */
		break;
	    }
	    /* advance pointers for next field */
	    dptr++;
	    cp = cp2;
	}
	if ( errmsg != NULL ) {
	    /* print message */
	    fprintf (stderr, "line %d, field %d: %s, skipping the line\n", line, n, errmsg );
	    /** TODO - decide whether to skip this line and continue, or 
		abort the program.  Right now it skips the line. */
	} else {
	    /* good data, keep it */
	    fifo->in = newin;
	}
	line++;
    }
    /* run was succesfull */
    exitval = 0;

out:
    ignore_sig = 1;
    if ( shmem_id >= 0 ) {
	rtapi_shmem_delete(shmem_id, comp_id);
    }
    if ( comp_id >= 0 ) {
	hal_exit(comp_id);
    }
    return exitval;
}
Пример #13
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;
}
Пример #14
0
int main(int argc, gchar * argv[])
{
    int retval;
    int num_samples = SCOPE_NUM_SAMPLES_DEFAULT;
    void *shm_base;

    /* process and remove any GTK specific command line args */
    gtk_init(&argc, &argv);
    /* process halscope command line args (if any) here */
    if(argc > 1) num_samples = atoi(argv[1]);
    if(num_samples <= 0)
	num_samples = SCOPE_NUM_SAMPLES_DEFAULT;

    /* connect to the HAL */
    comp_id = hal_init("halscope");
    if (comp_id < 0) {
	rtapi_print_msg(RTAPI_MSG_ERR, "SCOPE: ERROR: hal_init() failed\n");
	return -1;
    }

    if (!halpr_find_funct_by_name("scope.sample")) {
	char buf[1000];
	sprintf(buf, EMC2_BIN_DIR "/halcmd loadrt scope_rt num_samples=%d",
		num_samples);
	if(system(buf) != 0) {
	    rtapi_print_msg(RTAPI_MSG_ERR, "loadrt scope_rt failed\n");
	    hal_exit(comp_id);
	    exit(1);
	}
    }
    /* set up a shared memory region for the scope data */
    shm_id = rtapi_shmem_new(SCOPE_SHM_KEY, comp_id, sizeof(scope_shm_control_t));
    if (shm_id < 0) {
	rtapi_print_msg(RTAPI_MSG_ERR,
	    "SCOPE: ERROR: failed to get shared memory\n");
	hal_exit(comp_id);
	return -1;
    }
    retval = rtapi_shmem_getptr(shm_id, &shm_base);
    if (retval < 0) {
	rtapi_print_msg(RTAPI_MSG_ERR,
	    "SCOPE: ERROR: failed to map shared memory\n");
	rtapi_shmem_delete(shm_id, comp_id);
	hal_exit(comp_id);
	return -1;
    }

    hal_ready(comp_id);

    /* register an exit function to cleanup and disconnect from the HAL */
    g_atexit(exit_from_hal);

    /* init control structure */
    ctrl_usr = &ctrl_struct;
    init_usr_control_struct(shm_base);

    /* init watchdog */
    ctrl_shm->watchdog = 10;
    /* set main window */
    define_scope_windows();
    /* this makes the application exit when the window is closed */
    gtk_signal_connect(GTK_OBJECT(ctrl_usr->main_win), "destroy",
	GTK_SIGNAL_FUNC(main_window_closed), NULL);
    gtk_signal_connect(GTK_OBJECT(ctrl_usr->main_win), "focus-in-event",
	GTK_SIGNAL_FUNC(set_focus), NULL);
    /* define menu windows */
    /* do next level of init */
    init_horiz();
    init_vert();
    init_trig();
    init_display();
    init_run_mode_window();
    /* register signal handlers for ctrl-C and SIGTERM */
    signal(SIGINT, quit);
    signal(SIGTERM, quit);

    /* The interface is now completely set up */
    /* show the window */
    gtk_widget_show(ctrl_usr->main_win);
    /* read the saved config file */
    read_config_file(".scope.cfg");
    /* arrange for periodic call of heartbeat() */
    gtk_timeout_add(100, heartbeat, NULL);
    /* enter the main loop */
    gtk_main();
    write_config_file(".scope.cfg");

    return (0);
}
Пример #15
0
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;
    }

}
Пример #16
0
int main(int argc, char **argv)
{
    int n, channel, retval, size, tag;
    long int samples;
    unsigned long this_sample;
    char  *cp2;
    char *name = NULL;
    void *shmem_ptr;
    fifo_t *fifo;
    shmem_data_t *data, *dptr, buf[MAX_PINS];
    int tmpout, newout;
    struct timespec delay;

    /* set return code to "fail", clear it later if all goes well */
    exitval = 1;
    channel = 0;
    tag = 0;
    samples = -1;  /* -1 means run forever */
    int  opt;

    while ((opt = getopt(argc, argv, "tn:c:N:")) != -1) {
	switch (opt) {
	case 'c':
	    channel = strtol(optarg, &cp2, 10);
	    if (( *cp2 ) || ( channel < 0 ) || ( channel >= MAX_SAMPLERS )) {
		fprintf(stderr,"ERROR: invalid channel number '%s'\n", optarg );
		exit(1);
	    }
	    break;
	case 'n':
	    samples = strtol(optarg, &cp2, 10);
	    if (( *cp2 ) || ( samples < 0 )) {
		fprintf(stderr, "ERROR: invalid sample count '%s'\n", optarg );
		exit(1);
	    }
	    break;
	case 'N':
	    name = optarg;
	    break;
	case 't':
	    tag = 1;
	    break;
	default: /* '?' */
	    fprintf(stderr,"ERROR: unknown option '%c'\n", opt);
	    fprintf(stderr,"valid options are:\n" );
	    fprintf(stderr,"\t-t\t\ttag values with sample number\n" );
	    fprintf(stderr,"\t-c <int>\t channel number\n" );
	    fprintf(stderr,"\t-n <int>\t sample count\n" );
	    fprintf(stderr,"\t-N <name>\t set HAL component name\n" );
	    exit(1);
	    exit(EXIT_FAILURE);
	}
    }
    if (optind < argc) {
	int fd;
	if(argc > optind+1) {
	    fprintf(stderr, "ERROR: At most one filename may be specified\n");
	    exit(1);
	}
	// make stdout be the named file
	fd = open(argv[optind], O_WRONLY | O_CREAT, 0666);
	close(1);
	dup2(fd, 1);
    }

    /* register signal handlers - if the process is killed
       we need to call hal_exit() to free the shared memory */
    signal(SIGINT, quit);
    signal(SIGTERM, quit);
    signal(SIGPIPE, quit);
    /* connect to HAL */
    if (name == NULL) {
	/* create a unique module name, to allow for multiple samplers */
	snprintf(comp_name, sizeof(comp_name), "halsampler%d", getpid());
	name = comp_name;
    }
    /* connect to the HAL */
    ignore_sig = 1;
    comp_id = hal_init(name);
    ignore_sig = 0;
    /* check result */
    if (comp_id < 0) {
	fprintf(stderr, "ERROR: hal_init() failed: %d\n", comp_id );
	goto out;
    }
    hal_ready(comp_id);
    /* open shmem for user/RT comms (fifo) */
    /* initial size is unknown, assume only the fifo structure */
    shmem_id = rtapi_shmem_new(SAMPLER_SHMEM_KEY+channel, comp_id, sizeof(fifo_t));
    if ( shmem_id < 0 ) {
	fprintf(stderr, "ERROR: couldn't allocate user/RT shared memory\n");
	goto out;
    }
    retval = rtapi_shmem_getptr(shmem_id, &shmem_ptr, 0);
    if ( retval < 0 ) {
	fprintf(stderr, "ERROR: couldn't map user/RT shared memory\n");
	goto out;
    }
    fifo = shmem_ptr;
    if ( fifo->magic != FIFO_MAGIC_NUM ) {
	fprintf(stderr, "ERROR: channel %d realtime part is not loaded\n", channel );
	goto out;
    }
    /* now use data in fifo structure to calculate proper shmem size */
    size = sizeof(fifo_t) + (1+fifo->num_pins) * fifo->depth * sizeof(shmem_data_t);
    /* close shmem, re-open with proper size */
    rtapi_shmem_delete(shmem_id, comp_id);
    shmem_id = rtapi_shmem_new(SAMPLER_SHMEM_KEY+channel, comp_id, size);
    if ( shmem_id < 0 ) {
	fprintf(stderr, "ERROR: couldn't re-allocate user/RT shared memory\n");
	goto out;
    }
    retval = rtapi_shmem_getptr(shmem_id, &shmem_ptr, 0);
    if ( retval < 0 ) {
	fprintf(stderr, "ERROR: couldn't re-map user/RT shared memory\n");
	goto out;
    }
    fifo = shmem_ptr;
    data = fifo->data;
    while ( samples != 0 ) {
	while ( fifo->in == fifo->out ) {
            /* fifo empty, sleep for 10mS */
	    delay.tv_sec = 0;
	    delay.tv_nsec = 10000000;
	    nanosleep(&delay,NULL);
	}
	/* make pointer to fifo entry */
	tmpout = fifo->out;
	newout = tmpout + 1;
	if ( newout >= fifo->depth ) {
	    newout = 0;
	}
	dptr = &data[tmpout * (fifo->num_pins+1)];
	/* read data from shmem into buffer */
	for ( n = 0 ; n < fifo->num_pins ; n++ ) {
	    buf[n] = *(dptr++);
	}
	/* and read sample number */
	this_sample = dptr->u;
	if ( fifo->out != tmpout ) {
	    /* the sample was overwritten while we were reading it */
	    /* so ignore it */
	    continue;
	} else {
	    /* update 'out' for next sample */
	    fifo->out = newout;
	}
	if ( this_sample != ++(fifo->last_sample) ) {
	    printf ( "overrun\n" );
	    fifo->last_sample = this_sample;
	}
	if ( tag ) {
	    printf ( "%ld ", this_sample );
	}
	for ( n = 0 ; n < fifo->num_pins ; n++ ) {
	    switch ( fifo->type[n] ) {
	    case HAL_FLOAT:
		printf ( "%f ", buf[n].f);
		break;
	    case HAL_BIT:
		if ( buf[n].b ) {
		    printf ( "1 " );
		} else {
		    printf ( "0 " );
		}
		break;
	    case HAL_U32:
		printf ( "%lu ", (unsigned long)buf[n].u);
		break;
	    case HAL_S32:
		printf ( "%ld ", (long)buf[n].s);
		break;
	    default:
		/* better not happen */
		goto out;
	    }
	}
	printf ( "\n" );
	if ( samples > 0 ) {
	    samples--;
	}
    }
    /* run was succesfull */
    exitval = 0;

out:
    ignore_sig = 1;
    if ( shmem_id >= 0 ) {
	rtapi_shmem_delete(shmem_id, comp_id);
    }
    if ( comp_id >= 0 ) {
	hal_exit(comp_id);
    }
    return exitval;
}
Пример #17
0
static void exit_from_hal(void)
{
    rtapi_shmem_delete(shm_id, comp_id);
    hal_exit(comp_id);
}