<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      FreeRTOS學習

      1、動態創建任務

      #include "main.h"
      #include "driver_led.h"
      #include "driver_key.h"
      void FreeRTOS_Start(void);
      int main(void)
      {
          // 初始化HAL庫函數必須要調用此函數
          HAL_Init();
          // 系統時鐘即AHB/APB時鐘配置
          SystemClock_Config();
      
          // 初始化LED
          LedGpioInit();
          KeyInit();
          FreeRTOS_Start();
      }
      TaskHandle_t start_task_handle;
      TaskHandle_t task1_handle;
      TaskHandle_t task2_handle;
      TaskHandle_t task3_handle;
      
      void StartTask(void);
      void Task1(void);
      void Task2(void);
      void Task3(void);
      void FreeRTOS_Start(void)
      {
          xTaskCreate(
              (TaskFunction_t)    StartTask,              //任務函數的地址          
              (char *)            "StartTask",            //任務函數的名稱
              (uint16_t)          128,                    //任務函數??臻g大小
              (void *)            NULL,                   //任務函數的參數
              (UBaseType_t)       1,                      //任務函數的優先級
              (TaskHandle_t*)     &start_task_handle      //任務函數的句柄
          );
      
          //啟動調度器
          vTaskStartScheduler();
      
      }
      
      void StartTask(void)
      {
          taskENTER_CRITICAL();
          xTaskCreate(
              (TaskFunction_t)    Task1,
              (char *)            "Task1",
              (uint16_t)          128,
              (void *)            NULL,
              (UBaseType_t)       2,
              (TaskHandle_t*)     &task1_handle
          );
          xTaskCreate(
              (TaskFunction_t)    Task2,
              (char *)            "Task2",
              (uint16_t)          128,
              (void *)            NULL,
              (UBaseType_t)       3,
              (TaskHandle_t*)     &task2_handle
          );
          xTaskCreate(
              (TaskFunction_t)    Task3,
              (char *)            "Task3",
              (uint16_t)          128,
              (void *)            NULL,
              (UBaseType_t)       4,
              (TaskHandle_t*)     &task3_handle
          );
          vTaskDelete(NULL);
          taskEXIT_CRITICAL();
      }
      
      void Task1(void)
      {
          while(1)
          {
              LED_TOGGLE(LED0_GPIO_PORT,LED0_GPIO_PIN);
              vTaskDelay(500);
          }
      }
      void Task2(void)
      {
          while(1)
          {
              LED_TOGGLE(LED1_GPIO_PORT,LED1_GPIO_PIN);
              vTaskDelay(500);
          }
      }
      void Task3(void)
      {
          while(1)
          {
              if(KeyScan() == 0)
              {
                  if(task1_handle != NULL) vTaskDelete(task1_handle);
                  task1_handle = NULL;
              }
          vTaskDelay(500);
          }
      }
      

      2、靜態創建任務

      #include "main.h"
      #include "driver_led.h"
      #include "driver_key.h"
      
      /* 啟動任務的配置 */
      #define START_TASK_STACK 128
      #define START_TASK_PRIORITY 1
      TaskHandle_t start_task_handle;
      StackType_t start_task_stack[START_TASK_STACK]; // 靜態任務的任務棧,以數組形式存儲
      StaticTask_t start_task_tcb;                    // 靜態任務的TCB結構體類型
      void start_task(void);
      
      /* 任務1的配置 */
      #define TASK1_STACK 128
      #define TASK1_PRIORITY 2
      TaskHandle_t task1_handle;
      StackType_t task1_stack[TASK1_STACK]; // 靜態任務的任務棧,以數組形式存儲
      StaticTask_t task1_tcb;               // 靜態任務的TCB結構體類型
      void task1(void);
      
      /* 任務2的配置 */
      #define TASK2_STACK 128
      #define TASK2_PRIORITY 3
      TaskHandle_t task2_handle;
      StackType_t task2_stack[TASK2_STACK]; // 靜態任務的任務棧,以數組形式存儲
      StaticTask_t task2_tcb;               // 靜態任務的TCB結構體類型
      void task2(void);
      
      /* 任務3的配置 */
      #define TASK3_STACK 128
      #define TASK3_PRIORITY 4
      TaskHandle_t task3_handle;
      StackType_t task3_stack[TASK3_STACK]; // 靜態任務的任務棧,以數組形式存儲
      StaticTask_t task3_tcb;               // 靜態任務的TCB結構體類型
      void task3(void);
      
      /* ======================= 靜態創建方式,需要手動指定2個特殊任務的資源=============================== */
      /* 空閑任務的配置 */
      StackType_t idle_task_stack[configMINIMAL_STACK_SIZE]; // 靜態任務的任務棧,以數組形式存儲
      StaticTask_t idle_task_tcb;                            // 靜態任務的TCB結構體類型
      
      /* 軟件定時器任務的配置 */
      StackType_t timer_task_stack[configTIMER_TASK_STACK_DEPTH]; // 靜態任務的任務棧,以數組形式存儲
      StaticTask_t timer_task_tcb;                            // 靜態任務的TCB結構體類型
      
      /* 分配空閑任務的資源 */
      void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer,
                                         StackType_t **ppxIdleTaskStackBuffer,
                                         uint32_t *pulIdleTaskStackSize)
      {
          *ppxIdleTaskTCBBuffer = &idle_task_tcb;
          *ppxIdleTaskStackBuffer = idle_task_stack;
          *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
      }
      
      /* 分配軟件定時器任務的資源 */
      void vApplicationGetTimerTaskMemory(StaticTask_t **ppxTimerTaskTCBBuffer,
                                          StackType_t **ppxTimerTaskStackBuffer,
                                          uint32_t *pulTimerTaskStackSize)
      {
          *ppxTimerTaskTCBBuffer = &timer_task_tcb;
          *ppxTimerTaskStackBuffer = timer_task_stack;
          *pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
      }
      
      /**
       * @description: 啟動FreeRTOS
       * @return {*}
       */
      void FreeRTOS_Start(void)
      {
          /* 1.創建一個啟動任務 */
          start_task_handle = xTaskCreateStatic(
              (TaskFunction_t)start_task,       // 任務函數的地址
              (char *)"start_task",             // 任務名字符串
              (uint32_t)START_TASK_STACK,       // 任務棧大小,默認最小128,單位4字節
              (void *)NULL,                     // 傳遞給任務的參數
              (UBaseType_t)START_TASK_PRIORITY, // 任務的優先級
              (StackType_t *)start_task_stack,  // 我們創建的任務棧(數組存儲)的地址
              (StaticTask_t *)&start_task_tcb   // 我們創建的tcb的地址
          );
      
          /* 2.啟動調度器:會自動創建空閑任務和軟件定時器(如果開啟),
             靜態創建的方式需要去實現2個分配資源的接口函數 */
          vTaskStartScheduler();
      }
      
      int main(void)
      {
          // 初始化HAL庫函數必須要調用此函數
          HAL_Init();
          // 系統時鐘即AHB/APB時鐘配置
          SystemClock_Config();
      
          // 初始化LED
          LedGpioInit();
          KeyInit();
          FreeRTOS_Start();
      }
      
      /**
       * @description: 啟動任務:用來創建其他Task
       * @param {void} *pvParameters
       * @return {*}
       */
      void start_task(void)
      {
          /* 進入臨界區:保護臨界區里的代碼不會被打斷 */
          taskENTER_CRITICAL();
      
          /* 使用靜態創建3個任務 */
          task1_handle = xTaskCreateStatic(
              (TaskFunction_t)task1,
              (char *)"task1",
              (configSTACK_DEPTH_TYPE)TASK1_STACK,
              (void *)NULL,
              (UBaseType_t)TASK1_PRIORITY,
              (StackType_t *)task1_stack, // 我們創建的任務棧(數組存儲)的地址
              (StaticTask_t *)&task1_tcb  // 我們創建的tcb的地址
          );
      
          task2_handle = xTaskCreateStatic(
              (TaskFunction_t)task2,
              (char *)"task2",
              (configSTACK_DEPTH_TYPE)TASK2_STACK,
              (void *)NULL,
              (UBaseType_t)TASK2_PRIORITY,
              (StackType_t *)task2_stack, // 我們創建的任務棧(數組存儲)的地址
              (StaticTask_t *)&task2_tcb  // 我們創建的tcb的地址
          );
      
          task3_handle = xTaskCreateStatic(
              (TaskFunction_t)task3,
              (char *)"task3",
              (configSTACK_DEPTH_TYPE)TASK3_STACK,
              (void *)NULL,
              (UBaseType_t)TASK3_PRIORITY,
              (StackType_t *)task3_stack, // 我們創建的任務棧(數組存儲)的地址
              (StaticTask_t *)&task3_tcb  // 我們創建的tcb的地址
          );
      
          /* 啟動任務只需要執行一次即可,用完就刪除自己 */
          vTaskDelete(NULL);
      
          /* 退出臨界區 */
          taskEXIT_CRITICAL();
      }
      
      void task1(void)
      {
          while(1)
          {
              LED_TOGGLE(LED0_GPIO_PORT,LED0_GPIO_PIN);
              vTaskDelay(500);
          }
      }
      void task2(void)
      {
          while(1)
          {
              LED_TOGGLE(LED1_GPIO_PORT,LED1_GPIO_PIN);
              vTaskDelay(500);
          }
      }
      void task3(void)
      {
          while(1)
          {
              if(KeyScan() == 0)
              {
                  if(task1_handle != NULL) vTaskDelete(task1_handle);
                  task1_handle = NULL;
              }
          vTaskDelay(500);
          }
      }
      

      3、任務掛起與回復

      3.1、任務掛起

      /*傳入參數為任務句柄,若傳入NULL,則代表掛起當前任務*/
      vTaskSuspend(task1_handle);
      

      3.2 任務恢復

      /* 任務恢復,傳入參數為任務句柄*/
      vTaskResume(task1_handle);
      

      3.3 掛起任務調度器

      僅執行當前任務

      vTaskSuspendAll();
      

      3.4 恢復任務調度器

      xTaskResumeAll();
      

      3.5 打印任務狀態

      /* 傳入參數為字符串 */
      vTaskList(str);
      

      3.6 中斷管理

      /*執行此函數后,在中斷優先級閾值以下的中斷將被屏蔽*/
      portDISABLE_INTERRUPTS();
      
      /* 使能中斷 */
      portENABLE_INTERRUPTS();
      

      5、時間函數

      /* 相對延時,每隔n個時間片執行一次代碼,不能保證代碼執行時間相同 */
      vtaskDelay(n);
      /* 絕對延時,代碼整體執行時間為n個時間片,保證代碼執行周期*/
      xTaskDelayUntil();
      

      6、任務之間通過隊列傳輸數據

      #include "main.h"
      #include "driver_led.h"
      #include "driver_key.h"
      #include "driver_uart.h"
      
      void StartTask(void);
      void Task1(void);
      void Task2(void);
      void FreeRTOS_Start(void);
      
      
      int main(void)
      {
          // 初始化HAL庫函數必須要調用此函數
          HAL_Init();
          // 系統時鐘即AHB/APB時鐘配置
          SystemClock_Config();
      
          // 初始化LED
          LedInit();
          KeyInit();
          UartInit(115200);
          FreeRTOS_Start();
      
          while(1)
          {
              HAL_Delay(1000);
              UartSendData("hello\r\n");
              LED_TOGGLE(LED0_GPIO_PORT,LED0_GPIO_PIN);
          }
      }
      /* 任務句柄,用以保存不同任務的配置 */
      TaskHandle_t start_task_handle;
      TaskHandle_t task1_handle;
      TaskHandle_t task2_handle;
      
      /*
       * 函數作用:常規寫法,起始任務,用以創建其他任務
       * 輸入參數:無
       * 返回值:無
       * 作者:LSK
      */
      void FreeRTOS_Start(void)
      {
          xTaskCreate(
              (TaskFunction_t)    StartTask,              //任務函數的地址          
              (char *)            "StartTask",            //任務函數的名稱
              (uint16_t)          128,                    //任務函數??臻g大小
              (void *)            NULL,                   //任務函數的參數
              (UBaseType_t)       1,                      //任務函數的優先級
              (TaskHandle_t*)     &start_task_handle      //任務函數的句柄
          );
      
          /* 啟用調度器,負責任務切換*/
          vTaskStartScheduler();
      
      }
      
      /* 隊列句柄*/
      QueueHandle_t handle1;
      
      void StartTask(void)
      {
          /* 創建一個隊列 */
          handle1 = xQueueCreate(1,sizeof(char *));
          if(handle1 == NULL) UartSendData("task err");
      
          /* 進入臨界保護區,保證在臨界區的代碼不會被打斷*/
          taskENTER_CRITICAL();
          xTaskCreate(
              (TaskFunction_t)    Task1,
              (char *)            "Task1",
              (uint16_t)          128,
              (void *)            NULL,
              (UBaseType_t)       2,
              (TaskHandle_t*)     &task1_handle
          );
          xTaskCreate(
              (TaskFunction_t)    Task2,
              (char *)            "Task2",
              (uint16_t)          128,
              (void *)            NULL,
              (UBaseType_t)       4,
              (TaskHandle_t*)     &task2_handle
          );
          vTaskDelete(NULL);  //刪除任務本身
          /* 退出臨界保護區*/
          taskEXIT_CRITICAL();
      }
      /*
       * 函數作用:負責創建一個字符串,通過隊列發送出去
       * 輸入參數:無
       * 返回值:無
       * 作者:LSK
      */
      void Task1(void)
      {
          char* str = "tehsjncncncncc";
          while(1)
          {
              if(KeyScan() == KEY0)
              {
                  /* 往隊列插入一個值,并設置阻塞等待*/
                  xQueueSend(handle1,&str,portMAX_DELAY);
                  UartSendData("Send Pass\r\n");
              }
              vTaskDelay(20);
          }
      }
      
      /*
       * 函數作用:接收數據任務
       * 輸入參數:無
       * 返回值:無
       * 作者:LSK
      */
      void Task2(void)
      {
          char *buffer;
          BaseType_t res;
          while(1)
          {
              /* 接收隊列的任務,并進入阻塞等待*/
              res = xQueueReceive(handle1,&buffer,portMAX_DELAY);
              if(res == pdPASS) 
              {
                  UartSendData("buffer:\r\n");
                  UartSendData(buffer);
                  UartSendData("\r\n");
              }
              vTaskDelay(500);
          }
      }
      

      7、二進制信號量釋放與接收

      7.1 二進制信號量

      #include "main.h"
      
      void StartTask(void);
      void Task1(void);
      void Task2(void);
      void FreeRTOS_Start(void);
      
      int main(void)
      {
          // 初始化HAL庫函數必須要調用此函數
          HAL_Init();
          // 系統時鐘即AHB/APB時鐘配置
          SystemClock_Config();
      
          // 初始化LED
          LedInit();
          KeyInit();
          UartInit(115200);
          FreeRTOS_Start();
      
          while(1)
          {
              HAL_Delay(1000);
              UartSendData("hello\r\n");
              LED_TOGGLE(LED0_GPIO_PORT,LED0_GPIO_PIN);
          }
      }
      /* 任務句柄,用以保存不同任務的配置 */
      TaskHandle_t start_task_handle;
      TaskHandle_t task1_handle;
      TaskHandle_t task2_handle;
      
      /*
       * 函數作用:常規寫法,起始任務,用以創建其他任務
       * 輸入參數:無
       * 返回值:無
       * 作者:LSK
      */
      void FreeRTOS_Start(void)
      {
          xTaskCreate(
              (TaskFunction_t)    StartTask,              //任務函數的地址          
              (char *)            "StartTask",            //任務函數的名稱
              (uint16_t)          128,                    //任務函數??臻g大小
              (void *)            NULL,                   //任務函數的參數
              (UBaseType_t)       1,                      //任務函數的優先級
              (TaskHandle_t*)     &start_task_handle      //任務函數的句柄
          );
      
          /* 啟用調度器,負責任務切換*/
          vTaskStartScheduler();
      
      }
      
      /* 隊列句柄*/
      QueueHandle_t handle1;
      SemaphoreHandle_t semaphore_handle;
      
      void StartTask(void)
      {
          /* 創建一個信號量 */
          vSemaphoreCreateBinary(semaphore_handle);
          if(semaphore_handle != NULL) UartSendData("Create success!\r\n");
      
          /* 創建一個隊列 */
          handle1 = xQueueCreate(1,sizeof(char *));
          if(handle1 == NULL) UartSendData("task err");
      
          /* 進入臨界保護區,保證在臨界區的代碼不會被打斷*/
          taskENTER_CRITICAL();
          xTaskCreate(
              (TaskFunction_t)    Task1,
              (char *)            "Task1",
              (uint16_t)          128,
              (void *)            NULL,
              (UBaseType_t)       2,
              (TaskHandle_t*)     &task1_handle
          );
          xTaskCreate(
              (TaskFunction_t)    Task2,
              (char *)            "Task2",
              (uint16_t)          128,
              (void *)            NULL,
              (UBaseType_t)       4,
              (TaskHandle_t*)     &task2_handle
          );
          vTaskDelete(NULL);  //刪除任務本身
          /* 退出臨界保護區*/
          taskEXIT_CRITICAL();
      }
      /*
       * 函數作用:釋放信號量
       * 輸入參數:無
       * 返回值:無
       * 作者:LSK
      */
      void Task1(void)
      {
          BaseType_t res;   
          while(1)
          {
              if(KeyScan() == KEY0)
              {
                  /* 釋放信號量 */
                  res = xSemaphoreGive(semaphore_handle);
                  if (res == pdPASS) UartSendData("Send Pass\r\n");
              }
              vTaskDelay(20);
          }
      }
      
      /*
       * 函數作用:接收信號量
       * 輸入參數:無
       * 返回值:無
       * 作者:LSK
      */
      void Task2(void)
      {
          BaseType_t res;
          while(1)
          {
              /* 接收信號量是否釋放 */
              res = xSemaphoreTake(semaphore_handle, portMAX_DELAY);
              if(res == pdPASS) 
              {
                  UartSendData("Take success!\r\n");
                  UartSendData("\r\n");
              }
              vTaskDelay(500);
          }
      }
      
      

      7.2 互斥二進制信號量

      它會將阻塞高優先級的低優先級提升,從而保證高優先級不會被低優先級阻塞。

      8、計數信號量釋放與接收

      #include "main.h"
      
      void StartTask(void);
      void Task1(void);
      void Task2(void);
      void FreeRTOS_Start(void);
      
      int main(void)
      {
          // 初始化HAL庫函數必須要調用此函數
          HAL_Init();
          // 系統時鐘即AHB/APB時鐘配置
          SystemClock_Config();
      
          // 初始化LED
          LedInit();
          KeyInit();
          UartInit(115200);
          FreeRTOS_Start();
      
          while(1)
          {
              HAL_Delay(1000);
              UartSendData("hello\r\n");
              LED_TOGGLE(LED0_GPIO_PORT,LED0_GPIO_PIN);
          }
      }
      /* 任務句柄,用以保存不同任務的配置 */
      TaskHandle_t start_task_handle;
      TaskHandle_t task1_handle;
      TaskHandle_t task2_handle;
      
      /*
       * 函數作用:常規寫法,起始任務,用以創建其他任務
       * 輸入參數:無
       * 返回值:無
       * 作者:LSK
      */
      void FreeRTOS_Start(void)
      {
          xTaskCreate(
              (TaskFunction_t)    StartTask,              //任務函數的地址          
              (char *)            "StartTask",            //任務函數的名稱
              (uint16_t)          128,                    //任務函數??臻g大小
              (void *)            NULL,                   //任務函數的參數
              (UBaseType_t)       1,                      //任務函數的優先級
              (TaskHandle_t*)     &start_task_handle      //任務函數的句柄
          );
      
          /* 啟用調度器,負責任務切換*/
          vTaskStartScheduler();
      
      }
      
      char str[100];
      /* 隊列句柄*/
      QueueHandle_t handle1;
      
      void StartTask(void)
      {
          UBaseType_t Count = 0;
          /* 創建一個信號量 */
          handle1 = xSemaphoreCreateCounting(100, 0);
          if(!(handle1 == NULL))
          {
              UartSendData("Create success!\r\n");
              Count = uxSemaphoreGetCount(handle1);
              sprintf(str, "the init count: %d", Count);
              UartSendData(str);
          } 
      
          /* 進入臨界保護區,保證在臨界區的代碼不會被打斷*/
          taskENTER_CRITICAL();
          xTaskCreate(
              (TaskFunction_t)    Task1,
              (char *)            "Task1",
              (uint16_t)          128,
              (void *)            NULL,
              (UBaseType_t)       3,
              (TaskHandle_t*)     &task1_handle
          );
          xTaskCreate(
              (TaskFunction_t)    Task2,
              (char *)            "Task2",
              (uint16_t)          128,
              (void *)            NULL,
              (UBaseType_t)       4,
              (TaskHandle_t*)     &task2_handle
          );
          vTaskDelete(NULL);  //刪除任務本身
          /* 退出臨界保護區*/
          taskEXIT_CRITICAL();
      }
      
      /*
       * 函數作用:釋放信號量
       * 輸入參數:無
       * 返回值:無
       * 作者:LSK
      */
      void Task1(void)
      {
          BaseType_t res;   
          while(1)
          {
              if(KeyScan() == KEY0)
              {
                  /* 釋放信號量 */
                  res = xSemaphoreGive(handle1);
                  if (res == pdPASS) UartSendData("Send Pass\r\n");
              }
              vTaskDelay(20);
          }
      }
      
      /*
       * 函數作用:接收信號量
       * 輸入參數:無
       * 返回值:無
       * 作者:LSK
      */
      void Task2(void)
      {
          char str[100];
          UBaseType_t Count = 0;
          BaseType_t res;
          while(1)
          {
              /* 接收信號量是否釋放 */
              res = xSemaphoreTake(handle1, portMAX_DELAY);
              if(res == pdPASS) 
              {
                 UartSendData("Take success!\r\n");
                 UartSendData("\r\n");
                 UartSendData(str);
              }
              Count = uxSemaphoreGetCount(handle1);
              sprintf(str, "the init count: %d\r\n", Count);
              UartSendData(str);
              vTaskDelay(1000);
          }
      }
      
      

      9、隊列集

      10、事件標志組

      比信號量更靈活,每一個bit位都代表一個信號量。

      #include "main.h"
      
      void StartTask(void);
      void Task1(void);
      void Task2(void);
      void FreeRTOS_Start(void);
      
      int main(void)
      {
          // 初始化HAL庫函數必須要調用此函數
          HAL_Init();
          // 系統時鐘即AHB/APB時鐘配置
          SystemClock_Config();
      
          // 初始化LED
          LedInit();
          KeyInit();
          UartInit(115200);
          FreeRTOS_Start();
      
          while(1)
          {
              HAL_Delay(1000);
              UartSendData("hello\r\n");
              LED_TOGGLE(LED0_GPIO_PORT,LED0_GPIO_PIN);
          }
      }
      
      /* 任務句柄,用以保存不同任務的配置 */
      TaskHandle_t start_task_handle;
      TaskHandle_t task1_handle;
      TaskHandle_t task2_handle;
      
      /*
       * 函數作用:常規寫法,起始任務,用以創建其他任務
       * 輸入參數:無
       * 返回值:無
       * 作者:LSK
      */
      void FreeRTOS_Start(void)
      {
          xTaskCreate(
              (TaskFunction_t)    StartTask,              //任務函數的地址          
              (char *)            "StartTask",            //任務函數的名稱
              (uint16_t)          128,                    //任務函數??臻g大小
              (void *)            NULL,                   //任務函數的參數
              (UBaseType_t)       1,                      //任務函數的優先級
              (TaskHandle_t*)     &start_task_handle      //任務函數的句柄
          );
      
          /* 啟用調度器,負責任務切換*/
          vTaskStartScheduler();
      
      }
      
      char str[100];
      EventGroupHandle_t event_handle;
      
      void StartTask(void)
      {
          UBaseType_t Count = 0;
          /* 創建一個信號量 */
          event_handle = xEventGroupCreate();
          if(!(event_handle == NULL))
          {
              UartSendData("Create success!\r\n");
          } 
          /* 進入臨界保護區,保證在臨界區的代碼不會被打斷*/
          taskENTER_CRITICAL();
          xTaskCreate(
              (TaskFunction_t)    Task1,
              (char *)            "Task1",
              (uint16_t)          128,
              (void *)            NULL,
              (UBaseType_t)       3,
              (TaskHandle_t*)     &task1_handle
          );
          xTaskCreate(
              (TaskFunction_t)    Task2,
              (char *)            "Task2",
              (uint16_t)          128,
              (void *)            NULL,
              (UBaseType_t)       4,
              (TaskHandle_t*)     &task2_handle
          );
          vTaskDelete(NULL);  //刪除任務本身
          /* 退出臨界保護區*/
          taskEXIT_CRITICAL();
      }
      
      /*
       * 函數作用:發送事件
       * 輸入參數:無
       * 返回值:無
       * 作者:LSK
      */
      #define EVENTBIT_0 (1 << 0)
      #define EVENTBIT_1 (1 << 1)
      
      void Task1(void)
      {
          EventBits_t res;   
          while(1)
          {
      
              xEventGroupSetBits(event_handle, 1<<3);
              if(KeyScan() == KEY0)
              {
                  /* 設置標志位*/
                  res = xEventGroupSetBits(event_handle, EVENTBIT_0);
                  sprintf(str,"event flag: %#x\r\n", res);
                  UartSendData(str);
                  res = xEventGroupSetBits(event_handle, EVENTBIT_1);
                  sprintf(str,"event flag: %#x\r\n", res);
                  UartSendData(str);
      
                  UartSendData("KEY0 PRESS!\r\n");
              }
              vTaskDelay(20);
          }
      }
      
      /*
       * 函數作用:接收事件
       * 輸入參數:無
       * 返回值:無
       * 作者:LSK
      */
      void Task2(void)
      {
          EventBits_t res;
          while(1)
          {
              /* 接收信號量是否釋放 */
              res = xEventGroupWaitBits(
                  event_handle,                // 事件句柄
                  ((EVENTBIT_0 | EVENTBIT_1)), // 等待的標志位
                  pdTRUE,                      // 是否清楚標志位
                  pdTRUE,                      // 是否等待標志位
                  portMAX_DELAY                // 等待事件
              );
              sprintf(str, "task2: %x\r\n", res);
              UartSendData(str);
          }
      }
      
      

      11 任務通知

      11.1 任務通知模擬信號量

      #include "main.h"
      #include "portmacro.h"
      #include "projdefs.h"
      #include <stdint.h>
      
      
      void StartTask(void);
      void Task1(void);
      void Task2(void);
      void FreeRTOS_Start(void);
      
      int main(void)
      {
          // 初始化HAL庫函數必須要調用此函數
          HAL_Init();
          // 系統時鐘即AHB/APB時鐘配置
          SystemClock_Config();
          // 初始化LED
          LedInit();
          KeyInit();
          UartInit(115200);
          FreeRTOS_Start();
      
          while(1)
          {
              HAL_Delay(1000);
              UartSendData("hello\r\n");
              LED_TOGGLE(LED0_GPIO_PORT,LED0_GPIO_PIN);
          }
      }
      
      /* 任務句柄,用以保存不同任務的配置 */
      TaskHandle_t start_task_handle;
      TaskHandle_t task1_handle;
      TaskHandle_t task2_handle;
      
      /*
       * 函數作用:常規寫法,起始任務,用以創建其他任務
       * 輸入參數:無
       * 返回值:無
       * 作者:LSK
      */
      void FreeRTOS_Start(void)
      {
          xTaskCreate(
              (TaskFunction_t)    StartTask,              //任務函數的地址          
              (char *)            "StartTask",            //任務函數的名稱
              (uint16_t)          128,                    //任務函數??臻g大小
              (void *)            NULL,                   //任務函數的參數
              (UBaseType_t)       1,                      //任務函數的優先級
              (TaskHandle_t*)     &start_task_handle      //任務函數的句柄
          );
      
          /* 啟用調度器,負責任務切換*/
          vTaskStartScheduler();
      
      }
      char str[100];
      
      void StartTask(void)
      {
          /* 進入臨界保護區,保證在臨界區的代碼不會被打斷*/
          taskENTER_CRITICAL();
          xTaskCreate(
              (TaskFunction_t)    Task1,
              (char *)            "Task1",
              (uint16_t)          128,
              (void *)            NULL,
              (UBaseType_t)       3,
              (TaskHandle_t*)     &task1_handle
          );
          xTaskCreate(
              (TaskFunction_t)    Task2,
              (char *)            "Task2",
              (uint16_t)          128,
              (void *)            NULL,
              (UBaseType_t)       4,
              (TaskHandle_t*)     &task2_handle
          );
          vTaskDelete(NULL);  //刪除任務本身
          /* 退出臨界保護區*/
          taskEXIT_CRITICAL();
      }
      
      /*
       * 函數作用:任務通知發送
       * 輸入參數:無
       * 返回值:無
       * 作者:LSK
      */
      void Task1(void)
      {
          EventBits_t res;   
          while(1)
          {
              if(KeyScan() == KEY0)
              {
                  /* 實際使取出task2的通知值,然后+1*/
                  xTaskNotifyGive(task2_handle); 
                  UartSendData("KEY0 PRESS!\r\n");
              }
              vTaskDelay(200);
          }
      }
      
      /*
       * 函數作用:任務通知接收
       * 輸入參數:無
       * 返回值:無
       * 作者:LSK
      */
      void Task2(void)
      {
          uint32_t res_notify;
          while(1)
          { 
              res_notify = ulTaskNotifyTake(
                  pdTRUE,             //接收完通知后,是否對通知值處理,pdTRUE:置0;pdFALSE:-1
                  portMAX_DELAY       //設置等待時間
              );
              sprintf(str, "task2 notify: %d\r\n", res_notify);
              UartSendData(str);
          }
      }
      
      

      11.2 任務通知模擬消息隊列(郵箱)

      #include "main.h"
      #include "portmacro.h"
      #include "projdefs.h"
      #include <stdint.h>
      
      
      void StartTask(void);
      void Task1(void);
      void Task2(void);
      void FreeRTOS_Start(void);
      
      int main(void)
      {
          // 初始化HAL庫函數必須要調用此函數
          HAL_Init();
          // 系統時鐘即AHB/APB時鐘配置
          SystemClock_Config();
          // 初始化LED
          LedInit();
          KeyInit();
          UartInit(115200);
          FreeRTOS_Start();
      
          while(1)
          {
              HAL_Delay(1000);
              UartSendData("hello\r\n");
              LED_TOGGLE(LED0_GPIO_PORT,LED0_GPIO_PIN);
          }
      }
      
      /* 任務句柄,用以保存不同任務的配置 */
      TaskHandle_t start_task_handle;
      TaskHandle_t task1_handle;
      TaskHandle_t task2_handle;
      
      /*
       * 函數作用:常規寫法,起始任務,用以創建其他任務
       * 輸入參數:無
       * 返回值:無
       * 作者:LSK
      */
      void FreeRTOS_Start(void)
      {
          xTaskCreate(
              (TaskFunction_t)    StartTask,              //任務函數的地址          
              (char *)            "StartTask",            //任務函數的名稱
              (uint16_t)          128,                    //任務函數棧空間大小
              (void *)            NULL,                   //任務函數的參數
              (UBaseType_t)       1,                      //任務函數的優先級
              (TaskHandle_t*)     &start_task_handle      //任務函數的句柄
          );
      
          /* 啟用調度器,負責任務切換*/
          vTaskStartScheduler();
      
      }
      char str[100];
      
      void StartTask(void)
      {
          /* 進入臨界保護區,保證在臨界區的代碼不會被打斷*/
          taskENTER_CRITICAL();
          xTaskCreate(
              (TaskFunction_t)    Task1,
              (char *)            "Task1",
              (uint16_t)          128,
              (void *)            NULL,
              (UBaseType_t)       3,
              (TaskHandle_t*)     &task1_handle
          );
          xTaskCreate(
              (TaskFunction_t)    Task2,
              (char *)            "Task2",
              (uint16_t)          128,
              (void *)            NULL,
              (UBaseType_t)       4,
              (TaskHandle_t*)     &task2_handle
          );
          vTaskDelete(NULL);  //刪除任務本身
          /* 退出臨界保護區*/
          taskEXIT_CRITICAL();
      }
      
      /*
       * 函數作用:模擬消息隊列發送
       * 輸入參數:無
       * 返回值:無
       * 作者:LSK
      */
      void Task1(void)
      {
          EventBits_t res;   
          while(1)
          {
              if(KeyScan() == KEY0)
              {
                  xTaskNotify(task2_handle,          // 要發送的任務句柄
                              100,                   // 要發送的數據
                              eSetValueWithOverwrite // 發送方式
                  );
                  UartSendData("KEY0 PRESS!\r\n");
              }
              vTaskDelay(200);
          }
      }
      
      /*
       * 函數作用:模擬消息隊列接收
       * 輸入參數:無
       * 返回值:無
       * 作者:LSK
      */
      void Task2(void)
      {
          uint32_t res_notify;
          while(1)
          {
            xTaskNotifyWait(
                0x00000000,   // 接收通知前是否清楚通知值,按位,全為0表示不不清楚
                0xffffffff,   // 接收通知后是否要清楚通知值,按位,全為f表示清楚
                &res_notify,  // 接受值存放地址
                portMAX_DELAY // 等待事件
            );
            sprintf(str, "task2 notify: %d\r\n", res_notify);
            UartSendData(str);
          }
      }
      

      11.3 模擬事件標志組

      #include "main.h"
      #include "portmacro.h"
      #include "projdefs.h"
      #include <stdint.h>
      
      
      void StartTask(void);
      void Task1(void);
      void Task2(void);
      void FreeRTOS_Start(void);
      
      int main(void)
      {
          // 初始化HAL庫函數必須要調用此函數
          HAL_Init();
          // 系統時鐘即AHB/APB時鐘配置
          SystemClock_Config();
          // 初始化LED
          LedInit();
          KeyInit();
          UartInit(115200);
          FreeRTOS_Start();
      
          while(1)
          {
              HAL_Delay(1000);
              UartSendData("hello\r\n");
              LED_TOGGLE(LED0_GPIO_PORT,LED0_GPIO_PIN);
          }
      }
      
      /* 任務句柄,用以保存不同任務的配置 */
      TaskHandle_t start_task_handle;
      TaskHandle_t task1_handle;
      TaskHandle_t task2_handle;
      
      /*
       * 函數作用:常規寫法,起始任務,用以創建其他任務
       * 輸入參數:無
       * 返回值:無
       * 作者:LSK
      */
      void FreeRTOS_Start(void)
      {
          xTaskCreate(
              (TaskFunction_t)    StartTask,              //任務函數的地址          
              (char *)            "StartTask",            //任務函數的名稱
              (uint16_t)          128,                    //任務函數??臻g大小
              (void *)            NULL,                   //任務函數的參數
              (UBaseType_t)       1,                      //任務函數的優先級
              (TaskHandle_t*)     &start_task_handle      //任務函數的句柄
          );
      
          /* 啟用調度器,負責任務切換*/
          vTaskStartScheduler();
      
      }
      char str[100];
      
      void StartTask(void)
      {
          /* 進入臨界保護區,保證在臨界區的代碼不會被打斷*/
          taskENTER_CRITICAL();
          xTaskCreate(
              (TaskFunction_t)    Task1,
              (char *)            "Task1",
              (uint16_t)          128,
              (void *)            NULL,
              (UBaseType_t)       3,
              (TaskHandle_t*)     &task1_handle
          );
          xTaskCreate(
              (TaskFunction_t)    Task2,
              (char *)            "Task2",
              (uint16_t)          128,
              (void *)            NULL,
              (UBaseType_t)       4,
              (TaskHandle_t*)     &task2_handle
          );
          vTaskDelete(NULL);  //刪除任務本身
          /* 退出臨界保護區*/
          taskEXIT_CRITICAL();
      }
      
      /*
       * 函數作用:模擬事件標志組發送
       * 輸入參數:無
       * 返回值:無
       * 作者:LSK
      */
      void Task1(void)
      {
          EventBits_t res;   
          while(1)
          {
            if (KeyScan() == KEY0) {
              xTaskNotify(task2_handle, // 要發送的任務句柄
                          1 << 8,       // 要發送的數據位
                          eSetBits      // 發送方式
              );
              UartSendData("KEY0 PRESS!\r\n");
            }
              vTaskDelay(200);
          }
      }
      
      /*
       * 函數作用:模擬事件標志組接收
       * 輸入參數:無
       * 返回值:無
       * 作者:LSK
      */
      void Task2(void)
      {
          uint32_t res_notify;
          while (1) {
            xTaskNotifyWait(
                0x00000000,   // 接收通知前是否清楚通知值,按位,全為0表示不不清楚
                0xffffffff,   // 接收通知后是否要清楚通知值,按位,全為f表示清楚
                &res_notify,  // 接受值存放地址
                portMAX_DELAY // 等待時間
            );
            sprintf(str, "task2 notify: %0x\r\n", res_notify);
            UartSendData(str);
          }
      }
      

      12、軟件定時器

      #include "main.h"
      #include <stdint.h>
      
      
      void StartTask(void);
      void Task1(void);
      void FreeRTOS_Start(void);
      
      int main(void)
      {
          // 初始化HAL庫函數必須要調用此函數
          HAL_Init();
          // 系統時鐘即AHB/APB時鐘配置
          SystemClock_Config();
          // 初始化LED
          LedInit();
          KeyInit();
          UartInit(115200);
          FreeRTOS_Start();
      }
      
      /* 任務句柄,用以保存不同任務的配置 */
      TaskHandle_t start_task_handle;
      TaskHandle_t task1_handle;
      
      
      /*
       * 函數作用:常規寫法,起始任務,用以創建其他任務
       * 輸入參數:無
       * 返回值:無
       * 作者:LSK
      */
      void FreeRTOS_Start(void)
      {
          xTaskCreate(
              (TaskFunction_t)    StartTask,              //任務函數的地址          
              (char *)            "StartTask",            //任務函數的名稱
              (uint16_t)          128,                    //任務函數棧空間大小
              (void *)            NULL,                   //任務函數的參數
              (UBaseType_t)       1,                      //任務函數的優先級
              (TaskHandle_t*)     &start_task_handle      //任務函數的句柄
          );
      
          /* 啟用調度器,負責任務切換*/
          vTaskStartScheduler();
      
      }
      char str[100];
      
      void TimerCallBack_1(TimerHandle_t timer);
      
      TimerHandle_t timer_handle_1;
      
      /*
       * 函數作用:開始任務回調函數
       * 輸入參數:無
       * 返回值:無
       * 作者:LSK
      */
      void StartTask(void)
      {
          /* 創建軟件定時器,由軟件定時器任務(通過定義宏,由系統創建)控制*/
          timer_handle_1 = xTimerCreate("time_1",       // 創建名稱
                                        500,            // 定時器延遲時間
                                        pdTRUE,         // 是否重載(周期/一次)
                                        (void *)1,      // 定時器唯一ID
                                        TimerCallBack_1 // 定時器回調函數
          );
      
          /* 進入臨界保護區,保證在臨界區的代碼不會被打斷*/
          taskENTER_CRITICAL();
          xTaskCreate((TaskFunction_t)Task1, (char *)"Task1", (uint16_t)128,
                      (void *)NULL, (UBaseType_t)3, (TaskHandle_t *)&task1_handle);
      
          vTaskDelete(NULL); // 刪除任務本身
          /* 退出臨界保護區*/
          taskEXIT_CRITICAL();
      }
      
      /*
       * 函數作用:開啟軟件定時器
       * 輸入參數:無
       * 返回值:無
       * 作者:LSK
      */
      void Task1(void)
      {
          EventBits_t res;
          while (1) {
            if (KeyScan() == KEY0) {
              /* 開啟軟件定時器*/
              xTimerStart(timer_handle_1, // 定時器句柄
                          portMAX_DELAY); // 等待時間
              UartSendData(("timer start!\r\n"));
            }
              vTaskDelay(200);
          }
      }
      
      /*
       * 函數作用:定時器回調函數
       * 輸入參數:定時器句柄
       * 返回值:無
       * 作者:LSK
      */
      void TimerCallBack_1(TimerHandle_t timer)
      {
          if(timer == timer_handle_1)
          {
              UartSendData("Call back!\r\n");
              LED_TOGGLE(LED0_GPIO_PORT, LED0_GPIO_PIN);
          }
      }
      
      posted @ 2025-11-02 22:27  比特向陽  閱讀(6)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 极品尤物被啪到呻吟喷水| 国产毛片三区二区一区| 精品久久一线二线三线区| 国产成人不卡一区二区| 国产v综合v亚洲欧美久久| 成人网站免费在线观看| 一级片黄色一区二区三区| 一区二区三区av在线观看 | 国产白嫩护士在线播放| 久久午夜夜伦鲁鲁片免费无码| 毛片大全真人在线| 精品无码人妻一区二区三区| 在线永久看片免费的视频| 偷拍专区一区二区三区| 高级会所人妻互换94部分| 老男人久久青草av高清| 中文字幕国产日韩精品| 精品无码成人久久久久久| 免费现黄频在线观看国产| 洪雅县| 国产95在线 | 欧美| 四虎国产精品成人| 成人国产精品中文字幕| 天堂av资源在线免费| 国产熟妇久久777777| 免费无码成人AV片在线| 无码一区中文字幕| 52熟女露脸国语对白视频| 成年女性特黄午夜视频免费看| 国产果冻豆传媒麻婆精东| 精品人妻免费看一区二区三区| 亚洲最大av资源站无码av网址| 精品国精品国自产在国产| 精品无码成人片一区二区| 亚洲一本二区偷拍精品| 黄男女激情一区二区三区| 夜夜添无码一区二区三区| 国产欧美在线手机视频| 白丝乳交内射一二三区| 国产精品福利片在线观看| 亚洲国产精品无码久久电影|