zoukankan      html  css  js  c++  java
  • FreeRTOS--二元信号量--任务与中断的同步

    一般二元信号量用于任务同步,利用二元信号量对任务与中断同步,中断服务例程中只是释放信号量,相当于把中断应该处理的事情放到了任务里进行处理,如果某个中断处理任务特别紧急,则相应的任务优先级可以设置为最高,以保证此任务随时抢占系统中的其他任务。

     

    使用一个定时器TIM6,每隔3秒释放一次信号量,TASK2设置优先级最高,等待信号量而被阻塞,TASK1每间隔一秒打印信息。

     1  /* Create the thread(s) */
     2   /* definition and creation of vTask1 */
     3   osThreadDef(vTask1, Task1, osPriorityNormal, 0, 128);
     4   vTask1Handle = osThreadCreate(osThread(vTask1), NULL);
     5 
     6   /* definition and creation of vTask2 */
     7   osThreadDef(vTask2, Task2, osPriorityAboveNormal, 0, 128);
     8   vTask2Handle = osThreadCreate(osThread(vTask2), NULL);
     9 
    10 /* Task1 function */
    11 void Task1(void const * argument)
    12 {
    13 
    14   /* USER CODE BEGIN Task1 */
    15   /* Infinite loop */
    16   for(;;)
    17   {
    18       printf("Task1 is running,will be in the ready state!
    ");
    19       osDelay(1000);
    20   }
    21   /* USER CODE END Task1 */
    22 }
    23 
    24 /* Task2 function */
    25 void Task2(void const * argument)
    26 {
    27   /* USER CODE BEGIN Task2 */
    28   /* Infinite loop */
    29   for(;;)
    30   {
    31       if(osOK == osSemaphoreWait(myBinarySemHandle,osWaitForever))
    32           printf("Task2 is running!
    ");
    33   }
    34   /* USER CODE END Task2 */
    35 }
    36 
    37 
    38 void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
    39 {
    40   /* USER CODE BEGIN Callback 0 */
    41 
    42   /* USER CODE END Callback 0 */
    43   if (htim->Instance == TIM1) {
    44     HAL_IncTick();
    45   }
    46   /* USER CODE BEGIN Callback 1 */
    47   if (htim->Instance == TIM6)
    48   {
    49       g_msCount++;
    50       if(3000 == g_msCount)
    51       {
    52           g_msCount = 0;
    53           osSemaphoreRelease(myBinarySemHandle);
    54       }
    55   }
    56   /* USER CODE END Callback 1 */

    在freeRTOS标准API中释放信号量要分为xSemaphoreGiveFromISR和xSemaphoreGive,前者用于中断ISR。在STM32CUbe封装的osSemaphoreRelease内部已经区分了两者,所以只需要调用osSemaphoreRelease即可

     1 osStatus osSemaphoreRelease (osSemaphoreId semaphore_id)
     2 {
     3   osStatus result = osOK;
     4   portBASE_TYPE taskWoken = pdFALSE;
     5   
     6   
     7   if (inHandlerMode()) {
     8     if (xSemaphoreGiveFromISR(semaphore_id, &taskWoken) != pdTRUE) {
     9       return osErrorOS;
    10     }
    11     portEND_SWITCHING_ISR(taskWoken);
    12   }
    13   else {
    14     if (xSemaphoreGive(semaphore_id) != pdTRUE) {
    15       result = osErrorOS;
    16     }
    17   }
    18   
    19   return result;
    20 }

    测试结果如下图所示:

  • 相关阅读:
    Oracle面试题及答案整理
    Oracle问题总结
    Dubbo(四) -- telnet命令
    Dubbo(三) -- 多协议支持与多注册中心
    每天一算法 -- (冒泡排序)
    Dubbo(二) -- Simple Monitor
    数据库优化
    ActiveMQ内存配置和密码设置
    Dubbo源码导入Eclipse遇到的问题
    Dubbo(一) -- 初体验
  • 原文地址:https://www.cnblogs.com/mickey-double/p/11453578.html
Copyright © 2011-2022 走看看