void init_rtapi_data(rtapi_data_t * data) { int n, m; /* has the block already been initialized? */ if (data->magic == RTAPI_MAGIC) { /* yes, nothing to do */ return; } /* no, we need to init it, grab mutex unconditionally */ rtapi_mutex_try(&(data->mutex)); /* set magic number so nobody else init's the block */ data->magic = RTAPI_MAGIC; /* set version code and flavor ID so other modules can check it */ data->serial = RTAPI_SERIAL; data->thread_flavor_id = THREAD_FLAVOR_ID; data->ring_mutex = 0; /* and get busy */ data->rt_module_count = 0; data->ul_module_count = 0; data->task_count = 0; data->shmem_count = 0; data->timer_running = 0; data->timer_period = 0; /* init the arrays */ for (n = 0; n <= RTAPI_MAX_MODULES; n++) { data->module_array[n].state = EMPTY; data->module_array[n].name[0] = '\0'; } for (n = 0; n <= RTAPI_MAX_TASKS; n++) { data->task_array[n].state = EMPTY; data->task_array[n].prio = 0; data->task_array[n].owner = 0; data->task_array[n].taskcode = NULL; data->task_array[n].cpu = -1; // use default } for (n = 0; n <= RTAPI_MAX_SHMEMS; n++) { data->shmem_array[n].key = 0; data->shmem_array[n].rtusers = 0; data->shmem_array[n].ulusers = 0; data->shmem_array[n].size = 0; for (m = 0; m < RTAPI_BITMAP_SIZE(RTAPI_MAX_SHMEMS +1); m++) { data->shmem_array[n].bitmap[m] = 0; } } /* done, release the mutex */ rtapi_mutex_give(&(data->mutex)); return; }
void vs_ring_write(msg_level_t level, const char *format, va_list ap) { int n; rtapi_msg_t logmsg; #if defined(RTAPI) && defined(BUILD_SYS_USER_DSO) static pid_t rtapi_pid; if (rtapi_pid == 0) rtapi_pid = getpid(); #endif if (global_data) { // one-time initialisation if (!rtapi_message_buffer.header) { ringbuffer_init(&global_data->rtapi_messages, &rtapi_message_buffer); } logmsg.hdr.origin = MSG_ORIGIN; #if defined(RTAPI) && defined(BUILD_SYS_KBUILD) logmsg.hdr.pid = 0; #endif #if defined(RTAPI) && defined(BUILD_SYS_USER_DSO) logmsg.hdr.pid = rtapi_pid; #endif #if defined(ULAPI) logmsg.hdr.pid = getpid(); #endif logmsg.hdr.level = level; logmsg.hdr.encoding = MSG_ASCII; strncpy(logmsg.hdr.tag, logtag, sizeof(logmsg.hdr.tag)); // do format outside critical section n = vsnprintf(logmsg.buf, RTPRINTBUFFERLEN, format, ap); if (rtapi_message_buffer.header->use_wmutex && rtapi_mutex_try(&rtapi_message_buffer.header->wmutex)) { global_data->error_ring_locked++; return; } // use copying writer to shorten criticial section record_write(&rtapi_message_buffer, (void *) &logmsg, sizeof(rtapi_msgheader_t) + n + 1); // trailing zero if (rtapi_message_buffer.header->use_wmutex) rtapi_mutex_give(&rtapi_message_buffer.header->wmutex); } }
/** init_hal_data() initializes the entire HAL data structure, by the RT hal_lib component */ int init_hal_data(void) { /* has the block already been initialized? */ if (hal_data->version != 0) { /* yes, verify version code */ if (hal_data->version == HAL_VER) { return 0; } else { HALERR("version code mismatch"); return -1; } } /* no, we need to init it, grab the mutex unconditionally */ rtapi_mutex_try(&(hal_data->mutex)); // some heaps contain garbage, like xenomai memset(hal_data, 0, global_data->hal_size); /* set version code so nobody else init's the block */ hal_data->version = HAL_VER; /* initialize everything */ hal_data->comp_list_ptr = 0; hal_data->pin_list_ptr = 0; hal_data->sig_list_ptr = 0; hal_data->param_list_ptr = 0; hal_data->funct_list_ptr = 0; hal_data->thread_list_ptr = 0; hal_data->vtable_list_ptr = 0; hal_data->base_period = 0; hal_data->threads_running = 0; hal_data->oldname_free_ptr = 0; hal_data->comp_free_ptr = 0; hal_data->pin_free_ptr = 0; hal_data->sig_free_ptr = 0; hal_data->param_free_ptr = 0; hal_data->funct_free_ptr = 0; hal_data->vtable_free_ptr = 0; list_init_entry(&(hal_data->funct_entry_free)); hal_data->thread_free_ptr = 0; hal_data->exact_base_period = 0; hal_data->group_list_ptr = 0; hal_data->member_list_ptr = 0; hal_data->ring_list_ptr = 0; hal_data->inst_list_ptr = 0; hal_data->group_free_ptr = 0; hal_data->member_free_ptr = 0; hal_data->ring_free_ptr = 0; hal_data->inst_free_ptr = 0; RTAPI_ZERO_BITMAP(&hal_data->rings, HAL_MAX_RINGS); // silly 1-based shm segment id allocation FIXED // yeah, 'user friendly', how could one possibly think zero might be a valid id RTAPI_BIT_SET(hal_data->rings,0); /* set up for shmalloc_xx() */ hal_data->shmem_bot = sizeof(hal_data_t); hal_data->shmem_top = global_data->hal_size; hal_data->lock = HAL_LOCK_NONE; int i; for (i = 0; i < MAX_EPSILON; i++) hal_data->epsilon[i] = 0.0; hal_data->epsilon[0] = DEFAULT_EPSILON; /* done, release mutex */ rtapi_mutex_give(&(hal_data->mutex)); return 0; }
void init_global_data(global_data_t * data, int flavor, int instance_id, int hal_size, int rt_level, int user_level, const char *name, int stack_size) { // force-lock - we're first, so thats a bit theoretical rtapi_mutex_try(&(data->mutex)); // touch all memory exposed to RT memset(data, 0, sizeof(global_data_t)); // lock the global data segment if (flavor != RTAPI_POSIX_ID) { if (mlock(data, sizeof(global_data_t))) { syslog_async(LOG_ERR, "MSGD:%d mlock(global) failed: %d '%s'\n", instance_id, errno,strerror(errno)); } } // report progress data->magic = GLOBAL_INITIALIZING; /* set version code so other modules can check it */ data->layout_version = GLOBAL_LAYOUT_VERSION; data->instance_id = instance_id; if ((name == NULL) || (strlen(name) == 0)) { snprintf(data->instance_name, sizeof(data->instance_name), "inst%d",rtapi_instance); } else { strncpy(data->instance_name,name, sizeof(data->instance_name)); } // separate message levels for RT and userland data->rt_msg_level = rt_level; data->user_msg_level = user_level; // next value returned by rtapi_init (userland threads) // those dont use fixed sized arrays // start at 1 because the meaning of zero is special data->next_module_id = 1; // tell the others what we determined as the proper flavor data->rtapi_thread_flavor = flavor; // HAL segment size data->hal_size = hal_size; // stack size passed to rtapi_task_new() in hal_create_thread() data->hal_thread_stack_size = stack_size; // init the error ring ringheader_init(&data->rtapi_messages, 0, SIZE_ALIGN(MESSAGE_RING_SIZE), 0); memset(&data->rtapi_messages.buf[0], 0, SIZE_ALIGN(MESSAGE_RING_SIZE)); // attach to the message ringbuffer ringbuffer_init(&data->rtapi_messages, &rtapi_msg_buffer); rtapi_msg_buffer.header->refcount = 1; // rtapi not yet attached rtapi_msg_buffer.header->reader = getpid(); data->rtapi_messages.use_wmutex = 1; // locking hint // demon pids data->rtapi_app_pid = -1; // not yet started data->rtapi_msgd_pid = 0; /* done, release the mutex */ rtapi_mutex_give(&(data->mutex)); return; }