INT gen_idle(EQUIPMENT * pequipment) { INT act, status; GEN_INFO *gen_info; gen_info = (GEN_INFO *) pequipment->cd_info; /* select next measurement channel */ act = (gen_info->last_channel + 1) % gen_info->num_channels; /* measure channel */ status = gen_read(pequipment, act); gen_info->last_channel = act; return status; }
void gen_statement(tree_t *t) { int local_if_label; int local_while_label; int local_for_label; int num_args; if (t->type == ARRAY || t->right->type == ARRAY || t->left->type == ARRAY) { yyerror("Array access not supported"); } switch(t->type) { case ASSIGNOP: // Generate code for expression gen_label(t->right, 1); gen_expression(t->right); fprintf(yyout, "\tmovl\t%%ebx, %%eax\n"); // If this is actually a return statement, then return with correct value in %eax if(!strcmp(t->left->attribute.variable->name, top_scope->curr->name)) fprintf(yyout, "\tjmp\tsubprog%send\n", top_scope->curr->name); else { // Generate code for assignment gen_assignment(t->left); } break; case IF: local_if_label = if_label++; //Generate code for expression gen_label(t->left, 1); gen_expression(t->left); //Compare and jump accordingly fprintf(yyout, "\tcmpl\t$1, %%ebx\n\tjge\tiftrue%d\n", local_if_label); //Generate code for else first if (t->right->right != NULL) { gen_statement(t->right->right); fprintf(yyout, "\tjmp\tifend%d\n", local_if_label); } //Generate code for true section fprintf(yyout, "iftrue%d:\n", local_if_label); gen_statement(t->right->left); fprintf(yyout, "ifend%d:\n", local_if_label); break; case WHILE: local_while_label = while_label++; //Plant label for beginning of loop fprintf(yyout, "beginwhile%d:\n", local_while_label); //Generate code for expression gen_label(t->left, 1); gen_expression(t->left); //Compare and jump to end if needed fprintf(yyout, "\tcmpl\t$0, %%ebx\n\tje\tendwhile%d\n", local_while_label); //Generate code for statements gen_statement(t->right); fprintf(yyout, "\tjmp\tbeginwhile%d\n", local_while_label); fprintf(yyout, "endwhile%d:\n", local_while_label); break; case PROCEDURE: if (!strcmp(t->left->attribute.variable->name, "read")) gen_read(t->right); else if (!strcmp(t->left->attribute.variable->name, "write")) gen_write(t->right); else if (t->right != NULL) { // push arguments on the stack num_args = gen_expression_list(t->right); fprintf(yyout, "\tcall\tsubprog%s\n", t->left->attribute.variable->name); // move the top of the stack below args fprintf(yyout, "\taddl\t$%d, %%esp\n", 4*num_args); } else { fprintf(yyout, "\tcall\tsubprog%s\n", t->left->attribute.variable->name); } break; case COMMA: // Generate left and right statements if (t->left->type == ARRAY || t->right->type == ARRAY) yyerror("Array access not supported"); else { gen_statement(t->left); gen_statement(t->right); } break; case FOR: local_for_label = for_label++; // Generate assignment gen_statement(t->left->left); //Plant label for beginning fprintf(yyout, "forloop%d:\n", local_for_label); // Generate expression for TO value gen_label(t->left->right, 1); gen_expression(t->left->right); //Compare and jump to end if needed if (t->left->left->left->attribute.variable->local_or_parameter == LOCAL) fprintf(yyout, "\tcmpl\t-%i(%%ebp), %%ebx\n\tjl\tforend%d\n", t->left->left->left->attribute.variable->offset, local_for_label); else fprintf(yyout, "\tcmpl\t-%i(%%ebp), %%ebx\n\tjl\tforend%d\n", t->left->left->left->attribute.variable->offset, local_for_label); //Generate code for statements gen_statement(t->right); //Increment, jump to top then plant end label fprintf(yyout, "\tincl\t-%i(%%ebp)\n\tjmp\tforloop%d\nforend%d:\n", t->left->left->left->attribute.variable->offset, local_for_label, local_for_label); break; default: fprintf(stderr, "TYPE: %d\n", t->type); yywarn("Statement not supported"); break; } }
INT gen_init(EQUIPMENT * pequipment) { int status, size, i, j, index, offset; char str[256]; HNDLE hDB, hKey, hNames, hThreshold; GEN_INFO *gen_info; BOOL partially_disabled; /* allocate private data */ pequipment->cd_info = calloc(1, sizeof(GEN_INFO)); gen_info = (GEN_INFO *) pequipment->cd_info; /* get class driver root key */ cm_get_experiment_database(&hDB, NULL); sprintf(str, "/Equipment/%s", pequipment->name); db_create_key(hDB, 0, str, TID_KEY); db_find_key(hDB, 0, str, &gen_info->hKeyRoot); /* save event format */ size = sizeof(str); db_get_value(hDB, gen_info->hKeyRoot, "Common/Format", str, &size, TID_STRING, TRUE); if (equal_ustring(str, "Fixed")) gen_info->format = FORMAT_FIXED; else if (equal_ustring(str, "MIDAS")) gen_info->format = FORMAT_MIDAS; else if (equal_ustring(str, "YBOS")) gen_info->format = FORMAT_YBOS; /* count total number of channels */ for (i = 0, gen_info->num_channels = 0; pequipment->driver[i].name[0]; i++) { if (pequipment->driver[i].channels == 0) { cm_msg(MERROR, "gen_init", "Driver with zero channels not allowed"); return FE_ERR_ODB; } gen_info->num_channels += pequipment->driver[i].channels; } if (gen_info->num_channels == 0) { cm_msg(MERROR, "gen_init", "No channels found in device driver list"); return FE_ERR_ODB; } /* Allocate memory for buffers */ gen_info->names = (char *) calloc(gen_info->num_channels, NAME_LENGTH); gen_info->demand = (float *) calloc(gen_info->num_channels, sizeof(float)); gen_info->measured = (float *) calloc(gen_info->num_channels, sizeof(float)); gen_info->update_threshold = (float *) calloc(gen_info->num_channels, sizeof(float)); gen_info->demand_mirror = (float *) calloc(gen_info->num_channels, sizeof(float)); gen_info->measured_mirror = (float *) calloc(gen_info->num_channels, sizeof(float)); gen_info->channel_offset = (INT *) calloc(gen_info->num_channels, sizeof(INT)); gen_info->driver = (void *) calloc(gen_info->num_channels, sizeof(void *)); if (!gen_info->driver) { cm_msg(MERROR, "hv_init", "Not enough memory"); return FE_ERR_ODB; } /*---- Initialize device drivers ----*/ /* call init method */ for (i = 0; pequipment->driver[i].name[0]; i++) { sprintf(str, "Settings/Devices/%s", pequipment->driver[i].name); status = db_find_key(hDB, gen_info->hKeyRoot, str, &hKey); if (status != DB_SUCCESS) { db_create_key(hDB, gen_info->hKeyRoot, str, TID_KEY); status = db_find_key(hDB, gen_info->hKeyRoot, str, &hKey); if (status != DB_SUCCESS) { cm_msg(MERROR, "hv_init", "Cannot create %s entry in online database", str); free_mem(gen_info); return FE_ERR_ODB; } } /* check enabled flag */ size = sizeof(pequipment->driver[i].enabled); pequipment->driver[i].enabled = 1; sprintf(str, "Settings/Devices/%s/Enabled", pequipment->driver[i].name); status = db_get_value(hDB, gen_info->hKeyRoot, str, &pequipment->driver[i].enabled , &size, TID_BOOL, TRUE); if (status != DB_SUCCESS) return FE_ERR_ODB; if (pequipment->driver[i].enabled) { status = device_driver(&pequipment->driver[i], CMD_INIT, hKey); if (status != FE_SUCCESS) { free_mem(gen_info); return status; } } else partially_disabled = TRUE; } /* compose device driver channel assignment */ for (i = 0, j = 0, index = 0, offset = 0; i < gen_info->num_channels; i++, j++) { while (j >= pequipment->driver[index].channels && pequipment->driver[index].name[0]) { offset += j; index++; j = 0; } gen_info->driver[i] = &pequipment->driver[index]; gen_info->channel_offset[i] = offset; } /*---- create demand variables ----*/ /* get demand from ODB */ status = db_find_key(hDB, gen_info->hKeyRoot, "Variables/Demand", &gen_info->hKeyDemand); if (status == DB_SUCCESS) { size = sizeof(float) * gen_info->num_channels; db_get_data(hDB, gen_info->hKeyDemand, gen_info->demand, &size, TID_FLOAT); } /* let device driver overwrite demand values, if it supports it */ for (i = 0; i < gen_info->num_channels; i++) { if (gen_info->driver[i]->flags & DF_PRIO_DEVICE) { device_driver(gen_info->driver[i], CMD_GET_DEMAND, i - gen_info->channel_offset[i], &gen_info->demand[i]); gen_info->demand_mirror[i] = gen_info->demand[i]; } else gen_info->demand_mirror[i] = -12345.f; /* use -12345 as invalid value */ } /* write back demand values */ status = db_find_key(hDB, gen_info->hKeyRoot, "Variables/Demand", &gen_info->hKeyDemand); if (status != DB_SUCCESS) { db_create_key(hDB, gen_info->hKeyRoot, "Variables/Demand", TID_FLOAT); db_find_key(hDB, gen_info->hKeyRoot, "Variables/Demand", &gen_info->hKeyDemand); } size = sizeof(float) * gen_info->num_channels; db_set_data(hDB, gen_info->hKeyDemand, gen_info->demand, size, gen_info->num_channels, TID_FLOAT); db_open_record(hDB, gen_info->hKeyDemand, gen_info->demand, gen_info->num_channels * sizeof(float), MODE_READ, gen_demand, pequipment); /*---- create measured variables ----*/ db_merge_data(hDB, gen_info->hKeyRoot, "Variables/Measured", gen_info->measured, sizeof(float) * gen_info->num_channels, gen_info->num_channels, TID_FLOAT); db_find_key(hDB, gen_info->hKeyRoot, "Variables/Measured", &gen_info->hKeyMeasured); for (i=0 ; i<gen_info->num_channels ; i++) gen_info->measured[i] = (float)ss_nan(); /*---- get default names from device driver ----*/ for (i = 0; i < gen_info->num_channels; i++) { sprintf(gen_info->names + NAME_LENGTH * i, "Default%%CH %d", i); device_driver(gen_info->driver[i], CMD_GET_LABEL, i - gen_info->channel_offset[i], gen_info->names + NAME_LENGTH * i); } db_merge_data(hDB, gen_info->hKeyRoot, "Settings/Names", gen_info->names, NAME_LENGTH * gen_info->num_channels, gen_info->num_channels, TID_STRING); /*---- set labels form midas SC names ----*/ for (i = 0; i < gen_info->num_channels; i++) { gen_info = (GEN_INFO *) pequipment->cd_info; device_driver(gen_info->driver[i], CMD_SET_LABEL, i - gen_info->channel_offset[i], gen_info->names + NAME_LENGTH * i); } /* open hotlink on channel names */ if (db_find_key(hDB, gen_info->hKeyRoot, "Settings/Names", &hNames) == DB_SUCCESS) db_open_record(hDB, hNames, gen_info->names, NAME_LENGTH*gen_info->num_channels, MODE_READ, gen_update_label, pequipment); /*---- get default update threshold from device driver ----*/ for (i = 0; i < gen_info->num_channels; i++) { gen_info->update_threshold[i] = 1.f; /* default 1 unit */ device_driver(gen_info->driver[i], CMD_GET_THRESHOLD, i - gen_info->channel_offset[i], &gen_info->update_threshold[i]); } db_merge_data(hDB, gen_info->hKeyRoot, "Settings/Update Threshold Measured", gen_info->update_threshold, sizeof(float)*gen_info->num_channels, gen_info->num_channels, TID_FLOAT); /* open hotlink on update threshold */ if (db_find_key(hDB, gen_info->hKeyRoot, "Settings/Update Threshold Measured", &hThreshold) == DB_SUCCESS) db_open_record(hDB, hThreshold, gen_info->update_threshold, sizeof(float)*gen_info->num_channels, MODE_READ, NULL, NULL); /*---- set initial demand values ----*/ gen_demand(hDB, gen_info->hKeyDemand, pequipment); /* initially read all channels */ for (i = 0; i < gen_info->num_channels; i++) gen_read(pequipment, i); return FE_SUCCESS; }