首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

ucOS移植学习

ucOS移植学习

系统是基于移植到LP17XX,CMD的核
ucOS移植需要重写OS_ENTER_CRITICAL()
第一种方法可通过使用 直接快速操作关中断就可以实现,记得先把要用的寄存器保护好
OS_ENTER_CRITICAL_1:
CPSID   I  
OS_EXIT_CRITICAL_1:
CPSIE   I  
第二种方法可以通过同第一种方法,只是多了一个push操作待
//这种方法有问题£?会破坏掉r0的值£?后续还需修改
#define  OS_ENTER_CRITICAL()  __ASM ("PUSH primask;
                                      mov r0, 0;
                                      msr primask, r0 ;");//asm {PUSHF; CLI}            /* Disable interrupts                        */
#define  OS_EXIT_CRITICAL()   __ASM("POP R0;
                                     msr primask, r0 ;")//asm  POPF                   /* Enable  interrupts                        */
现在用第四种方法,
OS_ENTER_CRITICAL_4
    IF OS_CRITICAL_INT_PRIO > 0
      PUSH  {R1,R2}
      LDR  R1, =OS_CRITICAL_INT_PRIO                               ;  Disable priorities between
                                                                        ;  OS_CRITICAL_INT_PRIO & 0xFF
  MSR  BASEPRI,  R1                                            ;  禁能优先级在OS_CRITICAL_INT
                                                                        ;  _PRIO到0xFF的中断
    ELSE
  CPSID   I                                                       ;  Disable all the interrupts
                                                                        ;  禁能所有中断
  PUSH  {R1,R2}
    ENDIF
;如果出现多层嵌套。不会出错
  LDR  R1, =OsEnterSum                                   ;  OsEnterSum++
        LDRB  R2, [R1]
        ADD    R2, R2, #1
        STRB  R2, [R1]
  POP     {R1,R2}
    BX LR

;*********************************************************************************************************
;** name:   OS_EXIT_CRITICAL
;** Deions:   Exit the critical section  退出临界区
;** Output parameters:     None 无
;** Input parameters:  None 无
;** Returned value:   None 无
;** Created by:    Steven Zhou 周绍刚
;** Created Date:      2007.01.18
;**-------------------------------------------------------------------------------------------------------
;** Modified by:            Ni Likao 倪力考
;** Modified date:          2007.11.02
;**-------------------------------------------------------------------------------------------------------
;*********************************************************************************************************
OS_EXIT_CRITICAL_4
  PUSH    {R1, R2}
  LDR     R1, =OsEnterSum                                         ;  OsEnterSum--
        LDRB    R2, [R1]
        SUB     R2, R2, #1
        STRB    R2, [R1]
  MOV     R1,  #0
  CMP     R2,  #0                                           ;  if OsEnterSum=0,enable
                                                                        ;  interrupts如果OsEnterSum=0,
IF OS_CRITICAL_INT_PRIO > 0                                         ;  开中断;
          IT EQ
   MSREQ BASEPRI, R1
ELSE
          IT EQ
   MSREQ  PRIMASK, R1
ENDIF
            MSR PRIMASK,R1
     POP    {R1, R2}
  BX LR

;*********************************************************************************************************
;** name:   OSStartHighRdy
;** Deions:   Uses the context switcher  to cause the first task to start.
;**                         使用调度器运行第一个任务   
;** Input parameters:     None 无
;** Output parameters:     None 无
;** Returned value:   None 无
;** Created by:    Steven Zhou 周绍刚
;** Created Date:      2007.01.18
;**-------------------------------------------------------------------------------------------------------
;** Modified by:            Ni Likao 倪力考
;** Modified date:          2007.11.02
;**-------------------------------------------------------------------------------------------------------
;*********************************************************************************************************
OSStartHighRdy
        LDR     R4, =NVIC_SYSPRI2                                       ;  set the PendSV exception
                                                                        ;  priority设置PendSV优先级
        LDR     R5, =NVIC_PENDSV_PRI
        STR     R5, [R4]
     //用户可以知道第一次调用任务切换,PSP等于0
        MOV     R4, #0                                                  ;  set the PSP to 0 for initial  
                                                                        ;  context switch call 使PSP等于0
        MSR     PSP, R4
        LDR     R4, =OSRunning                                          ;  OSRunning = TRUE
        MOV     R5, #1
        STRB    R5, [R4]
        LDR     R4, =NVIC_INT_CTRL                                      ;  trigger the PendSV exception
                                                                        ;  触发软件中断
        LDR     R5, =NVIC_PENDSVSET
        STR     R5, [R4]
        CPSIE   I                                                       ;  enable interrupts at processor
                                                                        ;  level使能所有优先级的中断
      //上面已产生任务切换,程序已切换到系统任务中,因此这里死机是不会导致系统死机。
   //如果此处不设置死机的话,会出现程序后无死循环的话,会使整个程序退出。
OSStartHang
        B       OSStartHang
返回列表