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

來源:互聯網
上載者:User

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

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.