久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 8474|回復(fù): 0
打印 上一主題 下一主題
收起左側(cè)

LPC11C14 uCOS II 2.91移植

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:71922 發(fā)表于 2015-1-10 20:23 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
將uCOSii 加入到工程,編譯,如果報(bào)以下錯(cuò)誤錯(cuò)誤:
compiling ucos_ii.c...
linking...
.\out\test.axf: Error: L6200E: Symbol OSEventTbl multiply defined (by ucos_ii.o and os_core.o).
.\out\test.axf: Error: L6200E: Symbol OSFlagTbl multiply defined (by ucos_ii.o and os_core.o).
.\out\test.axf: Error: L6200E: Symbol OSTaskStatStk multiply defined (by ucos_ii.o and os_core.o).
.\out\test.axf: Error: L6200E: Symbol OSRdyTbl multiply defined (by ucos_ii.o and os_core.o).
.\out\test.axf: Error: L6200E: Symbol OSTaskIdleStk multiply defined (by ucos_ii.o and os_core.o).
.\out\test.axf: Error: L6200E: Symbol OSTCBPrioTbl multiply defined (by ucos_ii.o and os_core.o).
.\out\test.axf: Error: L6200E: Symbol OSTCBTbl multiply defined (by ucos_ii.o and os_core.o).
.... 還有很多
解決方法:將ucos_ii.c  從工程中移除。

如果出現(xiàn)以下未定義錯(cuò)誤:
.\out\test.axf: Error: L6218E: Undefined symbol OSCtxSw (referred from os_core.o).
.\out\test.axf: Error: L6218E: Undefined symbol OSIntCtxSw (referred from os_core.o).
.\out\test.axf: Error: L6218E: Undefined symbol OSStartHighRdy (referred from os_core.o).
.\out\test.axf: Error: L6218E: Undefined symbol OS_CPU_SR_Restore (referred from os_core.o).
.\out\test.axf: Error: L6218E: Undefined symbol OS_CPU_SR_Save (referred from os_core.o).


是因?yàn)?os_cpu_a.s 沒(méi)有加入工程,將其加入工程即可解決問(wèn)題。
------------------------------------------------------------------------
移植步驟:
1、修改OS_CPU.H 文件
    1、重定義與編譯器、uCOS II 有關(guān)的數(shù)據(jù)類型
typedef unsigned char  BOOLEAN;
typedef unsigned char  INT8U;                    /* Unsigned  8 bit quantity                           */
typedef signed   char  INT8S;                    /* Signed    8 bit quantity                           */
typedef unsigned short INT16U;                   /* Unsigned 16 bit quantity                           */
typedef signed   short INT16S;                   /* Signed   16 bit quantity                           */
typedef unsigned int   INT32U;                   /* Unsigned 32 bit quantity                           */
typedef signed   int   INT32S;                   /* Signed   32 bit quantity                           */
typedef float          FP32;                     /* Single precision floating point                    */
typedef double         FP64;                     /* Double precision floating point                    */

typedef unsigned int   OS_STK;                   /* Each stack entry is 32-bit wide                    */
typedef unsigned int   OS_CPU_SR;                /* Define size of CPU status register (PSR = 32 bits) */

    2、定義中斷的實(shí)現(xiàn)方式,一般是為了實(shí)現(xiàn)臨界區(qū)代碼保護(hù)

#define  OS_CRITICAL_METHOD   3
#if OS_CRITICAL_METHOD == 3
#define  OS_ENTER_CRITICAL()  {cpu_sr = OS_CPU_SR_Save();}
#define  OS_EXIT_CRITICAL()   {OS_CPU_SR_Restore(cpu_sr);}
#endif

    3、定義棧的生長(zhǎng)方式

            /*  堆棧1是從上往下長(zhǎng)的,0-從下往上的生長(zhǎng)方式         */
        #define  OS_STK_GROWTH        1          /* Stack grows from HIGH to LOW memory on ARM    */

    4、宏定義 優(yōu)先級(jí)任務(wù)切換 函數(shù),用于現(xiàn)場(chǎng)保護(hù)以及現(xiàn)場(chǎng)恢復(fù)實(shí)現(xiàn)任務(wù)切換
        #define  OS_TASK_SW()         OSCtxSw()        // 任務(wù)級(jí)任務(wù)切換


    5、定義開(kāi)、關(guān)中斷的函數(shù),在保護(hù)臨界區(qū)代碼時(shí)會(huì)用到。

#if OS_CRITICAL_METHOD == 3           /* See OS_CPU_A.ASM   */         
OS_CPU_SR  OS_CPU_SR_Save(void);
void         OS_CPU_SR_Restore(OS_CPU_SR cpu_sr);
#endif

    6、聲明函數(shù) 這些函數(shù)都是要自己實(shí)現(xiàn)或修改

void       OSCtxSw(void);                           // 任務(wù)級(jí)切換 觸發(fā)PendSV異常
void       OSIntCtxSw(void);                        // 中斷級(jí)切換 觸發(fā)PendSV異常
void       OSStartHighRdy(void);                // 運(yùn)行最高優(yōu)先級(jí)的任務(wù)
void       OS_CPU_PendSVHandler(void);         // 發(fā)生PendSV異常時(shí)被觸發(fā),OSCtxSw()、OSIntCtxSw() 最終實(shí)現(xiàn) 即任務(wù)切換                                               
void       OS_CPU_SysTickHandler(void);        /* See OS_CPU_C.C                                    */
void       OS_CPU_SysTickInit(void);          // 系統(tǒng)時(shí)鐘節(jié)拍初始化 用于任務(wù)切換                                                  
INT32U     OS_CPU_SysTickClkFreq(void);        /* See BSP.C OS_CPU_SysTickInit(void);用來(lái)獲得硬件的時(shí)鐘頻率,這里是直接指定并沒(méi)有用上。*/
OS_CPU_PendSVHandler(void)、OS_CPU_SysTickHandler(void) 需要在 startup_LPC11xx.s 定義
           



2、修改OS_CPU_C.C  文件
1、修改OSTaskStkInt()函數(shù)
    主要修改OSTaskStkInit()函數(shù),其他的HOOK函數(shù)根據(jù)需要實(shí)現(xiàn)(將文件OS_CFG.H中的#define constant OS_CPU_HOOKS_EN設(shè)為1,設(shè)為0表示不使用這些函數(shù)
    用戶創(chuàng)建任務(wù)時(shí),OSTasKCreat()會(huì)調(diào)用OSTaskStkInt()函數(shù)初始化該任務(wù)的堆棧,并把返回的堆棧指針保存到該任務(wù)的TCB結(jié)構(gòu)中
    的最前面的參數(shù)OSTCBStkPtr中,當(dāng)該任務(wù)要被恢復(fù)時(shí),任務(wù)切換函數(shù)從其TCB塊中取得其任務(wù)堆棧指針,依次將堆棧內(nèi)容彈到處理器
    對(duì)應(yīng)的CPSR、r0、r1,…,r12,lr,pc的寄存器中,完成現(xiàn)場(chǎng)的恢復(fù)和程序指針PC的返回。


// 創(chuàng)建任務(wù)時(shí)被調(diào)用 初始化任務(wù)堆棧  具體實(shí)現(xiàn)不是很明白
OS_STK *OSTaskStkInit (void (*task)(void *p_arg), void *p_arg, OS_STK *ptos, INT16U opt)

{
    OS_STK *stk;
    (void)opt;                                   /* 'opt' is not used, prevent warning                 */
    stk       = ptos;                            /* Load stack pointer 獲取堆棧指針                    */


                                                 /* Registers stacked as if auto-saved on exception    */
    *(stk)    = (INT32U)0x01000000L;             /* xPSR                                               */
    *(--stk)  = (INT32U)task;                    /* Entry Point 保存任務(wù)函數(shù)地址                       */
    *(--stk)  = (INT32U)0xFFFFFFFEL;             /* R14 (LR) (init value will cause fault if ever used)*/
    *(--stk)  = (INT32U)0x12121212L;             /* R12                                                */
    *(--stk)  = (INT32U)0x03030303L;             /* R3                                                 */
    *(--stk)  = (INT32U)0x02020202L;             /* R2                                                 */
    *(--stk)  = (INT32U)0x01010101L;             /* R1                                                 */
    *(--stk)  = (INT32U)p_arg;                   /* R0 : argument  保存參數(shù)                            */


                                                 /* Remaining registers saved on process stack         */
    *(--stk)  = (INT32U)0x11111111L;             /* R11                                                */
    *(--stk)  = (INT32U)0x10101010L;             /* R10                                                */
    *(--stk)  = (INT32U)0x09090909L;             /* R9                                                 */
    *(--stk)  = (INT32U)0x08080808L;             /* R8                                                 */
    *(--stk)  = (INT32U)0x07070707L;             /* R7                                                 */
    *(--stk)  = (INT32U)0x06060606L;             /* R6                                                 */
    *(--stk)  = (INT32U)0x05050505L;             /* R5                                                 */
    *(--stk)  = (INT32U)0x04040404L;             /* R4                                                 */


    return (stk);
}



  2、實(shí)現(xiàn)  void  OS_CPU_SysTickInit (void)、void  OS_CPU_SysTickHandler (void)
        // 初始化SysTick 用于在固定時(shí)產(chǎn)生中斷

void  OS_CPU_SysTickInit (void)
{
    INT32U  cnts;
    /* cnts = OS_CPU_SysTickClkFreq() / OS_TICKS_PER_SEC; */
        cnts = 48000000 / OS_TICKS_PER_SEC;        // OS_TICKS_PER_SEC 10ms 產(chǎn)生一次中斷


    OS_CPU_CM3_NVIC_ST_RELOAD = (cnts - 1);
        OS_CPU_CM3_NVIC_ST_CURRENT = 0;


        /* Set Priority of SysTick to 2 (0-3, 0 is highest)   */
        cnts = OS_CPU_CM0_NVIC_SHPR3;
        cnts &= 0x00FFFFFF;
        cnts |= 0x80000000;
        OS_CPU_CM0_NVIC_SHPR3 = cnts;
                                                 /* Enable timer.                                      */
    OS_CPU_CM3_NVIC_ST_CTRL  |= OS_CPU_CM3_NVIC_ST_CTRL_CLK_SRC | OS_CPU_CM3_NVIC_ST_CTRL_ENABLE;
                                                 /* Enable timer interrupt.                            */
    OS_CPU_CM3_NVIC_ST_CTRL  |= OS_CPU_CM3_NVIC_ST_CTRL_INTEN;
}


    // SysTick中斷服務(wù)函數(shù) 用于產(chǎn)生系統(tǒng)節(jié)拍
void  OS_CPU_SysTickHandler (void)
{
    OS_CPU_SR  cpu_sr;

    OS_ENTER_CRITICAL();                         /* Tell uC/OS-II that we are starting an ISR          */
    OSIntNesting++;
    OS_EXIT_CRITICAL();
    OSTimeTick();                                /* Call uC/OS-II's OSTimeTick()                       */
    OSIntExit();                                 /* Tell uC/OS-II that we are leaving the ISR          */
}


3、修改OS_CPU_A.S 文件
  1、定義寄存器地址
      NVIC_INT_CTRL   EQU     0xE000ED04                              ; Interrupt control state register.
NVIC_SCB_SHPR3  EQU     0xE000ED20
NVIC_PENDSV_PRI EQU     0x00FF0000
NVIC_PENDSVSET  EQU     0x10000000                              ; Value to trigger PendSV exception.

  2、實(shí)現(xiàn) OS_CPU_SR_Save()、OS_CPU_SR_Restore()、OSStartHighRdy()、OSCtxSw()、OSIntCtxSw()、OS_CPU_PendSVHandler()
  
    // 實(shí)現(xiàn)OS_CPU_SR_Save()、OS_CPU_SR_Restore()

    // 通過(guò)保存中斷狀態(tài)來(lái)禁用、啟用中斷 用在
OS_CPU_SR_Save                    ; 保存中斷狀態(tài)    MRS     R0, PRIMASK           ; Set prio int mask to mask all (except faults)    CPSID   I    BX      LR
OS_CPU_SR_Restore                 ; 恢復(fù)中斷狀態(tài)    MSR     PRIMASK, R0    BX      LR

// 實(shí)現(xiàn) OSStartHighRdy()
// 啟動(dòng)優(yōu)先級(jí)最高的任務(wù)
OSStartHighRdy
        ; 設(shè)置PendSV 異常優(yōu)先級(jí)為最低
        ldr     r0, =NVIC_SCB_SHPR3                                               
        ldr     r1, [r0]
        ldr     r2, =NVIC_PENDSV_PRI
        orrs    r1, r1, r2
        str     r1, [r0]

    ; 初始化PSP設(shè)置為 0    MOVS    R0, #0                                              ; Set the PSP to 0 for initial context switch call    MSR     PSP, R0                                                ; PSP為0 告訴上下文切換,這是第一次運(yùn)行
    ; 設(shè)置 任務(wù)運(yùn)行狀態(tài)為 1    LDR     R0, =OSRunning                                      ; OSRunning = TRUE    MOVS    R1, #1    STRB    R1, [R0]
    ; 觸發(fā)PendSV 異常,實(shí)現(xiàn)任務(wù)切換     LDR     R0, =NVIC_INT_CTRL                                  ; Trigger the PendSV exception (causes context switch)    LDR     R1, =NVIC_PENDSVSET    STR     R1, [R0]
     ; PendSV 異常處理函數(shù)會(huì)關(guān)閉中斷,所以需要開(kāi)中斷    CPSIE   I                                                   ; 使能中斷 Enable interrupts at processor level
OSStartHang    B       OSStartHang                                         ; Should never get here

[size=14.44444465637207px]// 實(shí)現(xiàn) OSCtxSw() 任務(wù)級(jí)切換任務(wù)
// 觸發(fā)PendSV 異常,實(shí)現(xiàn)任務(wù)切換
OSCtxSw    LDR     R0, =NVIC_INT_CTRL                                  ; Trigger the PendSV exception (causes context switch)    LDR     R1, =NVIC_PENDSVSET    STR     R1, [R0]    BX      LR

[size=14.44444465637207px]//
實(shí)現(xiàn) OSIntCtxSw() 中斷級(jí)切換任務(wù)
// 觸發(fā)PendSV 異常,實(shí)現(xiàn)任務(wù)切換

OSIntCtxSw
    LDR     R0, =NVIC_INT_CTRL                                  ; Trigger the PendSV exception (causes context switch)
    LDR     R1, =NVIC_PENDSVSET
    STR     R1, [R0]
    BX      LR


;/* Pendsv 中斷函數(shù) */
;/* 用于實(shí)現(xiàn)時(shí)間片輪轉(zhuǎn)法 中斷級(jí)任務(wù)調(diào)度、任務(wù)級(jí)中斷調(diào)度 切換上下文*/
; 進(jìn)入PendSV時(shí):
; xPSR、PC、LR、R12、R0~R3 已經(jīng)在處理?xiàng)V斜槐4?/font>
; 處理模式切換到線程模式
; 棧是主堆棧
OS_CPU_PendSVHandler
    CPSID   I                                                      ; 關(guān)閉中斷,避免上下文切換時(shí)發(fā)送中斷。
    MRS     R0, PSP                             ; PSP is process stack pointer
    ;CBZ     R0, OS_CPU_PendSVHandler_nosave    ; Skip register save the first time
        cmp                r0, #0                                                            ; 如果獲取任務(wù)的SP 為0 則跳到 OS_CPU_PendSVHandler_nosave
        beq                OS_CPU_PendSVHandler_nosave

        ; 保存R3~R11和SP
    SUBS    R0, R0, #0x20                       ; Save remaining regs r4-11 on process stack
        stm     r0!, {r4-r7}
        mov     r1, r8
        mov     r2, r9
        mov     r3, r10
        mov     r4, r11
        stm     r0!, {r1-r4}
        subs    r0, r0, #0x20

        ; 將當(dāng)前的堆棧指針給當(dāng)前進(jìn)程的任務(wù)塊
    LDR     R1, =OSTCBCur                       ; OSTCBCur->OSTCBStkPtr = SP;
    LDR     R1, [R1]
    STR     R0, [R1]                            ; R0 is SP of process being switched out

                                                ; At this point, entire context of process has been saved
OS_CPU_PendSVHandler_nosave
    ; 調(diào)用 OSTaskSwHook() 函數(shù) 用于擴(kuò)展
        mov     r0, lr
        push    {r0}
        ldr     r0, =OSTaskSwHook
        blx     r0
        pop     {r0}
        mov     lr, r0

        ; 獲取當(dāng)前最高優(yōu)先級(jí)的任務(wù)
    LDR     R0, =OSPrioCur                                      ; OSPrioCur = OSPrioHighRdy;
    LDR     R1, =OSPrioHighRdy
    LDRB    R2, [R1]
    STRB    R2, [R0]

    ; 獲取當(dāng)前就緒的線程
    LDR     R0, =OSTCBCur                                       ; OSTCBCur  = OSTCBHighRdy;
    LDR     R1, =OSTCBHighRdy
    LDR     R2, [R1]
    STR     R2, [R0]

        ; 得到新任務(wù)的SP和線程恢復(fù) R4~R11
    LDR     R0, [R2]                                            ; R0 is new process SP; SP = OSTCBHighRdy->OSTCBStkPtr;
        ldm     r0!, {r4-r7}
        ldm     r0!, {r1-r3}
        mov     r8, r1
        mov     r9, r2
        mov     r10, r3
        ldm     r0!, {r1}
        mov     r11, r1

        ; 載入新的SP和返回
    MSR     PSP, R0                                             ; Load PSP with new process SP
    mov     r0, lr
        movs    r1, #0x04
        orrs    r0, r0, r1
        mov     lr, r0
        CPSIE   I                                  ; 開(kāi)啟中斷                                                                                               
    BX      LR                                                  ; Exception return will restore remaining context
    b       .
    END

移植uCOS II 的難點(diǎn)在于:函數(shù)的實(shí)現(xiàn)。
總結(jié):
OS_CPU_C.C:
        void  OS_CPU_SysTickInit (void)、void  OS_CPU_SysTickHandler (void)
        任務(wù)調(diào)度,產(chǎn)生系統(tǒng)時(shí)鐘節(jié)拍,每一次節(jié)拍就切換一次當(dāng)前就緒表中優(yōu)先級(jí)最高的任務(wù)

OS_CPU_A.S:
        OS_CPU_SR_Save()、OS_CPU_SR_Restore():
        用于任務(wù)保存和恢復(fù)自身的中斷狀態(tài)。用于臨界區(qū)代碼。
       
        OSStartHighRdy():
        尋找就緒表中優(yōu)先級(jí)最高的任務(wù)。

        OSCtxSw()、OSIntCtxSw()、OS_CPU_PendSVHandler()
        OSCtxSw()、OSIntCtxSw()都是通過(guò)觸發(fā)PendSV異常進(jìn)行任務(wù)切換
        OSCtxSw():一般是在任務(wù)調(diào)用延時(shí)函數(shù) 如OSTimeDlyHMSM(0, 0, 0, 300); 時(shí)調(diào)用的。

        OSIntCtxSw():一般用在系統(tǒng)時(shí)鐘節(jié)拍中斷時(shí),會(huì)采用這種方式調(diào)度新的任務(wù)。
        OS_CPU_PendSVHandler() 產(chǎn)生異常PendSV異常就進(jìn)行一次任務(wù)切換







                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 国产欧美精品在线 | 久久精品| 亚洲国产精品久久久久久 | 婷婷色国产偷v国产偷v小说 | 国产欧美精品区一区二区三区 | 久久久人成影片一区二区三区 | 日韩国产一区二区三区 | 蜜臀网站 | 亚洲视频观看 | 欧美一区免费 | 日韩一区不卡 | 国产成人精品免费 | 免费黄色录像视频 | 91网视频 | 激情福利视频 | 成人免费激情视频 | 日韩美女在线看免费观看 | 三级国产三级在线 | 五月激情综合网 | 精品九九| a级大片免费观看 | 免费在线h视频 | 国产午夜三级一区二区三 | 日韩综合在线 | 97成人在线 | 一区二区三 | av男人的天堂在线 | 日本一区二区不卡 | 日韩在线一区二区三区 | 免费视频成人国产精品网站 | 色婷婷综合在线观看 | 国产我和子的乱视频网站 | 久久精品99国产精品 | 免费人成激情视频在线观看冫 | 国产精品不卡 | 在线不卡视频 | 99亚洲精品 | 色婷婷av久久久久久久 | 亚洲福利一区二区 | 婷婷激情综合 | 黄色国产 |