12.freertos任务
约 1299 字大约 4 分钟
2025-08-20
/* ======================== 系统配置 ======================== */
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"
#include "timers.h"
#include "event_groups.h"
#include "lvgl.h"
/* 任务优先级定义 */
#define LVGL_TASK_PRIORITY (tskIDLE_PRIORITY + 4) // 最高优先级
#define LIGHT_SENSOR_PRIORITY (tskIDLE_PRIORITY + 3)
#define KEY_SCAN_PRIORITY (tskIDLE_PRIORITY + 2)
#define SYSTEM_MONITOR_PRIORITY (tskIDLE_PRIORITY + 1)
/* 任务堆栈大小 */
#define LVGL_TASK_STACK_SIZE 512
#define LIGHT_SENSOR_STACK_SIZE 256
#define KEY_SCAN_STACK_SIZE 256
#define SYSTEM_MONITOR_STACK_SIZE 256
/* ======================== 数据结构定义 ======================== */
typedef struct {
float light_value;
uint32_t timestamp;
uint8_t sensor_status; // 传感器状态
} light_data_t;
typedef enum {
KEY_NONE = 0,
KEY_UP,
KEY_DOWN,
KEY_LEFT,
KEY_RIGHT,
KEY_SELECT,
KEY_LONG_PRESS
} key_event_t;
typedef struct {
key_event_t key;
uint32_t timestamp;
} key_message_t;
typedef struct {
uint32_t cpu_usage;
uint32_t free_heap;
uint32_t min_free_heap;
float temperature; // 可选:CPU温度
} system_info_t;
/* ======================== 全局变量和句柄 ======================== */
/* 队列句柄 */
QueueHandle_t light_data_queue;
QueueHandle_t key_event_queue;
QueueHandle_t system_info_queue;
/* 互斥锁 */
SemaphoreHandle_t display_mutex;
SemaphoreHandle_t i2c_mutex; // I2C总线互斥锁
SemaphoreHandle_t spi_mutex; // SPI总线互斥锁
/* 事件组 */
EventGroupHandle_t system_events;
#define SYSTEM_INIT_COMPLETE_BIT (1 << 0)
#define SENSOR_ERROR_BIT (1 << 1)
#define LOW_POWER_BIT (1 << 2)
#define SCREEN_UPDATE_BIT (1 << 3)
/* 软件定时器 */
TimerHandle_t heartbeat_timer;
TimerHandle_t screen_saver_timer;
/* LVGL对象句柄 */
lv_obj_t *main_screen;
lv_obj_t *light_label;
lv_obj_t *time_label;
lv_obj_t *system_info_label;
lv_obj_t *menu_container;
/* ======================== 任务实现 ======================== */
/* 1. 光照传感器任务 */
void light_sensor_task(void *pvParameters)
{
light_data_t light_data;
TickType_t last_wake_time;
uint32_t error_count = 0;
// 初始化传感器
if(light_sensor_init() != 0) {
// 设置传感器错误标志
xEventGroupSetBits(system_events, SENSOR_ERROR_BIT);
vTaskDelete(NULL); // 删除任务
}
last_wake_time = xTaskGetTickCount();
while(1)
{
// 获取I2C总线访问权限
if(xSemaphoreTake(i2c_mutex, pdMS_TO_TICKS(50)) == pdTRUE)
{
// 读取光照强度
if(read_light_sensor(&light_data.light_value) == 0)
{
light_data.timestamp = xTaskGetTickCount();
light_data.sensor_status = 1; // 正常
error_count = 0;
// 发送数据到队列
if(xQueueSend(light_data_queue, &light_data, 0) != pdTRUE)
{
// 队列满,清空队列重新发送
xQueueReset(light_data_queue);
xQueueSend(light_data_queue, &light_data, 0);
}
// 触发屏幕更新事件
xEventGroupSetBits(system_events, SCREEN_UPDATE_BIT);
}
else
{
error_count++;
if(error_count > 5)
{
// 连续错误,设置错误标志
xEventGroupSetBits(system_events, SENSOR_ERROR_BIT);
}
}
xSemaphoreGive(i2c_mutex);
}
// 定时采样,100ms间隔
vTaskDelayUntil(&last_wake_time, pdMS_TO_TICKS(100));
}
}
/* 2. 按键扫描任务 */
void key_scan_task(void *pvParameters)
{
key_message_t key_msg;
static uint8_t key_state[5] = {0}; // 按键状态
static uint32_t key_press_time[5] = {0}; // 按键按下时间
static uint32_t last_key_time = 0; // 防抖动
uint8_t key_raw, key_pressed;
int i;
while(1)
{
// 读取原始按键状态
key_raw = read_keys_gpio();
// 防抖动处理
if((xTaskGetTickCount() - last_key_time) < pdMS_TO_TICKS(20))
{
vTaskDelay(pdMS_TO_TICKS(10));
continue;
}
// 扫描每个按键
for(i = 0; i < 5; i++)
{
key_pressed = (key_raw >> i) & 0x01;
if(key_pressed && !key_state[i])
{
// 按键刚被按下
key_state[i] = 1;
key_press_time[i] = xTaskGetTickCount();
// 发送按键事件
key_msg.key = (key_event_t)(i + 1);
key_msg.timestamp = key_press_time[i];
xQueueSend(key_event_queue, &key_msg, 0);
last_key_time = xTaskGetTickCount();
// 重置屏保定时器
xTimerReset(screen_saver_timer, 0);
}
else if(!key_pressed && key_state[i])
{
// 按键释放,检查是否长按
uint32_t press_duration = xTaskGetTickCount() - key_press_time[i];
if(press_duration > pdMS_TO_TICKS(1000)) // 长按1秒
{
key_msg.key = KEY_LONG_PRESS;
key_msg.timestamp = xTaskGetTickCount();
xQueueSend(key_event_queue, &key_msg, 0);
}
key_state[i] = 0;
last_key_time = xTaskGetTickCount();
}
}
vTaskDelay(pdMS_TO_TICKS(20)); // 20ms扫描周期
}
}
/* 3. LVGL显示任务 */
void lvgl_task(void *pvParameters)
{
light_data_t light_data;
key_message_t key_msg;
system_info_t sys_info;
char display_buffer[64];
static uint8_t current_page = 0; // 当前显示页面
static float last_light_value = -1.0f;
EventBits_t events;
// 等待系统初始化完成
xEventGroupWaitBits(system_events, SYSTEM_INIT_COMPLETE_BIT,
pdFALSE, pdTRUE, portMAX_DELAY);
// 创建UI界面
create_main_ui();
while(1)
{
// 等待屏幕更新事件或超时
events = xEventGroupWaitBits(system_events,
SCREEN_UPDATE_BIT | SENSOR_ERROR_BIT,
pdTRUE, pdFALSE, pdMS_TO_TICKS(20));
// 获取显示互斥锁
if(xSemaphoreTake(display_mutex, pdMS_TO_TICKS(10)) == pdTRUE)
{
// 处理光照数据更新
if(xQueueReceive(light_data_queue, &light_data, 0) == pdTRUE)
{
if(fabs(light_data.light_value - last_light_value) > 0.5f)
{
snprintf(display_buffer, sizeof(display_buffer),
"Light: %.1f lux", light_data.light_value);
lv_label_set_text(light_label, display_buffer);
last_light_value = light_data.light_value;
}
}
// 处理按键事件
if(xQueueReceive(key_event_queue, &key_msg, 0) == pdTRUE)
{
handle_key_event(&key_msg, ¤t_page);
}
// 处理系统信息更新
if(xQueueReceive(system_info_queue, &sys_info, 0) == pdTRUE)
{
update_system_info_display(&sys_info);
}
// 处理传感器错误
if(events & SENSOR_ERROR_BIT)
{
lv_label_set_text(light_label, "Sensor Error!");
}
// LVGL任务处理
lv_task_handler();
xSemaphoreGive(display_mutex);
}
vTaskDelay(pdMS_TO_TICKS(20)); // 50fps刷新率
}
}
/* 4. 系统监控任务 */
void system_monitor_task(void *pvParameters)
{
system_info_t sys_info;
TaskStatus_t *task_status_array;
UBaseType_t task_count;
uint32_t total_runtime, task_runtime;
while(1)
{
// 获取系统信息
sys_info.free_heap = xPortGetFreeHeapSize();
sys_info.min_free_heap = xPortGetMinimumEverFreeHeapSize();
// 计算CPU使用率
task_count = uxTaskGetNumberOfTasks();
task_status_array = pvPortMalloc(task_count * sizeof(TaskStatus_t));
if(task_status_array != NULL)
{
task_count = uxTaskGetSystemState(task_status_array, task_count, &total_runtime);
// 简化的CPU使用率计算
sys_info.cpu_usage = 100 - (xTaskGetIdleTaskCount() * 100 / total_runtime);
vPortFree(task_status_array);
}
// 检查内存不足情况
if(sys_info.free_heap < 1024) // 小于1KB
{
xEventGroupSetBits(system_events, LOW_POWER_BIT);
}
// 发送系统信息
xQueueSend(system_info_queue, &sys_info, 0);
vTaskDelay(pdMS_TO_TICKS(1000)); // 1秒更新一次
}
}
/* ======================== 辅助函数 ======================== */
/* UI创建函数 */
void create_main_ui(void)
{
// 创建主屏幕
main_screen = lv_obj_create(NULL);
lv_scr_load(main_screen);
// 创建光照显示标签
light_label = lv_label_create(main_screen);
lv_label_set_text(light_label, "Light: -- lux");
lv_obj_align(light_label, LV_ALIGN_TOP_MID, 0, 20);
// 创建时间显示标签
time_label = lv_label_create(main_screen);
lv_label_set_text(time_label, "00:00:00");
lv_obj_align(time_label, LV_ALIGN_TOP_RIGHT, -10, 5);
// 创建系统信息标签
system_info_label = lv_label_create(main_screen);
lv_label_set_text(system_info_label, "CPU: --%");
lv_obj_align(system_info_label, LV_ALIGN_BOTTOM_LEFT, 10, -5);
}
/* 按键事件处理 */
void handle_key_event(key_message_t *key_msg, uint8_t *current_page)
{
switch(key_msg->key)
{
case KEY_UP:
// 处理向上按键
break;
case KEY_DOWN:
// 处理向下按键
break;
case KEY_LEFT:
if(*current_page > 0) (*current_page)--;
update_display_page(*current_page);
break;
case KEY_RIGHT:
(*current_page)++;
update_display_page(*current_page);
break;
case KEY_SELECT:
// 处理选择按键
break;
case KEY_LONG_PRESS:
// 进入设置菜单
enter_settings_menu();
break;
default:
break;
}
}
/* 软件定时器回调函数 */
void heartbeat_timer_callback(TimerHandle_t xTimer)
{
// 心跳LED闪烁
toggle_heartbeat_led();
}
void screen_saver_timer_callback(TimerHandle_t xTimer)
{
// 进入屏保模式
enter_screen_saver_mode();
}
/* ======================== 系统初始化 ======================== */
void system_init(void)
{
// 创建队列
light_data_queue = xQueueCreate(5, sizeof(light_data_t));
key_event_queue = xQueueCreate(10, sizeof(key_message_t));
system_info_queue = xQueueCreate(3, sizeof(system_info_t));
// 创建互斥锁
display_mutex = xSemaphoreCreateMutex();
i2c_mutex = xSemaphoreCreateMutex();
spi_mutex = xSemaphoreCreateMutex();
// 创建事件组
system_events = xEventGroupCreate();
// 创建软件定时器
heartbeat_timer = xTimerCreate("Heartbeat", pdMS_TO_TICKS(1000),
pdTRUE, NULL, heartbeat_timer_callback);
screen_saver_timer = xTimerCreate("ScreenSaver", pdMS_TO_TICKS(30000),
pdFALSE, NULL, screen_saver_timer_callback);
// 启动定时器
xTimerStart(heartbeat_timer, 0);
xTimerStart(screen_saver_timer, 0);
}
/* ======================== 主函数 ======================== */
int main(void)
{
// 硬件初始化
SystemClock_Config();
GPIO_Init();
USART_Init();
I2C_Init();
SPI_Init();
// 系统初始化
system_init();
// 创建任务
xTaskCreate(light_sensor_task, "LightSensor", LIGHT_SENSOR_STACK_SIZE,
NULL, LIGHT_SENSOR_PRIORITY, NULL);
xTaskCreate(key_scan_task, "KeyScan", KEY_SCAN_STACK_SIZE,
NULL, KEY_SCAN_PRIORITY, NULL);
xTaskCreate(lvgl_task, "LVGL", LVGL_TASK_STACK_SIZE,
NULL, LVGL_TASK_PRIORITY, NULL);
xTaskCreate(system_monitor_task, "SysMon", SYSTEM_MONITOR_STACK_SIZE,
NULL, SYSTEM_MONITOR_PRIORITY, NULL);
// 设置系统初始化完成标志
xEventGroupSetBits(system_events, SYSTEM_INIT_COMPLETE_BIT);
// 启动调度器
vTaskStartScheduler();
// 正常情况下不会执行到这里
while(1);
}