UCOS-II在LPC2210上的移植--os_cpu_c.c

 

CPU Philips ARM7 LPC2210

OS uC/OSII 2.52

IDE ADS 1.2

移植一个操作系统到一个CPU体系的结构上,移植者必须的要求:

1、对目标体系结构要有很深的了解 -- ARM Architecture Reference Manual

2、对OS原理要有较深入的了解 -- 嵌入式实时操作系统uC/OSII

3、对所使用的编译器要有较深入的了解 -- ADS自带的编译器和连接器的手册

4、对需要移植的操作系统要有相当的了解 -- 嵌入式实时操作系统uC/OSII

5、对具体使用的芯片也要有一定的了解 -- 芯片的数据手册

 

编写 OS_CPU_c.c

#define  OS_CPU_GLOBALS

#include "config.h"

/*******************************************************************************************

** 函数名称: OSTaskStkInit

** 功能描述: 任务堆栈初始化代码,本函数调用失败会使系统崩溃

** 输 入: task  : 任务开始执行的地址

**         pdata :传递给任务的参数

**         ptos  :任务的堆栈开始位置

**         opt   :附加参数,当前版本对于本函数无用,具体意义参见OSTaskCreateExt()opt参数

** 输 出: 栈顶指针位置

** 全局变量:

** 调用模块:

*******************************************************************************************/

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

{

    OS_STK *stk;

    opt    = opt;                        /* 'opt'  没有使用。作用是避免编译器警告    */

    stk    = ptos;                       /* 获取堆栈指针                             */

 

                                         /* 建立任务环境,ADS1.2使用满递减堆栈       */

    *stk = (OS_STK) task;                /*  PC( R15 )  */

    *--stk = (OS_STK) task;              /*  LR( R14 )  */

    *--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);

}

/*******************************************************************************************

** 函数名称: SWI_Exception

** 功能描述: 软中断异常处理程序,提供一些系统服务

**          

** 输 入:  SWI_Num:功能号

**          Regs[0] 为第一个参数,也是返回值

**          Regs[1] 为第二个参数

**          Regs[2] 为第三个参数

**          Regs[3] 为第四个参数

** 输 出: 根据功能而定

**        

** 全局变量:

** 调用模块:

**

******************************************************************************************/

#if OS_SELF_EN > 0

extern int const _OSFunctionAddr[];

extern int const _UsrFunctionAddr[];

#endif

void SWI_Exception(int SWI_Num, int *Regs)

{

    OS_TCB   *ptcb;

    switch(SWI_Num)

    {

        //case 0x00:                    /* 任务切换函数OS_TASK_SW,参考os_cpu_s.s文件     */

        //    break;

        //case 0x01:                    /* 启动任务函数OSStartHighRdy,参考os_cpu_s.s文件 */

        //    break;

/* ARM处理器核中断和开中断时,通过改变CPSR中的相应位实现。由于使用了软件中断,程序状态寄存器CPSR保存到SPSR中,软件中断退出时会将SPSR恢复到CPSR中,所以程序只需要改变SPSR中的相应控制位就可以了 */

        case 0x02:                      /* 关中断函数OS_ENTER_CRITICAL(),参考os_cpu.h文件 */

            __asm

            {

                MRS     R0, SPSR

                ORR     R0, R0, #NoInt  /* 禁止IRQ中断 */

                MSR     SPSR_c, R0

            }

            OsEnterSum++;               /* 中断嵌套计数器增加一 */

            break;

        case 0x03:                      /* 开中断函数OS_EXIT_CRITICAL(),参考os_cpu.h文件 */

            if (--OsEnterSum == 0)      /* 判断是否中断嵌套已经完了 */

            {

                __asm

                {

                    MRS     R0, SPSR

                    BIC     R0, R0, #NoInt /* 清楚IRQ标志,允许中断 */

                    MSR     SPSR_c, R0

                }

            }

            break;

#if OS_SELF_EN > 0

        case 0x40:

                                        /* 返回指定系统服务函数的地址       */

                                        /* 函数地址存于数组_OSFunctionAddr*/

                                        /* 数组_OSFunctionAddr需要另外定义  */

                                        /* Regs[0] 为第一个参数,也是返回值 */

                                        /* Regs[1] 为第二个参数             */

                                        /* Regs[2] 为第三个参数             */

                                        /* Regs[3] 为第四个参数             */

                                        /* 仅有一个参数为系统服务函数的索引 */

            Regs[0] =  _OSFunctionAddr[Regs[0]];

            break;

        case 0x41:

                                        /* 返回指定用户的服务函数的地址     */

                                        /* 函数地址存于数组_UsrFunctionAddr*/

                                        /* 数组_UsrFunctionAddr需要另外定义 */

                                        /* Regs[0] 为第一个参数,也是返回值 */

                                        /* Regs[1] 为第二个参数             */

                                        /* Regs[2] 为第三个参数             */

                                        /* Regs[3] 为第四个参数             */

                                        /* 仅有一个参数为用户服务函数的索引 */

            Regs[0] =  _UsrFunctionAddr[Regs[0]];

            break;

        case 0x42:                      /* 中断开始处理 */

            OSIntNesting++;

            break;

        case 0x43:                      /*  判断中断是否需要切换             */

            if (OSTCBHighRdy == OSTCBCur)

            {

                Regs[0] = 0;

            }

            else

            {

                Regs[0] = 1;

            }

            break;

#endif

        case 0x80:                      /* 任务切换到系统模式 */

            __asm

            {

                MRS     R0, SPSR

                BIC     R0, R0, #0x1f      /* 先清再赋值      */

                ORR     R0, R0, #SYS32Mode /* 设置为系统模式  */  

                MSR     SPSR_c, R0

            }

            break;

        case 0x81:                      /* 任务切换到用户模式 */

            __asm

            {

                MRS     R0, SPSR

                BIC     R0, R0, #0x1f

                ORR     R0, R0, #USR32Mode   

                MSR     SPSR_c, R0

            }

            break;

      // 0x820x83功能用于指定任务以ARM的那种指令集运行

        case 0x82:                      /* 任务是ARM代码 */

            if (Regs[0] <= OS_LOWEST_PRIO)     // 先确定任务有效

            {

                ptcb = OSTCBPrioTbl[Regs[0]];  // 获取任务控制块

                if (ptcb != NULL)

                {

                    ptcb -> OSTCBStkPtr[1] &= ~(1 << 5);  // 指向堆栈栈顶的指针

                }

            }

            break;

        case 0x83:                     /* 任务是THUMB代码 */

            if (Regs[0] <= OS_LOWEST_PRIO)

            {

                ptcb = OSTCBPrioTbl[Regs[0]];

                if (ptcb != NULL)

                {

                    ptcb -> OSTCBStkPtr[1] |= (1 << 5);

                }

            }

            break;

        default:

            break;

    }

}

/******************************************************************************************

** 函数名称: OSStartHighRdy

** 功能描述: uC/OS-II启动时使用OSStartHighRdy运行第一个任务,

**           实质是产生swi 1指令

** 输 入:  

** 输 出 : 

** 全局变量:

** 调用模块:

****************************************************************************************/

void OSStartHighRdy(void)

{

    _OSStartHighRdy();       // swi0x01功能号,运行优先级最高的任务

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值