Example #1
0
void GPIOPortB_Handler(void) {
    // handle port B0 interrupt
    if ((GPIO_PORTB_MIS_R&0x01) == 0x01) {
        GPIO_PORTB_ICR_R = 0x01;

        // handle rising edge
        if ((GPIO_PORTB_IEV_R&0x01) == 0x01) {
            Sensor0StartTime = OS_Time();
            GPIO_PORTB_IEV_R &= ~0x01;  // switch to falling edge
        }  else {	 // handle falling edge
            Sensor0Reading = OS_TimeDifference(Sensor0StartTime, OS_Time());
            GPIO_PORTB_IM_R &= ~0x01;		 // disable PB0 interrupts
            GPIO_PORTB_IEV_R |= 0x01;    // switch to rising edge (for next time)
            GPIO_PORTB_DIR_R |= 0x01;    // make PB0 out (for next time)
            OS_bSignal(&Sensor0DataAvailable);
        }
    }

    // handle port B1 interrupt
    if ((GPIO_PORTB_MIS_R&0x02) == 0x02) {
        GPIO_PORTB_ICR_R = 0x02;

        // handle rising edge
        if ((GPIO_PORTB_IEV_R&0x02) == 0x02) {
            Sensor1StartTime = OS_Time();
            GPIO_PORTB_IEV_R &= ~0x02;  // switch to falling edge
        }  else {	 // handle falling edge
            Sensor1Reading = OS_TimeDifference(Sensor1StartTime, OS_Time());
            GPIO_PORTB_IM_R &= ~0x02;		// disable PB1 interrupts
            GPIO_PORTB_IEV_R |= 0x02;   // switch to rising edge (for next time)
            GPIO_PORTB_DIR_R |= 0x02;   // make PB1 out (for next time)
            OS_bSignal(&Sensor1DataAvailable);
        }
    }
}
Example #2
0
void PseudoWork(unsigned short work){
unsigned long startTime;
  startTime = OS_Time();    // time in 100ns units
  timeDif = OS_TimeDifference(OS_Time(),startTime); 
  while(timeDif <= (long)work)
  {
    timeDif = OS_TimeDifference(OS_Time(),startTime);
  } 
}
Example #3
0
int main(void)
{
	unsigned int id;
	unsigned long time;	
	id = OS_Id();
	PF2 ^= 0x04;
	Display_Message(0,line++, "Hello world: ", id);
	OS_AddThread(thread, 128, 1);
  time = OS_Time();
	OS_Sleep(1000);
	time = (((OS_TimeDifference(time, OS_Time()))/1000ul)*125ul)/10000ul;
	Display_Message(0,line++, "Sleep time: ", time);
	PF2 ^= 0x04;
	OS_Kill();
}
Example #4
0
void OS_SW2Jitter(uint32_t period)
{
	unsigned static long LastTime;  // time at previous ADC sample
	unsigned long thisTime;         // time at current ADC sample
	long jitter;                    // time between measured and expected, in us
	uint8_t ignore = 0;

	thisTime = OS_Time();       // current time, 12.5 ns

	ignore++;        // calculation finished
	if(ignore>1){    // ignore timing of first interrupt
		unsigned long diff = OS_TimeDifference(LastTime,thisTime);
		if(diff>period){
			jitter = (diff-period+4)/8;  // in 0.1 usec
		}else{
			jitter = (period-diff+4)/8;  // in 0.1 usec
		}
		if(jitter > SW2MaxJitter){
			SW2MaxJitter = jitter; // in usec
		}       // jitter should be 0
		if(jitter >= SW2JitterSize){
			jitter = JITTERSIZE-1;
		}
		SW2JitterHistogram[jitter]++; 
	}
	LastTime = thisTime;
}
Example #5
0
void DAS(void)
{ 
  int index;
  static int i = 0;
  unsigned short input;
  static unsigned long LastTime;  // time at previous ADC sample  
  unsigned long thisTime;         // time at current ADC sample
  long jitter;                    // time between measured and expected
    if(NumSamples < RUNLENGTH){   // finite time run
	
//	GPIO_B0 ^= 0x01;
      input = ADC_In(1);    
	  thisTime = OS_Time();       // current time, 20 ns
      DASoutput = Filter(input);
      FilterWork++;        // calculation finished
      if(FilterWork>1){    // ignore timing of first interrupt
        jitter = ((OS_TimeDifference(thisTime,LastTime)-PERIOD)*CLOCK_PERIOD)/1000;  // in usec
        if(jitter > MaxJitter){
          MaxJitter = jitter;
        }
        if(jitter < MinJitter){
          MinJitter = jitter;
        }        // jitter should be 0
        index = jitter+JITTERSIZE/2;   // us units
        if(index<0)index = 0;
        if(index>=JitterSize)index = JITTERSIZE-1;
        JitterHistogram[index]++; 
      }
      LastTime = thisTime; 
	  
    }
}
Example #6
0
// ******** OS_SysTick_Handler ************
// Thread Switcher, uses SysTick as periodic timer, calls PendSV to actually switch threads
// Implement Thread Manager implicitly here 
// input: none, uses globals RUNPT and NEXTRUNPT 
// output: none, should switch threads when finished
void OS_SysTick_Handler(void){
	tcbType *i, *j;
	int pri;
	int x;
  
  	DisableInterrupts();
    
	//Thread Scheduler
	if(RRSCHEDULER){
	//ROUND ROBBIN SCHEDULER
		for(i=RUNPT->next; i->sleep>0 || i->blockedOn!=0; i=i->next){
			//OLD SLEEP DECRIMENTER
			//if(i->sleep>0){//decriment sleep counter
			//	i->sleep=i->sleep-1;
			//}
		}
		NEXTRUNPT=i;
	}else if(PRIORITYSCHEDULER){
	//PRIORITY SCHEDULER
		pri=7;
		j=RUNPT->next;
		x=0;
		do{
			x++;
			//find thread with highest priority that isnt sleeping or blocked
			if(j->blockedOn==NULL && j->sleep==0 && j->workingPriority<pri){
				pri=j->workingPriority;
				i=j;	
			}
		
			j=j->next;
		//}while(j!=RUNPT->next);
		}while(x<NUMTHREADS);


	/* 	//Priority Scheduler, failed for case where lowest thread got blocked.
		for(i=RUNPT->next,pri=RUNPT->workingPriority,x=0; i->sleep>0 || i->blockedOn!=NULL || (i->workingPriority > pri); i=i->next, x++){ //Possible ERROR HERE, needs rethought //search for next thread untill you find one that is not sleeping, not blocked, and has a priority equal or less than the current RUNPT
			if(x>=NUMTHREADS && pri<7){
				x=0;
				pri++;
			}
		}
	*/
			//OLD SLEEP DECRIMENTER
			//if(i->sleep>0){//decriment sleep counter
			//	i->sleep=i->sleep-1;
			//}

		NEXTRUNPT=i;
		RUNPT->lastRun=OS_Time();
		RUNPT->workingPriority = RUNPT->realPriority;		
	
	}
	  
  	EnableInterrupts();
  
	//Switch Threads (trigger PendSV)
	NVIC_INT_CTRL_R = 0x10000000;
	//PendSV_Handler();
}
Example #7
0
void DAS(void){ 
unsigned long input;  
unsigned static long LastTime;  // time at previous ADC sample
unsigned long thisTime;         // time at current ADC sample
long jitter;                    // time between measured and expected, in us
  if(NumSamples < RUNLENGTH){   // finite time run
    PE0 ^= 0x01;
    input = ADC_In();           // channel set when calling ADC_Init
    PE0 ^= 0x01;
    thisTime = OS_Time();       // current time, 12.5 ns
    DASoutput = Filter(input);
    FilterWork++;        // calculation finished
    if(FilterWork>1){    // ignore timing of first interrupt
      unsigned long diff = OS_TimeDifference(LastTime,thisTime);
      if(diff>PERIOD){
        jitter = (diff-PERIOD+4)/8;  // in 0.1 usec
      }else{
        jitter = (PERIOD-diff+4)/8;  // in 0.1 usec
      }
      if(jitter > MaxJitter){
        MaxJitter = jitter; // in usec
      }       // jitter should be 0
      if(jitter >= JitterSize){
        jitter = JITTERSIZE-1;
      }
      JitterHistogram[jitter]++; 
    }
    LastTime = thisTime;
    PE0 ^= 0x01;
  }
}
Example #8
0
//******** Robot *************** 
// foreground thread, accepts data from producer
// inputs:  none
// outputs: none
void Robot(void){   
unsigned long data;      // ADC sample, 0 to 1023
unsigned long voltage;   // in mV,      0 to 3000
unsigned long time = 0;      // in 10msec,  0 to 1000 
unsigned long t=0;
unsigned int i;
  //OS_ClearMsTime();
  char string[100];    
  DataLost = 0;          // new run with no lost data 
  OSuart_OutString(UART0_BASE, "Robot running...");
  eFile_Create("Robot");
  eFile_RedirectToFile("Robot");
  OSuart_OutString(UART0_BASE, "time(sec)\tdata(volts)\n\r");
  for(i = 1000; i > 0; i--){
    t++;
    time+=OS_Time()/10000;            // 10ms resolution in this OS
    while(!OS_Fifo_Get(&data));        // 1000 Hz sampling get from producer
    voltage = (300*data)/1024;   // in mV
    sprintf(string, "%0u.%02u\t\t%0u.%03u\n\r",time/100,time%100,voltage/1000,voltage%1000);
    OSuart_OutString(UART0_BASE, string);
  }
  eFile_EndRedirectToFile();
  OSuart_OutString(UART0_BASE, "done.\n\r");										    
  Running = 0;                // robot no longer running
  OS_Kill();
}
Example #9
0
File: OS.c Project: tach4455/EE345M
// ******** Jitter2 ***************
// records the jitter for the second periodic background thread
void Jitter2(void) {
  int index;
  unsigned static long LastTime;
  static char First = TRUE;
  unsigned long thisTime;
  long jitter;

  thisTime = OS_Time();

  if(First == FALSE) {
    jitter = (OS_TimeDifference(thisTime, LastTime) / 10) - (gThread2Period / 50); // in usec
    if(jitter > MaxJitter2) {
      MaxJitter2 = jitter;
    }
    if(jitter < MinJitter2) {
      MinJitter2 = jitter;
    }
    index = jitter + JITTERSIZE / 2; // us units
    if(index < 0)
      index = 0;
    if(index >= JitterSize)
      index = JITTERSIZE - 1;
    JitterHistogram2[index]++;
  } else {
    First = FALSE;
  }
  
  LastTime = thisTime;
}
Example #10
0
File: Lab3.c Project: jrife/rtos
void Thread3d(void){
	Count3 = 0;          
  for(;;){
		thisTime = NVIC_ST_CURRENT_R;
    Count3 = thisTime*2 - OS_Time();

  }
}
Example #11
0
void OS_DelayUntil(int t)
{
	int c = OS_Time();
	if (RTOS_BITS == 32) {
		assert(1 <= (t - c) && (t - c) <= 0x7FFFFFFF);
	} else { /* RTOS_BITS == 8 or 16 */
		assert(1 <= (t - c) && (t - c) <= 0x7FFF);
	}
}
Example #12
0
//----------------- PortB_Handler -----------------------
//occurs after PING_Signal arms ther interrupt
void GPIOPortB_Handler(void){
    static unsigned long startTime1, startTime2, startTime3, startTime4, data, time;
	
		time = OS_Time(); 	
		data = GPIO_PORTB_DATA_R;
   
	
		//--- PING 1
		if((GPIO_PORTB_DATA_R & 0x10) == 0x10){ //PB4 high
        startTime1 = time;
				GPIO_PORTB_ICR_R = 0x10;      //acknowledge flag4
    }
		else if((GPIO_PORTB_DATA_R & 0x10) == 0){ //PB4 low
				PING_Time1 = OS_TimeDifference(startTime1, time);
				//OS_AddThread(PING_PeriodicTask,128,1);
				GPIO_PORTB_ICR_R = 0x10;      // acknowledge flag4
		}
	
		//--- PING 2
		if((GPIO_PORTB_DATA_R & 0x20) == 0x20){ //PB5 high
        startTime2 = time;
				GPIO_PORTB_ICR_R = 0x20;      //acknowledge flag5
    }
		else if((GPIO_PORTB_DATA_R & 0x20) == 0){ //PB5 low
				PING_Time2 = OS_TimeDifference(startTime2, time);
				//OS_AddThread(PING_PeriodicTask,128,1);
				GPIO_PORTB_ICR_R = 0x20;      // acknowledge flag5
		}
		
		//--- PING 3
		if((GPIO_PORTB_DATA_R & 0x40) == 0x40){ //PB6 high
        startTime3 = time;
				GPIO_PORTB_ICR_R = 0x40;      // acknowledge flag6
    }
    else if((GPIO_PORTB_DATA_R & 0x40) == 0){ //PB6 low
				PING_Time3 = OS_TimeDifference(startTime3, time);
				//OS_AddThread(PING_PeriodicTask,128,1);
				GPIO_PORTB_ICR_R = 0x40;      // acknowledge flag6
		}	
		
		//--- PING 4
		if((GPIO_PORTB_DATA_R & 0x80) == 0x80){ //PB7 high
        startTime4 = time;
				GPIO_PORTB_ICR_R = 0x80;      // acknowledge flag7
    }
    else if((GPIO_PORTB_DATA_R & 0x80) == 0){ //PB7 low
				PING_Time4 = OS_TimeDifference(startTime4, time);
				//OS_AddThread(PING_PeriodicTask,128,1);
				GPIO_PORTB_ICR_R = 0x80;      // acknowledge flag7
		}
}
Example #13
0
//******** OS_AddThread *************** 
// add a foregound thread to the scheduler
// Inputs: pointer to a void/void foreground task
//         number of bytes allocated for its stack
//         priority (0 is highest)
// Outputs: 1 if successful, 0 if this thread can not be added
// stack size must be divisable by 8 (aligned to double word boundary)
// In Lab 2, you can ignore both the stackSize and priority fields
// In Lab 3, you can ignore the stackSize fields
int OS_AddThread(void(*task)(void), 
   unsigned long stackSize, unsigned long priority){
	  int x=0, found, status;
    /*
    // Find unused thread
    while(x<NUMTHREADS)
      if (tcbs[x++].used == 0)
        break;
        
    // No unused threads found
    if (x=NUMTHREADS)
      return 0;

    // Unused thread found. x+1=index of thread
    x--;
    
    if ()*/
    
	  for(x=0,found=0;(x<NUMTHREADS) && (found==0);x++){	 //loop untill you find a non used thread
			if(tcbs[x].used==0){
				TOTALNUMTHREADS++;
				found=1;
				status=StartCritical();			//possible critical section?	
				OS_ThreadInit(&tcbs[x],0xFFFA-x);
				tcbs[x].used=1;
				if(NumCreated==0){					//First Thread Ever, needs special case for it's RUNPT, b/c there is no run pointer previously
					RUNPT=&tcbs[x];					//set run pointer to point to initial thread
					tcbs[x].next=RUNPT;				//it is only thread, so it points to itself for prev and next
					tcbs[x].prev=RUNPT;
				} else{
					tcbs[x].next=RUNPT;				// set prev / next on new thread
					tcbs[x].prev=RUNPT->prev;		//
					RUNPT->prev->next=&tcbs[x];		// insert thread into current linked list of running threads
					RUNPT->prev=&tcbs[x];			//
				
				}
				tcbs[x].stack[STACKSIZE-2]=(long)task; //POSSIBLE ERROR, PC=task, i think this works... right??
				EndCritical(status);				//end of possible critical section?
				tcbs[x].realPriority=priority;
				tcbs[x].workingPriority=priority;
				tcbs[x].id=++IDCOUNT;
				tcbs[x].lastRun = OS_Time();
				
				//TODO: implement adjustable stacksize using input variable 'stackSize'
				
			}	  
	  }
return found;
}
// ******* OS_UpdateTimeInfoOnDisable **********
// Used in OS_DisableInterrupts and OS_StartCritical
// Used to keep track of how much time is spent when interrupts are enabled.
void OS_UpdateTimeInfoOnDisable(void) {
  if (continueMeasuring && OS_IsRunning) {
    unsigned long thisTime = OS_Time();
    if (interruptsEnabled) {  // interrupts were enabled. Calculate time spent in disabled mode
      if (lastEnableTime != 0) {
        if (thisTime >= lastEnableTime) {
          unsigned long diff = OS_TimeDifference(thisTime, lastEnableTime);
          if (enableTime > UINT32_T_MAX*80000 - diff) { 
            continueMeasuring = 0; 
          }    // overflowed
          enableTime += diff;
        } // else there was an overflow in the timer
      } // else this was the first time disabling interrupts. Don't calculate anything      
      //lastDisableTime = thisTime;
    }
    lastDisableTime = thisTime;
  }
  interruptsEnabled = 0;
}
// ******* OS_UpdateTimeInfoOnEnable **********
// Used in OS_EnableInterrupts and OS_EndCritical
// Used to keep track of how much time is spent when interrupts are disabled.
void OS_UpdateTimeInfoOnEnable(void) {
  if (continueMeasuring && OS_IsRunning) {
    unsigned long thisTime = OS_Time();
    // this is called when interrupts are going to be enabled
    // keep track of disabled time
    if (!interruptsEnabled) { // interrupts were disabled, calculate time spent in disabled mode
      if (lastDisableTime != 0) { 
        if (thisTime >= lastDisableTime) {
          unsigned long diff = OS_TimeDifference(thisTime, lastDisableTime);
          if (disableTime > UINT32_T_MAX*80000 - diff) { 
            continueMeasuring = 0; 
          }
          disableTime += diff;
          if (diff > maxDisableTime) { 
            maxDisableTime = diff; 
          }
        } // else there was an overflow in the timer
      } // else this is the first time enabling interrupts. Don't calculate anything
      //lastEnableTime = thisTime;
    } // else do nothing
    lastEnableTime = thisTime;
  }
  interruptsEnabled = 1;
}
Example #16
0
// ******** Timer Handlers ************
// various timer handlers, used for periodic tasks and incrimenting system time
// input: none,  
// output: none, 
// Timer0A Int Handler
void Timer0A_Handler(){	//happens every 1ms
  int i;
  tcbType *j;

  // Clear Interrupt
  TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
  
  // Update global 1ms timer
  TIMELORD++; 
   for(i=0,j=RUNPT;i<NUMTHREADS;i++,j=j->next){	  //cycle through all threads
  		deleteme++;
		// Decriment Sleep Timers on Everything
   		if(j->sleep>0){
			j->sleep = j->sleep-1; //deriment sleep counter
		}
		// Aging every 10ms
		if(j->lastRun -  OS_Time() > AGING){
			if(j->workingPriority-1 > 0){
				j->workingPriority--;
			}
		}
   }
   
}
Example #17
0
// add the following commands, leave other commands, if they make sense
// 1) print performance measures 
//    time-jitter, number of data points lost, number of calculations performed
//    i.e., NumSamples, NumCreated, MaxJitter-MinJitter, DataLost, FilterWork, PIDwork
//*****************************************************************************
//
// Interpret input from the terminal. Supported functions include
// addition, subtraction, division, and multiplication in the post-fix format.
//
// \param nextChar specifies the next character to be put in the global buffer
//
// \return none.
//
//*****************************************************************************
void
OS_Interpret(unsigned char nextChar)
{
  char operator = Buffer[BufferPt - 2];
  char * token;
  char * last;
  char string[10];
  int a;
  long total = 0;
  short first = 1;
  short command, equation = 0; 
  switch(nextChar)
  {
    case '\b':
     if(BufferPt != 0)
	 {
	   BufferPt--;
	   Buffer[BufferPt] = '\0';
	 }
     break;
    case '=':
     FirstSpace = 1;
     Buffer[BufferPt] = '=';
     equation = 1;
     break;
    case '\r':
     command = 1;
	 //Buffer[BufferPt] = ' ';
     break;
    default:
     Buffer[BufferPt] = nextChar;
     BufferPt++;
     break;
  }

  if(equation == 1)
  {  
    switch(operator)
    {
      case '+':
        for ( token = strtok_r(Buffer, " ", &last); token; token = strtok_r(NULL , " ", &last) )
        {
          total = total + atoi(token);
        }
        Int2Str(total, string);
        OSuart_OutString(UART0_BASE, string);
        OSuart_OutString(UART0_BASE, "\r\n");
        break;  
          
        case '-':
        for ( token = strtok_r(Buffer, " ", &last); token; token = strtok_r(NULL , " ", &last) )
        {
          if(first)
          {
            total = atoi(token);
            first = 0;
          }
          else
          {
            total = total - atoi(token);
          }
        }
        Int2Str(total, string);
		OSuart_OutString(UART0_BASE, string);
        OSuart_OutString(UART0_BASE, "\r\n");
        break;
      
      case '*':
        for ( token = strtok_r(Buffer, " ", &last); token; token = strtok_r(NULL , " ", &last) )
        {
          if(first)
          {
            total = atoi(token);
            first = 0;
          }
          else
          {
            if(atoi(token) != 0)
            {
              total = total * atoi(token);
            }
          }
        }
        Int2Str(total, string);
		OSuart_OutString(UART0_BASE, string);
        OSuart_OutString(UART0_BASE, "\r\n");
        break;
      
      case '/':
        for ( token = strtok_r(Buffer, " ", &last); token; token = strtok_r(NULL , " ", &last) )
        {
          if(first)
          {
            total = atoi(token);
            first = 0;
          }
          else
          {
            if(atoi(token) != 0)
            {
              total = total / atoi(token);
            }
          }
        }
        Int2Str(total, string);
        OSuart_OutString(UART0_BASE, string);
        OSuart_OutString(UART0_BASE, "\r\n");
        break;
      
      case 't':
        Int2Str(OS_Time(), string);
        OSuart_OutString(UART0_BASE, string);
        OSuart_OutString(UART0_BASE, "\r\n");
        break;

      case 'j':
	    break;
	      
      
      default:
        break;
        
    }
	equation = 0;
    BufferPt = 0;
	memset(Buffer,'\0',100);
  }
  if(command == 1)
  {
    // Interpret all of the commands in the line
	//    time-jitter, number of data points lost, number of calculations performed
    //    i.e., NumSamples, NumCreated, MaxJitter-MinJitter, DataLost, FilterWork, PIDwork
    for ( token = strtok_r(Buffer, " ", &last); token; token = strtok_r(NULL , " ", &last) )
    {
	   //strcat(token, "\");
	   //string = "PIDWork";
	   // Display the number of samples
	   /*a = strcasecmp(token, "PIDWork");
	   Int2Str(a, string);
	   OSuart_OutString(UART0_BASE, string);*/
	   if(strcasecmp(token, "NumSamples") == 0)
	   {	 
		 Int2Str(NumSamples, string);
		 OSuart_OutString(UART0_BASE, " ="); 
		 OSuart_OutString(UART0_BASE, string);	
	   }

	   // Display number of samples created
	   if(strcasecmp(token, "NumCreated") == 0)
	   {	 
		 Int2Str(NumCreated, string); 
		 OSuart_OutString(UART0_BASE, " =");
		 OSuart_OutString(UART0_BASE, string);	
	   }

	   // Displays delta jitter
	   if(strcasecmp(token, "MaxJitter-MinJitter") == 0)
	   {	 
		 Int2Str(MaxJitter-MinJitter, string);
		 OSuart_OutString(UART0_BASE, " =");
		 OSuart_OutString(UART0_BASE, string);	
	   }
	   
	   // Display the amount of data lost
	   if(strcasecmp(token, "DataLost") == 0)
	   {	 
		 Int2Str(DataLost, string);
		 OSuart_OutString(UART0_BASE, " =");
		 OSuart_OutString(UART0_BASE, string);	
	   }

	   // Display the variable FilterWork
	   if(strcasecmp(token, "FilterWork") == 0)
	   {	 
		 Int2Str(FilterWork, string);
		 OSuart_OutString(UART0_BASE, " =");
		 OSuart_OutString(UART0_BASE, string);	
	   }

	   // Display the variable PIDWork
	   if(strcasecmp(token, "PIDWork") == 0)
	   {	 
		 Int2Str(PIDWork, string);
		 OSuart_OutString(UART0_BASE, " =");
		 OSuart_OutString(UART0_BASE, string);	
	   } 
    }
	command = 0; 
  	BufferPt = 0;
	memset(Buffer,'\0',100);
    OSuart_OutString(UART0_BASE, "\r\n");
  }
}  
Example #18
0
long JitterStart(void){ 
	long thisTime;
	thisTime=OS_Time();
	return thisTime;
}
Example #19
0
//*******PseudoWork*************
// simple time delay, simulates user program doing real work
// Input: amount of work in 100ns units (free free to change units
// Output: none
void PseudoWork(unsigned short work){
unsigned short startTime;
  startTime = OS_Time();    // time in 100ns units
  while(OS_TimeDifference(startTime,OS_Time()) <= work){} 
}