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

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

CPU: Philips ARM7 LPC2210
OS: uC/OS-II 2.52
IDE: ADS 1.2

移植一個操作系統到一個CPU體系的結構上,移植者必須的要求:
1、對目標體系結構要有很深的瞭解 -- ARM Architecture Reference Manual
2、對OS原理要有較深入的瞭解 -- 嵌入式實時操作系統uC/OS-II
3、對所使用的編譯器要有較深入的瞭解 -- ADS自帶的編譯器和連接器的手冊
4、對需要移植的操作系統要有相當的瞭解 -- 嵌入式實時操作系統uC/OS-II
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;
      // 0x82和0x83功能用於指定任務以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();       // swi的0x01功能號,運行優先級最高的任務
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章