⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 os_cpu_c.c

📁 mips下的ucos
💻 C
📖 第 1 页 / 共 2 页
字号:
  // Get the stack pointer of the task to resume
  $SP = (OS_REGS *)OSTCBHighRdy->OSTCBStkPtr;
  
  OSTCBCur = OSTCBHighRdy;
  OSPrioCur = OSPrioHighRdy;

  // Execute return from interrupt;
  RFI();
}



#if OS_CPU_HOOKS_EN
/*
*********************************************************************************************************
*                                          TASK CREATION HOOK
*
* Description: This function is called when a task is created.
*
* Arguments  : ptcb   is a pointer to the task control block of the task being created.
*
* Note(s)    : 1) Interrupts are disabled during this call.
*********************************************************************************************************
*/
void OSTaskCreateHook (OS_TCB *ptcb)
{
    ptcb = ptcb;                       /* Prevent compiler warning                                     */
}


/*
*********************************************************************************************************
*                                           TASK DELETION HOOK
*
* Description: This function is called when a task is deleted.
*
* Arguments  : ptcb   is a pointer to the task control block of the task being deleted.
*
* Note(s)    : 1) Interrupts are disabled during this call.
*********************************************************************************************************
*/
void OSTaskDelHook (OS_TCB *ptcb)
{
    ptcb = ptcb;                       /* Prevent compiler warning                                     */
}

/*
*********************************************************************************************************
*                                           TASK SWITCH HOOK
*
* Description: This function is called when a task switch is performed.  This allows you to perform other
*              operations during a context switch.
*
* Arguments  : none
*
* Note(s)    : 1) Interrupts are disabled during this call.
*              2) It is assumed that the global pointer 'OSTCBHighRdy' points to the TCB of the task that
*                 will be 'switched in' (i.e. the highest priority task) and, 'OSTCBCur' points to the
*                 task being switched out (i.e. the preempted task).
*********************************************************************************************************
*/
void OSTaskSwHook (void)
{
}

/*
*********************************************************************************************************
*                                           STATISTIC TASK HOOK
*
* Description: This function is called every second by uC/OS-II's statistics task.  This allows your
*              application to add functionality to the statistics task.
*
* Arguments  : none
*********************************************************************************************************
*/
void OSTaskStatHook (void)
{
}

/*
*********************************************************************************************************
*                                               TICK HOOK
*
* Description: This function is called every tick.
*
* Arguments  : none
*
* Note(s)    : 1) Interrupts may or may not be ENABLED during this call.
*********************************************************************************************************
*/
void OSTimeTickHook (void)
{
}

#if OS_VERSION >= 204
void OSInitHookBegin(void)
{
}

void OSInitHookEnd(void)
{
}

void OSTCBInitHook(OS_TCB *ptcb)
{
}
#endif

#if OS_VERSION >= 251
void OSTaskIdleHook(void)
{
}
#endif


#endif



void (*OSDispatcher)(INT32U, INT32U) 
     __attribute__ ((section (".data"))) = IRQDispatch;

void OSInterruptHandler(void) 
     __attribute__ ((naked, section (".interrupt")));
void OSInterruptHandler(void)
{
  register INT32U cause, sr;

  // Get the address of the interrupted context
  __asm__ volatile ("mfc0 	$kt0,$14");

  // Allocate space on the stack to save all the 
  // registers
  $SP--;
  SAVE_ALL();

  // Get the cause register to figure out what type of interrupt
  // we have
  __asm__ volatile 
    (".set	noreorder	\n"
     "mfc0	%0,$13		\n" /* Cause reg */
     "mfc0	%1,$12		\n" /* Status reg */
     "sw 	$kt0,%2($sp)	\n" /* Save exception address 	*/
     ".set	reorder         "
     : "=d"(cause), "=d"(sr)
     : "I"(offsetof(OS_REGS, reg_pc)));

  (*OSDispatcher)(cause, sr);
}


void OSCtxSw(void) __attribute__((naked));
void OSCtxSw(void)
{
  register INT32U  $RA __asm__("$31");

  // Allocate space on the stack to save all the 
  // registers
  $SP--;
  $SP->reg_pc = $RA;

  // We only need to save the non volatile registers because 
  // we come here through a normal function call.
  SAVE_NON_VOLATILE();

  // Save the current stack pointer
  OSTCBCur->OSTCBStkPtr = (OS_STK *)$SP;

  // Call use definable
  OSTaskSwHook();

  OSTCBCur = OSTCBHighRdy;
  OSPrioCur = OSPrioHighRdy;

  __asm__ volatile ("mfc0	$kt0,$12");
  $SP = (OS_REGS *)OSTCBHighRdy->OSTCBStkPtr;
  __asm__ volatile 
    ("ori	$kt0,$kt0,4     \n"
     "mtc0	$kt0,$12	");
  
  // Return from interrupt
  RFI();
}


/*********************/
/* Interrupt support */
/*********************/

#define MAXINTERRUPTS 8
FUNC IRQVector[MAXINTERRUPTS];

static void IRQEnable(int IRQNum)
{
  register INT32U tmp;
  register INT32U mask;

  // The IntMask field is at offset 8, but the 
  // first 2 bits are for the Software interrupts
  mask = (1<<(8+IRQNum))+1;
  __asm__ volatile 
    ("mfc0	%0,$12		\n"
     "nop                	\n"
     "or	%0,%1,%2	\n"
     "mtc0	%1,$12  	\n"
     : "=d"(tmp) 
     : "d"(tmp), "d"(mask));
}


FUNC IRQInstall(int IRQNum, FUNC ISRFun)
{
  FUNC OldISR;
  
  if (IRQNum < 0 || IRQNum >= MAXINTERRUPTS)
    return((FUNC)0);
  
  /* Get old ISR function */
  OldISR = IRQVector[IRQNum];
  
  /* Replace with new ISR function */
  IRQVector[IRQNum] = ISRFun;
  
  /* Enable the interrupt */
  IRQEnable(IRQNum);
  
  return(OldISR);
}


void IRQDispatch(INT32U exc_cause, INT32U exc_sr)
{
  INT32U Mask = SR_IBIT8;
  INT32U Status,imask;
  int	IRQNum = 7;
  
  OSIntNesting++;

  if (OSIntNesting == 1)
    {
      OSTCBCur->OSTCBStkPtr = (OS_STK *)$SP;
    }

  Status = exc_cause & exc_sr & SR_IMASK;
  while (IRQNum >= 0) {
    if (Status & Mask) {
      if (IRQVector[IRQNum])
	(*(IRQVector[IRQNum]))();
      else
	;/* spurious interrupt */
      break;
    }
    Mask = Mask >> 1;
    IRQNum--;
  }
  
  OSIntExit();

  // Return from interrupt
  RFI();
} 
 
OS_CPU_SR disable_ints()
{                     		  
  register OS_CPU_SR sr, sr_off;  

  sr = GET_SR();
  sr_off = sr & 0xfffffffe;
  SET_SR(sr_off);

  return (sr);
}

void enable_ints(OS_CPU_SR cpu_sr)
{
  register OS_CPU_SR sr;

  sr = GET_SR();
  cpu_sr &= 0x00000001;
  sr |= cpu_sr;
  SET_SR(sr);
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -