基于MSP430F5529的μc/os嵌入式实时操作系统移植

2019-10-25来源: eefocus关键字:MSP430F5529  μc  os  实时操作系统  移植

μc/os移植的条件

uCOS II的移植需要满足以下要求: 

  1)处理器的C编译器可以产生可重入代码:可以使用C调用进入和退出Critical Code(临界区代码); 

  2)处理器必须支持硬件中断,并且需要一个定时中断源; 

  3)处理器需能容纳一定数据的硬件堆栈; 

  4)处理器需有能在CPU寄存器与内存和堆栈交换数据的指令。


移植需要完成的工作

CPU的接口部分(Ports)–需要移植的代码部分 

汇编文件(OS_CPU_A.ASM)、处理器相关C文件(OS_CPU.H、OS_CPU_C.C)中相关函数和变量的声明定义


OS_CPU_A.ASM文件改写

OSStartHighRdy()    //OS启动时调用,加载用户最高优先级的任务 

OSCtxSw()       //任务级调度 

OSIntCtxSw()      //中断级调度 

OSTickISR()       //时钟中断响应,将检测到延时结束的任务加入就绪队列,


    .cdecls C, LIST, "msp430.h"


;用户钩子,对应os_cpu_c.c中的HOOK函数

    .ref     OSIntExit

    .ref     OSIntNesting

    .ref     OSISRStkPtr

    .ref     OSPrioCur

    .ref     OSPrioHighRdy

    .ref     OSRunning

    .ref     OSTCBCur

    .ref     OSTCBHighRdy

    .ref     OSTaskSwHook

    .ref     OSTimeTick

;全局量

    .global  OSCtxSw

    .global  OSCPURestoreSR

    .global  OSCPUSaveSR

    .global  OSIntCtxSw

    .global  OSStartHighRdy

    .global  OSTickISR

;中断使能操作之前保存SR,恢复中断使能时CPU状态不变

    .asmfunc            ;保存SR寄存器

OSCPUSaveSR:

    MOV.W       SR, R12

    DINT

    NOP

    RETA

    .endasmfunc


    .asmfunc            ;恢复SR寄存器,保持CPU状态

OSCPURestoreSR:

    MOV.W       R12, SR

    NOP

    RETA

    .endasmfunc


    .asmfunc

;OS初始化后,准备运行时调用

;准备运行的最高优先级的任务。任务就绪表第一个

;被OSStart()调用

OSStartHighRdy:

    CALLA       #OSTaskSwHook


    MOV.B       #1, &OSRunning          ; 内核运行标志


    MOVX.A      SP, &OSISRStkPtr        ; 保存中断堆栈,系统堆栈


    MOVX.A      &OSTCBHighRdy, R13      ; 将最高优先级任务准备

    MOVX.A      @R13, SP                ;将SP指向OSTCBHighRdy,即任务堆栈


    POPM.A      #12, R15



    RETI                                ; 模拟中断,中断退出应执行的内容在OSISRStkPtr中

    .endasmfunc


    .asmfunc

;任务级上下文切换

OSCtxSw:

    POP.W       R12                     ;CALLA调用,当前PC地址被压入系统栈

    POP.W       R13                     ;这里使用的是扩展内存地址,地址长度为20位


    PUSH.W      R12                     ;因此压栈的写法有变化


    RLAM.A      #4, R13                 

    RLAM.A      #4, R13

    RLAM.A      #4, R13

    MOVX.W      SR,  R12

    ADDX.A      R13, R12

    PUSH.W      R12                     ;保存PC和SR


    PUSHM.A     #12, R15                ; 保存上一个任务的上下文到它的任务堆栈


    MOVX.A      &OSTCBCur, R13          ;任务堆栈构建完成

    MOVX.A      SP, 0(R13)              ;前一个任务的上下文保存


    CALLA       #OSTaskSwHook           ;用户钩子


    MOV.B       &OSPrioHighRdy, R13     ;切换任务

    MOV.B       R13, &OSPrioCur


    MOVX.A      &OSTCBHighRdy, R13      ;

    MOVX.A      R13, &OSTCBCur


    MOVX.A      @R13, SP                ; 堆栈寄存器指向任务堆栈


    POPM.A      #12, R15                ; 从任务PCB中恢复寄存器内容,程序开始执行


    RETI                                ; 从中断返回

    .endasmfunc



;OSIntCtxSw()是唯一一个与编译器相关的函数,也是用户问的最多的。

;中断级上下文切换

;在此之前必须已经对上下文内容进行了保存

;由于中断已经发生,此处不需要再保存CPU寄存器

;OSIntCtxSw()需要调整堆栈指针,去掉堆栈中一些不需要的内容,以使堆栈中只包含任务的运行环境

    .asmfunc

OSIntCtxSw:

    CALLA       #OSTaskSwHook


    MOV.B       &OSPrioHighRdy, R13

    MOV.B       R13, &OSPrioCur


    MOVX.A      &OSTCBHighRdy, R13

    MOVX.A      R13, &OSTCBCur


    MOVX.A      @R13, SP                ; 堆栈寄存器指向任务PCB


    POPM.A      #12, R15                ;从任务PCB中恢复寄存器内容,程序开始执行


    RETI                                ; 中断返回

    .endasmfunc


;中断服务程序中会执行OSTimeTick()

;每进行一次中断,OSTimeTick()都会遍历所有挂起任务然后对有延时的任务控制块TCB中的OSTCBDly减1

;这样,当延时减为0时,就会把减为0的任务在就绪表中进行注册登记。

    .sect  ".text:_isr"                 ; 这个函数在中断向量空间

    .asmfunc

;

OSTickISR:                              ;看门狗时钟中断

    PUSHM.A     #12, R15                ;保存寄存器内容


    BIC.W       #0x01, &SFRIE1          ;禁止看门狗中断


    CMP.B       #0, &OSIntNesting       ;无中断嵌套,跳转

    JNE         OSTickISR1              ;跳转到下面的模块


    MOVX.A      &OSTCBCur, R13          ;保存任务堆栈

    MOVX.A      SP, 0(R13)


    MOVX.A      &OSISRStkPtr, SP        ;加载中断堆栈

;只有当中断全部执行完毕,

OSTickISR1:

    INC.B       &OSIntNesting           ;产生了一个时钟中断


    BIS.W       #0x01, &SFRIE1          ; 禁止看门狗

    NOP


    EINT                                ; 允许中断嵌套

    NOP


    CALLA       #OSTimeTick             ; 调用节拍处理函数


    DINT                                ; 一般禁用中断之前调用OSIntExit()

    NOP


    CALLA       #OSIntExit              ;退出中断


    CMP.B       #0, &OSIntNesting       ;中断无嵌套时,跳转

    JNE         OSTickISR2


    MOVX.A      &OSTCBHighRdy, R13      ;恢复任务堆栈寄存器

    MOVX.A      @R13, SP



OSTickISR2:

    POPM.A      #12, R15

    RETI                                ; 从中断中返回

    .endasmfunc


    .sect   WDT_VECTOR

    .short  OSTickISR                   ; 中断向量,看门狗定时器模式


    .end


OS_CPU_A.ASM中与MSP430硬件机制相关的部分

1.MSP430单片机有R0~R15十六个通用寄存器,其中PC占用R0,SP占用R1,SR占用R3,因此,切换任务时有16个寄存器值需要保存。

2.MSP430开关中断

_EINT开总中断