我爱嵌入式系统

当前位置:首页 > 软件天地 > 业内资讯 > 详细内容
uC/OS-II 在 AVR 上的移植
发布时间:2009/10/28  阅读次数:1349  字体大小: 【】 【】【


有兴趣的请讨论一下

uC/OS-II  在  AVR  上的移植

hotislandn@hotmail.com  www.mcuzone.com

IDE:  PN  Compiler:  AVR-GCC  (  WinAVR  20050214  )  Target:  ATmega16  @  7.3728MHz

2005-07-28  V1.0  1.  由于ATmega16的RAM资源很少,所以在OS_CFG.H中关闭所有不必要的功能,同时优化代码,减少RAM占用  在os_core.c中,有两个数组:  INT8U  const  OSMapTbl[8]与  INT8U  const  OSUnMapTbl[256],虽然声明为const类型,但是avr-gcc并不会将其放置在flash中,必须加以修改为INT8U  const  OSMapTbl[8]  PROGMEM  与INT8U  const  OSUnMapTbl[256]  PROGMEM  ,同样的,该文件中访问这些数组的语句也必须做相应的修改。这样的结果是速度会受到影响,但是由于仍然是查表操作,任务切换的时间还是确定的。  2.  任务说明  系统中一共有5个用户任务:Task1-Task5,其优先级依次为1,2,3,5,4。每个用户任务的堆栈均为OS_USER_TASK_STK_SIZE(定义于os_cfg.h,目前为64字节)。  系统中建立有一个信号量T2sem与一个邮箱Tmbox。  Task1完成了Timer0的初始化,并打开了定时器中断,使得任务调度可以正常进行。此后,该任务只隔一个很短的时间使得变量t1增加,同时取反PORTB.1。  Task2初始化了Timer2,并使能了Timer2中断,然后任务挂起,等待信号量T2sem,如果等到且无错误,则使得变量t2增加。  Task3使得PD2上出现一个脉冲,以触发INT0,并使得变量t3增加。  Task4使得PD3上出现一个脉冲,以触发INT1,并使得变量t4增加。  Task5使得该任务挂起等待邮箱中有一条消息,如果取得消息,就将t5的值更新。  3.  中断系统  需要引用系统服务的中断,其底层部分被定义于AVRect.S中,中断的处理函数被定义于AVRisr.c中,例如例子中外部中断0与外部中断1的服务函数。  对于无需引用系统服务的中断函数,比如例子中的Timer2比较匹配中断,可以全部定义于AVRisr.c中。  Timer2的中断只是使得变量t6增加。  INT0的中断向任务发出信号量。  INT1的中断发送一个消息到信箱。  由于AVR的RAM有限,移植并未考虑中断重入的问题。  2005-07-16  V0.9  1.  OS版本为2.76  2.  使用Timer0的比较匹配中断为系统定时,频率为100Hz  3.  三种临界代码保护方式均可以使用,在OS_CPU.h里直接设置即可

如果安装了WinAVR20050214,则直接运行start.bat,输入make  all即可开始编译。  如果需要在AVRStudio仿真,运行make  extcoff后即可生成调试所需的cof文件。


#include  <avr/io.h>



#include  "ucos_ii.h"



OS_STK  Task1Stk[OS_USER_TASK_STK_SIZE]={0};

OS_STK  Task2Stk[OS_USER_TASK_STK_SIZE]={0};

OS_STK  Task3Stk[OS_USER_TASK_STK_SIZE]={0};

OS_STK  Task4Stk[OS_USER_TASK_STK_SIZE]={0};

OS_STK  Task5Stk[OS_USER_TASK_STK_SIZE]={0};



volatile  unsigned  char  t1=0;

volatile  unsigned  char  t2=0;

volatile  unsigned  char  t3=0;

volatile  unsigned  char  t4=0;

volatile  unsigned  char  t5=0;

volatile  unsigned  char  t6=0;



OS_EVENT  *T2sem=(OS_EVENT  *)0;

OS_EVENT  *Tmbox=(OS_EVENT  *)0;



struct  msgTask

{

  unsigned  char  cnt;

  unsigned  char  *s;

};



struct  msgTask  T5mbox={1,"Hello"};

struct  msgTask  *pMsgTsk=&T5mbox;

  

void  Task1(void  *pdata)

{

  pdata=pdata;



  TIMSK&=0xFC;

  

#if  OS_TICKS_PER_SEC  <=  (F_CPU/1024/256)

  #error  "OS_TICKS_PER_SEC  <    (F_CPU/1024/256)  "

#endif



  OCR0=F_CPU/1024/OS_TICKS_PER_SEC;

  TCNT0=0;





  TCCR0=(1<<WGM01)|0x05;



  TIMSK|=2;

  

  DDRB|=0x02;



  while(1)

        {



  OSTimeDly(2);

  t1++;

  PORTB^=0x02;

}

}



void  Task2(void  *pdata)

{

  unsigned  char  err=0;

  pdata=pdata;



  MCUCR=0x02;

  GICR=0x40;



  TCCR2=0x08;            //  CTC  模式,  TOP=OCR2

  OCR2=72;                  //  7372800/1024/72=100

  TCCR2|=0x07;          //  1024分频

  TIMSK|=0x80;          //  比较中断使能

  

  while(1)

        {                

                            OSSemPend(T2sem,0,&err);

                            if(err==OS_NO_ERR)  

                                                t2++;

                            if(err==OS_TIMEOUT)

                                                {};

                            GIFR|=0x40;

//  OSTimeDly(10);   

}

}



void  Task3(void  *pdata)

{





  pdata=pdata;

  

  while(1)

        {

  t3++;

  OSTimeDly(4);

                              DDRD|=0x04;

                              PORTD|=0x04;

                              PORTD&=~0x04;   

}

}



void  Task4(void  *pdata)

{

  pdata=pdata;

  

  MCUCR|=0x08;

  GICR|=0x80;



  while(1)

        {

  t4++;

  OSTimeDly(8);

                              DDRD|=0x08;

                              PORTD|=0x08;

                              PORTD&=~0x08;   

}

}



void  Task5(void  *pdata)

{

  unsigned  char  err=0;  

  struct  msgTask  *p=(  struct  msgTask  *)0;

  

pdata=pdata;

  

  while(1)

        {

                              p=(  struct  msgTask  *)OSMboxPend(Tmbox,0,&err);

                              

  t5=p->cnt;   

}

}



int  main(void)

{

  OSInit();

  

  OSTaskCreate(Task1,0,&Task1Stk[OS_USER_TASK_STK_SIZE-1],1);

  OSTaskCreate(Task2,0,&Task2Stk[OS_USER_TASK_STK_SIZE-1],2);

  OSTaskCreate(Task3,0,&Task3Stk[OS_USER_TASK_STK_SIZE-1],3);  

  OSTaskCreate(Task4,0,&Task4Stk[OS_USER_TASK_STK_SIZE-1],5);  

  OSTaskCreate(Task5,0,&Task5Stk[OS_USER_TASK_STK_SIZE-1],4);  



  T2sem=OSSemCreate(0);

  Tmbox=OSMboxCreate((void  *)0);    


  OSStart();

}
我要评论
  • 匿名发表
  • [添加到收藏夹]
  • 发表评论:(匿名发表无需登录,已登录用户可直接发表。) 登录状态:未登录
最新评论
所有评论[0]
    暂无已审核评论!

51RTOS.com 版权所有  

Copyright 20006-2009 我爱嵌入式 ( 51RTOS.com ) All rights reserved 沪ICP备09080633号