单片机学习小组
直播中

邹俩珍

7年用户 1014经验值
私信 关注

如何利用FreeRTOS程序完成多任务功能?

如何利用FreeRTOS程序完成多任务功能?

回帖(1)

汪海源

2022-1-18 10:17:14
  FreeRTOS是一个迷你的实时操作系统内核.。作为一个轻量级的操作系统,功能包括:.任务管理、时间管理、信号量、消息队列、内存管理、记录功能、软件定时器、协程等,可基本满足较小系统的需要。
由于RTOS需占用一定的系统资源(尤其是RAM资源),只有μC/OS-II、embOS、salvo、FreeRTOS等少数实时操作系统能在小RAM单片机上运行。相对μC/OS-II、embOS等商业操作系统,FreeRTOS操作系统是.完全免费的操作系统,具有源码公开、可移植、可裁减、调度策略灵活的特点,可以方便地移植到各种单片机上运行,在嵌入式领域中,嵌入式实时操作系统正得到越来越广泛的应用。采用嵌入式实时操作系统(RTOS)可以更合理、更有效地利用CPU的资源,简化应用软件的设计,缩短系统开发时间,更好地保证系统的实时性和可靠性。
一、利用FreeRTOS程序完成多任务功能

本过程主要执行完成三个周期性task

  

  • 每间隔500ms闪烁(变化)一次LED;
  • 每间隔2000ms,向串口发送一次指令数据“helloworld!";
  • 每间隔5000ms,从AHT20采集一次温湿度数据(不考虑硬件情况,仅写出整个多任务框架模拟代码)

1. 创建FreeRTOS内核环境



  • 创建FreeRTOS工程
    这里创建工程需要用到我们的KEIL5,会发现利用KEIL建立FreeRTOS时,需要确保自己的keil中有Cortex-M3(Cortex-M4 或 Cortex-M7)内核的处理器,调试方式选择软件仿真。
    注:没有上面提到的内核没有关系,这里有现成的工程模板,具体的模板可以参考野火的产品,它的资源和代码都是开源的,本例介绍的就是直接使用的模板
    野火相关资源,可以根据自身所用的开发板类型进行选择。
  • FreeRTOS移植进入开发板
    再将FreeRTOS移植进入开发板中(本例选择的STM32开发板),其实主要的思想就是需要换一下启动文件,和添加BSP驱动就行了。

2. FreeRTOS程序实现



  • 主程序代码


/* FreeRTOS头文件 */
#include "FreeRTOS.h"
#include "task.h"
/* 开发板硬件BSP头文件 */
#include "bsp_led.h"
#include "bsp_usart.h"


/****************************任务句柄********************************/
/* 创建任务句柄 */
static TaskHandle_t AppTaskCreate_Handle = NULL;
/* LED1任务句柄 */
static TaskHandle_t LED1_Task_Handle = NULL;
/* LED2任务句柄 */
static TaskHandle_t AHT20_Task_Handle = NULL;


static TaskHandle_t Usart_Task_Handle = NULL;


/*
*************************************************************************
*                             函数声明
*************************************************************************
*/
static void AppTaskCreate(void);/* 用于创建多任务 */


static void LED1_Task(void* pvParameters);/* LED1_Task 任务实现*/
static void AHT20_Task(void* pvParameters);/* AHT20_Task任务实现 */
static void Usart_Task(void* pvParameters);/* Usart_Task任务实现*/
       
static void BSP_Init(void);/* 用于初始化板载资源 */


int main(void)
{       
  BaseType_t xReturn = pdPASS;/* 定义一个创建信息返回值,默认为pdPASS */


  /* 开发硬件初始化 */
  BSP_Init();
       
  //printf("FreeRTOS-动态创建多任务!rn");




   /* 创建AppTaskCreate任务 */
  xReturn = xTaskCreate((TaskFunction_t )AppTaskCreate,
                        (const char*    )"AppTaskCreate",
                        (uint16_t       )512,
                        (void*          )NULL,
                        (UBaseType_t    )1,
                        (TaskHandle_t*  )&AppTaskCreate_Handle);
  /*启动任务调度*/           
  if(pdPASS == xReturn)
    vTaskStartScheduler();   
  else
    return -1;  
  
  while(1);   
  }
static void AppTaskCreate(void)
{
  BaseType_t xReturn = pdPASS;
  taskENTER_CRITICAL();           


  /* 创建LED_TASK任务 */
  xReturn = xTaskCreate((TaskFunction_t )LED1_Task,
                        (const char*    )"LED1_Task",
                        (uint16_t       )512,   
                        (void*          )NULL,       
                        (UBaseType_t    )2,            
                        (TaskHandle_t*  )&LED1_Task_Handle);
  if(pdPASS == xReturn);
        /* 创建AHT20_TASK */
  xReturn = xTaskCreate((TaskFunction_t )AHT20_Task,
                        (const char*    )"AHT20_Task",
                        (uint16_t       )512,   
                        (void*          )NULL,       
                        (UBaseType_t    )3,            
                        (TaskHandle_t*  )&AHT20_Task_Handle);
  if(pdPASS == xReturn);
        /* 创建USART_TASK */
  xReturn = xTaskCreate((TaskFunction_t )Usart_Task,
                        (const char*    )"Usart",
                        (uint16_t       )512,   
                        (void*          )NULL,       
                        (UBaseType_t    )4,            
                        (TaskHandle_t*  )&Usart_Task_Handle);
  if(pdPASS == xReturn);
  vTaskDelete(AppTaskCreate_Handle);
  taskEXIT_CRITICAL();           
}
static void LED1_Task(void* parameter)
{       
    while (1)
    {
        LED1_ON;
        vTaskDelay(500);   
         LED1_OFF;
        vTaskDelay(500);            
    }
}


static void Usart_Task(void* parameter)
{       
    while (1)
    {   vTaskDelay(2000);
        Usart_SendString( DEBUG_USARTx," helloworld!nn");   
    }       
}


static void AHT20_Task(void* parameter)
{       
    while (1)
    {
        LED2_ON;
        vTaskDelay(5000);  
        LED2_OFF;     
        vTaskDelay(5000);             
    }       
}
static void BSP_Init(void)
{
        NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4 );
        LED_GPIO_Config();
        USART_Config();               
}
从代码中我们可以看到,我们创建了三个任务LED灯闪烁,字符串的发送,以及AHT20模块的实现。其中我们利用之前的模板进行修改,添加了一个用于发送的库。

二、运用串口助手进行窗口调试



  • 将程序烧录到开发板中
    首先需要进行相关的串口配置,这一部分已经在上一个博客中介绍了如何配置。
    然后则需要利用串口将程序下载到开发板内下载成功后就进行下一步。

  • 运行串口助手进行窗口调试
    打开串口助手,配置端口


    如图,我们已经看到通过窗口调试,FreeRTOS的三个任务已经完成

总结

本次学习了FreeRTOS多程序的编写实现,在整个过程中主要是代码需要进行完善,以及一些库的添加还有启动文件的变换,这次学习了解了FreeRTO的用法,很不错。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分