- 1、本文档共46页,可阅读全部内容。
- 2、有哪些信誉好的足球投注网站(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
序
自从 03 年以来,对单片机的 RTOS 的学习和应用的热潮可谓一浪高过一浪.03年,在离开校园前的,非 典的那几个月,在华师的后门那里买了本邵贝贝的《UCOSII 》,通读了几次,没有实验器材,也不了了之。在 21IC 上,大家都可以看到杨屹写的关于UCOSII 在 51 上的移植,于是掀起了 51 上的RTOS 的热潮。再后来,陈明计先生推出的 small ro,ts展示了一个用在 51 上的微内核,足以在 52 上进行任务调度。
前段时间,在 ouravr上面开有专门关于 AVR 的 Rtos的专栏,并且不少的兄弟把自己的作品拿出来,着实开了不少眼界。这时,我重新回顾了使用单片机的经历,觉得很有必要,从根本上对单片机的 RTOS 的知识进行整理,于是,我开始了编写一个用在 AVR 单片机的 RTOS 。
当时,我所有的知识和资源有:
Proteus6.7 可以用来模拟仿真avr系列的单片机
WinVAR v8基于 GCC A VR 的编译环境,好处在于可以在 C 语言中插入 asm 的语句
mega8 1的K ram 有 8K 的 rom,是开发 8 位的 RTOS 的一个理想的器件,并且我对它也比较熟悉。
写 UCOS 的 Jean J.Labross在e他的书上有这样一句话,“渐渐地,我自然会想到,写个实时内核直有那么难吗?不就是不断地保存,恢复 CPU 的那些寄存器嘛。”
好了,当这一切准备好后,我们就可以开始我们的Rtos for mega的8 实验之旅了。
本文列出的例子,全部完整可用。只需要一个文件就可以编译了。我相信,只要适当可用,最简单的就是最好的,这样可以排除一些不必要的干扰,让大家专注到每一个过程的学习。
第一篇:函数的运行
在一般的单片机系统中,是以前后台的方式(大循环+中断)来处理数据和作出反应的。例子如下:
makefi的le设定:运行 WinAvr 中的 Mfile,设定如下MCU Type: mega8
Optimization level: s Debug formatVR:-ACOFF
C/C++ source f选il译e:要编译的 C 文件
#include avr/io.h void fun1(void)
{
unsigned char i=0; while(1)
{
PORTB=i++;
PORTC=0x01(i%8);
}
}
int main(void)
{
fun1();
}
首先,提出一个问题:如果要调用一个函数,真是只能以上面的方式进行吗?
相信学习过 C 语言的各位会回答,No!我们还有一种方式,就是“用函数指针变量调用函数”,如果大家都和我一样,当初的教科书是谭浩强先生的《C 程序设计》的话,请找回书的第 9.5节。
例子:用函数指针变量调用函数
#include avr/io.h void fun1(void)
{
unsigned char i=0; while(1)
{
PORTB=i++;
PORTC=0x01(i%8);
}
}
void (*pfun)();指向//函数的指针
int main(void)
{
pfun=fun1; //
(*pfun)();运行/指/针所指向的函数
}
第二种,是“把指向函数的指针变量作函数参数”
#include avr/io.h void fun1(void)
{
unsigned char i=0; while(1)
{
PORTB=i++;
PORTC=0x01(i%8);
}
}
void RunFun(void (*pfun)()获) 得/了/ 要传递的函数的地址
{
(*pfun)();
}
在 RunFun 中/,/
运行指针所指向的函数
int main(void)
{
RunFun(fun1); 将函数的/指/ 针作为变量传递
}
看到上面的两种方式,很多人可能会说,“这的确不错”,但是这样与我们想要的RTOS ,有什么关系呢?各位请细心向下看。
以下是 GCC 对上面的代码的编译的情况:
对 main()中的 RunFun(fun1);的编译如下ldi r24,lo8(pm(fun1))
ldi r25,hi8(pm(fun1)) rcall RunFun
对 void RunFun(void (*pfun)的()编) 译如下
/*void RunFun(void (*pfun)())*/
/*(*pfun)();*/
.LM6:
movw r30,r24 icall
ret
在调用 void RunFun(void (*pfun)的()时) 候,的确可以把 fun1 的地址通过 r24 和 r25 传递给 RunFun()。但是,RTOS 如何才能有效地利用函数的地址呢?
第二篇: 人工
文档评论(0)