/* Function: mdlTerminate ===================================================== * Abstract: * In this function, you should perform any actions that are necessary * at the termination of a simulation. For example, if memory was * allocated in mdlStart, this is the place to free it. */ static void mdlTerminate(SimStruct *S) { struct comStruc_IN **dataIN = (struct comStruc_IN**) ssGetDWork(S,DVECSHMIN); struct comStruc_OUT **dataOUT = (struct comStruc_IN**) ssGetDWork(S,DVECSHMOUT); #ifdef _WIN32 #else rtai_free(nam2num(SHMNAM_IN), dataIN[0]); rtai_free(nam2num(SHMNAM_OUT), dataOUT[0]); printf("%s\n", "terminate"); #endif }
int rtapi_exit(int module_id) { module_data *module; int n; if (rtapi_data == NULL) { rtapi_print_msg(RTAPI_MSG_ERR, "RTAPI: ERROR: exit called before init\n"); return -EINVAL; } rtapi_print_msg(RTAPI_MSG_DBG, "RTAPI: module %02d exiting\n", module_id); /* validate module ID */ if ((module_id < 1) || (module_id > RTAPI_MAX_MODULES)) { rtapi_print_msg(RTAPI_MSG_ERR, "RTAPI: ERROR: bad module id\n"); return -EINVAL; } /* get mutex */ rtapi_mutex_get(&(rtapi_data->mutex)); /* point to the module's data */ module = &(module_array[module_id]); /* check module status */ if (module->state != USERSPACE) { rtapi_print_msg(RTAPI_MSG_ERR, "RTAPI: ERROR: not a userspace module\n"); rtapi_mutex_give(&(rtapi_data->mutex)); return -EINVAL; } /* clean up any mess left behind by the module */ for (n = 1; n <= RTAPI_MAX_SHMEMS; n++) { if (test_bit(module_id, shmem_array[n].bitmap)) { fprintf(stderr, "ULAPI: WARNING: module '%s' failed to delete shmem %02d\n", module->name, n); shmem_delete(n, module_id); } } for (n = 1; n <= RTAPI_MAX_FIFOS; n++) { if ((fifo_array[n].reader == module_id) || (fifo_array[n].writer == module_id)) { fprintf(stderr, "ULAPI: WARNING: module '%s' failed to delete fifo %02d\n", module->name, n); fifo_delete(n, module_id); } } /* update module data */ rtapi_print_msg(RTAPI_MSG_DBG, "RTAPI: module %02d exited, name = '%s'\n", module_id, module->name); module->state = NO_MODULE; module->name[0] = '\0'; rtapi_data->ul_module_count--; rtapi_mutex_give(&(rtapi_data->mutex)); nummods--; if(nummods == 0) { rtai_free(RTAPI_KEY, rtapi_data); rtapi_data = 0; } return 0; }
int main (void) { struct comStruc_IN *dataIN = rtai_malloc (nam2num(SHMNAM_IN), sizeof(struct comStruc_IN)) ; struct comStruc_OUT *dataOUT = rtai_malloc (nam2num(SHMNAM_OUT), sizeof(struct comStruc_OUT)) ; float pause = 100000; float t = 0; dataIN->index_counter = 0; while (1) { dataIN->index_counter = dataIN->index_counter + 1; dataIN->sin_value = (float)t*10000; dataIN->cos_value = t*10000+100.0; printf(" Counter : %d Sine : %f Cosine : %f \n", dataOUT->index_counter, dataOUT->sin_value, dataOUT->cos_value); usleep(pause); t=t+1.0/pause; printf("%f\n",t*1000); } rtai_free (nam2num(SHMNAM_IN), dataIN); rtai_free (nam2num(SHMNAM_OUT), dataOUT); return 0; }
int shmem_delete(int shmem_id, int module_id) { shmem_data *shmem; /* validate shmem ID */ if ((shmem_id < 1) || (shmem_id > RTAPI_MAX_SHMEMS)) { return -EINVAL; } /* point to the shmem's data */ shmem = &(shmem_array[shmem_id]); /* is the block valid? */ if (shmem->key == 0) { return -EINVAL; } /* validate module_id */ if ((module_id < 1) || (module_id > RTAPI_MAX_MODULES)) { return -EINVAL; } if (module_array[module_id].state != USERSPACE) { return -EINVAL; } /* is this module using the block? */ if (test_bit(module_id, shmem->bitmap) == 0) { return -EINVAL; } /* OK, we're no longer using it */ clear_bit(module_id, shmem->bitmap); shmem->ulusers--; /* unmap the block */ rtai_free(shmem->key, shmem_addr_array[shmem_id]); shmem_addr_array[shmem_id] = NULL; /* is somebody else still using the block? */ if ((shmem->ulusers > 0) || (shmem->rtusers > 0)) { /* yes, we're done for now */ return 0; } /* update the data array and usage count */ shmem->key = 0; shmem->size = 0; rtapi_data->shmem_count--; return 0; }
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; }