www.pudn.com > CAN_Ex1.rar > RTX_Config.c


/*---------------------------------------------------------------------------- 
 *      R T L  -  K e r n e l 
 *---------------------------------------------------------------------------- 
 *      Name:    RTX_CONFIG.C 
 *      Purpose: Configuration of RTX Kernel for Philips LPC23xx 
 *      Rev.:    V3.12 
 *---------------------------------------------------------------------------- 
 *      This code is part of the RealView Run-Time Library. 
 *      Copyright (c) 2004-2007 KEIL - An ARM Company. All rights reserved. 
 *---------------------------------------------------------------------------*/ 
 
#include                      /* LPC23xx definitions              */ 
#include                   /* RTX user configuration header    */ 
 
/*---------------------------------------------------------------------------- 
 *      RTX User configuration part BEGIN 
 *---------------------------------------------------------------------------*/ 
 
//-------- <<< Use Configuration Wizard in Context Menu >>> ----------------- 
// 
// Task Definitions 
// =================== 
// 
//   Number of concurrent running tasks <0-250> 
//    Define max. number of tasks that will run at the same time. 
//    Default: 6 
#ifndef OS_TASKCNT 
 #define OS_TASKCNT     7 
#endif 
 
//   Number of tasks with user-provided stack <0-250> 
//    Define the number of tasks that will use a bigger stack. 
//    The memory space for the stack is provided by the user. 
//    Default: 0 
#ifndef OS_PRIVCNT 
 #define OS_PRIVCNT     0 
#endif 
 
//   Task stack size [bytes] <20-4096:8><#/4> 
//    Set the stack size for tasks which is assigned by the system. 
//    Default: 200 
#ifndef OS_STKSIZE 
 #define OS_STKSIZE     50 
#endif 
 
// Check for the stack overflow 
// =============================== 
//  Include the stack checking code for a stack overflow. 
//  Note that additional code reduces the Kernel performance. 
#ifndef OS_STKCHECK 
 #define OS_STKCHECK    1 
#endif 
 
//   Number of user timers <0-250> 
//    Define max. number of user timers that will run at the same time. 
//    Default: 0  (User timers disabled) 
#ifndef OS_TIMERCNT 
 #define OS_TIMERCNT    0 
#endif 
 
//  
// System Timer Configuration 
// ============================= 
//   RTX Kernel timer number <0=> Timer 0 <1=> Timer 1 
//                              <2=> Timer 2 <3=> Timer 3 
//    Define the ARM timer used as a system tick timer. 
//    Default: Timer 0 
#ifndef OS_TIMER 
 #define OS_TIMER       0 
#endif 
 
//   Timer clock value [Hz] <1-1000000000> 
//    Set the timer clock value for selected timer. 
//    Default: 15000000  (15MHz at 60MHz CCLK and VPBDIV = 4) 
#ifndef OS_CLOCK 
 #define OS_CLOCK       12000000 
#endif 
 
//   Timer tick value [us] <1-1000000> 
//    Set the timer tick value for selected timer. 
//    Default: 10000  (10ms) 
#ifndef OS_TICK 
 #define OS_TICK        10000 
#endif 
 
//  
// Round-Robin Task switching 
// ============================= 
//  Enable Round-Robin Task switching. 
#ifndef OS_ROBIN 
 #define OS_ROBIN       1 
#endif 
 
//   Round-Robin Timeout [ticks] <1-1000> 
//    Define how long a task will execute before a task switch. 
//    Default: 5 
#ifndef OS_ROBINTOUT 
 #define OS_ROBINTOUT   5 
#endif 
 
//  
 
//------------- <<< end of configuration section >>> ----------------------- 
 
/*---------------------------------------------------------------------------- 
 *      RTX User configuration part END 
 *---------------------------------------------------------------------------*/ 
 
#if   (OS_TIMER == 0)                                   /* Timer 0          */ 
  #define OS_TID_       4                               /*  Timer ID        */ 
  #define PCON_VAL      1 
  #define TIMx(reg)     T0##reg 
  #define VICVectAddrX  VICVectAddr4 
#elif (OS_TIMER == 1)                                   /* Timer 1          */ 
  #define OS_TID_       5                               /*  Timer ID        */ 
  #define PCON_VAL      2 
  #define TIMx(reg)     T1##reg 
  #define VICVectAddrX  VICVectAddr5 
#elif (OS_TIMER == 2)                                   /* Timer 2          */ 
  #define OS_TID_       26                              /*  Timer ID        */ 
  #define PCON_VAL      22 
  #define TIMx(reg)     T2##reg 
  #define VICVectAddrX  VICVectAddr26 
#elif (OS_TIMER == 3)                                   /* Timer 3          */ 
  #define OS_TID_       27                              /*  Timer ID        */ 
  #define PCON_VAL      23 
  #define TIMx(reg)     T3##reg 
  #define VICVectAddrX  VICVectAddr27 
#else 
  #error OS_TIMER invalid 
#endif 
 
#define OS_TIM_         (1 << OS_TID_)                  /*  Interrupt Mask  */ 
#define OS_TRV          ((U32)(((double)OS_CLOCK*(double)OS_TICK)/1E6)-1) 
#define OS_TVAL         TIMx(TC)                        /*  Timer Value     */ 
#define OS_TOVF         (TIMx(IR) & 1)                  /*  Overflow Flag   */ 
#define OS_TREL()       ;                               /*  Timer Reload    */ 
#define OS_TFIRQ()      VICSoftInt   |= OS_TIM_;        /*  Force Interrupt */ 
#define OS_TIACK()      TIMx(IR) = 1;                   /*  Interrupt Ack   */ \ 
                        VICSoftIntClr = OS_TIM_;                               \ 
                        VICVectAddr   = 0; 
#define OS_TINIT()      PCONP |= (1<tsk_stack = stack; 
   os_runtask->full_ctx = __TRUE; 
   os_runtask->state  = READY; 
   os_put_rdy_first (os_runtask); 
   os_runtask = &os_clock_TCB; 
   os_clock_TCB.state = RUNNING; 
   return (os_runtask->tsk_stack); 
} /* end of os_clock_interrupt0 */ 
 
/*--------------------------- os_def_interrupt ------------------------------*/ 
 
void os_def_interrupt (void) __irq  { 
   /* Default Interrupt Function: may be called when timer ISR is disabled */ 
   OS_IACK(); 
} 
 
/*--------------------------- os_tmr_init -----------------------------------*/ 
 
void os_tmr_init (void) { 
   /* Initialize hardware timer as system tick timer. This function is     */ 
   /* called at the system startup.                                        */ 
   OS_TINIT(); 
#if (OS_ROBIN == 1) 
   os_robin_time = OS_ROBINTOUT; 
#endif 
} /* end of os_tmr_init */ 
 
/*--------------------------- os_tmr_reload ---------------------------------*/ 
 
void os_tmr_reload (void) { 
   /* Reload system timer for next period if a timer requires reload.        */ 
   OS_TREL(); 
} /* end of os_tmr_reload */ 
 
/*--------------------------- os_tmr_force_irq ------------------------------*/ 
 
void os_tmr_force_irq (void) { 
   /* Force a timer interrupt.                                               */ 
   OS_TFIRQ(); 
} /* end of os_tmr_force_irq */ 
 
/*--------------------------- os_tmr_inspect_cnt ----------------------------*/ 
 
U32 os_tmr_inspect_cnt (void) { 
   /* Inspect current value of rtx timer.                                    */ 
   return (OS_TVAL); 
} /* end of os_tmr_inspect_cnt */ 
 
/*--------------------------- os_tmr_inspect_ovf ----------------------------*/ 
 
BOOL os_tmr_inspect_ovf (void) { 
   /* Inspect current state of timer overflow flag.                          */ 
   return (OS_TOVF); 
} /* end of os_tmr_inspect_ovf */ 
 
/*--------------------------- tsk_lock --------------------------------------*/ 
 
void tsk_lock (void) { 
   /* Lock out tasks: prevents task switching by locking out scheduler       */ 
   /* activation on interrupt.                                            .  */ 
   OS_LOCK(); 
} /* end of tsk_lock */ 
 
/*--------------------------- tsk_unlock ------------------------------------*/ 
 
void tsk_unlock (void) { 
   /* Enable AR System Tick Timer Interrupts.                                */ 
   OS_UNLOCK(); 
} /* end of tsk_unlock */ 
 
/*--------------------------- os_init_mem -----------------------------------*/ 
 
void os_init_mem (void) { 
   U32 i; 
 
   for (i = 0; i < OS_TASKCNT; i++) { 
      os_active_TCB[i] = NULL; 
   } 
   _init_box (&m_tcb, sizeof(m_tcb), sizeof(struct OS_TCB)); 
   _init_box8 (&m_stk, sizeof(m_stk), OS_STKSIZE*4); 
#if (OS_TIMERCNT != 0) 
   _init_box (&m_tmr, sizeof(m_tmr), sizeof(struct OS_TMR)); 
#endif 
} /* end of os_init_mem */ 
 
/*--------------------------- os_alloc_TCB ----------------------------------*/ 
 
P_TCB os_alloc_TCB () { 
   return (_alloc_box (m_tcb)); 
} /* end of os_alloc_TCB */ 
 
/*--------------------------- os_free_TCB -----------------------------------*/ 
 
void os_free_TCB (P_TCB p_TCB) { 
   /* Free allocated memory resources for the task "p_TCB" */ 
   _free_box (m_stk, p_TCB->stack); 
   _free_box (m_tcb, p_TCB); 
#if (OS_STKCHECK == 1) 
   if (os_runtask == p_TCB) { 
      /* os_tsk_delete_self() called. */ 
      os_del_flag = __TRUE; 
   } 
#endif 
} /* end of os_free_TCB */ 
 
/*--------------------------- os_alloc_TMR ----------------------------------*/ 
 
P_TMR os_alloc_TMR () { 
#if (OS_TIMERCNT != 0) 
   return (_alloc_box (m_tmr)); 
#else 
   return (NULL); 
#endif 
} /* end of os_alloc_TMR */ 
 
/*--------------------------- os_free_TMR -----------------------------------*/ 
 
void os_free_TMR (P_TMR timer) { 
   /* Free allocated memory resources for user timer 'timer' */ 
#if (OS_TIMERCNT != 0) 
   _free_box (m_tmr, timer); 
#else 
   timer = timer; 
#endif 
} /* end of os_free_TMR */ 
 
/*--------------------------- os_init_context -------------------------------*/ 
 
void os_init_context (P_TCB p_TCB, U8 priority, 
                      FUNCP task_body, U8 full_context) { 
   /* Prepare TCB and saved context for a first time start of a task         */ 
   /* "p_TCB" points to TCB to be initialised. "priority" indicates desired  */ 
   /* execution priority. "task_body" is the start address of the task.      */ 
   /* "full_context" identifies context type.                                */ 
   U32 *stk,i; 
 
   /* Initialize general part of TCB */ 
   p_TCB->cb_type = TCB; 
   p_TCB->state   = READY; 
   p_TCB->prio    = priority; 
   p_TCB->p_lnk   = NULL; 
   p_TCB->p_rlnk  = NULL; 
   p_TCB->p_dlnk  = NULL; 
   p_TCB->p_blnk  = NULL; 
   p_TCB->delta_time    = 0; 
   p_TCB->interval_time = 0; 
   p_TCB->events  = 0; 
   p_TCB->waits   = 0; 
 
   /* Initialize ARM specific part of TCB */ 
   p_TCB->full_ctx = full_context; 
 
   /* Prepare a complete interrupt frame for first task start */ 
   if (p_TCB->priv_stack != 0) { 
      /* User has provided a memory space for the stack. */ 
      stk = &p_TCB->stack[p_TCB->priv_stack>>2]; 
   } 
   else { 
      /* Allocate the memory space for the stack. */ 
      p_TCB->stack = _alloc_box (m_stk); 
      /* Write to the top of stack. */ 
      stk = &p_TCB->stack[OS_STKSIZE]; 
   } 
 
   /* Initial PC and default CPSR */ 
   *--stk = (U32)task_body; 
   i      = INITIAL_CPSR; 
 
   /* If a task in THUMB mode, set T-bit. */ 
   if ((U32)task_body & 1) { 
      i |= 0x00000020; 
   } 
   *--stk = i; 
 
   /* Write initial registers. */ 
   for (i = full_context ? 13 : 8; i; i--) { 
      *--stk = 0; 
   } 
 
   /* For "full_context" assign a void pointer to R0. */ 
   if (full_context) { 
      *--stk = (U32)p_TCB->p_msg; 
   } 
 
   /* Initial Task stack pointer. */ 
   p_TCB->tsk_stack = (U32)stk; 
 
   /* Task entry point. */ 
   p_TCB->ptask = task_body; 
#if (OS_STKCHECK == 1) 
   /* Set a magic word for checking of stack overflow. */ 
   p_TCB->stack[0] = MAGIC_WORD; 
#endif 
} /* end of os_init_context */ 
 
 
/*--------------------------- os_switch_tasks -------------------------------*/ 
 
void __swi(0) os_switch_tasks (P_TCB p_new); 
void __SWI_0                  (P_TCB p_new) { 
   /* Switch to next task (identified by "p_new"). Saving old and restoring */ 
   /* new context is written in assembly (module: Swi_RTX.s)                */ 
 
#if (OS_STKCHECK == 1) 
   if (tstclrb (&os_del_flag) == __FALSE) { 
      /* Do not check if task has deleted itself. */ 
      if ((os_runtask->tsk_stack < (U32)os_runtask->stack) ||  
          (os_runtask->stack[0] != MAGIC_WORD )) { 
         os_stk_overflow (); 
      } 
   } 
#endif 
   os_runtask->full_ctx = __FALSE; 
   os_runtask = p_new; 
   p_new->state = RUNNING; 
#if (OS_ROBIN == 1) 
   if (p_new->full_ctx == __TRUE) { 
      os_tsk_robin = p_new; 
   } 
#endif 
   /* Tsk_Unlock */ 
   OS_UNLOCK(); 
} /* end of os_switch_tasks */ 
 
 
/*--------------------------- os_chk_robin ----------------------------------*/ 
 
void os_chk_robin (void) { 
   /* Check if Round Robin timeout expired and switch to the next ready task.*/ 
   /* This function is called from the "os_clock_demon()" task scheduler.    */ 
#if (OS_ROBIN == 1) 
   P_TCB p_new; 
 
   if (os_rdy.p_lnk != os_tsk_robin) { 
      os_robin_time = os_time + OS_ROBINTOUT; 
      return; 
      } 
   if (os_robin_time == os_time) { 
      /* Round Robin timeout has expired. */ 
      os_robin_time += OS_ROBINTOUT; 
      p_new = os_get_first (&os_rdy); 
      os_put_prio ((P_XCB)&os_rdy, p_new); 
      } 
#endif 
} /* end of os_chk_robin */ 
 
/*---------------------------------------------------------------------------- 
 * end of file 
 *---------------------------------------------------------------------------*/