arduino上跑freertos 运行多任务

来源:互联网 发布:抱枕材料 知乎 编辑:程序博客网 时间:2024/06/08 00:37

关于freertos介绍

http://blog.csdn.net/qq_38288618/article/details/76448806

资源下载

https://github.com/feilipu/Arduino_FreeRTOS_Library

测试源码

#include <Arduino_FreeRTOS.h>#include <semphr.h>  // add the FreeRTOS functions for Semaphores (or Flags).// Declare a mutex Semaphore Handle which we will use to manage the Serial Port.//声明信互斥号量用它来管理串口// It will be used to ensure only only one Task is accessing this resource at any time.//某时刻只有一个任务能获取到串口通讯这个资源SemaphoreHandle_t xSerialSemaphore;// define two Tasks for DigitalRead & AnalogRead//定义两个任务DigitalRead 和 AnalogReadvoid TaskDigitalRead( void *pvParameters );void TaskAnalogRead( void *pvParameters );void TaskInerrupt0Effect( void *pvParameters );volatile int state = LOW;void blink()  {    state = !state;  } //设置中断void setupInerrupt0()  {    attachInterrupt(0, blink, CHANGE); //attachInterrupt(pin, ISR, mode) //mode:定义中断触发类型,有四种形式://LOW:低电平触发;//CHANGE:电平变化触发;//RISING :上升沿触发(由LOW变为HIGH);//FALLING:下降沿触发(由HIGH变为LOW); //Due板子还支持高电平触发。} // the setup function runs once when you press reset or power the board// 当上电或reset时setup函数只运行一次void setup() {  setupInerrupt0();  // initialize serial communication at 9600 bits per second:  //初始化串口连接波特率  Serial.begin(115200);    while (!Serial) {    ; // wait for serial port to connect. Needed for native USB, on LEONARDO, MICRO, YUN, and other 32u4 based boards.    //等待串口连接。需要LEONARDO, MICRO, YUN, 或其他 32u4板子上的usb接口  }  // Semaphores are useful to stop a Task proceeding, where it should be paused to wait,  //信号量在需要让一个任务进程停一会儿时很有用,它让任务处于暂停等待的状态,  // because it is sharing a resource, such as the Serial port.  //就像串口这样的共享资源  // Semaphores should only be used whilst the scheduler is running, but we can set it up here.  //信号量应该只在调度运行的时候使用,在这里我们可以对它进行设置。  if ( xSerialSemaphore == NULL )  // Check to confirm that the Serial Semaphore has not already been created.//检查确认串口信号没被创建。  {    xSerialSemaphore = xSemaphoreCreateMutex();  // Create a mutex semaphore we will use to manage the Serial Port//创建信号来管理串口    if ( ( xSerialSemaphore ) != NULL )      xSemaphoreGive( ( xSerialSemaphore ) );  // Make the Serial Port available for use, by "Giving" the Semaphore.//调用xSemaphoreGive (“给”信号)使串口处于有效状态(没被占用)  }  // Now set up two Tasks to run independently.  //现在设置两个任务互不影响的运行。 xTaskCreate(    TaskDigitalRead    ,  (const portCHAR *)"DigitalRead"  // A name just for humans//只是人可识别的名称    ,  128  // This stack size can be checked & adjusted by reading the Stack Highwater堆栈大小可以被检查调整,通过读。。。    ,  NULL    ,  2  // Priority, with 3 (configMAX_PRIORITIES - 1) being the highest, and 0 being the lowest.优先级3(configMAX_PRIORITIES - 1)最大0最小    ,  NULL );  xTaskCreate(    TaskAnalogRead    ,  (const portCHAR *) "AnalogRead"    ,  128  // Stack size    ,  NULL    ,  1  // Priority    ,  NULL );  xTaskCreate(    vLEDFlashTask    ,  (const portCHAR *) "LEDFlash"    ,  128  // Stack size    ,  NULL    ,  1  // Priority    ,  NULL );  xTaskCreate(    TaskInerrupt0Effect    ,  (const portCHAR *) "Inerrupt0Effect"    ,  128  // Stack size    ,  NULL    ,  3  // Priority    ,  NULL );  // Now the Task scheduler, which takes over control of scheduling individual Tasks, is automatically started.  //现在,任务调度程序开始自动控制调度单个任务,它将自动启动。  }    void loop(){  // Empty. Things are done in Tasks.  //所有事情都在每个任务里做,这里留空。}/*--------------------------------------------------*//*---------------------- Tasks ---------------------*//*--------------------------------------------------*/// high priority for blinking LED//闪灯任务高优先级const uint8_t LED_PIN = 3;static void vLEDFlashTask(void *pvParameters) {  pinMode(LED_PIN, OUTPUT);    // Flash led every 200 ms.  //led每200ms闪烁一次  for (;;) {    digitalWrite(LED_PIN, HIGH);    // Turn LED on.点亮led    vTaskDelay((50L * configTICK_RATE_HZ) / 1000L);// Sleep for 50 milliseconds.//延时50ms    pinMode(LED_PIN, INPUT);//设置针脚为input    if ( xSemaphoreTake( xSerialSemaphore, ( TickType_t ) 5 ) == pdTRUE )    {            Serial.println(digitalRead(LED_PIN));      xSemaphoreGive( xSerialSemaphore ); // Now free or "Give" the Serial Port for others.//释放串口给其他任务使用    }    pinMode(LED_PIN, OUTPUT);     digitalWrite(LED_PIN, LOW); // Turn LED off.关闭led    vTaskDelay((150L * configTICK_RATE_HZ) / 1000L); // Sleep for 150 milliseconds.延时150ms    pinMode(LED_PIN, INPUT);    if ( xSemaphoreTake( xSerialSemaphore, ( TickType_t ) 5 ) == pdTRUE )    {            Serial.println(digitalRead(LED_PIN));      xSemaphoreGive( xSerialSemaphore ); // Now free or "Give" the Serial Port for others.    }    pinMode(LED_PIN, OUTPUT);     vTaskDelay(100);//1500ms  }}void TaskDigitalRead( void *pvParameters __attribute__((unused)) )  // This is a Task.{  /*    DigitalReadSerial    Reads a digital input on pin 2, prints the result to the serial monitor    This example code is in the public domain.    读取pin2的数字输入,然后用串口打印出来  */  // digital pin 2 has a pushbutton attached to it. Give it a name:  uint8_t pushButton = 2;  // make the pushbutton's pin an input:  pinMode(pushButton, INPUT);  for (;;) // A Task shall never return or exit.  {    // read the input pin:    int buttonState = digitalRead(pushButton);       if ( xSemaphoreTake( xSerialSemaphore, ( TickType_t ) 5 ) == pdTRUE )    {     Serial.print("B:");       Serial.println(buttonState);      xSemaphoreGive( xSerialSemaphore );     }    vTaskDelay(5);    }}void TaskAnalogRead( void *pvParameters __attribute__((unused)) )  // This is a Task.{  for (;;)  {    // read the input on analog pin 012:int x,y,z,sw;    x=analogRead(A0);    y=analogRead(A1);  sw= analogRead(A2);   z= (sw<50) ?0:1;      // See if we can obtain or "Take" the Serial Semaphore.    //看是否能拿到使用串口的信号    // If the semaphore is not available, wait 5 ticks of the Scheduler to see if it becomes free.    //如果信号无效,调度程序等5个tick再看信号是否被释放    if ( xSemaphoreTake( xSerialSemaphore, ( TickType_t ) 5 ) == pdTRUE )    {      // We were able to obtain or "Take" the semaphore and can now access the shared resource.      // We want to have the Serial Port for us alone, as it takes some time to print,      // so we don't want it getting stolen during the middle of a conversion.      // print out the value you read:      //我们能获取到了信号量,就可以访问共享资源。//因为需要一些时间来输出信息,所以我们此时想单独占有串口资源,//所以我们不希望串口资源在这个交互过程中被别的任务抢走。//打印出所读的值:      //Serial.println(sensorValue);  Serial.print("X:");    Serial.print(x);     Serial.print(":Y:");       Serial.print(y);   Serial.print(":sw:");      Serial.print(sw);   Serial.print(":z:");    Serial.println(z);       xSemaphoreGive( xSerialSemaphore ); // Now free or "Give" the Serial Port for others.//释放使用完的串口资源    }    vTaskDelay(10);  // one tick delay (15ms) in between reads for stability//为了稳定读取延时100tick ,1个tick 15ms  }}void TaskInerrupt0Effect( void *pvParameters __attribute__((unused)) )  // This is a Task.{  int pin = 13;  pinMode(pin, OUTPUT);  for (;;)  {   digitalWrite(pin, state);    vTaskDelay(10);  }}