访问电脑版页面

导航:老古开发网手机版其他

ARTX_CONFIG.C的中文注释

导读:
关键字:
学习ARTX,了解系统的配置非常重要。我加上中文的注释希望能帮助大家的更快的了解ARTX_CONFIG.C的内容。

/*----------------------------------------------------------------------------
 *      A R T X  -  K e r n e l
 *----------------------------------------------------------------------------
 *      Name:    ARTX_CONFIG.C
 *      Purpose: Configuration of ARTX Kernel for Atmel AT91SAM7S
 *      Rev.:    V1.10 / 11-jul-2005
 *----------------------------------------------------------------------------
 *      This code is part of the ARTX-ARM kernel package of Keil Software.
 *      Copyright (c) 2004-2005 Keil Software. All rights reserved.
 *---------------------------------------------------------------------------*/

#pragma INTERWORK
#define NOFRAME    __arm __task

#include <AT91SAM7S64.H>
#include <ARTX_Config.h>                 /* ARTX 用户配置头文件*/

/*----------------------------------------------------------------------------
 *      ARTX User configuration part BEGIN
 *---------------------------------------------------------------------------*/

//-------- <<< Use Configuration Wizard in Context Menu >>> -----------------
//
// <h>任务定义
// ===================
//
//   OS_TASKCNT:定义当前运行的任务数<0-250>
//    Can be less than the number of defined tasks or more if
//    multi instances of tasks will run. This define is used
//    to calculate the the memory block size that is reserved
//    for fixed memory block management.
//   默认任务数: 6
#define OS_TASKCNT      6

//   OS_PRIVCNT: 定义使用用户堆栈区的任务数<0-250>
//   某些需要比OS_STKSIZE更大的堆栈区的任务.
//   在这种情况下内存空间就需要用户自己来分配而不是用系统分配
//   默认数: 0
#define OS_PRIVCNT      0

//   OS_STKSIZE: 系统任务堆栈大小(字节byte) <20-4096:4><#/4>
//   This stack is used for task''s stack and context switch
//   <i> for registers and system stack storage.
//   默认值: 200
#define OS_STKSIZE      50

//   OS_TIMERCNT: 用户定时器数的定义<0-250>
//   Define max. number of user timers running. They act as
//   a watchdog timer counting down on each system clock tick.
//   On timeout the user provided function is called.
//   默认值: 0  (User timers disabled)
#define OS_TIMERCNT     0

// </h>
// <h>系统时钟配置
// =============================
//   OS_TIMER: ARTX 内核时钟<0=> PIT
//   定义ARM定时器作为系统节拍时钟
//   默认值: PIT
#define OS_TIMER        0

//   <o>OS_CLOCK: 定时时钟的值[Hz] <1-1000000000>
//  
//   <i> Default: 3000000  (3MHz at 48MHz MCLK and prescaler by 16)
#define OS_CLOCK        3000000

//   <o>OS_TICK: 定时器节拍值[us] <1-1000000>
//   为所选定的定时器设定节拍值
//   默认值: 10000  (10ms)
#define OS_TICK         10000

//
// Round-Robin Task switching
#define OS_ROBIN        1

//   OS_ROBINTOUT: Round-Robin Timeout in system ticks <1-1000>
//   这是一个分配给正在运行的任务的时间片
//   When this expires, round robin task switch takes place.
//   Default: 5
#define OS_ROBINTOUT    5

// </e>

//------------- <<< end of configuration section >>> -----------------------

/*----------------------------------------------------------------------------
 *      ARTX User configuration part END
 *---------------------------------------------------------------------------*/

#if   (OS_TIMER == 0)                                   /* PIT */
  #define OS_TIM        (1 << AT91C_ID_SYS)             /*  Interrupt Mask */
  #define OS_TRV        ((DWORD)(((double)OS_CLOCK*(double)OS_TICK)/1E6)-1)
  #define OS_TVAL       (*AT91C_PITC_PIIR & 0x000FFFFF) /*  Timer Value */
  #define OS_TOVF       (*AT91C_PITC_PISR & 1)          /*  Overflow Flag */
  #define OS_TREL()     ;                               /*  Timer Reload */
  #define OS_TFIRQ()    *AT91C_AIC_ISCR  = OS_TIM;      /*  Force Interrupt */
  #define OS_TIACK()    *AT91C_AIC_EOICR = *AT91C_PITC_PIVR;                   \
                        *AT91C_AIC_ICCR  = OS_TIM;      /*  Interrupt Ack */
  #define OS_TINIT()    *AT91C_PITC_PIMR = OS_TRV      /*  Initialization */  \
                          AT91C_PITC_PITIEN AT91C_PITC_PITEN;                \
                        *(AT91C_AIC_SPU) = (DWORD)os_def_interrupt;            \
                        *(AT91C_AIC_SVR + AT91C_ID_SYS) =                      \
                          (DWORD)os_clock_interrupt;                           \
                        *(AT91C_AIC_SMR + AT91C_ID_SYS) =                      \
                          AT91C_AIC_SRCTYPE_INT_EDGE_TRIGGERED 0;            \
                        *(AT91C_AIC_IECR) = OS_TIM;
#else
  #error OS_TIMER invalid
#endif

#define OS_LOCK()       *AT91C_AIC_IDCR = OS_TIM;       /* Lock */
#define OS_UNLOCK()     *AT91C_AIC_IECR = OS_TIM;       /* Unlock */

/* WARNING ! Do not use IDLE mode if you are using a JTAG interface  */
/*           for debugging your application.                         */
#define _idle_()        *AT91C_PMC_SCDR = 1;
#define INITIAL_CPSR    0x40000010

/*----------------------------------------------------------------------------
 *      Global Variables全局变量
 *---------------------------------------------------------------------------*/

extern P_TCB os_runtask;
extern struct OS_XCB os_rdy;
extern struct OS_TCB os_clock_TCB;
extern WORD os_time;
WORD  const os_maxtaskrun = OS_TASKCNT;
/* Export following defines to uVision debugger. */
WORD  const os_stacksize  = OS_STKSIZE * 4;
DWORD const os_clockrate  = (DWORD)((double)(OS_TRV+1)*1E6/(double)OS_CLOCK);
DWORD const os_timernum   = (OS_TIMER << 16) OS_TIMERCNT;
DWORD const os_rrobin     = (OS_ROBIN << 16) OS_ROBINTOUT;

/*----------------------------------------------------------------------------
 *      Local Variables局部变量
 *---------------------------------------------------------------------------*/
/* Memory pool for TCB allocation    */
static DWORD m_tcb[(sizeof(struct OS_TCB) * OS_TASKCNT)/4 + 3];

/* Memory pool for System stack allocation. Need to allocate 2 additional  */
/* entries for ''os_clock_demon()'' and ''os_idle_demon()''.                   */
static DWORD m_stk[OS_STKSIZE * (OS_TASKCNT-OS_PRIVCNT+2) + 3];

/* An array of Active task pointers.                                       */
P_TCB os_active_TCB[OS_TASKCNT];

#if (OS_ROBIN == 1)
  static WORD  os_robin_time;
  static P_TCB os_tsk_robin;
#endif

#if (OS_TIMERCNT != 0)
  /* Memory pool for User Timer allocation                                 */
  static DWORD m_tmr[(sizeof(struct OS_TMR) * OS_TIMERCNT)/4 + 3];
#endif

/*----------------------------------------------------------------------------
 *      Global Functions全局函数
 *---------------------------------------------------------------------------*/

/*--------------------------- os_idle_demon ---------------------------------*/

void os_idle_demon (void) __task {
   /* The idle demon is a system task. It is running when no other task is   */
   /* ready to run (idle situation). It must not terminate. Therefore it     */
   /* should contain at least an endless loop.                               */

   for (;;) {
   /* HERE: include here optional user code to be executed when no task runs.*/
   }
} /* end of os_idle_demon */


/*--------------------------- os_tmr_call -----------------------------------*/

void os_tmr_call (WORD info) {
   /* This function is called when the user timer has expired.               */
   /* Parameter "info" is the parameter defined when the timer was created.  */
   /* HERE: include here optional user code to be executed on timeout.       */
   info = info;
} /* end of os_tmr_call */

/*--------------------------- os_clock_interrupt ----------------------------*/

void os_clock_interrupt (void) NOFRAME {
   /* Do task switch to clock demon: entered upon a clock interrupt. */
   __asm {
        STMDB   SP!,{R0-R1}                 ; Save Full Context
        STMDB   SP,{SP}^                    ; User SP
        LDMDB   SP,{R0}
        MRS     R1,SPSR                     ; User CPSR
        SUB     LR,LR,#0x4
        STMDB   R0!,{R1,LR}                 ; Push PC, CPSR
        STMDB   R0,{LR}^                    ; Push User LR
        SUB     R0,R0,#0x4                  ; Write back problem !!
        STMDB   R0!,{R2-R12}                ; Push R12-R2
        LDMIA   SP!,{R2-R3}
        STMDB   R0!,{R2-R3}                 ; Push R1-R0

        LDR     R1,=os_runtask              ; os_runtask
        LDR     R1,[R1,#0x0]                ; os_runtask
        STR     R0,[R1,#TCB_TSTACK]         ; os_runtask->tsk_stack
   }
   OS_TIACK();
   tsk_lock ();
   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;
   __asm {
        LDR     R0,=os_runtask              ; os_runtask
        LDR     R0,[R0,#0x0]                ; os_runtask
        LDR     R0,[R0,#TCB_TSTACK]         ; os_runtask->tsk_stack

        LDMIA   R0!,{R4-R8,R12}
        MSR     SPSR_cxsf,R8
        STMDB   SP,{R0}                     ; Set User SP
        LDMDB   SP,{SP}^
        MOVS    PC,R12                      ; RETI
   }
} /* end of os_clock_interrupt */

/*--------------------------- os_def_interrupt ------------------------------*/

void os_def_interrupt (void) __irq  {
   /* Default Interrupt Function: may be called when timer ISR is disabled */
}

/*--------------------------- 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 ----------------------------*/

DWORD 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) {
   WORD 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_box (&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);
} /* 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, BYTE  priority,
                      FUNCP task_body, BYTE  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.                                */
   DWORD *stk,i;

   /* Initialise 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;

   /* Initialise 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 = (DWORD)task_body;
   i      = INITIAL_CPSR;

   /* If a task in THUMB mode, set T-bit. */
   if ((DWORD)task_body & 1) {
      i = 0x00000020;
   }
   *--stk = i;

   /* Write initial registers. */
   for (i = full_context ? 13 : 4; i; i--) {
      *--stk = 0;
   }

   /* For "full_context" assign a void pointer to R0. */
   if (full_context) {
      *--stk = (DWORD)p_TCB->p_msg;
   }

   /* Initial Task stack pointer. */
   p_TCB->tsk_stack = (DWORD)stk;

   /* Task entry point. */
   p_TCB->ptask = task_body;
} /* end of os_init_context */


/*--------------------------- os_set_env ------------------------------------*/

void os_set_env (P_TCB p_TCB) {
   /* Fix up runtime environment to fit idle task. It is called after the  */
   /* idle task TCB initialization. "p_TCB" identifies the TCB to be used. */
   p_TCB = p_TCB;
   __asm {
        LDR     R0,[R0,#TCB_TSTACK]         ; p_TCB in R0
        MOV     SP,R0
        ADD     SP,SP,#24                   ; ignore default context
   }
} /* end of os_set_env */


/*--------------------------- os_switch_tasks -------------------------------*/

void os_switch_tasks (P_TCB p_new) __swi (0) {
   /* Switch to next task (identified by "p_new"). Saving old and restoring */
   /* new context is written in assembly (module: Swi_ARTX.s)               */

   os_runtask->full_ctx = FALSE;
   os_runtask = p_new;
   p_new->state = RUNNING;
#if (OS_ROBIN == 1)
   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
 *---------------------------------------------------------------------------*/
边理解边改


来源:   作者:  2006/9/25 16:50:53
栏目: [ ]

相关阅读

安森美推出新的高功率图腾柱PFC控制器,满足具挑战的能效标准

动态功耗低至60μA/MHz!助力设备超长续航,首选国民技术低功耗MCU!