原创 建立一个属于自己的AVR的RTOS(第一篇:函数的运行)

2010-5-6 08:30 1801 5 5 分类: MCU/ 嵌入式

                                 第一篇:函数的运行

    
在一般的单片机系统中,是以前后台的方式(大循环+中断)来处理数据和作出反应的。
    
例子如下:
   
    makefile
的设定:运行WinAvr中的Mfile,设定如下
    MCU Type: mega8
    Optimization level: s
    Debug format :AVR-COFF
    C/C++ source file: 
选译要编译的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的地址通过r24r25传递给RunFun()。但是,RTOS如何才能有效地利用函数的地址呢?<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
5
关闭 站长推荐上一条 /3 下一条