コード例 #1
0
/*! 
    \brief C part of the SVC exception handler

     SVC 0 is initializing the OS and starting the scheduler.
     Each thread stack frame is initialized.
     
    \param svc_args Used to extract the SVC number 
*/
void SVC_Handler_C(unsigned int * svc_args)
{
  uint8_t svc_number;
  svc_number = ((char *) svc_args[6])[-2]; // Memory[(Stacked PC)-2]
	// marking kernel as busy
	kernel_busy = 1;
  switch(svc_number) {
		
		//************* SVC( 0 )   OS Start	
    case (0): // OS start		  
 	    // Starting the task scheduler
		  //TWP  playing a trick here!? by making curr = next, will make next's stack and current's stack the same stack!
		  //   will save (garbage) current register values, and then immediately restore them as next's initial values :-)
		curr_task = rtr_q_h; // Switch to head ready-to-run task (Current task)		
		//     when current task was put in RTRQ its state was set to RUNNING 
		  
		svc_exc_return = HW32_REG(( curr_task->stack_p )); // Return to thread with PSP
		__set_PSP(( (uint32_t) curr_task->stack_p + 10*4));  // Set PSP to @R0 of task 0 exception stack frame

		NVIC_SetPriority(PendSV_IRQn, 0xFF);       // Set PendSV to lowest possible priority
		if (SysTick_Config(os_sysTickTicks) != 0)  // 1000 Hz SysTick interrupt on 16MHz core clock
			{
				stop_cpu2;
				// Impossible SysTick_Config number of ticks
			}
		__set_CONTROL(0x3);                  // Switch to use Process Stack, unprivileged state
		__ISB();       // Execute ISB after changing CONTROL (architectural recommendation)			
		break;
		
		//************* SVC( 1 )	Thread Yield
    case (1): // Thread Yield
		if (curr_task != rtr_q_h)
			{ 
				// Context switching needed
				ScheduleContextSwitch();
			}		
		__ISB();       					
		break;
    
		//************* SVC( 2 )    Stack Frame Allocation for First Launch
		//TWPV6: no longer used!  Functionality moved to osThreadCreate ... case left here (for now) 
    case (2): // Stack Allocation
		__ISB();       			
		break;			
    default:
#if ((ENABLE_KERNEL_PRINTF) && (ENABLE_KERNEL_PRINTF == 1))
		printf("ERROR: Unknown SVC service number\n\r");
		printf("- SVC number 0x%x\n\r", svc_number);
#endif
		stop_cpu2;
		break;
  } // end switch
	
	// marking kernel as normal
	kernel_busy = 0;
}	
コード例 #2
0
ファイル: kernel.c プロジェクト: rozmov/RavenOS
/*! 
    \brief Invokes the scheduler

     Increment systick counter, invoke scheduler and flag any context switching needed for PendSV to take care of.
*/
void SysTick_Handler(void) // 1KHz
{
	os_KernelEnterCriticalSection();
	// Increment systick counter 
  systick_count++;
	// Run scheduler to determine if a context switch is needed
  scheduler();
  if (curr_task != next_task)
	{ 
		// Context switching needed
    ScheduleContextSwitch();
  }
	os_KernelExitCriticalSection();
  return;	
}
コード例 #3
0
ファイル: kernel.c プロジェクト: rozmov/RavenOS
/*! 
    \brief C part of the SVC exception handler

     SVC 0 is initializing the OS and starting the scheduler.
     Each thread stack frame is initialized.
     
    \param svc_args Used to extract the SVC number 
*/
void SVC_Handler_C(unsigned int * svc_args)
{
  uint8_t svc_number, i;	
  svc_number = ((char *) svc_args[6])[-2]; // Memory[(Stacked PC)-2]
	// marking kernel as busy
	kernel_busy = 1;
  switch(svc_number) {
    case (0): // OS start		  
 	    // Starting the task scheduler
			// Update thread to be run based on priority
	    scheduler();
      curr_task = next_task; // Switch to head ready-to-run task (Current task)		
			th_q_h = curr_task;
			th_q[curr_task]->status = TH_RUNNING;
		  if (PSP_array[curr_task] == NULL)
			{
				// Stack not allocated for current task, allocating
				i = curr_task;
				th_q[i]->stack_p = (uint32_t) task_stack[i];
				PSP_array[i] = ((unsigned int) th_q[i]->stack_p) + (th_q[i]->stack_size) - 18*4;
				HW32_REG((PSP_array[i] + (16<<2))) = (unsigned long) th_q[i]->start_p; // initial Program Counter
				HW32_REG((PSP_array[i] + (17<<2))) = 0x01000000;            // initial xPSR
				HW32_REG((PSP_array[i]          )) = 0xFFFFFFFDUL;          // initial EXC_RETURN
				HW32_REG((PSP_array[i] + ( 1<<2))) = 0x3;// initial CONTROL : unprivileged, PSP	
				
				th_q[i]->stack_p = PSP_array[i];				
			}

			svc_exc_return = HW32_REG((PSP_array[curr_task])); // Return to thread with PSP
			__set_PSP((PSP_array[curr_task] + 10*4));  // Set PSP to @R0 of task 0 exception stack frame

      NVIC_SetPriority(PendSV_IRQn, 0xFF);       // Set PendSV to lowest possible priority
      if (SysTick_Config(os_sysTickTicks) != 0)  // 1000 Hz SysTick interrupt on 16MHz core clock
			{
				stop_cpu2;
				// Impossible SysTick_Config number of ticks
			}
      __set_CONTROL(0x3);                  // Switch to use Process Stack, unprivileged state
      __ISB();       // Execute ISB after changing CONTROL (architectural recommendation)			
		  break;
    case (1): // Thread Yield
			// Run scheduler to determine if a context switch is needed
			scheduler();		  
			if (curr_task != next_task)
			{ 
				// Context switching needed
				ScheduleContextSwitch();
		  }		
      __ISB();       					
			break;
    case (2): // Stack Allocation
      // Create stack frame for thread
		  i = svc_args[0];  

			th_q[i]->stack_p = (uint32_t) task_stack[i];
			PSP_array[i] = ((unsigned int) th_q[i]->stack_p) + (th_q[i]->stack_size) - 18*4;
			HW32_REG((PSP_array[i] + (16<<2))) = (unsigned long) th_q[i]->start_p; // initial Program Counter
			HW32_REG((PSP_array[i] + (17<<2))) = 0x01000000;            // initial xPSR
			HW32_REG((PSP_array[i]          )) = 0xFFFFFFFDUL;          // initial EXC_RETURN
			HW32_REG((PSP_array[i] + ( 1<<2))) = 0x3;// initial CONTROL : unprivileged, PSP		
			
			th_q[i]->stack_p = PSP_array[i];
      __ISB();       			
			break;			
    default:
#if ((ENABLE_KERNEL_PRINTF) && (ENABLE_KERNEL_PRINTF == 1))
      printf("ERROR: Unknown SVC service number\n\r");
      printf("- SVC number 0x%x\n\r", svc_number);
#endif
      stop_cpu2;
      break;
  } // end switch
	
	// marking kernel as normal
	kernel_busy = 0;
}