Exemple #1
0
// ******** OS_Kill ************
// kill the currently running thread, release its TCB memory
// input:  none
// output: none
void OS_Kill(void) {

  int id;
  tcbType *temp;

  // Starting critical section to delete TCB
  OS_DisableInterrupts();

  NumThreads--;
  id = (*RunPt).id;

  // Make TCB invalid
  tcbs[id].valid = INVALID;

  // Remove TCB from linked list
  temp = tcbs[id].prev;
  (*temp).next = tcbs[id].next;
  temp = tcbs[id].next;
  (*temp).prev = tcbs[id].prev;

  // Check if thread is Head or Tail
  if(&tcbs[id] == Head) {
    Head = tcbs[id].next;
  } else if(&tcbs[id] == Tail) {
    Tail = tcbs[id].prev;
  }

  // Trigger threadswitch
  OS_Suspend();
  while(1) {
  } // Never leave
}
Exemple #2
0
// ******** OS_Init ************
// initialize operating system, disable interrupts until OS_Launch
// initialize OS controlled I/O: systick, 50 MHz PLL
// input:  none
// output: none
 void OS_Init(void){
  OS_DisableInterrupts();
  PLL_Init();                 // set processor clock to 50 MHz
  NVIC_ST_CTRL_R = 0;         // disable SysTick during setup
  NVIC_ST_CURRENT_R = 0;      // any write to current clears it
  NVIC_SYS_PRI3_R =(NVIC_SYS_PRI3_R&0x00FFFFFF)|0xE0000000; // priority 7
}
int OS_AddThread(void(*task)(void), unsigned long stackSize, unsigned long priority)
{
	uint32_t status;
	status = OS_StartCritical();
	//we will take the first thread from the dead pool
	if(DeadPt == '\0')
	{
		OS_DisableInterrupts();
		while(1){}
	}
	(DeadPt)->id = uniqueId; //unique id
	(DeadPt)->active = 1;
	(DeadPt)->sleepState = 0; //flag
	(DeadPt)->priority = priority; 
	(DeadPt)->blockedState = 0; //flag
	(DeadPt)->needToWakeUp = 0; //flag
	SetInitialStack(DeadPt, stackSize);
	(DeadPt)->stack[stackSize - 2] = (uint32_t)task; //push PC
	uniqueId++;
	addDeadToScheduler(&DeadPt);
	if(higherPriorityAdded == 1)
	{
		OS_Suspend();
	}
	OS_EndCritical(status);
	
	return 1;
}
Exemple #4
0
// ******** OS_Suspend ************
// suspend execution of currently running thread
// scheduler will choose another thread to execute
// Can be used to implement cooperative multitasking
// Same function as OS_Sleep(0)
// input:  none
// output: none
void OS_Suspend(void) {

  long curPriority;
  unsigned long curTimeSlice;
  volatile int i;

  OS_DisableInterrupts();

  // Determines NextPt
  Scheduler();

  // Get priority of next thread and calculate timeslice
  curPriority = (*NextPt).priority;
  curTimeSlice = calcTimeSlice(curPriority);

  // Sets next systick period, does not rest counting
  SysTickPeriodSet(curTimeSlice);

  // Write to register forces systick to reset counting
  NVIC_ST_CURRENT_R = 0;

  IntPendSet(FAULT_PENDSV);
  OS_EnableInterrupts();

  return;
}
// ******** OS_Sleep ************
// place this thread into a dormant state
// input:  number of msec to sleep
// output: none
// You are free to select the time resolution for this function
// Sleep time is a multiple of context switch time period
// OS_Sleep(0) implements cooperative multitasking
void OS_Sleep(unsigned long sleepTime)
{
	OS_DisableInterrupts();
	threadRemover(&SleepPt, sleepTime * 2);
	sleepCount++;
	switched = 1;
	OS_Suspend();
	OS_EnableInterrupts();
}
// ******** OS_Kill ************
// kill the currently running thread, release its TCB and stack
// input:  none
// output: none
void OS_Kill(void)
{
	OS_DisableInterrupts();
	threadRemover(&DeadPt, 0); //parameter 0 will be ignored
	deadCount++;
	switched = 1;
	OS_Suspend();
	OS_EnableInterrupts();

}
int OS_AddPeriodicThread(void(*task)(void), unsigned long period, unsigned long priority){
	int32_t status;
	status = OS_StartCritical();
	//now need to add to linked list
	if(DeadPeriodicPt == '\0') //cant add this thread
	{
		OS_DisableInterrupts();
		while(1){};
	}
	removeAndAddToSingleList(&DeadPeriodicPt, period, task, priority);
	EndCritical(status );
	return 0; //added sucesfully
}
Exemple #8
0
void TriggerSensor0(void) {
    int i;
    OS_DisableInterrupts();
    GPIO_PORTB0 = 0x01;

    // delay 5 us
    for (i = 0; i < 75; i++);

    GPIO_PORTB0 = 0x00;
    GPIO_PORTB_DIR_R &= ~0x01;   // make PB0 in
    GPIO_PORTB_IM_R |= 0x01;		// enable PB0 interrupts
    OS_EnableInterrupts();
}
// ******** OS_Wait ************
// decrement semaphore 
// Lab2 spinlock
// Lab3 block if less than zero
// input:  pointer to a counting semaphore
// output: none
void OS_Wait(Sema4Type *semaPt)
{
	uint32_t status;
	status = OS_StartCritical();
	(*semaPt).Value--; //decrease count
	if((*semaPt).Value < 0)
	{
		OS_Block(semaPt); //block and put into semaphore blocked list
		OS_Suspend();
		OS_EnableInterrupts();
		OS_DisableInterrupts();
	} 
	OS_EndCritical(status);
}
Exemple #10
0
// ******** OS_bWait ************
// Lab2 spinlock, set to 0
// Lab3 block if less than zero
// input:  pointer to a binary semaphore
// output: none
void OS_bWait(Sema4Type *semaPt)
{
	int32_t status;
	status = OS_StartCritical();
	while((*semaPt).Value == 0)
	{
		OS_Block(semaPt); //block and put into semaphore blocked list
		OS_Suspend();
		OS_EnableInterrupts();
		OS_DisableInterrupts();
	} //while someone has the semaphor
	(*semaPt).Value = 0; //take the semaphore
	EndCritical(status );
}
Exemple #11
0
BOOL FIFO_Get(TFIFO * const FIFO, uint8_t * const dataPtr)
{
  OS_DisableInterrupts();                         //Enter Critical Section

  if (FIFO->NbBytes != 0)
  {
    FIFO->NbBytes--;
    *dataPtr = FIFO->Buffer[FIFO->Start];
    FIFO->Start = (FIFO->Start + 1) % FIFO_SIZE;

    OS_EnableInterrupts();
    return (bTRUE);
  }

  OS_EnableInterrupts();
  return (bFALSE);
}
Exemple #12
0
BOOL FIFO_Put(TFIFO * const FIFO, const uint8_t data)
{
  OS_DisableInterrupts();                     //Enter Critical Section

  if (FIFO->NbBytes < FIFO_SIZE)              //Ensure that the buffer is not full before putting data within it
  {
    FIFO->NbBytes++; 				                  //Increment data counter
    FIFO->Buffer[FIFO->End] = data; 		      //Store data in the buffer
    FIFO->End = (FIFO->End + 1) % FIFO_SIZE; 	//increment end pointer within FIFO_SIZE

    OS_EnableInterrupts();
    return (bTRUE);
  }

  OS_EnableInterrupts();
  return (bFALSE);
}
Exemple #13
0
void Ping_Init(void) {
    volatile unsigned long delay;
    OS_DisableInterrupts();
    SYSCTL_RCGC2_R |= SYSCTL_RCGC2_GPIOB; // activate port B
    delay = SYSCTL_RCGC2_R;
    // **** Port B Edge Trigger Initialization ****
    GPIO_PORTB_DIR_R |= 0x03;   // make PB0-1 out
    GPIO_PORTB_DEN_R |= 0x03;   // enable digital I/O on PB0-1
    GPIO_PORTB_PUR_R |= 0x03;		// enable pull up on PB0-1
    GPIO_PORTB_IEV_R |= 0x03;	  // make PB0-1 rising edge triggered
    GPIO_PORTB_IS_R &= ~0x03;		// make PB0-1 edge-sensitive
    GPIO_PORTB_ICR_R = 0x03;		// clear flag
    NVIC_PRI0_R = (NVIC_PRI1_R&0xFFFF00FF)|0x00006000;  // priority 3
    NVIC_EN0_R |= NVIC_EN0_INT1;

    OS_InitSemaphore(&Sensor0Free, 1);
    OS_InitSemaphore(&Sensor1Free, 1);
    OS_InitSemaphore(&Sensor0DataAvailable, 0);
    OS_InitSemaphore(&Sensor1DataAvailable, 0);

    OS_EnableInterrupts();
}
Exemple #14
0
// ******** OS_Init ************
// initialize operating system, disable interrupts until OS_Launch
// initialize OS controlled I/O: serial, ADC, systick, LaunchPad I/O and timers 
// input:  none
// output: none
void OS_Init()
{
	uint8_t counter = 0;
	Timer2_Init(80000000); //timer2 keeps track oftime
	OS_DisableInterrupts();
	PLL_Init(Bus80MHz);
	
	//ADC_Init(0);
	UART_Init();              					 // initialize UART
	
	//construct linked list
	for (counter = 0; counter<NUMBEROFTHREADS - 1; counter++)
	{
		threadPool[counter].nextTCB = &threadPool[(counter + 1)]; //address of next TCB
	}
	threadPool[NUMBEROFTHREADS - 1].nextTCB = '\0'; 
	//lab3 linked list for periodic threads
	for (counter = 0; counter<NUMBEROFPERIODICTHREADS - 1; counter++)
	{
		periodicPool[counter].nextPeriodicThread = &periodicPool[(counter + 1)]; //address of next TCB
	}
	periodicPool[NUMBEROFPERIODICTHREADS - 1].nextPeriodicThread = '\0'; 
	
	
	DeadPt = &threadPool[0]; //point to first element of not active threads 
	DeadPeriodicPt = &periodicPool[0];
	deadCount = NUMBEROFTHREADS;
	deadPeriodicCount = NUMBEROFPERIODICTHREADS;
	RunPt = '\0';
	SchedulerPt = '\0';
	SleepPt = '\0';
	PeriodPt = '\0';
	//Timer2_Init(20000); //1 ms period for taking time!!!!!!
	NVIC_ST_CTRL_R = 0;         // disable SysTick during setup
  NVIC_ST_CURRENT_R = 0;      // any write to current clears it
  NVIC_SYS_PRI3_R =(NVIC_SYS_PRI3_R&0x00FFFFFF)|0xE0000000; // priority 7 on systick
	NVIC_SYS_PRI3_R = (NVIC_SYS_PRI3_R & 0xFF1FFFFF) |  0x00E00000; //priority 7 on pendsv
}
Exemple #15
0
// ************ OS_Init ******************
// initialize operating system, disable interrupts until OS_Launch
// initialize OS controlled I/O: serial, ADC, systick, select switch and timer2
// input: none
// output: non
void OS_Init(void) {

  int i; // Used for indexing

  // Disable interrupts
  OS_DisableInterrupts();

  // Setting the clock to 50 MHz
  SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_8MHZ);

  // Initialze peripherals
  UART0_Init();
  ADC_Open();
  Output_Init();

  // Select switch
  SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
  GPIOPinTypeGPIOInput(GPIO_PORTF_BASE, GPIO_PIN_1);
  GPIOPadConfigSet(GPIO_PORTF_BASE, GPIO_PIN_1, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU);
  GPIOIntTypeSet(GPIO_PORTF_BASE, GPIO_PIN_1, GPIO_RISING_EDGE);
  GPIOPinIntClear(GPIO_PORTF_BASE, GPIO_PIN_1);

  // Down switch
  SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);
  GPIOPinTypeGPIOInput(GPIO_PORTE_BASE, GPIO_PIN_1);
  GPIOPadConfigSet(GPIO_PORTE_BASE, GPIO_PIN_1, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU);
  GPIOIntTypeSet(GPIO_PORTE_BASE, GPIO_PIN_1, GPIO_RISING_EDGE);
  GPIOPinIntClear(GPIO_PORTE_BASE, GPIO_PIN_1);

  // Initialize Timer2A and Timer2B: Periodic Background Threads
  SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER2);
  TimerDisable(TIMER2_BASE, TIMER_A | TIMER_B);
  TimerConfigure(TIMER2_BASE, TIMER_CFG_16_BIT_PAIR | TIMER_CFG_A_PERIODIC | TIMER_CFG_B_PERIODIC);
  
  // Initialize Timer0B: Used for time keeping
  TimerDisable(TIMER0_BASE, TIMER_B);
  TimerConfigure(TIMER0_BASE, TIMER_CFG_16_BIT_PAIR | TIMER_CFG_A_PERIODIC | TIMER_CFG_B_PERIODIC);
  TimerIntDisable(TIMER0_BASE, TIMER_TIMB_TIMEOUT);
  TimerLoadSet(TIMER0_BASE, TIMER_B, 65535);
  TimerPrescaleSet(TIMER0_BASE, TIMER_B, 5); // One unit is 100ns
  TimerEnable(TIMER0_BASE, TIMER_B);

  // Initialize Timer1A: Used for sleep decrementing
  SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER1);
  TimerDisable(TIMER1_BASE, TIMER_A);
  TimerConfigure(TIMER1_BASE, TIMER_CFG_16_BIT_PAIR | TIMER_CFG_A_PERIODIC | TIMER_CFG_B_PERIODIC);
  TimerIntDisable(TIMER1_BASE, TIMER_TIMA_TIMEOUT);
  TimerLoadSet(TIMER1_BASE, TIMER_A, 50000); // Every interrupt is 1ms

  // Setting priorities for all interrupts
  // To add more, look up correct names in inc\hw_ints.h

  IntPrioritySet(FAULT_PENDSV, (0x07 << 5));
  IntPrioritySet(FAULT_SYSTICK, (0x06 << 5));

  IntPrioritySet(INT_TIMER1A, (0x02 << 5));
  IntPrioritySet(INT_UART0, (0x03 << 5));
  IntPrioritySet(INT_ADC0SS0, (0x01 << 5));
  IntPrioritySet(INT_ADC0SS3, (0x01 << 5));

  // Initializing TCBs
  for(i = 0; i < MAXTHREADS; i++) {
    tcbs[i].valid = INVALID;
    tcbs[i].blockedState = '\0';
  }

  RunPt = &tcbs[0]; // Thread 0 will run first
}
Exemple #16
0
void addThreadToBlocked(struct TCB ** toAdd)
{
	struct TCB * removed;
	struct TCB * temp;
	
	(*RunPt).active = 0;
	(*RunPt).blockedState = 1;
	//remove from active 
	temp = SchedulerPt;
	
	if(RunPt == temp) //first element
	{
		if(schedulerCount == 0)
		{
			OS_DisableInterrupts();
			while(1){};
		}
		if(schedulerCount == 1)
		{
			OS_DisableInterrupts();
			removed = SchedulerPt; //store before we remove
			SchedulerPt = '\0';
			while(1){};
		}
		else //remove and fix
		{
			while((*temp).nextTCB != (SchedulerPt))
			{
				temp = (*temp).nextTCB;
			}
			//now at end of Scheduler pool
			(*temp).nextTCB = (*SchedulerPt).nextTCB;
			removed = SchedulerPt; //store before we remove
			SchedulerPt = (*SchedulerPt).nextTCB;
			nextBeforeSwitch = SchedulerPt; //hax
		}
	}
	else //not the first element, could be middle or end (theres no end in circular)
	{
			while((*temp).nextTCB != (RunPt))
			{
				temp = (*temp).nextTCB;
			}
			nextBeforeSwitch = temp->nextTCB->nextTCB; //hax
			removed = (*temp).nextTCB;
			(*temp).nextTCB = (*(*temp).nextTCB).nextTCB; //remove from linked list
	}
	//now we have the node we took out in the "removed" variable	
	
	temp = *toAdd;
	if(temp == '\0')
	{
		*toAdd = removed;
		(*removed).nextTCB = '\0';
	}
	else
	{
		struct TCB * temp = (*toAdd); 
		if((*removed).priority < (*(*toAdd)).priority) // gonna be added at beginning
		{
				temp = (*(*toAdd)).nextTCB; //save before removing which node should be the first after removal
				(*toAdd) = removed;
				(*removed).nextTCB = temp; //point node to first element of where it will be added
		}
		else
		{
			while( ((*temp).nextTCB != '\0') &&  ((*removed).priority >= (*(*temp).nextTCB).priority))
			{
				temp = (*temp).nextTCB;
			}
				//now we are at the priority where we want to add to
			struct TCB * nextBeforeAdding = (*temp).nextTCB; //save before rerouting to restore at end
			(*temp).nextTCB = removed;
			temp = (*temp).nextTCB; //temp now equals thread
			(*temp).nextTCB = nextBeforeAdding;  //restore connection
		}
	}
	schedulerCount--;
}
Exemple #17
0
static void threadRemover(struct TCB ** toAdd, unsigned long sleepTime)
{
	struct TCB * removed;
	struct TCB * temp;
	
	(*RunPt).active = 0;
	//remove from active 
	temp = SchedulerPt;
	
	if(RunPt == temp) //first element
	{
		if(schedulerCount == 0)
		{
			OS_DisableInterrupts();
			while(1){};
		}
		if(schedulerCount == 1)
		{
			OS_DisableInterrupts();
			removed = SchedulerPt; //store before we remove
			SchedulerPt = '\0';
			while(1){};
		}
		else //remove and fix
		{
			while((*temp).nextTCB != (SchedulerPt))
			{
				temp = (*temp).nextTCB;
			}
			//now at end of Scheduler pool
			(*temp).nextTCB = (*SchedulerPt).nextTCB;
			removed = SchedulerPt; //store before we remove
			SchedulerPt = (*SchedulerPt).nextTCB;
			nextBeforeSwitch = SchedulerPt; //hax
		}
	}
	else //not the first element, could be middle or end (theres no end in circular)
	{
			while((*temp).nextTCB != (RunPt))
			{
				temp = (*temp).nextTCB;
			}
			nextBeforeSwitch = temp->nextTCB->nextTCB; //hax
			removed = (*temp).nextTCB;
			(*temp).nextTCB = (*(*temp).nextTCB).nextTCB; //remove from linked list
	}
	
	//now we have the node we took out in the "removed" variable
	if(*toAdd == SleepPt) //if putting thread to sleep need to update flag
	{
		(*removed).sleepState = sleepTime;
		if(sleepTime == 0)
		{
			(*removed).needToWakeUp = 1;
		}
	}
	
	temp = *toAdd;
	if(temp != '\0')
	{
		while((*temp).nextTCB != '\0')
		{
			temp = (*temp).nextTCB;
		}
		(*temp).nextTCB = removed;
		temp = (*temp).nextTCB;
		(*temp).nextTCB = '\0';
	}
	else
	{
		*toAdd = removed;
		(*removed).nextTCB = '\0';
	}
	
	schedulerCount--;
}