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功能號,運行優先級最高的任務

}

 

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