赞
踩
现在我手上的参考书是很薄很薄的用x86作为实验的参考书,提供了不太完整的c51移植代码,移植主要需要修改的底层抽象层文件大致是一下四个:
这里的六个函数中也就只有OSTaskStkInit需要改写,另外的五个函数只要声明即可。
将一个操作系统移植到不同的硬件环境中,需要修改操作系统硬件抽象层来适应不同的实际环境,这里不仅是与硬件相同,与编译器也息息相关。在不同的硬件环境以及不同的编译器面前可能都会采用不同的策略来实现或者提高效率。这里我用的是C51 STC89C51 以及Keil51编译器,而因为C51的片内内存非常少,所以对于函数而言默认是不可重入的,如果需要重入就需要添加关键字reentrant。
如果有两个函数void A(){ int a =0;[输出a]} void B(){int b=0;[输出b]}
默认这两个函数是不可重入的,那么他们的数据段中的临时变量将会定位在一个可以被覆盖的段中,此时如果发生中断,这个段可能被覆盖,如果A函数在执行到输出a的那个部分的代码段被中断转而运行B函数时,如果恰好a所在的存储位置被覆盖,在执行完B回去执行A的时候,A的结果就非常有可能出错。这是不希望出现的结果。那么就应该将函数声明为可重入的函数。
这个时候在KEIL里的STARTUP文件中声明的全局指针变量?C_XBP指向的便是模拟堆栈(这个堆栈存储在片外内存,以改善51单片机片内内存小的特点)的栈顶地址,也依赖这个编译器的特点来实现移植。
系统堆栈与模拟堆栈。
。。未完待续
于是在复习完51的汇编后,一切感觉都能迎刃而解。
Note:
临界段的本质作用:
· 普通任务与中断任务的不同:
中断任务会使用OSIntEnter()与 OSIntExit
而在OSIntExit中会使OSIntNesting-=1;然后检查OSIntNesting与OSLockNesting确定目前是否可以进行任务调度。也就是说中断任务本身会更快完成,因为OSIntNesting不为0的时候不会进行新的任务调度,肯定会先完成中断的任务。而OSTickISR函数会一直调用OSIntEnter与OSIntExit来调度最新的优先度最高的函数,当然 在符合以上条件时。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。