/**
   * 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);
  }
 @Override
 protected void sendOutputVariableAccess(
     ComponentInstance processInstance, UnparseText mainImplCode, ProcessProperties pp) {
   for (GlobalQueueInfo gqi : pp.globalQueueInfo) {
     mainImplCode.addOutputNewline("extern thread_queue_t " + gqi.id + ";");
   }
 }
  private void genCTask(ProcessSubcomponent ps, ThreadSubcomponent thread) {
    String threadName = thread.getComponentImplementation().getQualifiedName();
    threadName = GenerationUtilsC.getGenerationCIdentifier(threadName);
    _mainCCode.addOutputNewline("/*** Task " + threadName + " ***/");
    _mainCCode.addOutputNewline("extern void *" + threadName + "_Job(void);");
    _mainCCode.addOutputNewline("");

    _mainHCode.addOutputNewline("DeclareTask(" + thread.getName() + ");");
    _mainCCode.addOutputNewline("");

    _mainCCode.addOutputNewline("TASK(" + thread.getName() + ")");
    _mainCCode.addOutputNewline("{");
    _mainCCode.incrementIndent();

    _mainCCode.addOutputNewline(threadName + "_Job();");

    _mainCCode.decrementIndent();
    _mainCCode.addOutputNewline("}");
    _mainCCode.addOutputNewline("");
  }
  /**
   * 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("");
  }
  private void genMainImpl(ProcessSubcomponent process) {
    _mainCCode.addOutputNewline("#include \"main.h\"");
    genCpu(process);

    StringBuilder sb = new StringBuilder(process.getQualifiedName());
    ProcessProperties pp = new ProcessProperties(sb.substring(0, sb.lastIndexOf("::") + 2));

    ProcessImplementation processImpl =
        (ProcessImplementation) process.getComponentImplementation();

    this.findCommunicationMechanism(processImpl, pp);

    ComponentInstance processInstance =
        (ComponentInstance) HookAccessImpl.getTransformationTrace(process);

    genSendOutputImpl(processInstance, _mainCCode, _mainHCode, pp);
  }
 @Override
 protected void sendOutputPrologue(
     ComponentInstance processInstance, UnparseText mainImplCode, ProcessProperties pp) {
   mainImplCode.addOutputNewline("StatusType ret;");
 }
 @Override
 protected void sendOutputBuffer(UnparseText mainImplCode, QueueInfo info) {
   mainImplCode.addOutputNewline(
       "ret = SendOutput_runtime(&" + info.gQueue.id + ", " + info.threadPortId + ", value);");
 }
 private void genMainHeader() {
   String guard = GenerationUtilsC.generateHeaderInclusionGuard("main.h");
   _mainHCode.addOutputNewline(guard);
 }
  /** Méthode appelée après le parcours de l'AST via les methodes process. */
  public void close() {

    String msg = "Hooks generation";
    _LOGGER.trace(msg);

    _mainCCode.addOutputNewline("void StartupHook(void)");
    _mainCCode.addOutputNewline("{");
    _mainCCode.incrementIndent();
    for (Subprogram subprogram : _startupHook.getCalls()) {
      _mainCCode.addOutput(subprogram.getName());
      _mainCCode.addOutput("(");

      for (String parameter : subprogram.getParameters()) _mainCCode.addOutput(parameter);

      _mainCCode.addOutputNewline(");");
    }
    _mainCCode.decrementIndent();
    _mainCCode.addOutputNewline("}");
    _mainCCode.addOutputNewline("");

    _mainCCode.addOutputNewline("void ShutdownHook(StatusType ercd)");
    _mainCCode.addOutputNewline("{");
    _mainCCode.incrementIndent();
    for (Subprogram subprogram : _shutdownHook.getCalls()) {
      _mainCCode.addOutput(subprogram.getName());
      _mainCCode.addOutput("(");

      for (String parameter : subprogram.getParameters()) _mainCCode.addOutput(parameter);

      _mainCCode.addOutputNewline(");");
    }
    _mainCCode.decrementIndent();
    _mainCCode.addOutputNewline("}");
    _mainCCode.addOutputNewline("");

    _mainHCode.addOutputNewline("DeclareCounter(" + oil.getCpu().getCounter().getName() + ");");
    _mainCCode.addOutputNewline("");

    /* LEJOS OSEK hook to be invoked from an ISR in category 2 */
    _mainCCode.addOutputNewline("void user_1ms_isr_type2(void)");
    _mainCCode.addOutputNewline("{");
    _mainCCode.incrementIndent();
    _mainCCode.addOutputNewline("StatusType ercd;");

    _mainCCode.addOutputNewline(
        "ercd = SignalCounter("
            + oil.getCpu().getCounter().getName()
            + "); /* Increment OSEK Alarm Counter */");
    _mainCCode.addOutputNewline("if(ercd != E_OK)");
    _mainCCode.addOutputNewline("{");
    _mainCCode.incrementIndent();
    _mainCCode.addOutputNewline("ShutdownOS(ercd);");
    _mainCCode.addOutputNewline("}");
    _mainCCode.incrementIndent();
    _mainCCode.addOutputNewline("}");
    _mainCCode.incrementIndent();

    // Generate OIL
    oil.generateOil(_oilCode);

    _mainHCode.addOutputNewline("#include \"gtypes.h\"");
    _mainHCode.addOutputNewline("#endif");
  }