/** * Generate the OIL/C code for a processor * * @param processor L'AST du processeur. */ private void genCpu(ProcessSubcomponent ps) { Cpu cpu = oil.getCpu(); Os os = cpu.getOs(); _mainHCode.addOutputNewline("#include \"kernel.h\""); _mainHCode.addOutputNewline("#include \"kernel_id.h\""); /* Generate code for threads process */ ProcessImplementation pi = (ProcessImplementation) ps.getComponentImplementation(); cpu.addAllDataSubcomponent(pi.getOwnedDataSubcomponents()); buildDataAccessMapping(pi, dataAccessMapping); EList<ThreadSubcomponent> subcomponents = pi.getOwnedThreadSubcomponents(); _mainCCode.addOutputNewline("/*********** Tasks ***********/"); for (ThreadSubcomponent threadSubcomponent : subcomponents) { genTask(ps, threadSubcomponent, COUNTER_NAME); genCTask(ps, threadSubcomponent); } /* Generate code for OS */ /* * If one data contains Concurrency_Control_Protocol at * Priority_Ceiling STATUS => EXTENDED */ if (os.getStatus() == Status.STANDARD) { ProcessImplementation processImpl = (ProcessImplementation) ps.getComponentImplementation(); EList<Subcomponent> subcmpts = processImpl.getAllSubcomponents(); for (Subcomponent s : subcmpts) { if (s instanceof DataSubcomponent) { String value = PropertyUtils.getEnumValue(s, "Concurrency_Control_Protocol"); if (value != null) { if (value.equals("Priority_Ceiling")) { os.setStatus(Status.EXTENDED); break; } } else { String errMsg = "cannot fetch Concurrency_Control_Protocol for \'" + s.getName() + '\''; _LOGGER.error(errMsg); ServiceProvider.SYS_ERR_REP.error(errMsg, true); } } } } List<String> modeIdList = getProcessModesIdentifiers(ps); cpu.setAppmode(modeIdList); cpu.setName(ps.getName()); genOsConfig(ps); }
List<String> getProcessModesIdentifiers(ProcessSubcomponent ps) { List<String> result = new ArrayList<String>(); ProcessImplementation pi = (ProcessImplementation) ps.getSubcomponentType(); List<Mode> modeList = pi.getOwnedModes(); if (modeList.isEmpty()) result.add(MAIN_APP_MODE); for (Mode m : modeList) { if (m.isInitial()) result.add(m.getName()); } for (Mode m : modeList) { if (!m.isInitial()) result.add(m.getName()); } return result; }
/** * Configuration de l'OS * * @param processSubcomponent */ private void genOsConfig(ProcessSubcomponent processSubcomponent) { /* C Data declaration */ Os os = oil.getCpu().getOs(); os.setName("config"); os.setAppName(processSubcomponent.getName()); _mainCCode.addOutputNewline("/*********** Data ***********/"); ProcessImplementation pi = (ProcessImplementation) processSubcomponent.getComponentImplementation(); for (DataSubcomponent ds : pi.getOwnedDataSubcomponents()) { if (ds.getSubcomponentType().getName().equalsIgnoreCase(EVENTDATA_PORT_TYPE) || ds.getSubcomponentType().getName().equalsIgnoreCase(DATA_PORT_TYPE)) { _mainHCode.addOutputNewline("DeclareResource(" + ds.getName() + "_rez);"); // _mainHCode.addOutputNewline("extern const ResourceType "+ds.getName()+"_rez;"); } if (ds.getSubcomponentType().getName().equalsIgnoreCase(EVENTDATA_PORT_TYPE)) { _mainHCode.addOutputNewline("DeclareEvent(" + ds.getName() + "_evt);"); // _mainHCode.addOutputNewline("extern const EventMaskType "+ds.getName()+"_evt;"); } } _mainCCode.addOutputNewline(""); }
/** * Génération du code OIL d'un thread. * * @param ps Le processeur conteannt les threads. * @param thread L'AST du thread. * @param counterName Le nom du compteur sur lequel la tâche se synchronise */ private void genTask(ProcessSubcomponent ps, ThreadSubcomponent thread, String counterName) { final Cpu cpu = oil.getCpu(); final Counter counter = cpu.getCounter(); final Os os = cpu.getOs(); /* * If one thread/device contains Initialize_Entrypoint STARTUPHOOK = * true */ if (os.getStartupHook() == false) { if (PropertyUtils.findPropertyAssociation("Initialize_Entrypoint", thread) != null) os.setStartupHook(true); } /* * If one thread/device contains Finalize_Entrypoint SHUTDOWNHOOK = true */ if (os.getShutdownHook() == false) { if (PropertyUtils.findPropertyAssociation("Finalize_Entrypoint", thread) != null) os.setShutdownHook(true); } /* Begin task */ Task task = new Task(); Schedule schedule; Long stackSize = PropertyUtils.getIntValue(thread, "Stack_Size"); Long priority = PropertyUtils.getIntValue(thread, "Priority"); if (priority == null) { String errMsg = "cannot fetch Priority for \'" + thread.getName() + '\''; _LOGGER.error(errMsg); ServiceProvider.SYS_ERR_REP.error(errMsg, true); priority = -1l; } if (stackSize == null) { stackSize = THREAD_STACKSIZE; String msg = "set default stack size for \'" + thread.getName() + '\''; _LOGGER.warn(msg); ServiceProvider.SYS_ERR_REP.warning(msg, true); } Boolean scheduler = PropertyUtils.getBooleanValue(ps, "Preemptive_Scheduler"); if (scheduler == null) { schedule = Schedule.FULL; String msg = "set default scheduler for \'" + thread.getName() + '\''; _LOGGER.warn(msg); ServiceProvider.SYS_ERR_REP.warning(msg, true); } else { if (scheduler) schedule = Schedule.FULL; else schedule = Schedule.NON; } task.setName(thread.getName()); task.setPriority(priority.intValue()); task.setActivation(THREAD_ACTIVATION); task.setSchedule(schedule); task.setStacksize(stackSize.intValue()); ThreadImplementation ti = (ThreadImplementation) thread.getSubcomponentType(); ThreadType tt = (ThreadType) ti.getType(); for (DataAccess da : this.dataAccessMapping.keySet()) { for (DataAccess tda : tt.getOwnedDataAccesses()) { if (tda.equals(da)) { task.addResource(this.dataAccessMapping.get(tda)); if (da.getDataFeatureClassifier().getName().equalsIgnoreCase(EVENTDATA_PORT_TYPE)) task.addEvent(this.dataAccessMapping.get(da)); } } } /* End task */ /* * Generate alarme associated to periodic tasks */ { String dispatchProtocol = PropertyUtils.getEnumValue(thread, "Dispatch_Protocol"); if ("Periodic".equals(dispatchProtocol)) { /* Begin Alarm */ Long period = PropertyUtils.getIntValue(thread, "Period"); if (period == null) { String errMsg = "cannot fetch Period for " + thread.getName(); _LOGGER.error(errMsg); ServiceProvider.SYS_ERR_REP.error(errMsg, true); period = -1l; } int alarmTime = 0; try { alarmTime = 1; } catch (Exception exc) { } List<String> inModeIdList = new ArrayList<String>(); ProcessImplementation pi = (ProcessImplementation) ps.getSubcomponentType(); if (pi.getOwnedModes().isEmpty()) inModeIdList.add(MAIN_APP_MODE); else { if (thread.getAllInModes().isEmpty()) { for (Mode m : pi.getOwnedModes()) { inModeIdList.add(m.getName()); } } else { for (Mode m : thread.getAllInModes()) { inModeIdList.add(m.getName()); } } } Alarm alarm = new Alarm(counter, task, cpu, inModeIdList); alarm.setName("wakeUp" + thread.getName()); alarm.setAction(Action.ACTIVATETASK); alarm.setAutostart(true); alarm.setAlarmTime(alarmTime); alarm.setCycleTime(period.intValue()); task.setAutostart(false); cpu.addPeriodicTask(new PeriodicTask(task, alarm)); /* End Alarm */ } else { task.setAutostart(true); cpu.addTask(task); } } }