分享一个 FreeRTOS 任务通知的例子,基于C++的混合开发尝试
首先创建一个 led.h 和一个 led.cpp,文件内容如下:
led.h
#pragma once
#include "FreeRTOS.h"
#include "task.h"
#include "at32f413.h"
class Led
{
public:
    Led(gpio_type* _gpiox, uint32_t _pins);
    void gpio_config(void);
    void toggle();
    void on();
    void off();
private:
    uint32_t m_pins;
    gpio_pull_type m_pull;
    crm_periph_clock_type m_crm_periph_clock;
    gpio_type* m_gpiox;
};
led.cpp
#include "led.h"
#define USER_LED_TASK_PRIO 2			/* 定义任务优先级 */
#define USER_LED_TASK_STACK_SIZE 120	/* 定义任务堆栈大小 */
TaskHandle_t user_led_handle;			/* 定义任务句柄 */
void led_task(void* pvParameters); /* 任务函数 */
extern Led led;
/// @brief LED 构造函数,必须提供必要的参数
/// @param _gpiox 
/// @param _pins 
Led::Led(gpio_type* _gpiox, uint32_t _pins)
{
    xTaskCreate(
        (TaskFunction_t)led_task,
        (const char*)"led_task",
        (uint16_t)USER_LED_TASK_STACK_SIZE,
        (void*)NULL,
        (UBaseType_t)USER_LED_TASK_PRIO,
        (TaskHandle_t*)user_led_handle
    );
    m_gpiox = _gpiox;
    m_pins = _pins;
	if (_gpiox == GPIOA)
	{
		m_crm_periph_clock = CRM_GPIOA_PERIPH_CLOCK;
	}
    else if (_gpiox == GPIOB)
    {
        m_crm_periph_clock = CRM_GPIOB_PERIPH_CLOCK;
    }
    else if (_gpiox == GPIOC)
    {
        m_crm_periph_clock = CRM_GPIOC_PERIPH_CLOCK;
    }
    else if (_gpiox == GPIOD)
    {
        m_crm_periph_clock = CRM_GPIOD_PERIPH_CLOCK;
    }
}
/** @brief gpio config
  *	@biref LED IO Config
  */
void Led::gpio_config(void)
{
    /* 定义 GPIO 初始化结构体 */
    gpio_init_type gpio_init_struct;
    /* 使能 GPIOA 外设时钟 */
    crm_periph_clock_enable(m_crm_periph_clock, TRUE);
    /* 设置默认参数 */
    gpio_default_para_init(&gpio_init_struct);
    /* 配置 GPIO 参数 */
    gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER; /* 较大电流推动/吸入能力 */
    gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; /* 推挽输出 */
    gpio_init_struct.gpio_mode = GPIO_MODE_OUTPUT;
    gpio_init_struct.gpio_pins = m_pins;
    gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
    gpio_init(m_gpiox, &gpio_init_struct);
}
/// @brief led FreeRTOS 任务函数
/// @param pvParameters 
void led_task(void* pvParameters)
{
    led.gpio_config();
    uint32_t num = 0;
    uint32_t ul_notify_value;
    while (1)
    {
        ul_notify_value = ulTaskNotifyTake(pdTRUE, 0);
        if (ul_notify_value>0)
        {
            led.toggle();
        }
    }
}
void Led::toggle()
{
    m_gpiox->odt ^= m_pins;
}
void Led::on()
{
    gpio_bits_write(m_gpiox, m_pins, TRUE);
}
void Led::off()
{
    gpio_bits_write(m_gpiox, m_pins, FALSE);
}
main.cpp
该例子通过 Tick 钩子函数发送通知的方式来使 LED 函数,任务通知的代码如下:
 xTaskNotifyGive(xTaskGetHandle("led_task"));
由于 led_task 任务函数的定义在 led.cpp 中定义的,所以使用 xTaskGetHandle() 函数来获取任务句柄。
创建任务的函数 xTaskCreate() 我们放到了 Led 的构造函数中,这样在实例化 Led 时就会自动创建任务了。
#include "at32f413_clock.h"
#include "FreeRTOS.h"
#include "task.h"
#include "led.h"
#include "xtp_defines.h"
Led led(GPIOA, GPIO_PINS_0);
/**
  * @brief  main function.
  * @param  none
  * @retval none
  */
int main(void)
{
    system_clock_config();
    /* 开启任务调度器 */
    vTaskStartScheduler();
    while (1)
    {
    }
}
// Tick 钩子函数
void vApplicationTickHook(void)
{
    global_num_1++;
    if(global_num_1>=500)
    {
		global_num_1 = 0;
        // 给 led_task 任务发送通知
        xTaskNotifyGive(xTaskGetHandle("led_task"));
    }
}

 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号