Beispiel #1
0
int main(int argc, char** argv)
{
	ASSERT(argc > 1, "Specify a bytecode file in the first and only argument, please\n");

	init_mdata();                       // Initalize the instruction defs
	init_adata();
	init_ins_def();

	rt_t* runtime = proc_init(argv[1]); // Initalize process

	proc_run(runtime);                  // Execute runtime

	proc_clean(runtime);                // Once `proc_run` returns, clean
	                                    // what sort of mess it made.

	return 0;
}
Beispiel #2
0
int init_module(void) {
    int n;
    struct shm_status sm;
    int retval;

    rtapi_switch = rtapi_get_handle();

    // first thing: attach global_data
    sm.key = OS_KEY(GLOBAL_KEY, rtapi_instance);
    sm.size = 0;
    sm.flags = 0;

    if ((retval = shmdrv_attach(&sm, (void **)&global_data)) < 0) {
	// cant use the  message ringbuffer just yet
	printk("RTAPI:%d ERROR: can attach global segment: %d\n",
	       rtapi_instance, retval);
	return -EINVAL;
    }
    
    // fail immediately if the global segment isnt in shape yet
    // this catches https://github.com/zultron/linuxcnc/issues/49 early
    if (global_data->magic != GLOBAL_READY) {
	
	printk("RTAPI:%d ERROR: bad global magic: 0x%x\n",
	       rtapi_instance,global_data->magic);

	// TBD: remove once cause identified
	printk("halsize=%d\n", global_data->hal_size);
	printk("msgd pid=%d\n", global_data->rtapi_msgd_pid);
	printk("magic=%x\n", global_data->magic);
	printk("flavor=%d\n", global_data->rtapi_thread_flavor);
	// fail the insmod
	return -EINVAL;
    }

    // say hello - this now goes through the message ringbuffer
    rtapi_print_msg(RTAPI_MSG_INFO, "RTAPI:%d %s %s init\n", 
		    rtapi_instance,
		    rtapi_get_handle()->thread_flavor_name, 
		    GIT_VERSION);


    sm.key = OS_KEY(RTAPI_KEY, rtapi_instance);
    sm.size = sizeof(rtapi_data_t);
    sm.flags = 0;
    if ((retval = shmdrv_create(&sm)) < 0) {
	rtapi_print_msg(RTAPI_MSG_ERR,
			"RTAPI:%d ERROR: can create rtapi segment: %d\n",
			rtapi_instance, retval);
	return -EINVAL;
    }
    if ((retval = shmdrv_attach(&sm, (void **)&rtapi_data)) < 0) {
	rtapi_print_msg(RTAPI_MSG_ERR,
			"RTAPI:%d ERROR: cant attach rtapi segment: %d\n",
			rtapi_instance, retval);
	return -EINVAL;
    }

    // make error ringbuffer accessible within RTAPI
    ringbuffer_init(&global_data->rtapi_messages, &rtapi_message_buffer);
    global_data->rtapi_messages.refcount += 1;   // rtapi is 'attached'

    // tag messages originating from RT proper
    rtapi_set_logtag("rt");

    /* this will take care of any threads flavor hook */
    init_rtapi_data(rtapi_data);

    /* check flavor and serial codes */
    if (rtapi_data->thread_flavor_id != THREAD_FLAVOR_ID) {
	/* mismatch - release master shared memory block */
	rtapi_print_msg(RTAPI_MSG_ERR,
			"RTAPI: ERROR: flavor mismatch %d vs %d\n",
			rtapi_data->thread_flavor_id, THREAD_FLAVOR_ID);

	sm.key = OS_KEY(RTAPI_KEY, rtapi_instance);
	sm.size = sizeof(global_data_t);
	sm.flags = 0;
	if ((retval = shmdrv_detach(&sm)) < 0) {
	    rtapi_print_msg(RTAPI_MSG_ERR,
			    "INSTANCE:%d ERROR: shmdrv_detach() returns %d\n",
			    rtapi_instance, retval);
	}
	sm.key = OS_KEY(GLOBAL_KEY, rtapi_instance);
	sm.size = sizeof(global_data_t);
	sm.flags = 0;
	if ((retval = shmdrv_detach(&sm)) < 0) {
	    rtapi_print_msg(RTAPI_MSG_ERR,
			    "INSTANCE:%d ERROR: shmdrv_detach() returns %d\n",
			    rtapi_instance, retval);
	}
	return -EINVAL;
    }
    if (rtapi_data->serial != RTAPI_SERIAL) {
	/* mismatch - release master shared memory block */
	rtapi_print_msg(RTAPI_MSG_ERR,
			"RTAPI: ERROR: serial mismatch '%d' vs '%d'\n",
			rtapi_data->serial, RTAPI_SERIAL);
	return -EINVAL;
    }
    /* set up local pointers to global data */
    module_array = rtapi_data->module_array;
    task_array = rtapi_data->task_array;
    shmem_array = rtapi_data->shmem_array;

    /* perform local init */
    for (n = 0; n <= RTAPI_MAX_TASKS; n++) {
	ostask_array[n] = NULL;
    }
    for (n = 0; n <= RTAPI_MAX_SHMEMS; n++) {
	shmem_addr_array[n] = NULL;
    }
    rtapi_data->timer_running = 0;
    rtapi_data->timer_period = 0;
    max_delay = DEFAULT_MAX_DELAY;

#ifdef RT_LINUX_USE_FPU
    rt_linux_use_fpu(1);
#endif

#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
    /* on SMP machines, we want to put RT code on the last CPU */
    n = NR_CPUS-1;
    while ( ! cpu_online(n) ) {
	n--;
    }
    rtapi_data->rt_cpu = n;
#else
    /* old kernel, the SMP hooks aren't available, so use CPU 0 */
    rtapi_data->rt_cpu = 0;
#endif


#ifdef CONFIG_PROC_FS
    /* set up /proc/rtapi */
    if (proc_init() != 0) {
	rtapi_print_msg(RTAPI_MSG_WARN,
	    "RTAPI: WARNING: Could not activate /proc entries\n");
	proc_clean();
    }
#endif

#ifdef HAVE_RTAPI_MODULE_INIT_HOOK
    _rtapi_module_init_hook();
#endif

    /* done */
    rtapi_print_msg(RTAPI_MSG_INFO, "RTAPI:%d Init complete\n", 
		    rtapi_instance);
    return 0;
}
Beispiel #3
0
void cleanup_module(void) {
    int n;
    struct shm_status sm;
    int retval;

    if (rtapi_data == NULL) {
	/* never got inited, nothing to do */
	return;
    }

#ifdef HAVE_RTAPI_MODULE_EXIT_HOOK
    _rtapi_module_exit_hook();
#endif

    /* grab the mutex */
    rtapi_mutex_get(&(rtapi_data->mutex));
    rtapi_print_msg(RTAPI_MSG_INFO, "RTAPI:%d exit\n", rtapi_instance);

    /* clean up leftover modules (start at 1, we don't use ID 0 */
    for (n = 1; n <= RTAPI_MAX_MODULES; n++) {
	if (module_array[n].state == REALTIME) {
	    rtapi_print_msg(RTAPI_MSG_WARN,
			    "RTAPI: WARNING: module '%s' (ID: %02d) did not "
			    "call rtapi_exit()\n",
			    module_array[n].name, n);
	    module_delete(n);
	}
    }

    /* cleaning up modules should clean up everything, if not there has
       probably been an unrecoverable internal error.... */
    for (n = 1; n <= RTAPI_MAX_SHMEMS; n++) {
	if (shmem_array[n].rtusers > 0) {
	    rtapi_print_msg(RTAPI_MSG_ERR,
		"RTAPI: ERROR: shared memory block %02d not deleted\n", n);
	}
    }
    for (n = 1; n <= RTAPI_MAX_TASKS; n++) {
	if (task_array[n].state != EMPTY) {
	    rtapi_print_msg(RTAPI_MSG_ERR,
		"RTAPI: ERROR: task %02d not deleted\n", n);
	    /* probably un-recoverable, but try anyway */
	    _rtapi_task_pause(n);
	    /* rtapi_task_delete should not grab mutex  */
	    task_array[n].state = DELETE_LOCKED;
	    _rtapi_task_delete(n);
	}
    }
    if (rtapi_data->timer_running != 0) {
#ifdef HAVE_RTAPI_MODULE_TIMER_STOP
	_rtapi_module_timer_stop();
#endif
	rtapi_data->timer_period = 0;
	timer_counts = 0;
	rtapi_data->timer_running = 0;
	max_delay = DEFAULT_MAX_DELAY;
    }
    rtapi_mutex_give(&(rtapi_data->mutex));
#ifdef CONFIG_PROC_FS
    proc_clean();
#endif

    sm.key = OS_KEY(RTAPI_KEY, rtapi_instance);
    sm.size = sizeof(rtapi_data_t);
    sm.flags = 0;
    if ((retval = shmdrv_detach(&sm)) < 0) {
	rtapi_print_msg(RTAPI_MSG_ERR,
			"RTAPI:%d ERROR: detach rtapi returns %d\n",
			rtapi_instance, retval);
    }
    rtapi_data = NULL;

    global_data->rtapi_messages.refcount -= 1;   // detach rtapi end

    sm.key = OS_KEY(GLOBAL_KEY, rtapi_instance);
    sm.size = sizeof(global_data_t);
    sm.flags = 0;
    if ((retval = shmdrv_detach(&sm)) < 0) {
	rtapi_print_msg(RTAPI_MSG_ERR,
			"RTAPI:%d ERROR: detach global returns %d\n",
			rtapi_instance, retval);
    }
    global_data = NULL;
    rtapi_print_msg(RTAPI_MSG_INFO, "RTAPI:%d Exit complete\n",
		    rtapi_instance);
    return;
}