历史上的今天
今天是:2024年10月25日(星期五)
2019年10月25日 | 基于MSP430F5529的μc/os嵌入式实时操作系统移植
2019-10-25 来源:eefocus
μ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开总中断
DINT关总中断
3.中断处理流程
任何当前执行的指令完成。
指向下一条指令的PC 被压入堆栈。
SR 被压入堆栈。
如果在最后一个指令执行期间由多个中断出现,那么具有最高优先级的中断被选中并等待被处理。
在单一源标志上,中断请求标志自动复位。对于软件处理,多个源标志保持被设定。
SR 被清除。这将终止任何低功耗模式。由于GIE 位被清除,之后的中断被禁用。
中断矢量的内容被载入到PC:程序继续在中断处理例程所处的地址上执行。
4.中断处理程序由以下指令终止:
RETI(从中断处理例程返回)
5.时钟中断源时钟的选择
在这里使用的是看门狗时钟那么相应的也要打开看门时钟的中断,但是不要错误的把看门狗设置成安全模式,这样会造成系统反复重启
6.MSP430为16位单片机,堆栈是向下生长
os_cpu_c.c文件的改写
μC/OS-II 的移植需要用户改写OS_CPU_C.C中的六个函数:
OSTaskStkInit()
OSTaskCreateHook()
OSTaskDelHook()
OSTaskSwHook()
OSTaskStatHook()
OSTimeTickHook()
实际需要修改的只有OSTaskStkInit()函数,其他五个函数需要声明,但不一定有实际内容。这五个函数都是用户定义的对操作系统功能的扩展
其他的钩子函数已经嵌入到系统,会在操作系统执行某些操作时被调用,可以通过os_cfg.h来配置让系统不使用这些钩子
/*
* os_cpu.c
*
* Created on: 2016年11月20日
* Author: Tom
*/
#define OS_CPU_GLOBALS
#include "ucos_ii.h"
#if OS_CPU_HOOKS_EN > 0 && OS_VERSION > 203
void OSInitHookBegin (void) //进入OSInit()函数后,OSInitHookBegin就会被调用
{
}
#endif
#if OS_CPU_HOOKS_EN > 0 && OS_VERSION > 203
void OSInitHookEnd (void) //:OSInitHookEnd与OSInitHookBegin相似,
{
}
#endif
#if OS_CPU_HOOKS_EN > 0
void OSTaskCreateHook (OS_TCB *ptcb) //OS_TCBInit会调用OSTaskCreateHook
{
ptcb = ptcb; /* 防止编译警告 */
}
#endif
#if OS_CPU_HOOKS_EN > 0
void OSTaskDelHook (OS_TCB *ptcb) //OSTaskDel()会调用OSTaskDelHook(ptcb)
{
ptcb = ptcb; /* 防止编译警告 */
上一篇:MSP430时钟模块详解
史海拾趣
|
mobile 6,一个最前端显示的程序隐藏了OK和×按钮,但是 × 按钮经常还是会出现,恳请大家帮忙看看 mobile 6,一个最前端显示的程序隐藏了OK和×按钮,但是 × 按钮经常还是会出现,点击开始中其他程序之后有消失了,怀疑是被我关闭的“信息”收件箱留下,点击之后我的程序就再也启动不起来了。 点击自己添加的返回按钮之后,屏幕最上面还显示我的 ...… 查看全部问答> |
|
!!销售/收购/维修agilent 8714et hp8714et,agilent 8714et509239856 !!销售/收购/维修agilent 8714et hp8714et,agilent 8714et09239856 银通仪器有限公司 手机:13509239856 TEL:0769-87912629 FAX:0769-87912842 QQ:350534337 E-MAIL:yonglin__2007@126.com(下划线两横) 地址:广东省东莞市塘厦镇东方花 ...… 查看全部问答> |
|
手边的摄像头都是这个德性,光线稍微暗一点帧率就降到12左右了,还拖影,比较烦 请问为什么为出现这样的情况呢 会不会是在摄像头的芯片上在做白平衡,运算量比较大,才导致了帧率下降? 我在一些应用中不想让图像被处理过,只是想获得比较高的帧率,并且 ...… 查看全部问答> |
|
大家好,求问 我用pwm波控制电热丝的功率,pwm波的周期大概为33ms,那么是用可控硅好还是用固态继电器好啊,开关频率太频繁是不是会影响固态继电器的使用寿命啊 谢谢帮忙啊~… 查看全部问答> |
|
有木有用verilog语言做过视频图像色空间转换从RGB 到YCbCr,有工程能否参考一下 有木有用verilog语言做过视频图像色空间转换从RGB 到YCbCr,有工程能否参考一下。。。急啊… 查看全部问答> |
|
给客户设计了好几次电路板,每次供电都不给力,不是电池很快没电就是MCU程序不稳定,废了好长的时间终于找到了原因,罪魁祸首就是选错了电感,升压电路的有磁芯功率电感给弄成了贴片的滤波电感。现在还是不太明白为什么我弄成了贴片电感,电池工作2 ...… 查看全部问答> |
|
我在用Cadence做电路板时,在原理图中二极管器件是2个引脚的,但是给它添加了一个3脚的封装,然后我就不可以将这个封装拉倒Allegro PCB中,怎样设置才可以将这个三角封装拉倒Allegro PCB中呢?希望大家赐教。… 查看全部问答> |




