中文字幕精品亚洲无线码二区,国产黄a三级三级三级看三级,亚洲七七久久桃花影院,丰满少妇被猛烈进入,国产小视频在线观看网站

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,                    //任務函數棧空間大小
        (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,                    //任務函數棧空間大小
        (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,                    //任務函數棧空間大小
        (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 互斥二進制信號量

它會將阻(zu)塞高優(you)先級(ji)的低(di)優(you)先級(ji)提升,從(cong)而(er)保證高優(you)先級(ji)不會被(bei)低(di)優(you)先級(ji)阻(zu)塞。

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,                    //任務函數棧空間大小
        (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、事件標志組

比信號量(liang)更靈活,每一(yi)個(ge)bit位都代表(biao)一(yi)個(ge)信號量(liang)。

#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,                    //任務函數棧空間大小
        (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,                    //任務函數棧空間大小
        (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,                    //任務函數棧空間大小
        (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  比特向陽  閱讀(9)  評論(0)    收藏  舉報