freertos学习

freertos的基本框架如下

  

 注意有三点很重要:

  1.任务的资源

    (1)任务优先级:freertos 能够调度的任务优先级在freertosConfig.h中的configMAX_PRIORITIES中定义,每一个任务的优先级都在0~configMAX_PRIORITIES -1 中取值 优先级是数值越小,优先级越小,空闲任务的优先级为0.高优先级的任务必须有延时,低优先级的任务才能获得人物使用权。

      任务优先级在定义时,可参考以下的规则:

         ① IRQ 任务:IRQ 任务是指通过中断服务程序进行触发的任务,此类任务应该设置为所有任务里面优先级最高的。

      ② 高优先级后台任务:比如按键检测,触摸检测,USB 消息处理,串口消息处理等,都可以归为这一类任务。

      ③ 低优先级的时间片调度任务:比如 emWin 的界面显示,LED 数码管的显示等不需要实时执行的都可以归为这一类任务。 实际应用中用户不必拘泥于将这些任务都设置为优先级 1 的同优先级任务,可以设置多个优先级,只需注意这类任务不需要高实时性。

              (2)任务栈的大小:在freertosConfig.h中定义了一个总的堆栈的大小configTOTAL_HEAP_SIZE。如何这个值不够使用的话可以增大这个值。每个任务的栈都是特别要注意的。如果任务出现不运行,很大可能是任务栈不够用了。在freertos中有一个API可以获取在程序运行到现在,栈的接近历史最高水平线的值。我们需要在配置头文件将宏configCHECK_FOR_STACK_OVERFLOW 打开,这宏可定义为两个值1或者2,这两个值有着不同的检测方法,这两个方法不在赘叙。我们还需要调用任务栈溢出的时候,将溢出的任务的名字打印出来,或者进行其他处理。

    2.线程间的通讯

  (1)信号量 :二值信号量、计数信号量、互斥信号量。在多个任务等待同一个信号量来进行同步时,当这些任务优先级相等时,他们依次交叉获取 ,当这些任务优先级不同时,就会只有高优先级的任务会获取。

  (2)队列:注意取队列的速度和发送队列的速度,与他们的等待时长。注意判断返回值

  (3)事件组:事件组相当于一个软件寄存器,每一位都有一个标志。常用于当一个任务同时满足多个条件(与的关系)或者满足多个条件的某一个条件(或的关系)时使用。

   3.所有的API都要注意是不是在中断中调用。

              

 其他:软件定时器:本质上就是队列,需要自己注册定时到后的回调函数。

  1 #include "mytask.h"
  2 #include "task.h"
  3 #include "timers.h"
  4 
  5 
  6 /* TASK HANDLERS */
  7 TaskHandle_t startHandle;
  8 TaskHandle_t ledHandle;
  9 TaskHandle_t printfHandle;
 10 TaskHandle_t writeQueueHandle;
 11 TaskHandle_t SemaphoreBinaryHandle;
 12 TaskHandle_t eventgrupHandle;
 13 TimerHandle_t timer;
 14 /* TASK INPUT VARIABLES */
 15 u32 led_params = 500;
 16 char *databuf = "hello world";
 17 u8 queue_buff[11];
 18 u8 TIMER_ID = 1;
 19 /* thread commutication variables */
 20 xQueueHandle myqueue;
 21 xSemaphoreHandle semphorebinary;
 22 EventGroupHandle_t eventgroup;
 23 /* task status */
 24 portBASE_TYPE status;
 25 
 26 void start_task(void *param)
 27 {
 28     printf("start task
");
 29     
 30     myqueue = xQueueCreate(5,11*sizeof(char));
 31     
 32   vSemaphoreCreateBinary(semphorebinary);
 33     timer = xTimerCreate("timer test",1000/portTICK_PERIOD_MS,pdTRUE,(void*)&TIMER_ID,AutoReloadTimer_Handle_callback);
 34     eventgroup  = xEventGroupCreate(); 
 35     
 36     taskENTER_CRITICAL();
 37     xTaskCreate(led_task,"led task",START_STA_SIZE,(void*)&led_params,LED_TASK_PRTO,ledHandle);
 38     xTaskCreate(printf_task,"printf task",PRINTF_STA_SIZE,(void *)databuf,PRTINF_TASK_PRIO,printfHandle);
 39     xTaskCreate(writeQueue_task,"write queue task",WRITEQUEUE_STA_SIZE,NULL,WRITEQUEUE_TASK_PRIO,writeQueueHandle);
 40     xTaskCreate(SemaphoreBinary_task,"xsemphorebinary task",BINARY_STA_SIZE,NULL,PRTINF_TASK_PRIO,SemaphoreBinaryHandle);
 41     xTaskCreate(eventgrup_task,"eventgrup task",EVENT_STA_SIZE,NULL,EVENT_TASK_PRIO,eventgroup);
 42     taskEXIT_CRITICAL();
 43     //xTimerStart(timer,0);
 44     vTaskDelete(NULL);
 45 }
 46 
 47 void led_task(void*param)
 48 {
 49 
 50     while(1)
 51     {
 52     
 53             HAL_GPIO_WritePin(GPIOJ,GPIO_PIN_13,GPIO_PIN_SET);    //PB1置1
 54           HAL_GPIO_WritePin(GPIOJ,GPIO_PIN_5, GPIO_PIN_RESET);    //PB1置1
 55             vTaskDelay(*(u32*)param);
 56           HAL_GPIO_WritePin(GPIOJ,GPIO_PIN_13,GPIO_PIN_RESET);    //PB1置1
 57           HAL_GPIO_WritePin(GPIOJ,GPIO_PIN_5, GPIO_PIN_SET);    //PB1置1
 58           vTaskDelay(*(u32*)param);
 59             xEventGroupSetBits(eventgroup,0x1);
 60     }
 61 
 62 }
 63 
 64 void printf_task(void*param)
 65 {
 66     while(1)
 67     {
 68       status =  xQueueReceive(myqueue,queue_buff,portMAX_DELAY);
 69         if(status == pdPASS)
 70         {
 71             taskENTER_CRITICAL();
 72             printf("%s
",queue_buff);
 73             
 74             taskEXIT_CRITICAL();
 75         }
 76         else printf("queue null 
");
 77         vTaskDelay(1000);
 78     }
 79 }
 80 
 81 void writeQueue_task(void *param)
 82 {
 83     u8 i =0;
 84     while(1)
 85     {
 86         status = xQueueSend(myqueue,queue_buff,0);
 87         if(status!= pdPASS) printf("queue full
");
 88         i++;
 89         if(!(i%10))
 90         {
 91 //            xSemaphoreTake(semphorebinary,portMAX_DELAY);
 92 //                printf("get once baniry
");
 93                 xEventGroupSetBits(eventgroup,0x4);
 94         }
 95         vTaskDelay(1000);
 96     }
 97 }
 98 
 99 void SemaphoreBinary_task(void*param)
100 {
101      u8 i =0;
102         while(1)
103         {
104             i++;
105             if(!(i%5))
106             {
107                 xSemaphoreGive(semphorebinary);
108                 
109             }                
110             vTaskDelay(1000);
111             xEventGroupSetBits(eventgroup,0x2);
112         }
113 
114 
115 }
116 
117 void eventgrup_task(void*param)
118 {
119     while(1)
120     {
121             xEventGroupWaitBits(eventgroup,0x7,pdTRUE,pdFALSE,portMAX_DELAY);
122             printf(" event groups test!!! 
");
123   }
124 
125 }
126 
127 void vApplicationStackOverflowHook( TaskHandle_t xTask, char *pcTaskName )
128 {
129     printf("task overflow name :%s
",pcTaskName);
130     
131 }
132 void AutoReloadTimer_Handle_callback(TimerHandle_t xTimer)
133 {
134     static u32 count  = 0;
135     count++;
136     if(count>20)
137     {
138     //    xTimerReset(timer,0);
139         xTimerStop(timer,0);
140     }
141     printf("timer count: %d
",count);
142 }
143 
144 
145 void print_high_stack_mark_value(void)
146 {
147     if(STACK_DEBUG)
148     {
149         u8 num =0;
150         num = uxTaskGetStackHighWaterMark(ledHandle);
151         printf("%s  : %d
",pcTaskGetTaskName(ledHandle),num);    
152         num = uxTaskGetStackHighWaterMark(ledHandle);
153         printf("%s  : %d
",pcTaskGetTaskName(ledHandle),num);    
154         num = uxTaskGetStackHighWaterMark(ledHandle);
155         printf("%s  : %d
",pcTaskGetTaskName(ledHandle),num);    
156     
157     }
158     
159 }
freertos test code
原文地址:https://www.cnblogs.com/st-home/p/10930412.html