【RTOS】在Arduino上跑个系统吧(多任务并行)【二】

2017-04-022.7万
AI 快速预览详细 收起
本文介绍了如何在Arduino上使用FreeRTOS实现多任务并行。通过具体的代码示例和Proteus仿真,展示了三个任务的创建与调度过程。每个任务有不同的优先级和栈大小配置,实现了LED闪烁和串口打印的功能。


为了观看实验效果,这里我使用Proteus进行仿真
代码部分用三种颜色显示不用的任务

仿真文件:【RTOS】在Arduino上跑个系统吧(多任务并行)【二】图2
下载附件Proteus_ArduinoUno.zip


来看一下代码吧-------------------------------------------------------------
#include <FreeRTOS_AVR.h>

const uint8_t LED_PIN_1 = 13;//定义第一个led
const uint8_t LED_PIN_2 = 12;//定义第二个led

volatile uint32_t count = 0;//计数用的变量

//------------------------------------------------------------------------------
//创建任务vLEDFlashTask_1,(必须按照这样的格式)
//**程序效果:每200ms闪烁一次led1,占空比1/3**
static void vLEDFlashTask_1(void *pvParameters) {
  pinMode(LED_PIN_1, OUTPUT);//配置IO模式
  
  // 每200ms闪烁一次.
  for (;;) {//直接死循环,就是这么任性(因为RTOS会自动调度,不用担心)
    // 点亮
    digitalWrite(LED_PIN_1, HIGH);
   
    // 等待50ms
    vTaskDelay((50L * configTICK_RATE_HZ) / 1000L);
   
    // 熄灭
    digitalWrite(LED_PIN_1, LOW);
   
    // 等待150ms
    vTaskDelay((150L * configTICK_RATE_HZ) / 1000L);
  }
}
//------------------------------------------------------------------------------
//创建任务vLEDFlashTask_2,(必须按照这样的格式)
//**程序效果:每200ms闪烁一次led2,占空比50%**
static void vLEDFlashTask_2(void *pvParameters) {
  pinMode(LED_PIN_2, OUTPUT);//配置IO模式
  
  // 每200ms闪烁一次.
  for (;;) {//直接死循环,就是这么任性(因为RTOS会自动调度,不用担心)
    // 点亮
    digitalWrite(LED_PIN_2, HIGH);
   
    // 等待100ms
    vTaskDelay((100L * configTICK_RATE_HZ) / 1000L);
   
    // 熄灭
    digitalWrite(LED_PIN_2, LOW);
   
    // 等待100ms
    vTaskDelay((100L * configTICK_RATE_HZ) / 1000L);
  }
}
//------------------------------------------------------------------------------
//创建任务vPrintTask,(必须按照这样的格式)
//**程序效果:每1s打印一次当前的count的值**
static void vPrintTask(void *pvParameters) {
  while (1) {//直接死循环,就是这么任性(因为RTOS会自动调度,不用担心)
    // 等待1000ms
    vTaskDelay(configTICK_RATE_HZ);
   
    // 打印当前的计数Count
    Serial.print(F("Count: "));
    Serial.println(count);
    // Zero count.
    count = 0;
  }
}
//------------------------------------------------------------------------------
void setup() {
  Serial.begin(9600);
  // 等待Leonardo响应
  while(!Serial) {}

  //======创建函数解读===================================================================================
  // xTaskCreate(vLEDFlashTask_1,//对应任务的名称,比如这里的是vLEDFlashTask_1
  //   "Task1",                  //这个名字没有实际用途,主要用来识别(just for human)
  //   configMINIMAL_STACK_SIZE + 50, //栈的大小,栈简单的来说是数据的存放,栈越大,越不会溢出,但同时占用资源也越多,需要根据任务的实际需要来调整
  //   NULL,
  //   tskIDLE_PRIORITY + 2,  //任务的优先级,这里的是2,需要说明的是0是优先级最低,最高优先级有上限,和芯片的资源以及RTOS本身有关
  //   NULL);
  //   
  //   补充:configMINIMAL_STACK_SIZE,指loop()的栈(Task)大小,其他的任务在此基础上增加栈(Task)大小
  //   补充:tskIDLE_PRIORITY,指loop()的优先级,其他任务需要在此基础上提高优先级
  //====================================================================================================


  // 创建vLEDFlashTask_1
  xTaskCreate(vLEDFlashTask_1,
    "Task1",
    configMINIMAL_STACK_SIZE + 50,
    NULL,
    tskIDLE_PRIORITY + 3,
    NULL);

  // 创建vLEDFlashTask_2
  xTaskCreate(vLEDFlashTask_2,
    "Task2",
    configMINIMAL_STACK_SIZE + 50,
    NULL,
    tskIDLE_PRIORITY + 2,
    NULL);


  // 创建vPrintTask
  xTaskCreate(vPrintTask,
    "Task3",
    configMINIMAL_STACK_SIZE + 100,
    NULL,
    tskIDLE_PRIORITY + 1,
    NULL);

  // 启动 FreeRTOS
  vTaskStartScheduler();

  while(1);
}
//------------------------------------------------------------------------------
void loop() {
  while(1) {
    noInterrupts();
    count++;//每次+1
    //loop()中不要写其他程序了,全部以任务的形式创建好,在setup()中配置后,RTOS会根据各自任务的优先级,调度运行
    interrupts();
  }
}


---------------------------------------------------------------------------------------------------------------------
实验效果


【RTOS】在Arduino上跑个系统吧(多任务并行)【二】图3


1:任务1,led每200ms闪烁一次,占空比1/3
2:任务2,led每200ms闪烁一次,占空比1/2
3:任务3,串口每1000ms打印一次count的值

代码
下载附件Blink1_Blink2_Print.zip


创作许可协议

本项目采用 None(不开放任何权利,保留所有权利) 进行许可。

评论(13)
20060606
20060606
高科技啊~看不懂
joone
joone
好东西要收藏起来
gada888
gada888
mark下,学习学习
DFry6Vdy1Xr
DFry6Vdy1Xr
学习一下
生我独孤
生我独孤
谢谢楼主,可以交流一下吗?和PT操作系统,那个更占用资源?
全天假日
全天假日
q2017
q2017
学习学习......................
zdweb
zdweb
Proteus没用过。学习一下
zxy2266
zxy2266
1.05R2 库装了没错
nicho
nicho
作者
回复zxy2266
1.05是Arduino IDE的版本??  好像有点旧也,换个新点的IDE试试?
zxy2266
zxy2266
1.05版本不能用吗?编译出现很多错误,俺英文不好,不知道啥意识
nicho
nicho
作者
回复zxy2266
1.05是什么的版本? 另外,需要安装库文件哦,看看第一篇
Lii
Lii
这是要自制操作系统的节奏吗...
luna
luna
好内容!
nicho
nicho
作者
占楼更新
[库的安装和示例]
【RTOS】在Arduino上跑个系统吧(多任务并行)【一】
https://mc.dfrobot.com.cn/thread-24089-1-1.html
[进阶程序解读]
【RTOS】在Arduino上跑个系统吧(多任务并行)【二】
https://mc.dfrobot.com.cn/thread-24100-1-1.html
.
.
.


- 没有更多了 -