/** 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; }
int hal_compile_comp(const char *name, hal_compiled_comp_t **ccomp) { hal_compiled_comp_t *tc; int pincount = 0; CHECK_HALDATA(); CHECK_STRLEN(name, HAL_NAME_LEN); { hal_comp_t *comp __attribute__((cleanup(halpr_autorelease_mutex))); int next, n; hal_comp_t *owner; hal_pin_t *pin; rtapi_mutex_get(&(hal_data->mutex)); if ((comp = halpr_find_comp_by_name(name)) == NULL) { HALERR("no such component '%s'", name); return -EINVAL; } // array sizing: count pins owned by this component next = hal_data->pin_list_ptr; n = 0; while (next != 0) { pin = SHMPTR(next); owner = halpr_find_owning_comp(pin->owner_id); if (owner->comp_id == comp->comp_id) { if (!(pin->flags & PIN_DO_NOT_TRACK)) n++; pincount++; } next = pin->next_ptr; } if (n == 0) { HALERR("component %s has no pins to watch for changes", name); return -EINVAL; } // a compiled comp is a userland/per process memory object if ((tc = malloc(sizeof(hal_compiled_comp_t))) == NULL) return -ENOMEM; memset(tc, 0, sizeof(hal_compiled_comp_t)); tc->comp = comp; tc->n_pins = n; // alloc pin array if ((tc->pin = malloc(sizeof(hal_pin_t *) * tc->n_pins)) == NULL) return -ENOMEM; // alloc tracking value array if ((tc->tracking = malloc(sizeof(hal_data_u) * tc->n_pins )) == NULL) return -ENOMEM; // alloc change bitmap if ((tc->changed = malloc(RTAPI_BITMAP_BYTES(tc->n_pins))) == NULL) return -ENOMEM; memset(tc->pin, 0, sizeof(hal_pin_t *) * tc->n_pins); memset(tc->tracking, 0, sizeof(hal_data_u) * tc->n_pins); RTAPI_ZERO_BITMAP(tc->changed,tc->n_pins); // fill in pin array n = 0; next = hal_data->pin_list_ptr; while (next != 0) { pin = SHMPTR(next); owner = halpr_find_owning_comp(pin->owner_id); if ((owner->comp_id == comp->comp_id) && !(pin->flags & PIN_DO_NOT_TRACK)) tc->pin[n++] = pin; next = pin->next_ptr; } assert(n == tc->n_pins); tc->magic = CCOMP_MAGIC; *ccomp = tc; } HALDBG("ccomp '%s': %d pins, %d tracked", name, pincount, tc->n_pins); return 0; }
int hal_ccomp_match(hal_compiled_comp_t *cc) { int i, nchanged = 0; hal_bit_t halbit; hal_s32_t hals32; hal_s32_t halu32; hal_float_t halfloat,delta; hal_pin_t *pin; hal_sig_t *sig; void *data_ptr; assert(cc->magic == CCOMP_MAGIC); RTAPI_ZERO_BITMAP(cc->changed, cc->n_pins); for (i = 0; i < cc->n_pins; i++) { pin = cc->pin[i]; if (pin->signal != 0) { sig = SHMPTR(pin->signal); data_ptr = SHMPTR(sig->data_ptr); } else { data_ptr = hal_shmem_base + SHMOFF(&(pin->dummysig)); } switch (pin->type) { case HAL_BIT: halbit = *((char *) data_ptr); if (cc->tracking[i].b != halbit) { nchanged++; RTAPI_BIT_SET(cc->changed, i); cc->tracking[i].b = halbit; } break; case HAL_FLOAT: halfloat = *((hal_float_t *) data_ptr); delta = HAL_FABS(halfloat - cc->tracking[i].f); if (delta > hal_data->epsilon[pin->eps_index]) { nchanged++; RTAPI_BIT_SET(cc->changed, i); cc->tracking[i].f = halfloat; } break; case HAL_S32: hals32 = *((hal_s32_t *) data_ptr); if (cc->tracking[i].s != hals32) { nchanged++; RTAPI_BIT_SET(cc->changed, i); cc->tracking[i].s = hals32; } break; case HAL_U32: halu32 = *((hal_u32_t *) data_ptr); if (cc->tracking[i].u != halu32) { nchanged++; RTAPI_BIT_SET(cc->changed, i); cc->tracking[i].u = halu32; } break; default: HALERR("BUG: hal_ccomp_match(%s): invalid type for pin %s: %d", cc->comp->name, pin->name, pin->type); return -EINVAL; } } return nchanged; }
int hal_compile_comp(const char *name, hal_compiled_comp_t **ccomp) { hal_compiled_comp_t *tc; int pincount = 0; if (!name) { hal_print_msg(RTAPI_MSG_ERR, "HAL:%d ERROR: hal_compile_comp() called with NULL name\n", rtapi_instance); return -EINVAL; } { hal_comp_t *comp __attribute__((cleanup(halpr_autorelease_mutex))); int next, n; hal_comp_t *owner; hal_pin_t *pin; rtapi_mutex_get(&(hal_data->mutex)); if ((comp = halpr_find_comp_by_name(name)) == NULL) { hal_print_msg(RTAPI_MSG_ERR, "HAL:%d ERROR: hal_comp_compile(%s): no such comp\n", rtapi_instance, name); return -EINVAL; } // array sizing: count pins owned by this component next = hal_data->pin_list_ptr; n = 0; while (next != 0) { pin = SHMPTR(next); owner = SHMPTR(pin->owner_ptr); if (owner->comp_id == comp->comp_id) { if (!(pin->flags & PIN_DO_NOT_TRACK)) n++; pincount++; } next = pin->next_ptr; } if (n == 0) { hal_print_msg(RTAPI_MSG_ERR, "ERROR: component %s has no pins to watch for changes\n", name); return -EINVAL; } // a compiled comp is a userland/per process memory object if ((tc = malloc(sizeof(hal_compiled_comp_t))) == NULL) return -ENOMEM; memset(tc, 0, sizeof(hal_compiled_comp_t)); tc->comp = comp; tc->n_pins = n; // alloc pin array if ((tc->pin = malloc(sizeof(hal_pin_t *) * tc->n_pins)) == NULL) return -ENOMEM; // alloc tracking value array if ((tc->tracking = malloc(sizeof(hal_data_u) * tc->n_pins )) == NULL) return -ENOMEM; // alloc change bitmap if ((tc->changed = malloc(RTAPI_BITMAP_BYTES(tc->n_pins))) == NULL) return -ENOMEM; memset(tc->pin, 0, sizeof(hal_pin_t *) * tc->n_pins); memset(tc->tracking, 0, sizeof(hal_data_u) * tc->n_pins); RTAPI_ZERO_BITMAP(tc->changed,tc->n_pins); // fill in pin array n = 0; next = hal_data->pin_list_ptr; while (next != 0) { pin = SHMPTR(next); owner = SHMPTR(pin->owner_ptr); if ((owner->comp_id == comp->comp_id) && !(pin->flags & PIN_DO_NOT_TRACK)) tc->pin[n++] = pin; next = pin->next_ptr; } assert(n == tc->n_pins); tc->magic = CCOMP_MAGIC; *ccomp = tc; } hal_print_msg(RTAPI_MSG_DBG, "hal_compile_comp(%s): %d pins, %d tracked", name, pincount, tc->n_pins); return 0; }