www.pudn.com > ucosforcodewarrior-hc12.rar > os_cpu_c.c, change:2006-01-05,size:26239b


/* 
********************************************************************************************************* 
*                                                uC/OS-II 
*                                          The Real-Time Kernel 
* 
*                          (c) Copyright 1992-2003, Jean J. Labrosse, Weston, FL 
*                                           All Rights Reserved 
*                                      MC9S12DP256 Specific code 
*                                       (MetroWerks C/C++ V4.2) 
* 
* 
* File         : OS_CPU_C.C 
* By   : Jean J. Labrosse 
* Ported to MC9S12DP256 by Abderrahmane Assal 
********************************************************************************************************* 
*/ 
 
#include <includes.h> 
/* 
******************************************************************************************************************** 
*                                        INITIALIZE A TASK'S STACK 
* 
* Description: This function is called by either OSTaskCreate() or OSTaskCreateExt() to initialize the 
*              stack frame of the task being created.  This function is highly processor specific. 
* 
* Arguments  : task          is a pointer to the task code 
* 
*              pdata         is a pointer to a user supplied data area that will be passed to the task 
*                            when the task first executes. 
* 
*              ptos          is a pointer to the top of stack.  It is assumed that 'ptos' points to 
*                            a 'free' entry on the task stack.  If OS_STK_GROWTH is set to 1 then  
*                            'ptos' will contain the HIGHEST valid address of the stack.  Similarly, if 
*                            OS_STK_GROWTH is set to 0, the 'ptos' will contains the LOWEST valid address 
*                            of the stack. 
* 
*              opt           specifies options that can be used to alter the behavior of OSTaskStkInit(). 
*                            (see uCOS_II.H for OS_TASK_OPT_???). 
* 
* Returns    : Always returns the location of the new top-of-stack' once the processor registers have 
*              been placed on the stack in the proper order. 
* 
* Note(s)    : 1) XIRQ interrupts are disabled when your task starts executing. You can change this by  
*                 clearing BIT6 in the CCR. 
*              2) The STOP instruction is disabled when your task starts executing.  You can change this 
*                 by clearing BIT7 in the CCR. 
*              3) The other interrupts (i.e. maskable interrupts) are enabled when your task starts 
*                 executing.  You can change this by setting BIT4 in the CCR. 
*              4) You can change pass the above options in the 'opt' argument.  You MUST only use the 
*                 upper 8 bits of 'opt' because the lower bits are reserved by uC/OS-II.  If you make 
*                 changes to the code below, you will need to ensure that it doesn't affect the behaviour 
*                 of OSTaskIdle() and OSTaskStat(). 
*              5) Registers are initialized to make them easy to differentiate with a debugger. 
*              6) Tasks do not have to be in NON-PAGED memory.That is why I added an extra byte in every task's  
*				  stack to save the PPAGE register that locate the memory page where the task is located. If a  
*                 context switch occurs, the proper page will be saved/restored by uC/OS-II.  This done automatically 
*                 by the hardware provided that we add the option -CpPPAGE=0x30 as a compiler argument.   
*            
********************************************************************************************************************** 
*/ 
 
void *OSTaskStkInit (void (*task)(void *pd), void *pdata, void *ptos, INT16U opt) 
{ 
    INT16U *wstk; 
    INT8U  *bstk; 
	INT8U regPage;						/* regPage is used to save the PAGE register                   */ 
    INT16U *OffsetAddress; 
    opt     = opt;                     /* 'opt' is not used, prevent warning                           */ 
    wstk    = (INT16U *)ptos;          /* Load stack pointer                                           */ 
    *--wstk = (INT16U)pdata;           /* Simulate call to function with argument                      */ 
	OffsetAddress = (INT16U*)&task; 
	regPage = (INT8U)task; 
    *--wstk = (INT16U)*OffsetAddress; 
    *--wstk = (INT16U)*OffsetAddress;            /* Put pointer to task   on top of stack                        */ 
 
    *--wstk = (INT16U)0x2222;          /* Y Register                                                   */ 
    *--wstk = (INT16U)0x1111;          /* X Register                                                   */ 
    *--wstk = (INT16U)0xBBAA;          /* D Register                                                   */ 
    bstk    = (INT8U *)wstk;           /* Convert WORD ptr to BYTE ptr to set CCR                      */ 
    *--bstk = 0x80;                    /* CCR Register (Disable STOP instruction)                      */ 
    #if defined( __BANKED__) || defined(__LARGE__) 
    *--bstk = regPage;  			   /* Save the PPAGE register in case of banked memory model (see note 6)      */                    
    #endif                   
            return ((void *)bstk);             /* Return pointer to new top-of-stack                           */ 
} 
 
/*$PAGE*/ 
 
/* 
********************************************************************************************************* 
*                                       OS INITIALIZATION HOOK 
*                                            (BEGINNING) 
* 
* Description: This function is called by OSInit() at the beginning of OSInit(). 
* 
* Arguments  : none 
* 
* Note(s)    : 1) Interrupts should be disabled during this call. 
********************************************************************************************************* 
*/ 
#if OS_CPU_HOOKS_EN > 0 && OS_VERSION > 203 
void  OSInitHookBegin (void) 
{ 
} 
#endif 
 
/* 
********************************************************************************************************* 
*                                       OS INITIALIZATION HOOK 
*                                               (END) 
* 
* Description: This function is called by OSInit() at the end of OSInit(). 
* 
* Arguments  : none 
* 
* Note(s)    : 1) Interrupts should be disabled during this call. 
********************************************************************************************************* 
*/ 
 
 
#if OS_CPU_HOOKS_EN > 0 && OS_VERSION > 203 
void  OSInitHookEnd (void) 
{ 
} 
#endif 
 
/*$PAGE*/ 
/* 
********************************************************************************************************* 
*                                          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. 
********************************************************************************************************* 
*/ 
#if OS_CPU_HOOKS_EN > 0  
void  OSTaskCreateHook (OS_TCB *ptcb) 
{ 
    ptcb = ptcb;                       /* Prevent compiler warning                                     */ 
} 
#endif 
 
/* 
********************************************************************************************************* 
*                                           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. 
********************************************************************************************************* 
*/ 
#if OS_CPU_HOOKS_EN > 0  
void  OSTaskDelHook (OS_TCB *ptcb) 
{ 
    ptcb = ptcb;                       /* Prevent compiler warning                                     */ 
} 
#endif 
 
/* 
********************************************************************************************************* 
*                                             IDLE TASK HOOK 
* 
* Description: This function is called by the idle task.  This hook has been added to allow you to do   
*              such things as STOP the CPU to conserve power. 
* 
* Arguments  : none 
* 
* Note(s)    : 1) Interrupts are enabled during this call. 
********************************************************************************************************* 
*/ 
#if OS_CPU_HOOKS_EN > 0 && OS_VERSION >= 251 
void  OSTaskIdleHook (void) 
{ 
asm stop; 
} 
#endif 
 
 
/* 
********************************************************************************************************* 
*                                           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 
********************************************************************************************************* 
*/ 
 
#if OS_CPU_HOOKS_EN > 0  
void  OSTaskStatHook (void) 
{ 
} 
#endif 
 
/* 
********************************************************************************************************* 
*                                           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). 
********************************************************************************************************* 
*/ 
 
#if OS_CPU_HOOKS_EN > 0  
void  OSTaskSwHook (void) 
{ 
} 
#endif 
 
/* 
********************************************************************************************************* 
*                                           OSTCBInit() HOOK 
* 
* Description: This function is called by OS_TCBInit() after setting up most of the TCB. 
* 
* Arguments  : ptcb    is a pointer to the TCB of the task being created. 
* 
* Note(s)    : 1) Interrupts may or may not be ENABLED during this call. 
********************************************************************************************************* 
*/ 
#if OS_CPU_HOOKS_EN > 0 && OS_VERSION > 203 
void  OSTCBInitHook (OS_TCB *ptcb) 
{ 
    ptcb = ptcb;                                           /* Prevent Compiler warning                 */ 
} 
#endif 
 
 
 
/* 
********************************************************************************************************* 
*                                               TICK HOOK 
* 
* Description: This function is called every tick. 
* 
* Arguments  : none 
* 
* Note(s)    : 1) Interrupts may or may not be ENABLED during this call. 
********************************************************************************************************* 
*/ 
 
#if OS_CPU_HOOKS_EN > 0  
void  OSTimeTickHook (void) 
{ 
} 
#endif 
 
 
 
/******************************************************************************************************** 
;                                  SAVE THE CCR AND DISABLE INTERRUPTS 
;                                                  & 
;                                              RESTORE CCR 
; 
; Description : These function implements OS_CRITICAL_METHOD #3  
; 
; Arguments   : The function prototypes for the two functions are: 
;               1) OS_CPU_SR  OSCPUSaveSR(void) 
;                             where OS_CPU_SR is the contents of the CCR register prior to disabling 
;                             interrupts. 
;               2) void       OSCPURestoreSR(OS_CPU_SR os_cpu_sr); 
;                             'os_cpu_sr' the the value of the CCR to restore. 
; 
; Note(s)     : 1) It's assumed that the compiler uses the B register to pass a single 8-bit argument 
;                  to and from an assembly language function. 
;********************************************************************************************************/ 
void OSCPUSaveSR(OS_CPU_SR os_cpu_sr)  
{ 
__asm  
	{ 
    tpa                         // copy the value of CCR to the register A 
    staa   os_cpu_sr  
    sei                                // Disable interrupts 
	} 
 
} 
 
void OSCPURestoreSR(OS_CPU_SR os_cpu_sr)  
{ 
__asm  
	{ 
    ldaa os_cpu_sr 
    tap                         // A contains the CCR value to restore, move to CCR 
	} 
}                       
 
/********************************************************************************************************* 
;******************************************************************************************************** 
;                               START HIGHEST PRIORITY TASK READY-TO-RUN 
; 
; Description : This function is called by OSStart() to start the highest priority task that was created 
;               by your application before calling OSStart(). 
; 
; Arguments   : none 
; 
; Note(s)     : 1) The stack frame is assumed to look as follows: 
;    
;                  OSTCBHighRdy->OSTCBStkPtr +  0  -->  PPAGE 
;                                            +  1       CCR 
;                                            +  2       B 
;                                            +  3       A 
;                                            +  4       X (H) 
;                                            +  5       X (L) 
;                                            +  6       Y (H) 
;                                            +  7       Y (L) 
;                                            +  8       PC(H) 
;                                            +  9       PC(L) 
; 
;               2) OSStartHighRdy() MUST: 
;                      a) Call OSTaskSwHook() then, 
;                      b) Set OSRunning to TRUE, 
;                      c) Switch to the highest priority task by loading the stack pointer of the 
;                         highest priority task into the SP register and execute an RTI instruction. 
;******************************************************************************************************** 
;********************************************************************************************************/ 
 
#pragma CODE_SEG NON_BANKED			 
#pragma TRAP_PROC 
void OSStartHighRdy(void) 
{ 
#if OS_CPU_HOOKS_EN > 0 
    OSTaskSwHook(); 	/* 4~, Invoke user defined context switch hook */                                          
#endif 
            
__asm{ 
    inc    OSRunning                  ;2~, Indicate that we are multitasking                   
    ldx    OSTCBHighRdy               ;3~, Point to TCB of highest priority task ready to run  
    lds    0,x                        ;3~, Load SP into 68HC12                                
     
    /* I need to set PPAGE */ 
    pula                              ;If you want to use Banked Flash. You have to use this code 
    staa PPAGE												;add this code by Hansol Park. 2006. 01. 04 
	 } 
 
} 
 
/******************************************************************************************************** 
;******************************************************************************************************** 
;                                       TASK LEVEL CONTEXT SWITCH 
; 
; Description : This function is called when a task makes a higher priority task ready-to-run. 
; 
; Arguments   : none 
; 
; Note(s)     : 1) Upon entry,  
;                  OSTCBCur     points to the OS_TCB of the task to suspend 
;                  OSTCBHighRdy points to the OS_TCB of the task to resume 
; 
;               2) The stack frame of the task to suspend looks as follows: 
; 
;                  SP +  0  -->  PPAGE 
;                     +  1       CCR 
;                     +  2       B 
;                     +  3       A 
;                     +  4       X (H) 
;                     +  5       X (L) 
;                     +  6       Y (H) 
;                     +  7       Y (L) 
;                     +  8       PC(H) 
;                     +  9       PC(L) 
; 
;               3) The stack frame of the task to resume looks as follows: 
;  
;                  OSTCBHighRdy->OSTCBStkPtr +  0  -->  PPAGE 
;                                            +  1       CCR 
;                                            +  2       B 
;                                            +  3       A 
;                                            +  4       X (H) 
;                                            +  5       X (L) 
;                                            +  6       Y (H) 
;                                            +  7       Y (L) 
;                                            +  8       PC(H) 
;                                            +  9       PC(L) 
;******************************************************************************************************** 
;*********************************************************************************************************/ 
 
#pragma TRAP_PROC 
#pragma CODE_SEG __NEAR_SEG NON_BANKED  // add this code by Hansol Park. 2006.1.2 
__interrupt void OSCtxSw(void) 
{ 
__asm{ 
    /* for Banked Flash */ 
    ldaa  PPAGE						            // add this code by Hansol Park. 2006.1.4 
    psha 
        
    ldx    OSTCBCur                   ;  3~, OSTCBCur->OSTCBStkPtr = Stack Pointer                       
    sts    0,x                        ;  3~        
    } 
#if OS_CPU_HOOKS_EN > 0 
    OSTaskSwHook(); 	/* 4~, Invoke user defined context switch hook */                                          
#endif 
                        
__asm{     
    ldx    OSTCBHighRdy               ;  3~, OSTCBCur  = OSTCBHighRdy 
    stx    OSTCBCur                   ;  3~                          
    ldab   OSPrioHighRdy              ;  3~, OSPrioCur = OSPrioHighRdy                         
    stab   OSPrioCur                  ;  3~ 
    lds    0,x                        ;  3~, Load SP into 68HC12                               
     
    /* I need to set PPAGE */ 
    pula                              ;If you want to use Banked Flash. You have to use this code 
    staa PPAGE												;add this code by Hansol Park. 2006. 01. 04 
	} 
 }   
#pragma CODE_SEG DEFAULT 
/******************************************************************************************************** 
;******************************************************************************************************** 
;                                    INTERRUPT LEVEL CONTEXT SWITCH 
; 
; Description : This function is called by OSIntExit() to perform a context switch to a task that has 
;               been made ready-to-run by an ISR. 
; 
; Arguments   : none 
;******************************************************************************************************** 
;********************************************************************************************************/ 
 
#pragma TRAP_PROC 
void OSIntCtxSw(void) 
{ 
    #if OS_CPU_HOOKS_EN > 0 
    OSTaskSwHook(); 	/* 4~, Invoke user defined context switch hook */                                          
	#endif                      
__asm{     
    ldx    OSTCBHighRdy               ;  3~, OSTCBCur  = OSTCBHighRdy 
    stx    OSTCBCur                   ;  3~                         
    ldab   OSPrioHighRdy              ;  3~, OSPrioCur = OSPrioHighRdy                         
    stab   OSPrioCur                  ;  3~ 
    lds    0,x                        ;  3~, Load SP into 68HC12 
    /* I need to set PPAGE */ 
    pula                              ;If you want to use Banked Flash. You have to use this code 
    staa PPAGE												;add this code by Hansol Park. 2006. 01. 04                         
	} 
} 
 
/********************************************************************************************************* 
;******************************************************************************************************** 
 
;                                           SYSTEM TICK ISR 
; 
; Description : This function is the ISR used to notify uC/OS-II that a system tick has occurred.  You  
;               must setup the 68HC12's interrupt vector table so that an OUTPUT COMPARE interrupt  
;               vectors to this function. 
; 
; Arguments   : none 
; 
; Notes       :  1) The 'tick ISR' assumes the we are using the Output Compare specified by OS_TICK_OC 
;                   (see OS_CFG.H and this file) to generate a tick that occurs every OS_TICK_OC_CNTS  
;                   (see OS_CFG.H and this file) which corresponds to the number of FRT (Free Running  
;                   Timer) counts to the next interrupt. 
; 
;                2) You must specify which output compare will be used by the tick ISR as follows: 
;                       Set OS_TICK_OC in OS_CFG.H (AND in this file) to 0 to use OUTPUT COMPARE #0 
;                       Set OS_TICK_OC in OS_CFG.H (AND in this file) to 1 to use OUTPUT COMPARE #1 
;                       Set OS_TICK_OC in OS_CFG.H (AND in this file) to 2 to use OUTPUT COMPARE #2 
;                       Set OS_TICK_OC in OS_CFG.H (AND in this file) to 3 to use OUTPUT COMPARE #3 
;                       Set OS_TICK_OC in OS_CFG.H (AND in this file) to 4 to use OUTPUT COMPARE #4 
;                       Set OS_TICK_OC in OS_CFG.H (AND in this file) to 5 to use OUTPUT COMPARE #5 
;                       Set OS_TICK_OC in OS_CFG.H (AND in this file) to 6 to use OUTPUT COMPARE #6 
;                       Set OS_TICK_OC in OS_CFG.H (AND in this file) to 7 to use OUTPUT COMPARE #7 
; 
;                3) TFLG1, TC0 ... TC7 are defined in 6812dp256.h. 
;******************************************************************************************************** 
;********************************************************************************************************/ 
 
#pragma TRAP_PROC 
 
#pragma CODE_SEG __NEAR_SEG NON_BANKED  // add this code by Hansol Park. 2006.1.2 
 
//void OSTickISR(void) 
__interrupt void OSTickISR(void)    // modify this code by Hansol Park. 2006.1.2 
{ 
 
__asm{  
  /* for Banked Flash */ 
  ldaa  PPAGE						            // add this code by Hansol Park. 2006. 1. 4 
  psha 
} 
 
 asm inc OSIntNesting;               // 4~, Notify uC/OS-II about ISR 
  
if (OSIntNesting == 1){				// 4~, if (OSIntNesting == 1) { 
 __asm  
   	{ 
        ldy    OSTCBCur               //  3~, OSTCBCur->OSTCBStkPtr = Stack Pointer      
    	  sts    0,y                    //  3~,}                                            
   	} 
} 
 
 #if OS_TICK_OC == 0 
 __asm{    
    ldab   #$01                        ;  2~, Clear C0F interrupt flag (bit 0) 
    stab   TFLG1                       ;  4~ 
    ldd    TC0                         ;  5~, Set TC0 to present time + desired counts to next ISR 
    addd   #OS_TICK_OC_CNTS            ;  4~     
    std    TC0                         ;  5~ 
 	} 
 #endif 
 
 #if OS_TICK_OC == 1 
  __asm{ 
    ldab   #$02                        ;  2~, Clear C1F interrupt flag (bit 1) 
    stab   TFLG1                       ;  4~ 
    ldd    TC1                         ;  5~, Set TC1 to present time + desired counts to next ISR 
    addd   #OS_TICK_OC_CNTS            ;  4~    
    std    TC1                         ;  5~ 
	}  
 #endif 
 
 #if OS_TICK_OC == 2 
 __asm{  
    ldab   #$04                        ;  2~, Clear C2F interrupt flag (bit 2) 
    stab   TFLG1                       ;  4~ 
    ldd    TC2                         ;  5~, Set TC2 to present time + desired counts to next ISR 
    addd   #OS_TICK_OC_CNTS            ;  4~     
    std    TC2                         ;  5~ 
 	} 
 #endif 
 
 #if OS_TICK_OC == 3 
 __asm{ 
    ldab   #$08                        ;  2~, Clear C3F interrupt flag (bit 3) 
    stab   TFLG1                       ;  4~ 
    ldd    TC3                         ;  5~, Set TC3 to present time + desired counts to next ISR 
    addd   #OS_TICK_OC_CNTS            ;  4~     
    std    TC3                         ;  5~ 
 	} 
 #endif 
 
 #if OS_TICK_OC == 4 
 __asm{ 
    ldab   #$10                        ;  2~, Clear C4F interrupt flag (bit 4) 
    stab   TFLG1                       ;  4~ 
    ldd    TC4                         ;  5~, Set TC4 to present time + desired counts to next ISR 
    addd   #OS_TICK_OC_CNTS            ;  4~     
    std    TC4                         ;  5~ 
	}  
 #endif 
 
 #if OS_TICK_OC == 5 
 __asm{ 
    ldab   #$20                        ;  2~, Clear C5F interrupt flag (bit 5) 
    stab   TFLG1                       ;  4~ 
    ldd    TC5                         ;  5~, Set TC5 to present time + desired counts to next ISR 
    addd   #OS_TICK_OC_CNTS            ;  4~     
    std    TC5                         ;  5~ 
 	} 
 #endif 
 
 #if OS_TICK_OC == 6 
 __asm{ 
    ldab   #$40                        ;  2~, Clear C6F interrupt flag (bit 6) 
    stab   TFLG1                       ;  4~ 
    ldd    TC6                         ;  5~, Set TC6 to present time + desired counts to next ISR 
    addd   #OS_TICK_OC_CNTS            ;  4~     
    std    TC6                         ;  5~ 
 	} 
 #endif 
 
 #if OS_TICK_OC == 7 
 __asm{ 
    ldab   #$80                        ;  2~, Clear C7F interrupt flag (bit 7) 
    stab   TFLG1                       ;  4~ 
    ldd    TC7                         ;  5~, Set TC7 to present time + desired counts to next ISR 
    addd   #OS_TICK_OC_CNTS            ;  4~     
    std    TC7                         ;  5~ 
 	} 
 #endif 
 
    asm cli;									/*  2~, Enable interrupts to allow interrupt nesting*/ 
    
    OSTimeTick();                 /* 6~+, Call uC/OS-II's tick updating function */                  
    OSIntExit ();                 /* 6~+, Notify uC/OS-II about end of ISR */ 
 
__asm { 
    /* for Banked Flash */ 
    pula									      // add this code by Hansol Park. 2006. 1. 4 
    staa  PPAGE 
      } 
} 
 
#pragma CODE_SEG DEFAULT