static void endme(int dummy)
{
	SEM *sem;
#ifndef DEBUG
    ssSetStopRequested(rtS, 1);
    /*printf("stop requested in pid %d\n", getpid());*/
#endif
	if ((sem = sysAuxClkSem(rtai_main_buddy))) {
		rt_sem_signal(sem);
	}
}
Example #2
0
/* Function: rt_MsgServerWork ==================================================
 * Abstract:
 *  If not connected, establish communication of the message line and the
 *  data upload line.  If connected, send/receive messages and parameters
 *  on the message line.
 */
PUBLIC boolean_T rt_MsgServerWork(SimStruct *S)
{
    MsgHeader  msgHdr;
    boolean_T  hdrAvail;
    boolean_T  error             = EXT_NO_ERROR;
    boolean_T  disconnectOnError = FALSE;
    
    /*
     * If not connected, attempt to make connection to host.
     */
    if (!connected) {
        error = ExtOpenConnection(extUD,&connected);
        if (error != EXT_NO_ERROR) goto EXIT_POINT;
    }

    /*
     * If ExtOpenConnection is not blocking and there are no pending
     * requests to open a connection, we'll still be unconnected.
     */
    if (!connected) goto EXIT_POINT; /* nothing do do */
    
    /*
     * Process messages.
     */

    /* Wait for a message. */
    error = GetMsgHdr(&msgHdr, &hdrAvail);
    if (error != EXT_NO_ERROR) {
        printf("\nError occured getting message header.\n");
        disconnectOnError = TRUE;
        goto EXIT_POINT;
    }
    
    if (!hdrAvail) goto EXIT_POINT; /* nothing to do */

    /*
     * This is the first message.  Should contain the string:
     * 'ext-mode'.  Its contents are not important to us.
     * It is used as a flag to start the handshaking process.
     */
    if (!commInitialized) {
        msgHdr.type = EXT_CONNECT;
    }

    /* 
     * At this point we know that we have a message: process it.
     */
    switch(msgHdr.type) {

    case EXT_GET_TIME:
    {
        time_T t = ssGetT(S);

        /* Skip verbosity print out - we get too many of these */
        /*PRINT_VERBOSE(("got EXT_GET_TIME message.\n"));*/

        error = SendMsgToHost(
            EXT_GET_TIME_RESPONSE,sizeof(time_T),(char_T *)&t);
        if (error != EXT_NO_ERROR) goto EXIT_POINT;
        break;
    }

    case EXT_ARM_TRIGGER:
    {
        PRINT_VERBOSE(("got EXT_ARM_TRIGGER message.\n"));
        UploadArmTrigger();
        break;
    }

    case EXT_SELECT_SIGNALS:
    {
        const char *msg;

        PRINT_VERBOSE(("got EXT_SELECT_SIGNALS message.\n"));

        msg = GetMsg(msgHdr.size);
        if (msg == NULL) {
            error = EXT_ERROR;
            goto EXIT_POINT;
        }

        error = UploadLogInfoInit(S, msg);
        if (error != NO_ERR) {
            printf(
                "\nError in UploadLogInfoInit(). Most likely a memory\n"
                "allocation error or an attempt to re-initialize the\n"
                "signal selection during the data logging process\n"
                "(i.e., multiple EXT_SELECT_SIGNAL messages were received\n"
                "before the logging session terminated or an\n"
                "EXT_CANCEL_LOGGING message was received)");

            goto EXIT_POINT;
        }
        break;
    }

    case EXT_SELECT_TRIGGER: 
    {
        const char *msg;

        PRINT_VERBOSE(("got EXT_SELECT_TRIGGER message.\n"));

        msg = GetMsg(msgHdr.size);
        if (msg == NULL) {
            error = EXT_ERROR;
            goto EXIT_POINT;
        }

        error = UploadInitTrigger(S, msg);
        if (error != EXT_NO_ERROR) {
            printf("\nError in UploadInitTrigger\n");
            goto EXIT_POINT;
        }
        break;
    }

    case EXT_CONNECT:
    {
        PRINT_VERBOSE(("got EXT_CONNECT message.\n"));
        error = ProcessConnectMsg(S);
        if (error != EXT_NO_ERROR) goto EXIT_POINT;
        break;
    }

    case EXT_SETPARAM:
    {
        PRINT_VERBOSE(("got EXT_SETPARAM message.\n"));
        error = ProcessSetParamMsg(S, msgHdr.size);
        if (error != EXT_NO_ERROR) goto EXIT_POINT;
        break;
    }

    case EXT_GETPARAMS:
    {
        PRINT_VERBOSE(("got EXT_GETPARAMS message.\n"));
        error = ProcessGetParamsMsg(S);
        if (error != EXT_NO_ERROR) goto EXIT_POINT;
        break;
    }

    case EXT_DISCONNECT_REQUEST:
    {
        PRINT_VERBOSE(("got EXT_DISCONNECT_REQUEST message.\n"));
        
        /*
         * Note that from the target's point of view this is
         * more a "notify" than a "request".  The host needs to
         * have this acknowledged before it can begin closing
         * the connection.
         */
        error = SendMsgToHost(EXT_DISCONNECT_REQUEST_RESPONSE, 0, NULL);
        if (error != EXT_NO_ERROR) goto EXIT_POINT;

        DisconnectFromHost(S);

        break;
    }

    case EXT_MODEL_START:
        PRINT_VERBOSE(("got EXT_MODEL_START message.\n"));
#ifdef VXWORKS
        {
            extern SEM_ID startStopSem;
            semGive(startStopSem);
        }
#endif
        startModel = TRUE;
        error = SendMsgToHost(EXT_MODEL_START_RESPONSE, 0, NULL);
        if (error != EXT_NO_ERROR) goto EXIT_POINT;

        break;

    case EXT_MODEL_STOP:
        PRINT_VERBOSE(("got EXT_MODEL_STOP message.\n"));
        ssSetStopRequested(S, TRUE);
        break;

    case EXT_MODEL_PAUSE:
        PRINT_VERBOSE(("got EXT_MODEL_PAUSE message.\n"));
        modelStatus = TARGET_STATUS_PAUSED;
        startModel  = FALSE;

        error = SendMsgToHost(EXT_MODEL_PAUSE_RESPONSE, 0, NULL);
        if (error != EXT_NO_ERROR) goto EXIT_POINT;

        break;

    case EXT_MODEL_STEP:
        PRINT_VERBOSE(("got EXT_MODEL_STEP message.\n"));
        if ((modelStatus == TARGET_STATUS_PAUSED) && !startModel) {
            startModel = TRUE;
        }
        
        error = SendMsgToHost(EXT_MODEL_STEP_RESPONSE, 0, NULL);
        if (error != EXT_NO_ERROR) goto EXIT_POINT;

        break;

    case EXT_MODEL_CONTINUE:
        PRINT_VERBOSE(("got EXT_MODEL_CONTINUE message.\n"));
        if (modelStatus == TARGET_STATUS_PAUSED) {
            modelStatus = TARGET_STATUS_RUNNING;
            startModel  = FALSE;
        }
        
        error = SendMsgToHost(EXT_MODEL_CONTINUE_RESPONSE, 0, NULL);
        if (error != EXT_NO_ERROR) goto EXIT_POINT;

        break;

    case EXT_CANCEL_LOGGING:
        PRINT_VERBOSE(("got EXT_CANCEL_LOGGING message.\n"));
        UploadCancelLogging();
        break;

    default:
        fprintf(stderr,"received invalid message.\n");
        break;
    } /* end switch */

EXIT_POINT:
    if (error != EXT_NO_ERROR) {
        if (disconnectOnError) {
            fprintf(stderr,
                "Error occured in rt_MsgServerWork.\n"
                "Disconnecting from host!\n");
            DisconnectFromHost(S);
            
            /*
             * Patch by Gopal Santhanam 5/25/2002 (for VXWORKS)
             * If there there was a problem and we have already disconnected
             * from the host, there is no point in returning that error
             * back to rt_MsgServer.  That would cause the task servicing
             * external messages to quit.  Once disconnected, we could
             * just as easily resume by waiting for a new connection.
             */
#ifdef VXWORKS
            error = EXT_NO_ERROR;
#endif            
        }
    }

    return(error);
} /* end rt_MsgServerWork */
Example #3
0
static void mdlOutputs(SimStruct *S, int_T tid)
{
  //printf("mdlOutputs at %g\n", ssGetT(S));
  rtsys = (RTsys*) ssGetUserData(S);

  if (rtsys->init_phase) {
    /* Failure during initialization */
    return;
  }

  real_T *y = ssGetOutputPortRealSignal(S,0);
  real_T *n = ssGetOutputPortRealSignal(S,1);
  real_T *s = ssGetOutputPortRealSignal(S,2);
  real_T *m = ssGetOutputPortRealSignal(S,3);
  real_T *energyConsumption = ssGetOutputPortRealSignal(S,4);
  int i, j, k, detected;
  double dTime; 
 
  DataNode *dn;
  Task* task;
  UserTask* t;
  InterruptHandler* hdl;
  Monitor *mon;

  if (!rtsys->started && ssGetT(S) == 0.0) {
    rtsys->started = true;
    return;
  }

  if (!rtsys->mdlzerocalled) {
    printf("Zero crossing detection must be turned on in order to run TrueTime!\n");
    ssSetErrorStatus(S, "Zero crossing detection must be turned on in order to run TrueTime!");
    return;
  }
  
  /* Storing the time */

  rtsys->time = ssGetT(S) * rtsys->clockDrift + rtsys->clockOffset;
  
  detected = 0;



  /* Check interrupts */
  
  i = 0;
  dn = (DataNode*) rtsys->triggerList->getFirst();
  while (dn != NULL) {
    if (fabs(rtsys->interruptinputs[i]-rtsys->oldinterruptinputs[i]) > 0.1) {
      hdl = (InterruptHandler*) dn->data;
      Trigger* trig = hdl->trigger;
      if (rtsys->time - trig->prevHit > trig->latency) { 
	// Trigger interrupt handler
	if (hdl->myList == rtsys->readyQ) {
	  // handler serving older interrupts
	  hdl->pending++;
	} else {
	  hdl->moveToList(rtsys->readyQ);
	  detected = 1;
	}
 	trig->prevHit = rtsys->time;
      } else { 
	//printf("Call to interrupt handler %s ignored at time %f. Within interrupt latency!\n", hdl->name, rtsys->time);
      }
      rtsys->oldinterruptinputs[i] = rtsys->interruptinputs[i];
    }
    i++;
    dn = (DataNode*) dn->getNext();
  }
  
  /* Check network */
  
  dn = (DataNode*) rtsys->networkList->getFirst();
  while (dn != NULL) {
    hdl = (InterruptHandler*) dn->data;
    Network* network = hdl->network;
    i = network->networkID - 1;
    //printf("mdlOutputs: checking network #%d inp: %d oldinp: %d\n",i,rtsys->networkinputs[i],rtsys->oldnetworkinputs[i]);
    if (fabs(rtsys->networkinputs[i] - rtsys->oldnetworkinputs[i]) > 0.1) {
      hdl->moveToList(rtsys->readyQ);
      detected = 1;
      rtsys->oldnetworkinputs[i] = rtsys->networkinputs[i];
    }
    dn = (DataNode*) dn->getNext();
  }
  
  /* Run kernel? */

  double externTime =  (rtsys->time- rtsys->clockOffset) / rtsys->clockDrift;
  if ((externTime >= rtsys->nextHit) || (detected > 0)) {
    dTime = runKernel(ssGetT(S));
    if (rtsys->error) {
      // Something went wrong executing a code function
      mxArray *bn[1];
      mexCallMATLAB(1, bn, 0, 0, "gcs"); // get current system
      char buf[200];
      mxGetString(bn[0], buf, 200);
      for (unsigned int i=0; i<strlen(buf); i++) if (buf[i]=='\n') buf[i]=' '; 
      printf("In block ==> '%s'\nSimulation aborted!\n", buf); 
      ssSetStopRequested(S, 1);
    } else {
      rtsys->nextHit = (rtsys->time + dTime - rtsys->clockOffset) / rtsys->clockDrift;
    }
  }

  
  /* Outputs */

  for (i=0; i<rtsys->nbrOfOutputs; i++) {
    y[i] = rtsys->outputs[i];
  }
  
  
  /* Network send */

  for (i=0; i<rtsys->nbrOfNetworks; i++) {
    n[i] = rtsys->nwSnd[i];
  }
  
  /* Task schedule */
  
  i = 0;
  j = 0;
  dn = (DataNode*) rtsys->taskList->getFirst();
  while (dn != NULL) {
    t = (UserTask*) dn->data;
    rtsys->taskSched[i] = (double) (j+1);
    if (t->display) j++;
    dn = (DataNode*) dn->getNext();
    i++;
  }
  
  task = (Task*) rtsys->readyQ->getFirst();
  while (task != NULL) {
    if (task->isUserTask()) {
      t = (UserTask*) task;
      rtsys->taskSched[t->taskID - 1] += 0.25;
    }
    task = (Task*) task->getNext();
  }
  
  if ((rtsys->running != NULL) && (rtsys->running->isUserTask())) {
    t = (UserTask*) rtsys->running;
    rtsys->taskSched[t->taskID - 1] += 0.25;
  }    

  i = 0;
  j = 0;
  dn = (DataNode*) rtsys->taskList->getFirst();
  while (dn != NULL) {
    t = (UserTask*) dn->data;
    if (t->display) {
      s[j] = rtsys->taskSched[i];
      j++;
    }
    dn = (DataNode*) dn->getNext();
    i++;
  }
  

  /* Handler schedule */
  
  i = 0;
  j = 0;
  dn = (DataNode*) rtsys->handlerList->getFirst();
  while (dn != NULL) {
    rtsys->handlerSched[i] = (double) (j+rtsys->nbrOfSchedTasks+2);
    if (i==0 && rtsys->contextSwitchTime > EPS) {
      // Context switch schedule, move graph down to task level
      rtsys->handlerSched[i] = rtsys->handlerSched[i] - 1;
    }
    hdl = (InterruptHandler*) dn->data;
    if (hdl->display) j++;
    dn = (DataNode*) dn->getNext();
    i++;
  }

  task = (Task*) rtsys->readyQ->getFirst();
  while (task != NULL) {
    if (!(task->isUserTask())) {
      hdl = (InterruptHandler*) task;
      rtsys->handlerSched[hdl->handlerID - 1] += 0.25;
    }
    task = (Task*) task->getNext();
  }

  if ((rtsys->running != NULL) && (!(rtsys->running->isUserTask()))) {
    hdl = (InterruptHandler*) rtsys->running;
    rtsys->handlerSched[hdl->handlerID - 1] += 0.25;
  }

  i = 0;
  j = 0;
  dn = (DataNode*) rtsys->handlerList->getFirst();
  while (dn != NULL) {
    hdl = (InterruptHandler*) dn->data;
    if (hdl->display) {
      s[j+rtsys->nbrOfSchedTasks] = rtsys->handlerSched[i];
      j++;
    }
    dn = (DataNode*) dn->getNext();
    i++;
  }
  
  /* Monitor graph */
  
  k = 0;
  dn = (DataNode*) rtsys->monitorList->getFirst();
  while (dn != NULL) {
    mon = (Monitor*) dn->data;
    
    for (j=0; j<rtsys->nbrOfTasks; j++)
      rtsys->monitorGraph[j] = (double) (j+1+k*(1+rtsys->nbrOfTasks));
    
    t = (UserTask*) mon->waitingQ->getFirst();
    while (t != NULL) {
      i = t->taskID;
      rtsys->monitorGraph[i-1] += 0.25;
      t = (UserTask*) t->getNext();
    }
    if (mon->heldBy != NULL) {
      i = mon->heldBy->taskID;
      rtsys->monitorGraph[i-1] += 0.5;
    }
    if (mon->display) {
      for (j=0; j<rtsys->nbrOfTasks; j++)
 	m[j+k*rtsys->nbrOfTasks] = rtsys->monitorGraph[j];
      k++;
    }
    dn = (DataNode*) dn->getNext();
  }

  /* Energy consumption */
  energyConsumption[0] = rtsys->energyConsumption;
}