int rtapi_app_main(void) { int retval; dlist_init_entry(&head); if ((comp_id = hal_xinit(TYPE_RT, 0, 0, instantiate_encoder_pair, delete_encoder_pair, compname)) < 0) return comp_id; hal_export_xfunct_args_t u = { .type = FS_XTHREADFUNC, .funct.x = update, .arg = &head, .uses_fp = 1, .reentrant = 0, .owner_id = comp_id }; if ((retval = hal_export_xfunctf(&u, "%s.update", prefix)) < 0) return retval; hal_export_xfunct_args_t mp = { .type = FS_XTHREADFUNC, .funct.x = sample, .arg = &head, .uses_fp = 0, .reentrant = 0, .owner_id = comp_id }; if ((retval = hal_export_xfunctf(&mp, "%s.sample", prefix)) < 0) return retval; hal_ready(comp_id); return 0; } void rtapi_app_exit(void) { hal_exit(comp_id); } static int instantiate_encoder_pair(const int argc, const char**argv) { encoder_pair_t *p; int retval; int msg; const char* name; if(argc >= 2) name = argv[1]; else HALFAIL_RC(EINVAL, "ERROR: insufficient args in argv"); /* This function exports a lot of stuff, which results in a lot of logging if msg_level is at INFO or ALL. So we save the current value of msg_level and restore it later. */ msg = rtapi_get_msg_level(); #ifndef VERBOSE_SETUP rtapi_set_msg_level(RTAPI_MSG_WARN); #endif if ((retval = hal_inst_create(name, comp_id, sizeof(encoder_pair_t), (void **)&p)) < 0) return retval; p->inst_id = retval; if ((retval = export_encoder_pair(name, p->inst_id, p)) != 0) HALFAIL_RC(retval, "%s: ERROR: export(%s) failed", compname, name); // append to instance list dlist_init_entry(&p->list); dlist_add_after(&p->list, &head); /* restore saved message level */ rtapi_set_msg_level(msg); return 0; }
int rtapi_app_main(void) { int n, retval; /* test for number of channels */ if ((num_chan <= 0) || (num_chan > MAX_CHAN)) { rtapi_print_msg(RTAPI_MSG_ERR, "ENCODER_RATIO: ERROR: invalid num_chan: %d\n", num_chan); return -1; } /* have good config info, connect to the HAL */ comp_id = hal_init("encoder_ratio"); if (comp_id < 0) { rtapi_print_msg(RTAPI_MSG_ERR, "ENCODER_RATIO: ERROR: hal_init() failed\n"); return -1; } /* allocate shared memory for encoder data */ encoder_pair_array = hal_malloc(num_chan * sizeof(encoder_pair_t)); if (encoder_pair_array == 0) { rtapi_print_msg(RTAPI_MSG_ERR, "ENCODER_RATIO: ERROR: hal_malloc() failed\n"); hal_exit(comp_id); return -1; } /* set up each encoder pair */ for (n = 0; n < num_chan; n++) { /* export all vars */ retval = export_encoder_pair(n, &(encoder_pair_array[n])); if (retval != 0) { rtapi_print_msg(RTAPI_MSG_ERR, "ENCODER_RATIO: ERROR: counter %d var export failed\n", n); hal_exit(comp_id); return -1; } /* init encoder pair */ encoder_pair_array[n].master_state = 0; encoder_pair_array[n].slave_state = 0; encoder_pair_array[n].master_increment = 0; encoder_pair_array[n].slave_increment = 0; encoder_pair_array[n].raw_error = 0; encoder_pair_array[n].output_scale = 1.0; *(encoder_pair_array[n].error) = 0.0; } /* export functions */ retval = hal_export_funct("encoder-ratio.sample", sample, encoder_pair_array, 0, 0, comp_id); if (retval != 0) { rtapi_print_msg(RTAPI_MSG_ERR, "ENCODER_RATIO: ERROR: sample funct export failed\n"); hal_exit(comp_id); return -1; } retval = hal_export_funct("encoder-ratio.update", update, encoder_pair_array, 1, 0, comp_id); if (retval != 0) { rtapi_print_msg(RTAPI_MSG_ERR, "ENCODER_RATIO: ERROR: update funct export failed\n"); hal_exit(comp_id); return -1; } rtapi_print_msg(RTAPI_MSG_INFO, "ENCODER_RATIO: installed %d encoder_ratio blocks\n", num_chan); hal_ready(comp_id); return 0; }