Ejemplo n.º 1
0
int main()
{
  double lambda = 8./6;
  double m = 2;
  short numberOfWorker = 1;
  PacketGenerator packGen = PacketGenerator(lambda,Priority::LOW);
  std::vector<PacketGenerator> vecPackGen {packGen};
  std::vector<Worker> vecWorker{};
  for(short index = 0; index < numberOfWorker;++index)
    {
      vecWorker.emplace_back(m);
    }
  std::function<bool(Packet&, Packet&)> earlierFun = earlier;
  std::function<short(std::vector<Worker>&,Packet&)> which = whichFree;
  DistributedSimulation sim(vecPackGen,vecWorker,false,0,earlierFun,which,0,0.00001);
  sim.run();

  ErlangC stats(lambda,m,numberOfWorker);
  stats.printStatistics();
  return 0;
}
Ejemplo n.º 2
0
int main(void) {

  //if (!(P1IN&usbminus)) usbwait = 0;  // no usb D- pullup, no bootloader
  // no pull-up, app present, run app
  if (!(P1IN&usbminus) && (*((char*) *((uint16_t*) 0xffbe)) != -1))
    asm("br &0xffbe");

  WDTCTL = WDTPW | WDTHOLD;     // Stop watchdog
  P1OUT = 0;              // Prepare Port 1
  usbdir = ~(usbplus | usbminus);   // USB lines are inputs
  //P1SEL |= BIT4;          // SMCLK for measurements on P1.4

  P1DIR |= BIT5;

#ifdef USE_32768HZ_XTAL
  BCSCTL1 = DIVA_3 | 15;        // ACLK / 8, Range 15
  DCOCTL = 127;           // ~15 MHz
  TACTL = TASSEL_2 | MC_2 | TACLR;  // Continous up mode with clocking from SMCLK
  TACCTL0 = CM_1 | CCIS_1 | CAP | CCIE; // Setup CCR0 for capturing on rising edges of ACLK with enabled interrupts
  __eint();
#else
  P2SEL = 0;
  P2DIR = BIT6|BIT7;          // indicator led
  P2OUT = 0;

  BCSCTL1 = 15;           // Range 15
  DCOCTL = 127;           // ~15 MHz
#endif

  __delay_cycles(2000000);      // Allow some time to stabilize power
  uint8_t usbwait=12;


  usbies = 0;       // Interrupt on rising edge of D+ because there is keep-alive signaling on
                    //   D- that would cause false syncs
  usbifg = 0;       // No interrupt pending

  uint16_t addrStart=0, addrEnd=0, addrCurrent=0, addrSave=0;
  uint8_t  initialized=0;
  uint16_t heartbeat = 0;

  uint8_t idx=0, inBuf[48];
  uint8_t *buffUp=0;
  uint8_t next_time_flash_erase = 0;

  static uint16_t const USB_IDLE_DETECT_THRESHOLD = 16384;
  uint16_t usb_idle_detect_counter = 0;
  uint8_t usb_idle = 0;

  /*    What is this usb idle thing ?
     We are in a bootloader, its aim is to receive via usb a new
     program to be flashed. But erasing and writing to flash takes
     quite a big time, and usb timing is tight. The usb protocol
     needs that response packets be sent within a certain time
     frame, and if the mcu misses that time frame, the host can
     consider the device as malfunctioning.
     The idea behind the usb idle thing is to delay operations that
     take time to a moment where we hope the mcu will not have any
     usb packet to answer.
     Specifically :
     1. when the host side sends an address where flash must be
        erased, the host sleeps for a certain amount T of milliseconds
        before sending another command. Within T milliseconds, the
        mcu has time to answer remaining usb packets and erase the
        requested flash segment.
     2. when the host side sends payload bytes (which are bytes of
        the program to be flashed), the mcu has no time to write them
        into flash and answer usb packets. It stores them in a small
        RAM buffer, and writes them to flash once the host sleeps a
        bit. Here, the host sends 32 bytes before sleeping and letting
        the mcu write those bytes to flash.
     To detect usb idle, we simply count how many "for-ever" loops we
     have done since last received usb packet, and beyond a threshold,
     we consider being in usb idle mode, that is to say : we consider
     the host will not send any other usb packet before we have
     finished with flashing and being able to handle a new usb packet.
  */

  for (;;) // for-ever
  {
    // Detect USB idle
    if(initialized && !usb_idle)
    {
      usb_idle_detect_counter++;
      if(usb_idle_detect_counter > USB_IDLE_DETECT_THRESHOLD)
        usb_idle = 1;
    }

    if (!heartbeat++)
    {
      if (initialized) // usb reset from host occured
      {
        P2OUT ^= BIT6;
      }//if
      else
      { // no reset, run app if present
        //if (!usbwait && (*((char*) 0xc000) != -1)) {
        if (!usbwait && (*((char*) *((uint16_t*) 0xffbe)) != -1))
        {
          _BIC_SR(GIE);
          TACTL = 0;
          P2DIR = P1DIR = 0;
          P2OUT = P1OUT = 0;
          asm("br &0xffbe");
        }
        else
        {
          usbwait--;
        }
      }
    }

    unsigned n = 80;        // Reset if both D+ and D- stay low for a while
                    // 10 ms in SE0 is reset
                    // Should this be done in the ISR somehow???
    while (!initialized && !(usbin & (usbplus | usbminus)))
    {
      if (!--n)
      {
        CurrentAddress = 0;   // Device has initial address of 0
        NewAddress = 0;     //
        addrCurrent = addrStart = addrEnd = 0;

#ifndef USE_32768HZ_XTAL
        if (!initialized)
        {
          TACTL = TASSEL_2 | MC_2 | TACLR;  // Continous up mode with clocking from SMCLK
          initialized = 1;
          //P2OUT |= BIT6;  // debug use, led indicate we are trying sync
          n = 1000; // time to stabilize clock
          while (--n)
          {
            while (!(usbin&usbminus));
            TACTL |= TACLR;
            while ((usbin&usbminus));
            if (TAR < 15000) ++DCOCTL;
            else --DCOCTL;
          }
          usbie = usbplus;
          _BIS_SR(GIE);
        }
#else
        usbie = usbplus;
        _BIS_SR(GIE);
        initialized = 1;
#endif

        break;
      }
    }


    if(DataPacketBuffer[0]) // Check if the USB SIE has received a packet
    {
	  uint8_t packet_size = *DataPacketBuffer;	// we save packet_size here to avoid it being
      DataPacketBuffer[0] = 0;					// overwritten by "fast" status packet that follows
      usb_idle_detect_counter = 0;
      usb_idle = 0;

      // At the end of the buffer is the PID of the preceding token packet
      // Check if it is a SETUP packet
      if(DataPacketBuffer[15] == USB_PID_SETUP)
      {
        // Handle the packet, get a response
        if((DataToTransmit = ProtocolSetupPacket(DataPacketBuffer)))
        {
          // Setup to send the response
          Data_PID_Toggle = USB_PID_DATA0;
          DataToTransmitOffset = 1;
        }
        else
        {
          // Send STALL PID if there is no response
          ReadyForTransmit = usb_packet_stall;
        }
      }
      else if (DataPacketBuffer[15] == USB_PID_OUT) // Check if it is an OUT packet
      {
        // will be getting stuffs here
        // incoming LL-PP-RI-(d0-d1-d2-d3-d4-d5)-C1-C2
        // ex.      0a-4b-01-(00-4b-0e-8d-0d-4e)-56-fa
        // LL - length, ours are always 0a or 08
        // PP - PID, should only be DATA0 or DATA1 (0xc3 or 0x4b) - 4b for us
        // RI - application level control byte - the HID report id. Here :
        //      == 1, request flash write, start address / length follows
        //      == 2, no special instruction, just carry data
        // d? - firmware data, each packet carries up to LL-4 bytes of data
        //      for report id 1 : report count = 6, LL = 0a, data bytes = 6
        //      for report id 2 : report count = 4, LL = 08, data bytes = 4
        // C? - packet checksum, application does not use these
        //

        uint8_t *cp = DataPacketBuffer+2;
        //if (*DataPacketBuffer == 0x0A && *cp == 0x01)
        if (packet_size == 0x0A)
        { // flash write request (report id 1)
          cp++;
          addrCurrent = addrStart = (*cp<<8) + *(cp+1); // get start address high bytes
          cp += 2;
          addrEnd = (*cp<<8) + *(cp+1);
          //______________ interrupt vector, don't do immediate flash write
          if (addrStart >= 0xff00)
          {
            buffUp = inBuf;
          }
          else
          {
            addrSave = addrEnd;
            buffUp = 0;
            idx = 0;
            next_time_flash_erase = 1;
          }
        }
        //else if (*DataPacketBuffer == 0x08 && *cp == 0x02)
        else if (packet_size == 0x08)
        {
          uint8_t c=0; // receive bytes (report id 2)
          cp++; // skip report id
          if (buffUp) // we are receiving interrupt vector bytes
          {
            for (c=0;c<4;c++)
              *((uint8_t *) buffUp++) = *cp++;
            addrCurrent += 4;
          }
          else
          { // we are receiving normal data
            for (c=0;c<4;c++)
              inBuf[c+idx] = *cp++;
            idx += 4;
          }
        }

      } // else if USB_PID_OUT
      //DataPacketBuffer[0] = 0; // Done with received packet, don't process again, allow USB SIE to receive the next packet
    } // if USB SIE has received a packet

    // Check if an outgoing packet needs chunking and the USB SIE
    //   is ready for it
    if (DataToTransmit && !ReadyForTransmit)
    {
      PacketGenerator(); // Make a chunk with CRC
    }

    if (!ReadyForTransmitIrqIn)
    { // Check if the USB SIE is ready for an endpoint 1 packet
      /*
      IrqIn(IrqInSendPacketBuffer); // Build the packet
      CRC(IrqInSendPacketBuffer); // Append CRC
      ReadyForTransmitIrqIn = IrqInSendPacketBuffer; // Send it
      */
    }


    // We have received interrupt vector address, and data bytes.
    // USB is idle which means we can write to flash
    if(usb_idle && buffUp && addrCurrent > addrStart && addrStart >= 0xff00)
    {
      //_____ we doing interrupt vector, so don't be interrupted
      uint16_t savIntr  = *((uint16_t *) 0xffe4);
      uint16_t savReset = *((uint16_t *) 0xfffe);
      _BIC_SR(GIE);
      FCTL1 = FWKEY+ERASE;
      FCTL3 = FWKEY;
      *((uint8_t *) 0xff00) = 0;
      FCTL1 = FWKEY+WRT;

      uint8_t *dp = (uint8_t *) 0xffa0;
      uint8_t *vp = (uint8_t *) 0xffe0;
      uint8_t *cp = inBuf;
      uint8_t i=0x20;
      while (i--) *dp++ = *cp++;  // write to flash backup copy

      *((uint16_t *) (inBuf+4))  = savIntr; // use bootloader's interrupt
      *((uint16_t *) (inBuf+30)) = savReset;// reset goes to bootloader

      i=0x20; cp = inBuf;
      while (i--) *vp++ = *cp++;  // write to flash real vector
      *((uint16_t *) (0xff80)) = addrSave; // save application's end address
      *((uint16_t *) (0xffde)) = 0xaa55;  // disable factory BSL
      buffUp = 0;
      FCTL1 = FWKEY;
      FCTL3 = FWKEY+LOCK;

      _BIS_SR(GIE);
    }


    // We have received addresses. USB is idle : erase flash.
    if(usb_idle && next_time_flash_erase)
    {
      FCTL2 = FWKEY+FSSEL0+(30);
      FCTL1 = FWKEY+ERASE;
      FCTL3 = FWKEY;
      *((uint8_t *) addrCurrent) = 0;
      FCTL1 = FWKEY+WRT;
      next_time_flash_erase = 0;
    }


    // We have received data bytes, and USB is idle : flash them.
    if(usb_idle && !buffUp && addrStart < 0xff00 && idx)
    {
      uint8_t c=0;
      for(c = 0; c < idx; c++)
        *((uint8_t *) addrCurrent++) = inBuf[c];
      idx = 0;

      if (!(addrCurrent&0x01ff))
      {
        //____ we are crossing 512byte/block boundary
        //____ erase and get ready for next block
        FCTL1 = FWKEY+ERASE;
        FCTL3 = FWKEY;
        *((uint8_t *) addrCurrent) = 0;
        FCTL1 = FWKEY+WRT;
      }
    }


    if(addrCurrent >= addrEnd && !buffUp) // !buffUp means that we have handled the interrupt vector in an usb idle time
    {
      //____ lockup flash, we are over.
      FCTL1 = FWKEY;
      FCTL3 = FWKEY+LOCK;

      addrCurrent = addrStart = addrEnd = 0;
      idx = 0;
    }

  }//for-ever
}