自从03年以来,对单片机的RTOS的学习和运用的热潮可谓一浪高过一浪.03年,在脱离学校前的,非典的那几个月,在华师的后门那里买了本邵贝贝的《UCOSII》,通读了几回,没有试验器材,也不了了之。
在21IC上,咱们都能够看到杨屹写的关于UCOSII在51上的移植,所以掀起了51上的RTOS的热潮。
再后来,陈明计先生推出的small rots,展现了一个用在51上的微内核,足以在52上进行使命调度。
前段时间,在ouravr上面开有专门关于AVR的Rtos的专栏,而且不少的兄弟把自己的著作拿出来,着实开了不少视野。这时,我从头回忆了运用单片机的阅历,觉得很有必要,从根本上对单片机的RTOS的常识进行收拾,所以,我开端了编写一个用在AVR单片机的RTOS。
其时,我一切的常识和资源有:
Proteus6.7能够用来模仿仿真avr系列的单片机
WinAVR v2.0.5.48根据GCC AVR的编译环境,优点在于能够在C言语中刺进asm的句子
mega8 1K的ram有8K的rom,是开发8位的RTOS的一个抱负的器材,而且我对它也比较了解。
写UCOS的Jean J.Labrosse在他的书上有这样一句话,“渐渐地,我自然会想到,写个实时内核直有那么难吗?不便是不断地保存,康复CPU的那些寄存器嘛。”
好了,当这一切准备好后,咱们就能够开端咱们的Rtos for mega8的试验之旅了。
本文列出的比如,悉数完好可用。只需要一个文件就能够编译了。我信任,只需恰当可用,最简略的便是最好的,这样能够扫除一些不必要的搅扰,让咱们专注到每一个进程的学习。
第一篇:函数的运转
在一般的单片机体系中,是以前后台的方法(大循环+中止)来处理数据和作出反应的。
比如如下:
makefile的设定:运转WinAvr中的Mfile,设定如下
MCU Type: mega8
Optimization level: s
Debug format :AVR-COFF
C/C++ source file:选译要编译的C文件
#include
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
void fun1(void)
{
unsigned char i=0;
while(1)
{
PORTB=i++;
PORTC=0x01<<(i%8);
}
}
void (*pfun)(); //指向函数的指针
int main(void)
{
pfun=fun1; //
(*pfun)(); //运转指针所指向的函数
}
第二种,是“把指向函数的指针变量作函数参数”
#include
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怎么才干有效地使用函数的地址呢?