基于STM32F407的FreeRTOS学习笔记(2)

描述

上一期配置完FreeRTOS的环境后,这一期记录自己关于任务创建的学习过程。

C语言

官方的API手册中有这些函数,xTaskCreate和xTaskCreateStatic分别是利用动态方法和静态方法创建任务。(动态和静态的区别之后再研究)vTaskDelete是删除任务,因为freeRTOS的任务内存空间存储在堆区,所以很像C语言的动态内存分配,任务使用和结束我们都应该创建和删除这些任务防止占用过多空间。

xTaskCreate的函数模型如下,参数内容总共有六项:任务函数的函数指针,任务函数的名称,任务函数所需堆栈空间,任务函数的类型,任务函数的优先级,以及任务函数的函数句柄

C语言

vTaskDelete的函数模型如下,参数内容为函数句柄,如果为NULL则删除该任务本身。

C语言

因此我们创建任务的步骤是:首先定义一个启动任务,该任务是为了启动我们的真正任务,因此在调用完一遍后要用vTaskDelete 中输入NULL删除启动函数本身。

C语言

任务函数编写

/*
LED1翻转
*/
void LED_TOG(void * pvParameters)//参数为 void * pvParameters
{
  while(1)
  {
    printf("LED_TOG runningrn");//串口打印运行信息
    HAL_GPIO_TogglePin(GPIOF,GPIO_PIN_10);//LED1翻转
    vTaskDelay(500);//延迟500ms
  }
}

要注意的是vTaskDelay是FreeRTOS用来延时的函数。

C语言

之后我们要创建任务函数的启动函数

TaskHandle_t Start_LED_Handler;


void Start_LED(void * pvParameters)
{
  xTaskCreate((TaskFunction_t        )LED_TOG,//任务函数
              (char *                )"LED_TOG",//任务名称
              (configSTACK_DEPTH_TYPE) 128,//堆栈空间128Byte
              (void*                 ) NULL,//无返回
              (UBaseType_t          ) 1,//优先级1
              (TaskHandle_t *        )LED_TOG_Handler);//任务函数句柄
  vTaskDelete(NULL);
}

我们创建启动任务的函数,将 任务函数的函数指针,任务函数的名称,任务函数所需堆栈空间,任务函数的类型,任务函数的优先级,以及任务函数的函数句柄 ,填入vTaskCreate函数中,其中每个参数都使用了强制类型转换防止出现错误。

同样的方法,我们创建启动 启动函数的任务(有点绕口因为启动函数本身是一个任务)

void FreeRTOS_Init()
{
  xTaskCreate((TaskFunction_t        )Start_LED,
              (char *                )"Start_LED",
              (configSTACK_DEPTH_TYPE) 128,
              (void*                 ) NULL,
              (UBaseType_t          ) 0,
              (TaskHandle_t *        )Start_LED_Handler);
  vTaskStartScheduler();//启动运行函数
}

这样子我们在主函数中添加刚刚定义的启动启动函数

int main(void)
{
  /* USER CODE BEGIN 1 */


  /* USER CODE END 1 */


  /* MCU Configuration--------------------------------------------------------*/


  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();


  /* USER CODE BEGIN Init */
  KEY_Init();
  /* USER CODE END Init */


  /* Configure the system clock */
  SystemClock_Config();


  /* USER CODE BEGIN SysInit */


  /* USER CODE END SysInit */


  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
  FreeRTOS_Init();
  /* USER CODE END 2 */


  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */


    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

我们的代码就可以正常运行啦!

我们在用上述的方法实现两个灯一起翻转

还是先编辑任务函数如下,并且定义其相关句柄

TaskHandle_t LED_TOG2_Handler;
void LED_TOG2(void * pvParameters)//参数为 void * pvParameters
{
  while(1)
  {
    printf("LED_TOG runningrn");//串口打印运行信息
    HAL_GPIO_TogglePin(GPIOF,GPIO_PIN_9);//LED0翻转
    vTaskDelay(500);//延迟500ms
  }
}

在任务启动函数中加入我们新建的任务。

void Start_LED(void * pvParameters)
{
  xTaskCreate((TaskFunction_t        )LED_TOG,//任务函数
              (char *                )"LED_TOG",//任务名称
              (configSTACK_DEPTH_TYPE) 128,//堆栈空间128Byte
              (void*                 ) NULL,//无返回
              (UBaseType_t          ) 1,//优先级1
              (TaskHandle_t *        )LED_TOG_Handler);//任务函数句柄

   xTaskCreate((TaskFunction_t        )LED_TOG2,//任务函数
              (char *                )"LED_TOG2",//任务名称
              (configSTACK_DEPTH_TYPE) 128,//堆栈空间128Byte
              (void*                 ) NULL,//无返回
              (UBaseType_t          ) 2,//优先级2
              (TaskHandle_t *        )LED_TOG2_Handler);//任务函数句柄

  vTaskDelete(NULL);
}

再次运行我们的代码。

麦克阿瑟将军曾说过:点灯对于嵌入式来说,就像Hello World对于程序员一样重要。我们不能不去点灯,就像西方不能失去耶路撒冷。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分