查看: 2051|回复: 0

在ATmega328P上使用FreeRTOS

[复制链接]
  • TA的每日心情
    奋斗
    2019-12-1 10:07
  • 签到天数: 1617 天

    连续签到: 1 天

    [LV.Master]伴坛终老

    发表于 2015-1-8 15:20:46 | 显示全部楼层 |阅读模式
    分享到:
    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的镜像,例如https://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中写一小段代码,进行简单的测试。

    • /*
    • 单个任务的使用。

    • * 使用 xTaskCreate 创建任务
    • * vTaskStartScheduler 启动调度器
    • * 在任务中使用 vTaskDelay 进行延时

    • */
    • #include "FreeRTOS.h"
    • #include "task.h"
    • #include "cfg.h"
    • #include "macromcu.h"
    • void vTaskCode( void * pvParameters )
    • {
    • const portTickType xDelay = 100 / portTICK_RATE_MS;
    • for( ;; )
    • {
    •     vTaskDelay( xDelay );
    •     PININV(LED1);
    • }
    • }
    • int main()
    • {
    • PINDIR(LED1, PIN_OUTPUT);
    • xTaskCreate( vTaskCode, "TASK1", configMINIMAL_STACK_SIZE, NULL, 1, NULL );
    • vTaskStartScheduler();
    • while(1);
    • return 0;
    • }
    复制代码
    先编译测试一下,发现编译有错误。检查后发现是port.c文件的问题,TIMSK没有定义。这是因为FreeRTOS是以atmega323为例的,和atmega328有一些区别。先将TIMSK修改为TIMSK1,在检查一下port.c中,还有没有问题。果然又发现TIMER1中断的名称需要修改。新版本的AVRGCC使用了新的命名方式,于是也修改为TIMER1_COMPA_vect。这次编译可以通过了。
    先在Proteus中仿真一下,发现RTOS没有跑起来。再次检查port.c,发现定时器中断允许位设置有问题,FreeRTOS中设置的是

    • #define portCOMPARE_MATCH_A_INTERRUPT_ENABLE ( ( uint8_t ) 0x10 )
    复制代码
    但是在atmega328P中,OCIE1A在TIMSK1的bit1上。于是再进行修改:

    • #define portCOMPARE_MATCH_A_INTERRUPT_ENABLE        (1<<OCIE1A)//( ( uint8_t ) 0x10 )
    复制代码
    在编译仿真,LED开始闪了,说明RTOS开始运行了。如图:

    移植FreeRTOS时,虽然中间有一点波折,但是还算比较快,使用也很方便。
    完整的AS4参考例程
    freertos_demo.zip
    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

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

    手机版|小黑屋|与非网

    GMT+8, 2024-4-20 10:10 , Processed in 0.122632 second(s), 18 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2020, Tencent Cloud.