ucos_test.rar今天终于将ucos移植到了TI6414上了。
这里TI6414采用小端方式,6414的堆栈是从高地址往低地址方向的。
首先要声明一下,任务一定要是一下两种格式的一种:
OS_CPU.H的移植:
/*
*********************************************************************************************************
* uC/OS-II
* The Real-Time Kernel
*
* (c) Copyright 1992-2002, Jean J. Labrosse, Weston, FL
* All Rights Reserved
*
* TI C6711 DSP Specific code
* Little Endian Mode
*
* Code Composer Studio V3.1
*
* File : OS_CPU.H
*********************************************************************************************************
*/
#ifdef OS_CPU_GLOBALS
#define OS_CPU_EXT
#else
#define OS_CPU_EXT extern
#endif
/*
*********************************************************************************************************
* DATA TYPES
* (Compiler Specific)
*********************************************************************************************************
*/
typedef unsigned char BOOLEAN;
typedef unsigned char INT8U; /* Unsigned 8 bit quantity */
typedef signed char INT8S; /* Signed 8 bit quantity */
typedef unsigned short INT16U; /* Unsigned 16 bit quantity */
typedef signed short INT16S; /* Signed 16 bit quantity */
typedef unsigned int INT32U; /* Unsigned 32 bit quantity */
typedef signed int INT32S; /* Signed 32 bit quantity */
typedef float FP32; /* Single precision floating point */
typedef double FP64; /* Double precision floating point */
typedef unsigned int OS_STK; /* Each stack entry is 32-bit wide in C6711DSP */
#define BYTE INT8S /* Define data types for backward compatibility ... */
#define UBYTE INT8U /* ... to uC/OS V1.xx. Not actually needed for ... */
#define WORD INT16S /* ... uC/OS-II. */
#define UWORD INT16U
#define LONG INT32S
#define ULONG INT32U
/*
*********************************************************************************************************
* Interrupter~!
*
* With TI CCS Library of C6x DSP
*********************************************************************************************************
*/
extern cregister volatile unsigned int CSR ;
void Disable_int(void); //function for disable interrupt
void Enable_int(void); //function for enable interrupt
#define OS_ENTER_CRITICAL() Disable_int() //CSR &= 0xfffe;asm(" nop 4"); /* Disable interrupts*/
#define OS_EXIT_CRITICAL() Enable_int() //CSR |= 0x0001;asm(" nop 4"); /* Enable interrupts*/
/*
*********************************************************************************************************
* TI C6414 DSP Miscellaneous
*********************************************************************************************************
*/
#define OS_STK_GROWTH 1 /* Stack grows from HIGH to LOW memory */
#define OS_TASK_SW() OSCtxSw()
/*$PAGE*/
/*
*********************************************************************************************************
* Some Definitions for operation of stack
*********************************************************************************************************
*/
typedef int REGISTERS; /* Define the REGISTERS type - 32bit */
/*------------------------------------------------------------------------
/ THE SP MUST BE ALIGNED ON AN 8-BYTE BOUNDARY. (Ref. Datasheet of C6711 DSP )
/ WHICH means that the framesize has to be a multiple of 8-BYTE.
/------------------------------------------------------------------------*/
typedef struct
{
//The start address of the Task (point of the task function) -------- 4-BYTE
void (*Start_Address)(void *Task_Data_Pointer);
//All the General-Purpose Registers of the DSP (32 Registers) -------- 64 X 4-BYTE
REGISTERS A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15;
REGISTERS A16, A17, A18, A19, A20, A21, A22, A23, A24, A25, A26, A27, A28, A29, A30, A31;
REGISTERS B0, B1, B2, B3, B4, B5, B6, B7, B8, B9, B10, B11, B12, B13, B14, B15;
REGISTERS B16, B17, B18, B19, B20, B21, B22, B23, B24, B25, B26, B27, B28, B29, B30, B31;
//Save all Control Registers of the DSP -------- 4 X 4-BYTE
int
AMR, //Adressing_Mode_Register
CSR, //Control_Status_Register
IER, //Interrupt_Enable_Register
IRP; //Interrupt_Return_Pointer
//A 4-BYTE dummy, just keep the SP is aligned on an 8-BYTE boundary
int Dummy;
} INIT_STACK_FRAME;
OS_CPU_A.ASM源程序:
1、OSStartHighRdy():使就绪状态的任务开始运行的函数叫做OSStart()。在用户调用OSStart()之前,用户必须至少已经建立了自己的一个任务(
参看OSTaskCreate()和OSTaskCteateExt())。OSStartHighRdy()假设OSTCBHighRdy指向的是优先级最高的任务的任务控制块。OSStartHighRdy()就是使程序
跳入具有最高优先级的就绪任务的函数入口。
2、OSCtxSw():任务切换函数,在有任务切换的时候调用这个函数。
OSCtxSw原型----
void OSCtxSw(void)
{
保存处理器寄存器;
将当前任务的堆栈指针保存到当前任务的OS_TCB中:
OSTCBCur->OSTCBStkPtr = Stack pointer;
调用用户定义的OSTaskSwHook();
OSTCBCur = OSTCBHighRdy;
OSPrioCur = OSPrioHighRdy;
得到需要恢复的任务的堆栈指针:
Stack pointer = OSTCBHighRdy->OSTCBStkPtr;
将所有处理器寄存器从新任务的堆栈中恢复出来;
执行中断返回指令;
}
3、OSIntCtxSw():在中断服务程序中的任务切换;
4、Disable_int()、Enable_int();
;********************************************************************************************************
; uC/OS-II
; The Real-Time Kernel
;
; (c) Copyright 1992-2002, Jean J. Labrosse, Weston, FL
; All Rights Reserved
; TI C6414 DSP Specific code
; Little Endian Mode
; Code Composer Studio V3.1
;
; File : OS_CPU_A.ASM
********************************************************************************************************
;********************************************************************************************************
; PUBLIC and EXTERNAL REFERENCES
;********************************************************************************************************
FP .set A15
DP .set B14
SP .set B15
.global $bss
_StartAddress .set 0+4 ;structrue of task/int stack
_A0 .set 4 +4
_A1 .set 8 +4
_A2 .set 12 +4
_A3 .set 16 +4
_A4 .set 20 +4
_A5 .set 24 +4
_A6 .set 28 +4
_A7 .set 32 +4
_A8 .set 36 +4
_A9 .set 40 +4
_A10 .set 44 +4
_A11 .set 48 +4
_A12 .set 52 +4
_A13 .set 56 +4
_A14 .set 60 +4
_A15 .set 64 +4
_A16 .set 68 +4
_A17 .set 72 +4
_A18 .set 76 +4
_A19 .set 80 +4
_A20 .set 84 +4
_A21 .set 88 +4
_A22 .set 92 +4
_A23 .set 96 +4
_A24 .set 100 +4
_A25 .set 104 +4
_A26 .set 108 +4
_A27 .set 112 +4
_A28 .set 116 +4
_A29 .set 120 +4
_A30 .set 124 +4
_A31 .set 128 +4
_B0 .set 132 +4
_B1 .set 136 +4
_B2 .set 140 +4
_B3 .set 144 +4
_B4 .set 148 +4
_B5 .set 152 +4
_B6 .set 156 +4
_B7 .set 160 +4
_B8 .set 164 +4
_B9 .set 168 +4
_B10 .set 172 +4
_B11 .set 176 +4
_B12 .set 180 +4
_B13 .set 184 +4
_B14 .set 188 +4
_B15 .set 192 +4
_B16 .set 196 +4
_B17 .set 200 +4
_B18 .set 204 +4
_B19 .set 208 +4
_B20 .set 212 +4
_B21 .set 216 +4
_B22 .set 220 +4
_B23 .set 224 +4
_B24 .set 228 +4
_B25 .set 232 +4
_B26 .set 236 +4
_B27 .set 240 +4
_B28 .set 244 +4
_B29 .set 248 +4
_B30 .set 252 +4
_B31 .set 256 +4
_AMR .set 260 +4
_CSR .set 264 +4
_IER .set 268 +4
_IRP .set 272 +4
_Framesize .set 276 +4
.global _OSStartHighRdy
.global _OSCtxSw
.global _OSIntCtxSw
.global _Disable_int ;
.global _Enable_int ;
.global _OSTaskSwHook ; extern function & var from other objects
.global _OSTCBHighRdy
.global _OSTCBCur
.global _OSPrioCur
.global _OSPrioHighRdy
.global _OSRunning
; /*$PAGE*/
;*********************************************************************************************************
; START MULTITASKING
; void OSStartHighRdy(void)
;
; Note : OSStartHighRdy() MUST:
; a) Call OSTaskSwHook() then,
; b) Set OSRunning to TRUE,
; c) Switch to the highest priority task:获取该任务的堆栈指针;LDW registers;B B3;
;*********************************************************************************************************
_OSStartHighRdy:
CALL _OSTaskSwHook
NOP 3
MVKL Back_Point,B3
MVKH Back_Point,B3
Back_Point: ;return here from _OSTaskSwHook
;OSRunning = TRUE
MVK 1,B1
STB B1,*+DP(_OSRunning)
; StackPointer = OSTCBHighRdy->OSTCBStkPtr
LDW *+DP(_OSTCBHighRdy),B4
nop 4
LDW *B4,SP
nop 4
;pop current task's context from stack
LDW *+SP(_StartAddress),B3 ; b3 start address
LDW *+SP(_AMR),B10 ; B10 = AMR
LDW *+SP(_CSR),B9 ; B9 = CSR
LDW *+SP(_IER),B8 ; B8 = IER
mvk 0,B13
mvc B13,IER
LDW *+SP(_A0),A0 ;
LDW *+SP(_A1),A1 ;
LDW *+SP(_A2),A2 ;
LDW *+SP(_A3),A3 ;
LDW *+SP(_A4),A4 ;
LDW *+SP(_A5),A5 ;
LDW *+SP(_A6),A6 ;
LDW *+SP(_A7),A7 ;
LDW *+SP(_A8),A8 ;
LDW *+SP(_A9),A9 ;
LDW *+SP(_A10),A10 ;
LDW *+SP(_A11),A11 ;
LDW *+SP(_A12),A12 ;
LDW *+SP(_A13),A13 ;
LDW *+SP(_A14),A14 ;
LDW *+SP(_A15),A15 ;
LDW *+SP(_A16),A16 ;
LDW *+SP(_A17),A17 ;
LDW *+SP(_A18),A18 ;
LDW *+SP(_A19),A19 ;
LDW *+SP(_A20),A20 ;
LDW *+SP(_A21),A21 ;
LDW *+SP(_A22),A22 ;
LDW *+SP(_A23),A23 ;
LDW *+SP(_A24),A24 ;
LDW *+SP(_A25),A25 ;
LDW *+SP(_A26),A26 ;
LDW *+SP(_A27),A27 ;
LDW *+SP(_A28),A28 ;
LDW *+SP(_A29),A29 ;
LDW *+SP(_A30),A30 ;
LDW *+SP(_A31),A31 ;
LDW *+SP(_B0),B0 ;
LDW *+SP(_B1),B1 ;
LDW *+SP(_B2),B2 ;
LDW *+SP(_B4),B4 ;
LDW *+SP(_B5),B5 ;
LDW *+SP(_B6),B6 ;
LDW *+SP(_B7),B7 ;
LDW *+SP(_B11),B11 ;
LDW *+SP(_B12),B12 ;
LDW *+SP(_B13),B13 ;
LDW *+SP(_B14),B14 ;
LDW *+SP(_B16),B16 ;
LDW *+SP(_B17),B17 ;
LDW *+SP(_B18),B18 ;
LDW *+SP(_B19),B19 ;
LDW *+SP(_B20),B20 ;
LDW *+SP(_B21),B21 ;
LDW *+SP(_B22),B22 ;
LDW *+SP(_B23),B23 ;
LDW *+SP(_B24),B24 ;
LDW *+SP(_B25),B25 ;
LDW *+SP(_B26),B26 ;
LDW *+SP(_B27),B27 ;
LDW *+SP(_B28),B28 ;
LDW *+SP(_B29),B29 ;
LDW *+SP(_B30),B30 ;
LDW *+SP(_B31),B31 ;
or 3,b9,B9 ; Set GIE
mvc B9,CSR ; set csr if IRP did not put a GIE
mvc B10,AMR ; Restore AMR
LDW *+SP(_B9),B9 ;
LDW *+SP(_B10),B10 ;
LDW *+SP(_B3),B3 ;
LDW *+SP(_B8),B8 ;
LDW *+SP(_B15),B15 ;
B b3 ;
mvc B8,IER ;
nop 5
; /*$PAGE*/
;*********************************************************************************************************
;
; PERFORM A CONTEXT SWITCH (From task level)
; void OSCtxSw(void)
;*********************************************************************************************************
; .align 32
_OSCtxSw:
addk (-_Framesize),SP ; Push one Frame
STW B3,*+SP(_StartAddress) ; b3 start address
STW B0,*+SP(_B0) ;
|| mvc AMR,B0
STW B0,*+SP(_AMR) ;
|| mvc CSR,B0
STW B0,*+SP(_CSR) ;
|| mvc IER,B0
STW B0,*+SP(_IER) ;
|| mvc IRP,B0
STW B0,*+SP(_IRP) ;
STW A0,*+SP(_A0) ;
|| MV SP,A0 ; A0 = SP
STW A1,*+SP(_A1) ;
|| addk (_Framesize),A0 ; Correct SP for POP of TCB
STW A0,*+SP(_B15) ; Save correct SP
STW A2,*+SP(_A2) ;
STW A3,*+SP(_A3) ;
STW A4,*+SP(_A4) ;
STW A5,*+SP(_A5) ;
STW A6,*+SP(_A6) ;
STW A7,*+SP(_A7) ;
STW A8,*+SP(_A8) ;
STW A9,*+SP(_A9) ;
STW A10,*+SP(_A10) ;
STW A11,*+SP(_A11) ;
STW A12,*+SP(_A12) ;
STW A13,*+SP(_A13) ;
STW A14,*+SP(_A14) ;
STW A15,*+SP(_A15) ;
STW A16,*+SP(_A16) ;
STW A17,*+SP(_A17) ;
STW A18,*+SP(_A18) ;
STW A19,*+SP(_A19) ;
STW A20,*+SP(_A20) ;
STW A21,*+SP(_A21) ;
STW A22,*+SP(_A22) ;
STW A23,*+SP(_A23) ;
STW A24,*+SP(_A24) ;
STW A25,*+SP(_A25) ;
STW A26,*+SP(_A26) ;
STW A27,*+SP(_A27) ;
STW A28,*+SP(_A28) ;
STW A29,*+SP(_A29) ;
STW A30,*+SP(_A30) ;
STW A31,*+SP(_A31) ;
LDW *+DP(_OSTCBCur),B0 ; B0 = OSTCBCur
STW B1,*+SP(_B1) ;
STW B2,*+SP(_B2) ;
STW B3,*+SP(_B3) ; Save for cosmetical reasons
STW B4,*+SP(_B4) ;
STW B5,*+SP(_B5) ;
STW B6,*+SP(_B6) ;
STW SP,*B0 ; previous OSTCBCur->OSTCBStkPtr = SP ;
STW B7 ,*+SP(_B7 ) ;
STW B8 ,*+SP(_B8 ) ;
STW B9 ,*+SP(_B9 ) ;
STW B10,*+SP(_B10) ;
STW B11,*+SP(_B11) ;
STW B12,*+SP(_B12) ;
STW B13,*+SP(_B13) ;
STW B14,*+SP(_B14) ;
STW B16 ,*+SP(_B16 ) ;
STW B17 ,*+SP(_B17 ) ;
STW B18 ,*+SP(_B18) ;
STW B19,*+SP(_B19) ;
STW B20,*+SP(_B20) ;
STW B21,*+SP(_B21) ;
STW B22,*+SP(_B22) ;
STW B23,*+SP(_B23) ;
STW B24,*+SP(_B24) ;
STW B25,*+SP(_B25) ;
STW B26,*+SP(_B26) ;
STW B27,*+SP(_B27) ;
STW B28,*+SP(_B28) ;
STW B29,*+SP(_B29) ;
STW B30,*+SP(_B30) ;
STW B31,*+SP(_B31) ;
; /*$PAGE*/
OSIntCtxSw_Here_Start: ; form here, the same with _OSIntCtxSw
CALL _OSTaskSwHook ; invoke the OSTaskSwHook function
NOP 3
MVKL Back_Point_2,B3
MVKH Back_Point_2,B3
Back_Point_2: ; return here from _OSTaskSwHook
; OSTCBCur = OSTCBHighRdy
; OSPrioCur = OSPrioHighRdy
LDW *+DP(_OSTCBHighRdy),B4
LDB *+DP(_OSPrioHighRdy),B5
NOP 3
STW B4,*+DP(_OSTCBCur)
STB B5,*+DP(_OSPrioCur)
; StackPointer = OSTCBHighRdy->OSTCBStkPtr
LDW *B4,SP
nop 4
;pop current task's context from stack
LDW *+SP(_StartAddress),B3 ; b3 start address
LDW *+SP(_IRP),B11 ; B10 = AMR
LDW *+SP(_AMR),B10 ; B10 = AMR
LDW *+SP(_CSR),B9 ; B9 = CSR
; LDW *+SP(_IER),B8 ; B8 = IER
mvc IER,B8 ; do not change IER when switch tasks
mvk 0,B13
mvc B13,IER
LDW *+SP(_A0),A0 ;
LDW *+SP(_A1),A1 ;
LDW *+SP(_A2),A2 ;
LDW *+SP(_A3),A3 ;
LDW *+SP(_A4),A4 ;
LDW *+SP(_A5),A5 ;
LDW *+SP(_A6),A6 ;
LDW *+SP(_A7),A7 ;
LDW *+SP(_A8),A8 ;
LDW *+SP(_A9),A9 ;
LDW *+SP(_A10),A10 ;
LDW *+SP(_A11),A11 ;
LDW *+SP(_A12),A12 ;
LDW *+SP(_A13),A13 ;
LDW *+SP(_A14),A14 ;
LDW *+SP(_A15),A15 ;
LDW *+SP(_A16),A16 ;
LDW *+SP(_A17),A17 ;
LDW *+SP(_A18),A18 ;
LDW *+SP(_A19),A19 ;
LDW *+SP(_A20),A20 ;
LDW *+SP(_A21),A21 ;
LDW *+SP(_A22),A22 ;
LDW *+SP(_A23),A23 ;
LDW *+SP(_A24),A24 ;
LDW *+SP(_A25),A25 ;
LDW *+SP(_A26),A26 ;
LDW *+SP(_A27),A27 ;
LDW *+SP(_A28),A28 ;
LDW *+SP(_A29),A29 ;
LDW *+SP(_A30),A30 ;
LDW *+SP(_A31),A31 ;
LDW *+SP(_B0),B0 ;
LDW *+SP(_B1),B1 ;
LDW *+SP(_B2),B2 ;
LDW *+SP(_B4),B4 ;
LDW *+SP(_B5),B5 ;
LDW *+SP(_B6),B6 ;
LDW *+SP(_B7),B7 ;
LDW *+SP(_B12),B12 ;
LDW *+SP(_B13),B13 ;
LDW *+SP(_B14),B14 ;
LDW *+SP(_B16),B16 ;
LDW *+SP(_B17),B17 ;
LDW *+SP(_B18),B18 ;
LDW *+SP(_B19),B19 ;
LDW *+SP(_B20),B20 ;
LDW *+SP(_B21),B21 ;
LDW *+SP(_B22),B22 ;
LDW *+SP(_B23),B23 ;
LDW *+SP(_B24),B24 ;
LDW *+SP(_B25),B25 ;
LDW *+SP(_B26),B26 ;
LDW *+SP(_B27),B27 ;
LDW *+SP(_B28),B28 ;
LDW *+SP(_B29),B29 ;
LDW *+SP(_B30),B30 ;
LDW *+SP(_B31),B31 ;
or 3,b9,B9 ; Set GIE
mvc B9,CSR ; set csr if IRP did not put a GIE
mvc B10,AMR ; Restore AMR
mvc B11,IRP ; Restore AMR
LDW *+SP(_B9),B9 ;
LDW *+SP(_B10),B10 ;
LDW *+SP(_B11),B11 ;
LDW *+SP(_B3),B3 ;
LDW *+SP(_B8),B8 ;
LDW *+SP(_B15),B15 ;
B b3 ;
mvc B8,IER ;
nop 5
; /*$PAGE*/
;*********************************************************************************************************
; PERFORM A CONTEXT SWITCH (From an ISR)
; void OSIntCtxSw(void)
;
; 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
;
; 3) The stack frame of the task to resume
;
;*********************************************************************************************************
_OSIntCtxSw:
B OSIntCtxSw_Here_Start
NOP 5
; /*$PAGE*/
;******************************************************************************
;* FUNCTION NAME: _Disable_int *
;* *
;* Notes: function for disable interrupt *
;******************************************************************************
;.align 32
_Disable_int: ;
mvc CSR,B4
and 1,B4,B0
[!B0] CLR B4,1,1,B4
[B0] SET B4,1,1,B4
CLR B4,0,0,B4
mvc B4,CSR
B B3
NOP 5
; /*$PAGE*/
;******************************************************************************
;* FUNCTION NAME: _Enable_int: *
;* *
;* Notes: function for enable interrupt *
;******************************************************************************
;.align 32
_Enable_int: ;
mvc CSR,B4
and 2,B4,B0
[!B0] CLR B4,0,0,B4
[B0] SET B4,0,0,B4
mvc B4,CSR
B B3
NOP 5
.end