STM32CubeIDE + FreeRTOS analog priority inversion experiment

Simulation experiments were priority inversion FreeRTOS created three tasks with a binary semaphore, the task are a high priority task, the task priority, a low priority task, for generating an analog priority inversion. Low-priority task at the time of acquisition semaphore, was interrupted in priority, the longer the priority task execution time, because of the low priority have not yet released the semaphore, then the high-priority task will not be able to obtain the semaphore to continue running At this time it happened priority inversion.

Create a project RTOS_BinarySem,

HCLK configuration, using an internal oscillator, the frequency of 180MHZ (set according to the board) to

 

 

The SYS timebase source (Timebase Source) to any other than the SysTick timer can, such as:

 Configuration FreeRTOS, use CMSIS_V1, define a binary semaphore.

 

Defined three tasks,

 

    

 

 

 

Ctrl + S generated code

Modify the code,

1, added in main.h

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "stdio.h"
/* USER CODE END Includes */

2, add the mian.c

/* USER CODE BEGIN PFP */
int _write(int file , char *ptr,int len)
{
    int i = 0;
    for(i = 0;i<len;i++)
        ITM_SendChar((*ptr++));
    return len;
}
/* USER CODE END PFP */

...
...
...

/* USER CODE BEGIN 2 */
printf("starting...\n");
/* USER CODE END 2 */

3,在main.c中修改3个任务入口函数的内容

 

 

/* USER CODE BEGIN Header_StartLowPriorityTask */
/**
  * @brief  Function implementing the LowPriority_Tas thread.
  * @param  argument: Not used 
  * @retval None
  */
/* USER CODE END Header_StartLowPriorityTask */
void StartLowPriorityTask(void const * argument)
{
  /* USER CODE BEGIN 5 */
    static uint32_t i;
  /* Infinite loop */
  for(;;)
  {
      printf("LowPriority_Task gets binarySem!\n");
      //获取二值信号量 xSemaphore,没获取到则一直等待
      if(osSemaphoreWait(myBinarySem01Handle, osWaitForever) == osOK)
      {
          printf("LowPriority_Task Runing\n\n");
      }

      for (i=0; i<2000000; i++) { //模拟低优先级任务占用信号量
          osThreadYield();//发起任务调度
      }
      printf("LowPriority_Task Releasing semaphore!\r\n");
      osSemaphoreRelease( myBinarySem01Handle );//给出二值信号量
      osDelay(500);
  }
  /* USER CODE END 5 */ 
}
/* USER CODE BEGIN Header_StartMidPriorityTask */
/**
* @brief Function implementing the MidPriority_Tas thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_StartMidPriorityTask */
void StartMidPriorityTask(void const * argument)
{
  /* USER CODE BEGIN StartMidPriorityTask */
  /* Infinite loop */
  for(;;)
  {
    printf("MidPriority_Task Runing\n");
    osDelay(500);
  }
  /* USER CODE END StartMidPriorityTask */
}
/* USER CODE BEGIN Header_StartHighPriority_Task */
/**
* @brief Function implementing the HighPriority_Ta thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_StartHighPriority_Task */
void StartHighPriority_Task(void const * argument)
{
  /* USER CODE BEGIN StartHighPriority_Task */
  /* Infinite loop */
  for(;;)
  {
      printf("HighPriority_Task gets binarySem!\n");
      //获取二值信号量 xSemaphore,没获取到则一直等待
      if(osSemaphoreWait(myBinarySem01Handle, osWaitForever) == osOK)
      {
          printf("HighPriority_Task Runing\n\n");
      }

      printf("HighPriority_Task Releasing semaphore!\r\n");
      osSemaphoreRelease( myBinarySem01Handle );//给出二值信号量
      osDelay(500);
  }
  /* USER CODE END StartHighPriority_Task */
}

修改完毕后点击 小锤子 构建工程,然后点击Debug,按如下步骤配置ITM调试

 

 

 

 全速运行之前一定要先点击SWV ITM data Console 页面中的红色圆圈

 

现象:

 

 分析:

3个任务,LowPriority_Task,的优先级为 osPriorityLow ,任务先获取二值信号量,获取成功后先不释放,进行任务调度2000000次,然后释放二值信号量。

MidPriority_Task的优先级为 osPriorityNormal ,任务每个500ms输出提示信息MidPriority_Task Runing。

HighPriority_Task的优先级为  osPriorityHigh,任务先获取二值信号量,获取成功后输出提示信息,然后立即释放二值信号量。

程序运行,先执行优先级最高的HighPriority_Task的,然后执行优先级第二高的MidPriority_Task,最后执行优先级最低的LowPriority_Task,在LowPriority_Task中,任务先获取二值信号量,获取成功后先不释放,进行任务调度,调度到优先级最高的HighPriority_Task,HighPriority_Task任务获取二值信号量,因为此时二值信号量被占用,所以会获取失败,进入阻塞态,执行MidPriority_Task,直到LowPriority_Task任务释放二值信号量执行完毕。因此就出现了一个奇怪的现象,优先级最高的HighPriority_Task要等到LowPriority_Task执行完毕后才能执行,而此时优先级较低的MidPriority_Task和LowPriority_Task在正常执行,也就是程序设置的优先级被反转了。

 

Guess you like

Origin www.cnblogs.com/tianxxl/p/12023102.html