5回答

1收藏

在ATmega328P上使用FreeRTOS

其他 其他 6187 人阅读 | 5 人回复 | 2015-01-08

AVR上的RTOS可能是种类最多的,有avrx、ucOS、FreeRTOS、ChibiRTOS、Atomthreads等等,还有很多国内高手写的小rtos,加起来起码有几十种吧。虽然现在很多已经停止开发,甚至网站也没有了,但是仍然是非常经典的。

下面先尝试移植FreeRTOS到ATmega328P Xplained Mini上。

首先需要安装FreeRTOS。目前FreeRTOS的最新稳定版本是8.1.2,8.2版本暂时还是beta状态,所以就选择了8.1.2版。FreeRTOS的下载是放在SourceForge上,但是一些原因现在SF经常下载不了。如果需要下载,可以通过SF的镜像,例如http://sourceforge.jp/

安装FreeRTOS后,就可以开始我们的移植了。为了速度更快一些,先以AS4为例,AS6下基本是一样的。先创建一个新项目,并在项目文件夹下创建FreeRTOS目录。这样项目就可以和FreeRTOS结合起来,方便使用相对目录管理。(这里因为可能会有多个例子,所有的例子会共用FreeRTOS的文件,所以例子程序中FreeRTOS的目录和项目文件的目录就平级了)

然后在将FreeRTOS的文件复制过来。FreeRTOS的源码很大,因为包括了很多架构的移植,以及100多兆的例程,为了节约空间,我在例子中删除了绝大部分的东西,只保留了AVR相关的部分。



下一步就是添加FreeRTOS的文件到项目中,具体的文件参考一下图片和例程。



然后在项目文件夹中新建一个文件,保存为FreeRTOSConfig.h,这就是项目文件对FreeRTOS的配置。可以从FreeRTOS的例程中复制一个过来,修改一下使用。主要就是定义configCPU_CLOCK_HZ(时钟频率)、configTICK_RATE_HZ(节拍频率)、configMAX_PRIORITIES(最大优先级)等。例程中时钟设置为8M,因为我将ATmega328P Xplained Mini改为了3.3V,所以开发板的时钟频率自动降低到8M。如果是5V供电,时钟还是16M。



在就是设置一下文件的搜索路径,需要将FreeRTOS文件的路径添加进来。此外还需要将当前目录也加进来,因为这是FreeRTOSConfig.h所在的目录。



在main.c中写一小段代码,进行简单的测试。
  1. /*
  2.   单个任务的使用。
  3.   
  4.   * 使用 xTaskCreate 创建任务
  5.   * vTaskStartScheduler 启动调度器
  6.   * 在任务中使用 vTaskDelay 进行延时
  7.   
  8. */

  9. #include "FreeRTOS.h"
  10. #include "task.h"

  11. #include "cfg.h"
  12. #include "macromcu.h"

  13. void vTaskCode( void * pvParameters )
  14. {
  15.   const portTickType xDelay = 100 / portTICK_RATE_MS;

  16.   for( ;; )
  17.   {
  18.     vTaskDelay( xDelay );
  19.     PININV(LED1);
  20.   }
  21. }


  22. int main()
  23. {
  24.   PINDIR(LED1, PIN_OUTPUT);

  25.   xTaskCreate( vTaskCode, "TASK1", configMINIMAL_STACK_SIZE, NULL, 1, NULL );

  26.   vTaskStartScheduler();

  27.   while(1);

  28.   return 0;
  29. }
复制代码
先编译测试一下,发现编译有错误。检查后发现是port.c文件的问题,TIMSK没有定义。这是因为FreeRTOS是以atmega323为例的,和atmega328有一些区别。先将TIMSK修改为TIMSK1,在检查一下port.c中,还有没有问题。果然又发现TIMER1中断的名称需要修改。新版本的AVRGCC使用了新的命名方式,于是也修改为TIMER1_COMPA_vect。这次编译可以通过了。

先在Proteus中仿真一下,发现RTOS没有跑起来。再次检查port.c,发现定时器中断允许位设置有问题,FreeRTOS中设置的是
  1. #define portCOMPARE_MATCH_A_INTERRUPT_ENABLE ( ( uint8_t ) 0x10 )
复制代码
但是在atmega328P中,OCIE1A在TIMSK1的bit1上。于是再进行修改:
  1. #define portCOMPARE_MATCH_A_INTERRUPT_ENABLE        (1<<OCIE1A)//( ( uint8_t ) 0x10 )
复制代码
在编译仿真,LED开始闪了,说明RTOS开始运行了。如图:



移植FreeRTOS时,虽然中间有一点波折,但是还算比较快,使用也很方便。

完整的AS4参考例程
freertos_demo.zip (319.82 KB, 下载次数: 983)

分享到:
回复

使用道具 举报

回答|共 5 个

倒序浏览

沙发

zhzhx66

发表于 2015-1-8 14:16:17 | 只看该作者

谢谢楼主分享!!!!!!!!!
板凳

枫飞

发表于 2015-1-9 20:29:12 | 只看该作者

呵呵,正好想学freerots,mark一下
地板

jwdxu2009

发表于 2015-1-10 16:02:11 | 只看该作者

写的好,学习和参考了,谢了
5#

时光碎了天

发表于 2015-1-19 18:05:29 | 只看该作者


谢谢楼主分享!!!!!!!!!
6#

虎爷

发表于 2015-10-27 12:53:56 | 只看该作者

ATmega328P 跑系统有点累吧
您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /2 下一条