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; }
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; }
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; }