从零开始学习UCOSII操作系统13–系统移植理论篇「建议收藏」

从零开始学习UCOSII操作系统13–系统移植理论篇「建议收藏」从零开始学习UCOSII操作系统13–系统移植理论篇1、什么是系统移植?(1)UCOSII移植到不同的处理器上,所谓的移植就是将一个实时的内核能在其他的微处理器或者微控制器上运行。为了方便移植,UCOSII的大部分的代码都是C语言写的,因为不同机器的汇编代码是不一样的。这是由于UCOSII在设计的时候已经充分考虑到了可移植性这一点。但是仍然有一部分的代码是需要用C语言

大家好,又见面了,我是你们的朋友全栈君。

从零开始学习UCOSII操作系统13–系统移植理论篇

1、什么是系统移植?

(1)UCOSII移植到不同的处理器上,所谓的移植就是将一个实时的内核能在其他的微处理器或者微控制器上运行。

为了方便移植,UCOSII的大部分的代码都是C语言写的,因为不同机器的汇编代码是不一样的。这是由于UCOSII在设计的时候已经充分考虑到了可移植性这一点。

但是仍然有一部分的代码是需要用C语言和汇编语言写一些与处理器有关的代码。

(2)要使用UCOSII正常的运行,处理器必须满足以下的条件
2.1、处理器的C编译器能产生可重入型的代码

原因:如果不行的话,那么就不能在任务之间随意的切换,因为当你切换到别的任务的时候,该任务在这个函数的数据就会被破坏。

2.2、处理器支持中断,并能产生定时中断

2.3、用C语言就可以开关中断

原因:连中断都没有的话,是不可能进行任务切换的。

2.4、处理器能够支持一定数量的数据存储硬件堆栈,也就是栈

2.5、处理器有将堆栈指针以及其他的CPU的寄存器的内容读出,并存储到堆栈或者内存中去的指令。

原因:因为我们在任务切换的时候,需要将当前的CPU指针保存到刚刚执行的任务当中。然后切换到优先级更高的任务当中。

2、移植UCOSII实际上需要移植什么文件?

其实我们移植UCOSII额时候,大部分的代码是基于底层进行编写的,所以我们不需要进行移植。有一些是对这个UCOSII进行的配置的,所以我们不需要进行移植。

我们唯一需要关注的三个文件就是下面的三个文件。
OS_CPU.h
OS_CPU_A.ASM
OS_CPU_C.c

一般我们在开发的时候,我们会把所有的头文件定义在同一个头文件当中,因为这样我们只需要包含一个头文件就可以了,不会重复的包含多个头文件。

需要移植的几个文件:
INCLUDES.H
是一个主头文件,出现在每个.c 文件的第一行。

使得每个.c的文件中无需分别考虑它实际上需要哪些头文件,使用INCLUDE.H唯一的缺点就是,它可能包含一些与当前的编译的.c文件不相干的头文件。

OS_CPU.H
包含了用#define 语句定义的,与处理器相关的常数,宏以及类型。
OS_CPU.H的大体结构如程序清单所列。

这里面使用typedef用的比#define更加的好,因为#define仅仅相当于字符串的拷贝,但是typedef相当于命名了一个别名。

/*        数据类型       */

typedef unsigned char BOOLEAN;

typedef unsigned int OS_STK;   //堆栈入口的宽度为16位
typedef unsigned short OS_CPU_SR; //定义CPU状态寄存器的宽度为16位

/*         与处理器有关的代码    */
#define OS_ENTER_CRITICAL()     //进入临界区的代码
#define OS_EXIT_CRITICAL()      //跳出临界区的代码

#define OS_STK_GHOWTH   1  定义堆栈的方向:1=向下递减,0=向上递增

#define OS_TASK_SW()  ??  //定义软件任务切换的函数。

最关键的移植文件:CPU的文件
移植文件3:OS_CPU_C.c
UCOSII的移植范例要求用户编写10个简单的C函数:

OSTaskStkInit();
OSTaskCreateHook();
OSTaskDelHook();
OSTaskSwHook();
OSTaskIdleHook();
OSTaskStatHook();
OSTimeTickHook();
OSInitHookBegin();
OSInitHookend();
OSTCBInitHook();

PS:唯一必要的函数是OSTaskStkinit();其余的9个函数必须声明,但是并不一定要包含任何代码,这些函数的原型放在本章的末尾。

(1)因此堆栈看起来就像中断刚发生的一样,所有的寄存器都保存在堆栈中,OSTaskStkInit()的示例性代码:

OS_STK * OSTaskStkInit(void (*task)(void * pd),
                        void * pada,
                        OS_STK  *ptos,
                        INT16U  opt);
{
    pada = pada;
    模拟ISR向量;

    //按照预先设计的寄存器值初始化堆栈结构;
    //不断的在堆栈中相应的位置填入你要传递的参数
    //返回栈顶指针给调用该函数的函数

    //在这里假定堆栈是从上往下递减的,下面讨论同样适用于以相反方向从下到上递增的堆栈结构。
}

(2)OSTaskCreateHook():
每当添加任务的时候,OS_TCBInit()函数都会调用OSTaskCreateHook()函数,该函数允许扩展UCOSII的功能,当UCOSII设置完任务控制块OS_TCB初始化的绝大部分的工作后,但是在任务控制块被链接到相应的任务链中之前,以及在该任务就绪运行之前,UCOSII会调用OSTaskCreateHook(),该函数被调用的时候中断是打开的。

钩子函数就是为了检查相应的操作有没有成功的。

(3)OSTaskIdleHook()
很多微处理器都允许执行相应的指令,将CPU置于低功耗模式。而当接收到中断信号的时候,CPU就会退出低功耗模式,OSTaskIdle()函数可调用OSTaskIdleHook()函数,实现CPU的这种低功耗的模式:

PS:其实这里真的设计的非常的巧妙,因为你没有任何的任务进行调度的时候,应该是没有什么执行的,但是我们UCOSII系统,规定当没有任何的任务需要强占CPU的时候,我们应该让其进入低功耗的模式,真的设计的很好。

void OS_TaskIdle(void *pdata)
{
    pdata = pdata;
    for(;;)
    {
        OS_ENTER_CRITICAL();
        OSIdleCtr++;
        OS_EXIT_CRITICAL();
        OSTaskIdleHook();
    }
}

void OSTaskIdleHook(void)
{
    asm("STOP");
    //收到中断并完成中断服务。
}

OS_CPU_A.ASm
UCOSII的移植实例就是要求用户编写4个简单的汇编语言函数:
OSStartHighRdy(); //使得最高优先级的任务运行的函数
OSCtxSw(); //任务的切换的函数
OSIntCtxSw();
OSTickISR();

如果编译器支持插入行汇编代码就可以将所有的与处理器相关的代码放置到OS_CPU_C.c里面种,就不需要适用汇编文件了。

(1)OSStartHighRdy()

OSStart()函数调用OSStartHighRdy()来使得就绪太任务中最高优先级的任务开始运行,这个函数的示例性的代码

void OSStartHighRdy()
{
    调用用户定义的OSTaskSwHook();
    OSRunning = TRUE;
    //得到将要恢复运行的任务的堆栈指针。
    stack pointer = OSTcbHighRdy->OSTCBStkPtr;
    //从新的堆栈中恢复处理器的所有的寄存器,就是把刚刚切换的堆栈保存到别的地方当中
    //执行中断返回,然后跳转PC指针到别的地方中去。

}

(2)OSCtxSw():

任务级的切换是通过执行软中断指令,或者依据处理器的不同,执行TPAP陷阱指令执行的。中断服务子程序,陷阱或者异常处理的向量的地址必须指向OSCtxSw();

void OSCtxSw()
{
    保存处理器寄存器;
    在当前的任务的任务控制块中保存当前任务的堆栈指针;
    OSTCBCur->OSTCBStkPtr = stack pointer;
    OSTaskSwHook();
    OSTCBCur = OSTCBHighRdy;
    OSPrioCur = OSPrioHighRdy;

    //得到将要重新开始运行的任务的堆栈指针:
    stack pointer = OSTCBHighRdy->OSTCBstkPtr;
    //从新的任务堆栈中恢复所有的寄存器的值;
    //执行中断返回的指令。
}

(3)OSTickISR()
UCOSII要求用户提供一个周期性的时钟源,来实现时间延迟和超时功能,时钟节拍应该每秒发生10或者100次每秒,为了完成任务,可以使用硬件定时器,也可以从交流电中获得50~60Hz的时钟频率。

必须在开启多任务后,即调用OSStart()后,启动时钟节拍中断,但是由于OSStart()函数不会返回。不能在还没有运行第一个任务的时候,启动时钟节拍中断。会导致程序跑飞。

在没有执行OSStart()之前不能打开时钟节拍中断。千万不能在这里开中断。

因为UCOSII此时仍然处于未知的状态,所以一旦跳入中断,就会跑飞。

定时器允许用户被挂起一定的时间:

void OSTickISR(void)
{
    //保存处理器的寄存器
    //调用OSIntEnter或者直接给OSIntNesting加1
    if(OSIntNesting ==1)
    {
        OSTCBCur->OSTCBStkPtr = Stack Pointer;
    }
    //给产生中断的设备清中断
    //重新允许中断
    OSTimeTick();   //硬件的产生中断的原理
    OSIntExit();    //中断退出
    //恢复处理器寄存器
    //执行中断返回指令
}

OSIntCtxSw()

void OSintCtxSw(void)
{
    //调整堆栈指针
    OSintExit();
    OSINTCtxSw();
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/136016.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • Ubuntu中dpkg命令「建议收藏」

    Ubuntu中dpkg命令「建议收藏」语法   dpkg(选项)(参数)选项   -i         安装软件包;   -r         删除软件包;   -P         删除软件包的同时删除其配置文件;   -L         显示于软件包关联的文件;   -l         显示已安装软件包列表;   –unpack      解开软件包;   -c    …

  • R语言画图时常见问题

    各位朋友,我已开通微信公共号:小程在线我会把文章及时的更新到公共号上,欢迎大家的关注。1如何在同一画面画出多张图?修改绘图参数,如par(mfrow=c(2,2))或par(mfcol=c(2,2));par():mar设置图离四个边缘的距离;bg设置背景颜色;xaxt和yaxt设置坐标轴标签的类型(=”n”表示不画轴标签);xlim和ylim设置坐标轴的范围…

  • Python定义函数

    Python定义函数其他形式1:1、定义函数deftest4(a=()):print('################test4################')print(type(a

  • 解决了无法显示验证码的问题怎么办_验证码不能显示的问题

    解决了无法显示验证码的问题怎么办_验证码不能显示的问题 晚上检测一个站的时候,猜解出了密码,扫出了后台,可验证码就是无法显示,难道管理员故意弄的?不太可能吧?于是上网一搜,没想到还真找到了解决的方法。我的是VistaUltimate,部分XPSP2也会有这个问题。好了,不废话了,解决办法如下:运行regedit,找到“HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/InternetExplorer/Securit

  • GPU视频编解码「建议收藏」

    GPU视频编解码「建议收藏」一视频编解码基础1.1识别编码流程视频编解码流程1.2YUV颜色空间YCbCr通常是YUV的同义词,Y为明度(luma),CbCr为色度(chroma),Cb为蓝色分量,Cr为红色分量。颜色空间转换公式:–      RGB转YUV•      y=[0.299,0.587,0.114]*[r,g,b]’•      u=[-0.147,-0.28…

  • java.lang.noclassdeffounderro_Android进阶实践pdf下载

    java.lang.noclassdeffounderro_Android进阶实践pdf下载错误描述今天使用第三方的so库时候,调用JNI方法时出现了错误。报错如下所示:11-0116:39:20.9794669-4669/com.netease.xtc.cloudmusicE/art:Noimplementationfoundforvoidcom.netease.xtc.cloudmusic.utils.NeteaseMusicUtils.nativeInit(…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号