예제 #1
0
int main()
{
    int fifo;
    char buffer[FIFO_SIZE + 1];
    int nchars;
    int retval;

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

    /* open the fifo */
    fifo = rtapi_fifo_new(FIFO_KEY, module, FIFO_SIZE, 'R');
    if (fifo < 0) {
	rtapi_print_msg(RTAPI_MSG_ERR,
	    "fifousr main: rtapi_fifo_new returned %d\n", fifo);
	rtapi_exit(module);
	return -1;
    }

    if (1 == setjmp(env))
	goto END;
    signal(SIGINT, quit);

    printf("waiting for fifo data, ctrl-C to quit\n");

    while (1) {
	nchars = rtapi_fifo_read(fifo, buffer, FIFO_SIZE);
	if (nchars <= 0) {
	    rtapi_print_msg(RTAPI_MSG_ERR,
		"fifousr main: rtapi_fifo_read returned %d\n", nchars);
	} else {
	    buffer[nchars] = '\0';
	    rtapi_print_msg(RTAPI_MSG_INFO,
		"fifousr main: read %d chars: '%s'\n", nchars, buffer);
	}
    }

  END:

    rtapi_print_msg(RTAPI_MSG_INFO, "shutting down\n");

    retval = rtapi_fifo_delete(fifo, module);
    if (retval < 0) {
	rtapi_print_msg(RTAPI_MSG_ERR,
	    "fifousr main: rtapi_fifo_delete returned %d\n", retval);
	rtapi_exit(module);
	return -1;
    }

    return rtapi_exit(module);
}
예제 #2
0
// this is now delayed to first hal_init() in this process
int hal_rtapi_attach()
{
    int retval;
    void *mem;
    char rtapi_name[RTAPI_NAME_LEN + 1];

    if (lib_mem_id < 0) {
	hal_print_msg(RTAPI_MSG_DBG, "HAL: initializing hal_lib\n");
	rtapi_snprintf(rtapi_name, RTAPI_NAME_LEN, "HAL_LIB_%d", (int)getpid());
	lib_module_id = rtapi_init(rtapi_name);
	if (lib_module_id < 0) {
	    hal_print_msg(RTAPI_MSG_ERR,
		"HAL: ERROR: could not not initialize RTAPI - realtime not started?\n");
	    return -EINVAL;
	}

	if (global_data == NULL) {
	    hal_print_msg(RTAPI_MSG_ERR,
			    "HAL: ERROR: RTAPI shutting down - exiting\n");
	    exit(1);
	}

	/* get HAL shared memory block from RTAPI */
	lib_mem_id = rtapi_shmem_new(HAL_KEY, lib_module_id, global_data->hal_size);
	if (lib_mem_id < 0) {
	    hal_print_msg(RTAPI_MSG_ERR,
		"HAL: ERROR: could not open shared memory\n");
	    rtapi_exit(lib_module_id);
	    return -EINVAL;
	}
	/* get address of shared memory area */
	retval = rtapi_shmem_getptr(lib_mem_id, &mem, 0);
	if (retval < 0) {
	    hal_print_msg(RTAPI_MSG_ERR,
		"HAL: ERROR: could not access shared memory\n");
	    rtapi_exit(lib_module_id);
	    return -EINVAL;
	}
	/* set up internal pointers to shared mem and data structure */
        hal_shmem_base = (char *) mem;
        hal_data = (hal_data_t *) mem;
	/* perform a global init if needed */
	retval = init_hal_data();
	if ( retval ) {
	    hal_print_msg(RTAPI_MSG_ERR,
		"HAL: ERROR: could not init shared memory\n");
	    rtapi_exit(lib_module_id);
	    return -EINVAL;
	}
    }
    return 0;
}
예제 #3
0
void rtapi_app_exit(void)
{
    int retval;

    /* disable parallel port hardware interrupts */
    rtapi_outb(rtapi_inb(PARPORT_BASE_ADDRESS + 2) & (~0x10),
	PARPORT_BASE_ADDRESS + 2);

    /* clear ISR */
    retval = rtapi_disable_interrupt(PARPORT_IRQ);
    if (retval < 0) {
	rtapi_print("extint exit: rtapi_disable_interrupt returned %d\n",
	    retval);
	return;
    }
    retval = rtapi_irq_delete(PARPORT_IRQ);
    if (retval < 0) {
	rtapi_print("extint exit: rtapi_irq_delete returned %d\n", retval);
	return;
    }

    rtapi_print("extint exit: interrupt count is %d\n", timer_count);

    retval = rtapi_exit(module);
    if (retval < 0) {
	rtapi_print("extint exit: rtapi_exit returned %d\n", retval);
	return;
    }
}
/* part of the Linux kernel module that stops the fifo task */
void rtapi_app_exit(void)
{
    int retval;

    retval = rtapi_task_pause(fifo_task);
    if (retval < 0) {
	rtapi_print("fifotask exit: rtapi_task_stop failed with %d\n",
	    retval);
    }

    retval = rtapi_task_delete(fifo_task);
    if (retval < 0) {
	rtapi_print("fifotask exit: rtapi_task_delete failed with %d\n",
	    retval);
    }

    retval = rtapi_fifo_delete(fifo, module);
    if (retval < 0) {
	rtapi_print("fifotask exit: rtapi_fifo_delete failed with %d\n",
	    retval);
    }

    rtapi_print("fifotask exit: done\n");

    rtapi_exit(module);
}
예제 #5
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);
}
예제 #6
0
파일: slave.c 프로젝트: chrmorais/miniemc2
/* part of the Linux kernel module that kicks off the timer task */
int rtapi_app_main(void)
{
    int retval;
    int slave_prio;

    module = rtapi_init("SEM_SLAVE");
    if (module < 0) {
	rtapi_print("sem slave init: rtapi_init returned %d\n", module);
	return -1;
    }

    /* open the semaphore */
    slave_sem = rtapi_sem_new(SEM_KEY, module);
    if (slave_sem < 0) {
	rtapi_print("sem slave init: rtapi_sem_new returned %d\n", slave_sem);
	rtapi_exit(module);
	return -1;
    }

    /* set the task priority to the lowest one; the master is higher */
    slave_prio = rtapi_prio_lowest();

    /* create the slave task */
    slave_task = rtapi_task_new(slave_code, 0 /* arg */ , slave_prio, module,
	SLAVE_STACKSIZE, RTAPI_NO_FP);
    if (slave_task < 0) {
	rtapi_print("sem slave init: rtapi_task_new returned %d\n",
	    slave_task);
	rtapi_exit(module);
	return -1;
    }

    /* start the slave task */
    retval = rtapi_task_resume(slave_task);
    if (retval != RTAPI_SUCCESS) {
	rtapi_print("sem slave init: rtapi_task_start returned %d\n", retval);
	rtapi_exit(module);
	return -1;
    }

    rtapi_print("sem slave init: started slave task\n");

    return 0;
}
예제 #7
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);
}
예제 #8
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;

}
예제 #9
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;
}
예제 #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
파일: slave.c 프로젝트: chrmorais/miniemc2
/* part of the Linux kernel module that stops the slave task */
void rtapi_app_exit(void)
{
    int retval;

    retval = rtapi_task_pause(slave_task);
    if (retval != RTAPI_SUCCESS) {
	rtapi_print("sem slave exit: rtapi_task_stop returned %d\n", retval);
    }
    retval = rtapi_task_delete(slave_task);
    if (retval != RTAPI_SUCCESS) {
	rtapi_print("sem slave exit: rtapi_task_delete returned %d\n",
	    retval);
    }

    retval = rtapi_sem_delete(slave_sem, module);
    if (retval != RTAPI_SUCCESS) {
	rtapi_print("sem slave exit: rtapi_sem_delete returned %d\n", retval);
    }
    rtapi_print("sem slave exit: slave count is %d\n", slave_count);

    rtapi_exit(module);
}
예제 #12
0
/* rtapi_app_exit() is substituted for cleanup_module() by a
   macro in rtapi_app.h */
void rtapi_app_exit(void)
{
    int retval;

    /* Stop the task */
    retval = rtapi_task_pause(timer_task);
    if (retval < 0) {
	rtapi_print("timertask exit: rtapi_task_pause returned %d\n", retval);
    }
    /* Remove the task from the list */

    retval = rtapi_task_delete(timer_task);
    if (retval < 0) {
	rtapi_print("timertask exit: rtapi_task_delete returned %d\n",
	    retval);
    }

    /* Print the final count just to show that the task did it's job */
    rtapi_print("timertask exit: timer count is %d\n", timer_count);
    /* Clean up and exit */
    rtapi_exit(module);

}
예제 #13
0
/* part of the Linux kernel module that kicks off the fifo task */
int rtapi_app_main(void)
{
    int retval;
    int fifo_prio;
    long period;

    module = rtapi_init("FIFOTASK");
    if (module < 0) {
	rtapi_print("fifotask init: rtapi_init failed with %d\n", module);
	return -1;
    }

    /* allocate and initialize the fifo */
    fifo = rtapi_fifo_new(FIFO_KEY, module, FIFO_SIZE, 'W');
    if (fifo < 0) {
	rtapi_print("fifotask init: rtapi_fifo_new failed with %d\n", fifo);
	rtapi_exit(module);
	return -1;
    }

    rtapi_print("fifotask: created fifo\n");

    /* is timer started? if so, what period? */
    period = rtapi_clock_set_period(0);
    if (period == 0) {
	/* not running, start it */
	rtapi_print("fifotask init: starting timer with period %ld\n",
	    TIMER_PERIOD_NSEC);
	period = rtapi_clock_set_period(TIMER_PERIOD_NSEC);
	if (period < 0) {
	    rtapi_print
		("fifotask init: rtapi_clock_set_period failed with %ld\n",
		period);
	    rtapi_exit(module);
	    return -1;
	}
    }
    /* make sure period <= desired period (allow 1% roundoff error) */
    if (period > (TIMER_PERIOD_NSEC + (TIMER_PERIOD_NSEC / 100))) {
	/* timer period too long */
	rtapi_print("fifotask init: clock period too long: %ld\n", period);
	rtapi_exit(module);
	return -1;
    }
    rtapi_print("fifotask init: desired clock %ld, actual %ld\n",
	TIMER_PERIOD_NSEC, period);

    /* set the task priority to lowest, since we only have one task */
    fifo_prio = rtapi_prio_lowest();

    /* create the fifo task */
    fifo_task = rtapi_task_new(fifo_code, 0 /* arg */ , fifo_prio, module,
	FIFO_STACKSIZE, RTAPI_NO_FP);
    if (fifo_task < 0) {
	rtapi_print("fifotask init: rtapi_task_new failed with %d\n",
	    fifo_task);
	rtapi_exit(module);
	return -1;
    }

    /* start the fifo task */
    retval = rtapi_task_start(fifo_task, FIFO_PERIOD_NSEC);
    if (retval < 0) {
	rtapi_print("fifotask init: rtapi_task_start failed with %d\n",
	    retval);
	rtapi_exit(module);
	return -1;
    }

    rtapi_print("fifotask: started fifo task\n");

    return 0;
}
예제 #14
0
/* part of the Linux kernel module that kicks off the shmem task */
int rtapi_app_main(void)
{
    int retval;
    int shmem_prio;
    long period;

    module = rtapi_init("SHMEMTASK");
    if (module < 0) {
	rtapi_print("shmemtask init: rtapi_init returned %d\n", module);
	return -1;
    }
    /* allocate and initialize the shared memory structure */
    shmem_mem = rtapi_shmem_new(key, module, sizeof(SHMEM_STRUCT));
    if (shmem_mem < 0) {
	rtapi_print("shmemtask init: rtapi_shmem_new returned %d\n",
	    shmem_mem);
	rtapi_exit(module);
	return -1;
    }
    retval = rtapi_shmem_getptr(shmem_mem, (void **) &shmem_struct);
    if (retval < 0) {
	rtapi_print("shmemtask init: rtapi_shmem_getptr returned %d\n",
	    retval);
	rtapi_exit(module);
	return -1;
    }

    shmem_struct->heartbeat = 0;

    /* is timer started? if so, what period? */
    period = rtapi_clock_set_period(0);
    if (period == 0) {
	/* not running, start it */
	rtapi_print("shmemtask init: starting timer with period %ld\n",
	    TIMER_PERIOD_NSEC);
	period = rtapi_clock_set_period(TIMER_PERIOD_NSEC);
	if (period < 0) {
	    rtapi_print
		("shmemtask init: rtapi_clock_set_period failed with %ld\n",
		period);
	    rtapi_exit(module);
	    return -1;
	}
    }
    /* make sure period <= desired period (allow 1% roundoff error) */
    if (period > (TIMER_PERIOD_NSEC + (TIMER_PERIOD_NSEC / 100))) {
	/* timer period too long */
	rtapi_print("shmemtask init: clock period too long: %ld\n", period);
	rtapi_exit(module);
	return -1;
    }
    rtapi_print("shmemtask init: desired clock %ld, actual %ld\n",
	TIMER_PERIOD_NSEC, period);

    /* set the task priority to lowest, since we only have one task */
    shmem_prio = rtapi_prio_lowest();

    /* create the shmem task */
    shmem_task = rtapi_task_new(shmem_code, 0 /* arg */ , shmem_prio, module,
	SHMEM_STACKSIZE, RTAPI_NO_FP);
    if (shmem_task < 0) {
	rtapi_print("shmemtask init: rtapi_task_new returned %d\n",
	    shmem_task);
	rtapi_exit(module);
	return -1;
    }

    /* start the shmem task */
    retval = rtapi_task_start(shmem_task, SHMEM_PERIOD_NSEC);
    if (retval < 0) {
	rtapi_print("shmemtask init: rtapi_task_start returned %d\n", retval);
	rtapi_exit(module);
	return -1;
    }

    rtapi_print("shmemtask init: started shmem task\n");

    return 0;
}
예제 #15
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;
}
예제 #16
0
int rtapi_app_main(void)
{
    int retval;
    void *mem;

    rtapi_switch = rtapi_get_handle();
    hal_print_msg(RTAPI_MSG_DBG,
		    "HAL_LIB:%d loading RT support gd=%pp\n",rtapi_instance,global_data);

    /* do RTAPI init */
    lib_module_id = rtapi_init("HAL_LIB");
    if (lib_module_id < 0) {
	hal_print_msg(RTAPI_MSG_ERR,
			"HAL_LIB:%d ERROR: rtapi init failed\n",
			rtapi_instance);
	return -EINVAL;
    }

    // paranoia
    if (global_data == NULL) {
	hal_print_msg(RTAPI_MSG_ERR,
			"HAL_LIB:%d ERROR: global_data == NULL\n",
			rtapi_instance);
	return -EINVAL;
    }

    /* get HAL shared memory block from RTAPI */
    lib_mem_id = rtapi_shmem_new(HAL_KEY, lib_module_id, global_data->hal_size);

    if (lib_mem_id < 0) {
	hal_print_msg(RTAPI_MSG_ERR,
			"HAL_LIB:%d ERROR: could not open shared memory\n",
			rtapi_instance);
	rtapi_exit(lib_module_id);
	return -EINVAL;
    }
    /* get address of shared memory area */
    retval = rtapi_shmem_getptr(lib_mem_id, &mem, 0);

    if (retval < 0) {
	hal_print_msg(RTAPI_MSG_ERR,
			"HAL_LIB:%d ERROR: could not access shared memory\n",
			rtapi_instance);
	rtapi_exit(lib_module_id);
	return -EINVAL;
    }
    /* set up internal pointers to shared mem and data structure */
    hal_shmem_base = (char *) mem;
    hal_data = (hal_data_t *) mem;
    /* perform a global init if needed */
    retval = init_hal_data();

    if ( retval ) {
	hal_print_msg(RTAPI_MSG_ERR,
			"HAL_LIB:%d ERROR: could not init shared memory\n",
			rtapi_instance);
	rtapi_exit(lib_module_id);
	return -EINVAL;
    }

    retval = hal_proc_init();

    if ( retval ) {
	hal_print_msg(RTAPI_MSG_ERR,
			"HAL_LIB: ERROR:%d could not init /proc files\n",
			rtapi_instance);
	rtapi_exit(lib_module_id);
	return -EINVAL;
    }

    /* done */
    hal_print_msg(RTAPI_MSG_DBG,
		    "HAL_LIB:%d kernel lib installed successfully\n",
		    rtapi_instance);
    return 0;
}
예제 #17
0
/* rtapi_app_main() is expanded to init_module() via a macro in
   rtapi_app.h */
int rtapi_app_main(void)
{
    int retval;
    int timer_prio;
    long period;

    module = rtapi_init("TIMERTASK");
    if (module < 0) {
	rtapi_print("timertask init: rtapi_init returned %d\n", module);
	return -1;
    }

    /* is timer started? if so, what period? */
    period = rtapi_clock_set_period(0);
    if (period == 0) {
	/* not running, start it */
	rtapi_print("timertask init: starting timer with period %ld\n",
	    TIMER_PERIOD_NSEC);
	period = rtapi_clock_set_period(TIMER_PERIOD_NSEC);
	if (period < 0) {
	    rtapi_print
		("timertask init: rtapi_clock_set_period failed with %ld\n",
		period);
	    rtapi_exit(module);
	    return -1;
	}
    }
    /* make sure period <= desired period (allow 1% roundoff error) */
    if (period > (TIMER_PERIOD_NSEC + (TIMER_PERIOD_NSEC / 100))) {
	/* timer period too long */
	rtapi_print("timertask init: clock period too long: %ld\n", period);
	rtapi_exit(module);
	return -1;
    }
    rtapi_print("timertask init: desired clock %ld, actual %ld\n",
	TIMER_PERIOD_NSEC, period);

    /* set the task priority to second lowest, since we only have one task */
    timer_prio = rtapi_prio_next_higher(rtapi_prio_lowest());

    /* create the timer task */
    /* the second arg is an abitrary int that is passed to the timer task on
       the first iterration */
    timer_task = rtapi_task_new(timer_code, 0 /* arg */ , timer_prio, module,
	TIMER_STACKSIZE, RTAPI_NO_FP);
    if (timer_task < 0) {
	/* See rtapi.h for the error codes returned */
	rtapi_print("timertask init: rtapi_task_new returned %d\n",
	    timer_task);
	rtapi_exit(module);
	return -1;
    }
    /* start the task running */
    retval = rtapi_task_start(timer_task, TASK_PERIOD_NSEC);
    if (retval < 0) {
	rtapi_print("timertask init: rtapi_task_start returned %d\n", retval);
	rtapi_exit(module);
	return -1;
    }
    rtapi_print("timertask init: started timer task\n");
    rtapi_print("timertask init: max delay = %ld\n", rtapi_delay_max());
    return 0;
}
예제 #18
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;
}
예제 #19
0
int hal_exit(int comp_id)
{
    int *prev, next;
    char name[HAL_NAME_LEN + 1];

    if (hal_data == 0) {
	hal_print_msg(RTAPI_MSG_ERR,
	    "HAL: ERROR: exit called before init\n");
	return -EINVAL;
    }
    hal_print_msg(RTAPI_MSG_DBG, "HAL: removing component %02d\n", 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... */
	    hal_print_msg(RTAPI_MSG_ERR,
			    "HAL: ERROR: component %d not found\n", comp_id);
	    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 */
		hal_print_msg(RTAPI_MSG_ERR,
				"HAL: ERROR: component %d not found\n", comp_id);
		return -EINVAL;
	    }
	    comp = SHMPTR(next);
	}
	/* found our component, unlink it from the list */
	*prev = comp->next_ptr;
	/* save component name for later */
	rtapi_snprintf(name, sizeof(name), "%s", comp->name);
	/* get rid of the component */
	free_comp_struct(comp);
	/*! \todo Another #if 0 */
#if 0
	/*! \todo FIXME - this is the beginning of a two pronged approach to managing
	  shared memory.  Prong 1 - re-init the shared memory allocator whenever
	  it is known to be safe.  Prong 2 - make a better allocator that can
	  reclaim memory allocated by components when those components are
	  removed. To be finished later. */
	/* was that the last component? */
	if (hal_data->comp_list_ptr == 0) {
	    /* yes, are there any signals or threads defined? */
	    if ((hal_data->sig_list_ptr == 0) && (hal_data->thread_list_ptr == 0)) {
		/* no, invalidate "magic" number so shmem will be re-inited when
		   a new component is loaded */
		hal_data->magic = 0;
	    }
	}
#endif
	// scope exit - mutex released
    }
    // the RTAPI resources are now released
    // on hal_lib shared library unload
    rtapi_exit(comp_id);
    /* done */
    hal_print_msg(RTAPI_MSG_DBG,
	"HAL: component %02d removed, name = '%s'\n", comp_id, name);

    return 0;
}