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); }
// 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; }
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); }
/* 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); }
/* 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; }
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); }
/* 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 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; }
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); }
/* 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); }
/* 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); }
/* 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; }
/* 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; }
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; }
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; }
/* 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; }
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; }
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; }