FreeRTOS_初步了解多任务并行

上次实验我们初步了解了RTOS的作用,这次实验我们主要学习RTOS的多任务并行和了解抢占运行的优势。

基于时间片的多任务运行基本机制

时间片:RTOS将CPU时间分成基本的时间片,每一个时间片的默认长度是1ms,也就是SisTick定时器的定时周期,在一个时间片内会有一个任务占用CPU执行任务,在时间片结束时会进行任务调度。

在抢占式运行时系统会按照优先级进行任务调度,同级别任务会轮流执行:即每个时间片结束时会切换同级别的任务,然后将自己的进度存入栈中;不同级别的会先执行高级别任务,高级别任务结束或者处于阻塞、挂起状态时,低级别任务才会执行;在低级别任务执行时要是有高级别任务进入就绪态,会立刻执行高级别的任务。

注意:在FreeRTOS中延时函数要使用vTaskDelay()函数,因为这个函数可以让任务在延时时释放CPU的使用权,然后系统会让其他任务使用CPU。

多任务编程实现

本次实验需要使用开发板上的LED2和LED3,用于在FreeRTOS中创建两个不同的任务,来验证任务的运行机制

CobeMX设置

首先先打开两个LED的GPIO口,将它们配置为输出模式

图 1 LED管脚图

配置完成后再打开时钟配置RTOS,具体配置和上次实验一样,具体可以查看上次实验:

RTOS基本配置

然后我们创建两个任务:

图 2任务的参数设置

点击Add可以增加任务,点击Delete可以删除任务。

上面需要注意Priority这一栏设置的是优先级,这里先配置两个LED为同等优先级。

按照上面参数设置完成后就可以生成代码了。

代码实现部分

本次实验无需对主函数有任何改变,直接进入freertos.c文件中,就可以看到我们上面配置的两个任务:

/* USER CODE BEGIN Header_APPTask_LED2 */

/**

* @brief Function implementing the Task_LED2 thread.

* @param argument: Not used

* @retval None

*/

/* USER CODE END Header_APPTask_LED2 */

void APPTask_LED2(void *argument)

{

  /* USER CODE BEGIN APPTask_LED2 */

//    TickType_t tick = pdMS_TO_TICK(1000);  // 这是FreeRTOS Dalay的前提条件

  /* Infinite loop */

  for(;;)

  {

              osDelay(1);

  }

  /* USER CODE END APPTask_LED2 */

}



/* USER CODE BEGIN Header_APPTask_LED3 */

/**

* @brief Function implementing the Task_LED3 thread.

* @param argument: Not used

* @retval None

*/

/* USER CODE END Header_APPTask_LED3 */

void APPTask_LED3(void *argument)

{

  /* USER CODE BEGIN APPTask_LED3 */

  /* Infinite loop */

  for(;;)

  {

    osDelay(1);

  }

  /* USER CODE END APPTask_LED3 */

}

然后我们只需要在for循环中分别实现两个LED灯不同的闪烁频率即可:

/* USER CODE BEGIN Header_APPTask_LED2 */

/**

* @brief Function implementing the Task_LED2 thread.

* @param argument: Not used

* @retval None

*/

/* USER CODE END Header_APPTask_LED2 */

void APPTask_LED2(void *argument)

{

  /* USER CODE BEGIN APPTask_LED2 */

//    TickType_t tick = pdMS_TO_TICK(1000);  // 这是FreeRTOS Dalay的前提条件

  /* Infinite loop */

  for(;;)

  {

              HAL_GPIO_TogglePin(LED2_GPIO_Port,LED2_Pin);

    vTaskDelay(1000);

  }

  /* USER CODE END APPTask_LED2 */

}



/* USER CODE BEGIN Header_APPTask_LED3 */

/**

* @brief Function implementing the Task_LED3 thread.

* @param argument: Not used

* @retval None

*/

/* USER CODE END Header_APPTask_LED3 */

void APPTask_LED3(void *argument)

{

  /* USER CODE BEGIN APPTask_LED3 */

  /* Infinite loop */

  for(;;)

  {

    HAL_GPIO_TogglePin(LED3_GPIO_Port,LED3_Pin);

    vTaskDelay(500);

  }

  /* USER CODE END APPTask_LED3 */

}

这里配置LED2每1000ms转换一次电平;LED3每500ms转换一次电平。

vTaskDelay()这个函数既有延时的作用又可以使任务挂起,放开CPU使用权。所以在操作系统这里都使用这个延时函数,而不再使用之前的HAL_Delay()。

完成代码的书写后,将其烧录进开发板,可以看到开发板的两个灯都在闪烁,并且频率不同。

接下来我们回到CobeMX配置将之前的FreeRTOS中设置任务的Priority一栏修改成不同优先级的。然后观察现象。发现基本和之前现象一样,这是因为高优先级使用CPU只是改变高低电平那一个时间片,然后就会进入延时函数,将CPU释放。如果将高优先级的延时函数改为HAL_Delay(),可以发现只有高优先级的LED在闪烁,而低优先级的没有CPU的使用权。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值