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; }
int rtapi_init(const char *modname) { int n, module_id; module_data *module; /* say hello */ rtapi_print_msg(RTAPI_MSG_DBG, "RTAPI: initing module %s\n", modname); /* get shared memory block from OS and save its address */ errno = 0; if(!rtapi_data) rtapi_data = rtai_malloc(RTAPI_KEY, sizeof(rtapi_data_t)); // the check for -1 here is because rtai_malloc (in at least // rtai 3.6.1, and probably others) has a bug where it // sometimes returns -1 on error if (rtapi_data == NULL || rtapi_data == (rtapi_data_t*)-1) { rtapi_print_msg(RTAPI_MSG_ERR, "RTAPI: ERROR: could not open shared memory (%s)\n", strerror(errno)); check_memlock_limit("could not open shared memory"); rtapi_data = 0; return -ENOMEM; } nummods++; /* perform a global init if needed */ init_rtapi_data(rtapi_data); /* check revision code */ if (rtapi_data->rev_code != rev_code) { /* mismatch - release master shared memory block */ rtapi_print_msg(RTAPI_MSG_ERR, "RTAPI: ERROR: version mismatch %d vs %d\n", rtapi_data->rev_code, rev_code); 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; sem_array = rtapi_data->sem_array; fifo_array = rtapi_data->fifo_array; irq_array = rtapi_data->irq_array; /* perform local init */ for (n = 0; n <= RTAPI_MAX_SHMEMS; n++) { shmem_addr_array[n] = NULL; } /* get the mutex */ rtapi_mutex_get(&(rtapi_data->mutex)); /* find empty spot in module array */ n = 1; while ((n <= RTAPI_MAX_MODULES) && (module_array[n].state != NO_MODULE)) { n++; } if (n > RTAPI_MAX_MODULES) { /* no room */ rtapi_mutex_give(&(rtapi_data->mutex)); rtapi_print_msg(RTAPI_MSG_ERR, "RTAPI: ERROR: reached module limit %d\n", n); return -EMFILE; } /* we have space for the module */ module_id = n; module = &(module_array[n]); /* update module data */ module->state = USERSPACE; if (modname != NULL) { /* use name supplied by caller, truncating if needed */ snprintf(module->name, RTAPI_NAME_LEN, "%s", modname); } else { /* make up a name */ snprintf(module->name, RTAPI_NAME_LEN, "ULMOD%03d", module_id); } rtapi_data->ul_module_count++; rtapi_mutex_give(&(rtapi_data->mutex)); rtapi_print_msg(RTAPI_MSG_DBG, "RTAPI: module '%s' inited, ID = %02d\n", module->name, module_id); return module_id; }
int rtapi_init(char *modname) { int n, module_id; module_data *module; /* say hello */ rtapi_print_msg(RTAPI_MSG_DBG, "RTAPI: initing module %s\n", modname); /* setup revision string and code, and print opening message */ setup_revision_info(); /* get shared memory block from OS and save its address */ errno = 0; rtapi_data = rtai_malloc(RTAPI_KEY, sizeof(rtapi_data_t)); if (rtapi_data == NULL || rtapi_data == (rtapi_data_t*)-1) { rtapi_print_msg(RTAPI_MSG_ERR, "RTAPI: ERROR: could not open shared memory (errno=%d)\n", errno); return RTAPI_NOMEM; } /* perform a global init if needed */ init_rtapi_data(rtapi_data); /* check revision code */ if (rtapi_data->rev_code != rev_code) { /* mismatch - release master shared memory block */ rtapi_print_msg(RTAPI_MSG_ERR, "RTAPI: ERROR: version mismatch %d vs %d\n", rtapi_data->rev_code, rev_code); rtai_free(RTAPI_KEY, rtapi_data); return RTAPI_FAIL; } /* 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; sem_array = rtapi_data->sem_array; fifo_array = rtapi_data->fifo_array; irq_array = rtapi_data->irq_array; /* perform local init */ for (n = 0; n <= RTAPI_MAX_SHMEMS; n++) { shmem_addr_array[n] = NULL; } /* get the mutex */ rtapi_mutex_get(&(rtapi_data->mutex)); /* find empty spot in module array */ n = 1; while ((n <= RTAPI_MAX_MODULES) && (module_array[n].state != NO_MODULE)) { n++; } if (n > RTAPI_MAX_MODULES) { /* no room */ rtapi_mutex_give(&(rtapi_data->mutex)); rtapi_print_msg(RTAPI_MSG_ERR, "RTAPI: ERROR: reached module limit %d\n", n); return RTAPI_LIMIT; } /* we have space for the module */ module_id = n; module = &(module_array[n]); /* update module data */ module->state = USERSPACE; if (modname != NULL) { /* use name supplied by caller, truncating if needed */ snprintf(module->name, RTAPI_NAME_LEN, "%s", modname); } else { /* make up a name */ snprintf(module->name, RTAPI_NAME_LEN, "ULMOD%03d", module_id); } rtapi_data->ul_module_count++; rtapi_mutex_give(&(rtapi_data->mutex)); rtapi_print_msg(RTAPI_MSG_DBG, "RTAPI: module '%s' inited, ID = %02d\n", module->name, module_id); return module_id; }