移植uCOS到RAM7

1. 要使uCOS-II正常运行,处理器必须满足以下要求:
    * 处理器的C编译器能够产生可重入型的代码;
    * 处理器支持中断,并且能够产生定时中断,通常为10 ~ 100Hz;
    * 用C语言可以开关中断;
    * 处理器能支持一定数量的数据存储硬件堆栈;
    * 处理器有将堆栈指针已经其他CPU寄存器内容读出,并存储到堆栈或内存中去的指令。


2. uC/OS-II硬件和软件结构体系
    ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
    ┃                                                                        ┃
    ┃                            应用软件(用户代码)                          ┃
    ┃                                                                        ┃
    ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
    ┏━━━━━━━━━━━━━━━━━━┓┏━━━━━━━━━━━━━━━━┓
    ┃                                    ┃┃                                ┃
    ┃             uC/OS-II               ┃┃           uC/OS-II配置         ┃
    ┃         (与处理器无关的代码)       ┃┃           (与应用有关)         ┃
    ┃                                    ┃┃                                ┃
    ┃            OS_CORE.C               ┃┃                                ┃
    ┃            OS_FLAG.C               ┃┃                                ┃
    ┃            OS_MBOX.C               ┃┃                                ┃
    ┃            OS_MUTEX.C              ┃┃           OS_CFG.H             ┃
    ┃            OS_Q.C                  ┃┃           INCLUDES.H           ┃
    ┃            OS_SEM.C                ┃┃                                ┃
    ┃            OS_TASK.C               ┃┃                                ┃
    ┃            OS_TIME.C               ┃┃                                ┃
    ┃            uCOS_II.C               ┃┃                                ┃
    ┃            uCOS_II.H               ┃┃                                ┃
    ┃                                    ┃┃                                ┃
    ┗━━━━━━━━━━━━━━━━━━┛┗━━━━━━━━━━━━━━━━┛
    ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
    ┃                                                                        ┃
    ┃                             uC/OS-II移植                               ┃
    ┃                            (处理器相关代码)                            ┃
    ┃                                                                        ┃
    ┃                              OS_CPU.H                                  ┃
    ┃                              OS_CPU_A.ASM                              ┃
    ┃                              OS_CPU_C.C                                ┃
soft┃                                                                        ┃
    ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
----------------------------------------------------------------------------------
    ┏━━━━━━━━━━━━━━━━━━━━━┓┏━━━━━━━━━━━━━┓
hard┃                                          ┃┃                          ┃
    ┃                    CPU                   ┃┃          TIMER           ┃
    ┃                                          ┃┃                          ┃
    ┗━━━━━━━━━━━━━━━━━━━━━┛┗━━━━━━━━━━━━━┛
3. 移植需要修改的部分


    ┏━━━━━━━━━━┳━━━━┳━━━━━━┳━━━━━━┳━━━━━━┓
    ┃       名称         ┃  类型  ┃  所在文件  ┃   语言类型 ┃  简单程度  ┃
    ┣━━━━━━━━━━╋━━━━╋━━━━━━╋━━━━━━╋━━━━━━┫
    ┃ BOOLEAN            ┃数据类型┃ OS_CPU.H   ┃     C      ┃ SUPER EASY ┃
    ┣━━━━━━━━━━╋━━━━╋━━━━━━╋━━━━━━╋━━━━━━┫
    ┃ INT8U              ┃数据类型┃ OS_CPU.H   ┃     C      ┃ SUPER EASY ┃
    ┣━━━━━━━━━━╋━━━━╋━━━━━━╋━━━━━━╋━━━━━━┫
    ┃ INT8S              ┃数据类型┃ OS_CPU.H   ┃     C      ┃ SUPER EASY ┃
    ┣━━━━━━━━━━╋━━━━╋━━━━━━╋━━━━━━╋━━━━━━┫
    ┃ INT16U             ┃数据类型┃ OS_CPU.H   ┃     C      ┃ SUPER EASY ┃
    ┣━━━━━━━━━━╋━━━━╋━━━━━━╋━━━━━━╋━━━━━━┫
    ┃ INT16S             ┃数据类型┃ OS_CPU.H   ┃     C      ┃ SUPER EASY ┃
    ┣━━━━━━━━━━╋━━━━╋━━━━━━╋━━━━━━╋━━━━━━┫
    ┃ INT32U             ┃数据类型┃ OS_CPU.H   ┃     C      ┃ SUPER EASY ┃
    ┣━━━━━━━━━━╋━━━━╋━━━━━━╋━━━━━━╋━━━━━━┫
    ┃ INT32S             ┃数据类型┃ OS_CPU.H   ┃     C      ┃ SUPER EASY ┃
    ┣━━━━━━━━━━╋━━━━╋━━━━━━╋━━━━━━╋━━━━━━┫
    ┃ FP32               ┃数据类型┃ OS_CPU.H   ┃     C      ┃ SUPER EASY ┃
    ┣━━━━━━━━━━╋━━━━╋━━━━━━╋━━━━━━╋━━━━━━┫
    ┃ FP64               ┃数据类型┃ OS_CPU.H   ┃     C      ┃ SUPER EASY ┃
    ┣━━━━━━━━━━╋━━━━╋━━━━━━╋━━━━━━╋━━━━━━┫
    ┃ OS_STK             ┃数据类型┃ OS_CPU.H   ┃     C      ┃ VERY EASY  ┃
    ┣━━━━━━━━━━╋━━━━╋━━━━━━╋━━━━━━╋━━━━━━┫
    ┃ OS_CPU_SR          ┃数据类型┃ OS_CPU.H   ┃     C      ┃ VERY EASY  ┃
    ┣━━━━━━━━━━╋━━━━╋━━━━━━╋━━━━━━╋━━━━━━┫
    ┃ OS_CRITCIAL_METHOD ┃ 宏定义 ┃ OS_CPU.H   ┃     C      ┃ EASY       ┃
    ┣━━━━━━━━━━╋━━━━╋━━━━━━╋━━━━━━╋━━━━━━┫
    ┃ OS_STK_GROWTH      ┃ 宏定义 ┃ OS_CPU.H   ┃     C      ┃ SUPER EASY ┃
    ┣━━━━━━━━━━╋━━━━╋━━━━━━╋━━━━━━╋━━━━━━┫
    ┃ OS_ENTER_CRITICAL()┃   宏   ┃ OS_CPU.H   ┃     C      ┃ EASY       ┃
    ┣━━━━━━━━━━╋━━━━╋━━━━━━╋━━━━━━╋━━━━━━┫
    ┃ OS_EXIT_CRITICAL() ┃   宏   ┃ OS_CPU.H   ┃     C      ┃ EASY       ┃
    ┣━━━━━━━━━━╋━━━━╋━━━━━━╋━━━━━━╋━━━━━━┫
    ┃ OSStartHighRdy()   ┃ 函  数 ┃OS_CPU_A.ASM┃    ASM     ┃ VERY EASY  ┃
    ┣━━━━━━━━━━╋━━━━╋━━━━━━╋━━━━━━╋━━━━━━┫
    ┃ OSCtxSw()          ┃ 函  数 ┃OS_CPU_A.ASM┃    ASM     ┃ EASY       ┃
    ┣━━━━━━━━━━╋━━━━╋━━━━━━╋━━━━━━╋━━━━━━┫
    ┃ OSIntCtxSw()       ┃ 函  数 ┃OS_CPU_A.ASM┃    ASM     ┃ EASY       ┃
    ┣━━━━━━━━━━╋━━━━╋━━━━━━╋━━━━━━╋━━━━━━┫
    ┃ OSTickISR()        ┃ 函  数 ┃OS_CPU_A.ASM┃    ASM     ┃ EASY       ┃
    ┣━━━━━━━━━━╋━━━━╋━━━━━━╋━━━━━━╋━━━━━━┫
    ┃ OSTaskStkInit()    ┃ 函  数 ┃OS_CPU_C.C  ┃     C      ┃ EASY       ┃
    ┣━━━━━━━━━━╋━━━━╋━━━━━━╋━━━━━━╋━━━━━━┫
    ┃ OSInitHookBegin()  ┃ 函  数 ┃OS_CPU_C.C  ┃     C      ┃ SUPER EASY ┃
    ┣━━━━━━━━━━╋━━━━╋━━━━━━╋━━━━━━╋━━━━━━┫
    ┃ OSInitHookEnd()    ┃ 函  数 ┃OS_CPU_C.C  ┃     C      ┃ SUPER EASY ┃
    ┣━━━━━━━━━━╋━━━━╋━━━━━━╋━━━━━━╋━━━━━━┫
    ┃ OSTaskCreaterHook()┃ 函  数 ┃OS_CPU_C.C  ┃     C      ┃ SUPER EASY ┃
    ┣━━━━━━━━━━╋━━━━╋━━━━━━╋━━━━━━╋━━━━━━┫
    ┃ OSTaskDelHook()    ┃ 函  数 ┃OS_CPU_C.C  ┃     C      ┃ SUPER EASY ┃
    ┣━━━━━━━━━━╋━━━━╋━━━━━━╋━━━━━━╋━━━━━━┫
    ┃ OSTCBInitHook()    ┃ 函  数 ┃OS_CPU_C.C  ┃     C      ┃ SUPER EASY ┃
    ┣━━━━━━━━━━╋━━━━╋━━━━━━╋━━━━━━╋━━━━━━┫
    ┃ OSTimeTickHook()   ┃ 函  数 ┃OS_CPU_C.C  ┃     C      ┃ SUPER EASY ┃
    ┣━━━━━━━━━━╋━━━━╋━━━━━━╋━━━━━━╋━━━━━━┫
    ┃ OSTimeTickHook()   ┃ 函  数 ┃OS_CPU_C.C  ┃     C      ┃ SUPER EASY ┃
    ┣━━━━━━━━━━╋━━━━╋━━━━━━╋━━━━━━╋━━━━━━┫
    ┃ OSTaskIdleHook()   ┃ 函  数 ┃OS_CPU_C.C  ┃     C      ┃ SUPER EASY ┃
    ┗━━━━━━━━━━┻━━━━┻━━━━━━┻━━━━━━┻━━━━━━┛


4. INCLUDES.H


5. OS_CPU.H


    5.1.与编译器相关的数据类型
    typedef unsigned char  BOOLEAN;                 /* 布尔变量                */
    typedef unsigned char  INT8U;                   /* 无符号8位整型变量       */
    typedef signed   char  INT8S;                   /* 有符号8位整型变量       */
    typedef unsigned short INT16U;                  /* 无符号16位整型变量      */
    typedef signed   short INT16S;                  /* 有符号16位整型变量      */
    typedef unsigned int   INT32U;                  /* 无符号32位整型变量      */
    typedef signed   int   INT32S;                  /* 有符号32位整型变量      */
    typedef float          FP32;                    /* 单精度浮点数(32位长度)*/
    typedef double         FP64;                    /* 双精度浮点数(64位长度)*/


    typedef INT32U         OS_STK;                  /* 堆栈是32位宽度          */


    /* 兼容UC/OS V1.XX的数据类型,在uC/OS-II中没有使用  */
    #define BYTE           INT8S
    #define UBYTE          INT8U
    #define WORD           INT16S
    #define UWORD          INT16U
    #define LONG           INT32S
    #define ULONG          INT32U


    5.2. OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()


        5.2.1  #define OS_CRITICAL_MEHTOD 1        /* 定义进入中断的类型      */
            实现:直接使用处理器的开关中断指令实现。
            优点:最简单的方法,指令关闭中断;
            缺点:调用uC/OS-II功能函数后可能将中断开关状态改变。
        5.2.2  #define OS_CRITICAL_METHOD 2、
            实现:利用堆栈保存PSW中断状态,退出功能函数后恢复PSW
            优点:不改变中断状态;
            缺点:可能延长应用程序的中断响应时间。
        5.2.3  #define OS_CRITICAL_MEHTOD 3
            实现:利用编译器本身提供的扩展功能将PSW保存在局部变量中去恢复PSW。*/
            优点:简单方便,对中断状态无影响。
            缺点:需要编译器支持。


    5.3 OS_STK_GROWTH
        设置系统堆栈的生长方式。


    5.3.1 #define OS_STK_GROWTH 0
        设置系统的堆栈方式为向上生长型(低地址向高地址生长)。


    5.3.2 #define OS_STK_GROWTH 1
        设置系统的堆栈方式位向下生长型(高地址向低地址生长)。


    5.3.3 OS_TASK_SW
        可以利用软件中断来完成。


6. OS_CPU_C.C


    OSTaskStkInit();                            /* 惟一必要的函数             */
    OSTaskDelHook();
    OSTaskSwHook();
    OSTaskIdleHook();
    OSTaskStatHook();
    OSTimeTickHook();
    OSTintHookBegin();
    OSInitHookBegin();
    OSInitHookEnd();
    OSTCBInitHook();


    6.1 OSTaskStkInit()


    OS_STK *OSTaskStkInit (void (*task)(void *pd),
                           void *pdata,
                           OS_STK *ptos,
                           INT16U opt)
    {
        OS_STK *stk;


        opt    = opt;                           /* Avoid complier warnings    */
        stk    = ptos;                          /* 获取堆栈指针               */


                                                /* ADS1.2使用满递减堆栈       */
        *stk = (OS_STK) task;                   /*  pc                        */
        *--stk = (OS_STK) task;                 /*  lr                        */


        *--stk = 0;                             /*  r12                       */
        *--stk = 0;                             /*  r11                       */
        *--stk = 0;                             /*  r10                       */
        *--stk = 0;                             /*  r9                        */
        *--stk = 0;                             /*  r8                        */
        *--stk = 0;                             /*  r7                        */
        *--stk = 0;                             /*  r6                        */
        *--stk = 0;                             /*  r5                        */
        *--stk = 0;                             /*  r4                        */
        *--stk = 0;                             /*  r3                        */
        *--stk = 0;                             /*  r2                        */
        *--stk = 0;                             /*  r1                        */
        *--stk = (unsigned int) pdata;          /*  r0,第一个参数使用R0传递   */
        *--stk = (USER_USING_MODE|0x00);     /*  spsr,允许 IRQ, FIQ 中断  */
        *--stk = 0;                             /*  关中断计数器OsEnterSum;   */


        return (stk);
    }


                ┣━━━━━━━━━┫
                ┃                  ┃
                ┣━━━━━━━━━┫
                ┃       PC         ┃
                ┣━━━━━━━━━┫
                ┃       LR         ┃
                ┣━━━━━━━━━┫
                ┃       R12        ┃
                ┣━━━━━━━━━┫
                ┃       R11        ┃
                ┣━━━━━━━━━┫
                ┃       R10        ┃
                ┣━━━━━━━━━┫
                ┃       R9         ┃
                ┣━━━━━━━━━┫
                ┃       R8         ┃
                ┣━━━━━━━━━┫
                ┃       R7         ┃
                ┣━━━━━━━━━┫
                ┃       R6         ┃
                ┣━━━━━━━━━┫
                ┃       R5         ┃
                ┣━━━━━━━━━┫
                ┃       R4         ┃
                ┣━━━━━━━━━┫
                ┃       R3         ┃
                ┣━━━━━━━━━┫
                ┃       R2         ┃
                ┣━━━━━━━━━┫
                ┃       R1         ┃
                ┣━━━━━━━━━┫
                ┃       R0         ┃
                ┣━━━━━━━━━┫
                ┃       CPSR       ┃
                ┣━━━━━━━━━┫
                ┃       OSEnterSum ┃<------- SP
                ┣━━━━━━━━━┫
                ┃                  ┃
                ┣━━━━━━━━━┫


 


7. OS_CPU_A.ASM
    uC/OS-II需要用户编写的4个简单的汇编语言函数:
    7.1. OSStartHighRdy()


__OSStartHighRdy
        MSR     CPSR_c, #(NoInt | SYS32Mode)    ;进入管理模式关掉中断


        LDR     R4, =OSRunning                  ;告诉OS任务正在运行
        MOV     R5, #1
        STRB    R5, [R4]


        BL      OSTaskSwHook                    ;调用钩子函数
        LDR     R6, =OSTCBHighRdy               ;获取最高就绪任务堆栈指针的指针
        LDR     R6, [R6]                        ;获取新任务堆栈指针
        LDR     R4, [R6]                        ;得到确切地址
        ADD     SP, R4, #68                     ;17寄存器CPSR,OsEnterSum,R0-R12,LR,SP
        LDR     LR, [SP, #-8]
        MSR     CPSR_c, #(NoInt | SVC32Mode)    ;进入管理模式
        MOV     SP, R4                          ;设置堆栈指针


        LDMFD   SP!, {R4, R5}                   ;CPSR,OsEnterSum
                                                ;恢复新任务的OsEnterSum
        LDR     R3, =OsEnterSum
        STR     R4, [R3]


        MSR     SPSR_cxsf, R5                   ;恢复CPSR
        LDMFD   SP!, {R0-R12, LR, PC }^         ;运行新任务



    7.2. OSCtxSw()


OSIntCtxSw
                                                    ;下面为保存任务环境
        LDR     R2, [SP, #20]                       ;获取PC
        LDR     R12, [SP, #16]                      ;获取R12
        MRS     R0, CPSR


        MSR     CPSR_c, #(NoInt | SYS32Mode)
        MOV     R1, LR
        STMFD   SP!, {R1-R2}                        ;保存LR,PC
        STMFD   SP!, {R4-R12}                       ;保存R4-R12


        MSR     CPSR_c, R0
        LDMFD   SP!, {R4-R7}                        ;获取R0-R3
        ADD     SP, SP, #8                          ;出栈R12,PC


        MSR     CPSR_c, #(NoInt | SYS32Mode)
        STMFD   SP!, {R4-R7}                        ;保存R0-R3


        LDR     R1, =OsEnterSum                     ;获取OsEnterSum
        LDR     R2, [R1]
        STMFD   SP!, {R2, R3}                       ;保存CPSR,OsEnterSum


                                                    ;保存当前任务堆栈指针到当前任务的TCB
        LDR     R1, =OSTCBCur
        LDR     R1, [R1]
        STR     SP, [R1]


        BL      OSTaskSwHook                        ;调用钩子函数
                                                    ;OSPrioCur <= OSPrioHighRdy
        LDR     R4, =OSPrioCur
        LDR     R5, =OSPrioHighRdy
        LDRB    R6, [R5]
        STRB    R6, [R4]
                                                    ;OSTCBCur <= OSTCBHighRdy
        LDR     R6, =OSTCBHighRdy
        LDR     R6, [R6]
        LDR     R4, =OSTCBCur
        STR     R6, [R4]


OSIntCtxSw_1
                                                    ;获取新任务堆栈指针
        LDR     R4, [R6]
        ADD     SP, R4, #68                         ;17寄存器CPSR,OsEnterSum,R0-R12,LR,SP
        LDR     LR, [SP, #-8]
        MSR     CPSR_c, #(NoInt | SVC32Mode)        ;进入管理模式
        MOV     SP, R4                              ;设置堆栈指针


        LDMFD   SP!, {R4, R5}                       ;CPSR,OsEnterSum
                                                    ;恢复新任务的OsEnterSum
        LDR     R3, =OsEnterSum
        STR     R4, [R3]


        MSR     SPSR_cxsf, R5                       ;恢复CPSR
        LDMFD   SP!, {R0-R12, LR, PC }^             ;运行新任务


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值