硬汉嵌入式论坛

 找回密码
 立即注册
查看: 445|回复: 5
收起左侧

[RTOS] FreeRTOS任务优先级问题

[复制链接]

51

主题

103

回帖

256

积分

高级会员

积分
256
发表于 2025-10-6 10:18:51 | 显示全部楼层 |阅读模式
我用STM32H7+FREERTOS+LVGL+SENSOR设计一个产品,SENSOR采集数据后在LVGL中显示。
FREERTOS中有三个任务A,B,C,
A:触摸按键的任务,
B: SENSOR采集数据后的计算任务(包括多重滤波,大量浮点运算,各种线性转换等),
C: LVGL图形任务,负责UI按钮控制和B中采集数据的显示。

我的操作流程是:
1,LVGL中主界面设置按钮,按一下按钮进入UI显示界面,同时发送通知给SENSOR计算任务,开始数据计算,计算完后通知LVGL任务显示,显示用的是双缓冲切换显示。
SENSOR计算任务中已经打开了STM32H7的硬件浮点单元,并开辟了两个AXI-SRAM块做双buffer

2,在LVGL显示UI界面,也设置一个按钮,按一下按钮,发送通知给SENSOR计算任务停止计算,然后停止显示退出显示界面。

以上任务如果优先级设置为 A为3,B为2,C为1,则一旦进入数据显示的UI界面,显示就非常卡顿,几乎无法正常显示,且容易导致整个系统死机。
未进入数据显示UI时,LVGL的其他UI都能流畅显示,唯独数据显示界面卡顿,无法正常显示。我无论怎么设置延时时间都无改善。
查看LVGL自带的内存和CPU监控,显示CPU占用已达96%以上。

如果A为3,B为1,C为2,则LVGL任务中的所有UI都可以正常显示,数据显示也很流畅,不卡顿,CPU占用只有8%

本人RTOS初学者,靠看了硬汉哥的文档就开始撸项目了,我有点不太明白,按照正常的生产-消费逻辑,B任务生产数据,C任务消费数据(显示和其他控制UI),A为3,B为2,C为1是合理的逻辑,但是为什么不能流畅显示?
我看到很多文档包括硬汉哥的示波器项目里,也是把DSP计算放在最高优先级,GUI在最低优先级
为什么A为3,B为1,C为2可以呢,有点想不通,难道是我B任务计算量太大了,耗时太长,阻塞了其他任务运行。

虽然A为3,B为1,C为2可以流畅运行,但是由于我知识浅薄,不清楚是否有什么风险,望大佬赐教



回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
119430
QQ
发表于 2025-10-6 11:51:00 | 显示全部楼层
你的LVGL发送消息后,不会没有释放CPU权限一直在死等待计算吧。我看应该是的。
回复

使用道具 举报

51

主题

103

回帖

256

积分

高级会员

积分
256
 楼主| 发表于 2025-10-6 14:59:52 | 显示全部楼层
本帖最后由 coolaimcu 于 2025-10-6 15:14 编辑
eric2013 发表于 2025-10-6 11:51
你的LVGL发送消息后,不会没有释放CPU权限一直在死等待计算吧。我看应该是的。

感谢回复!


如下是我的代码:


//////////任务A
static void vTask_A_Touch(void* pvParameters)  //触摸任务
{
      TickType_t xLastWakeTime;
      const TickType_t xFreq =1;

      xLastWakeTime = xTaskGetTickCount();  //从系统获取时间
      read_touch();
      vTaskDelayUntil(&xLastWakeTime,pdMS_TO_TICKS(xFreq));
}

//////////任务B
static void vTask_B_SensorCalculate(void* pvParameters)   //计算任务
{
   
       if(ulTaskNotifyTake(pdTRUE, 0)>0)  //等待来自任务C的开始计算通知,这里换成过无限期等待:ulTaskNotifyTake(pdTRUE, portMAX_DELAY), 问题也没有改善
       {
                Get_data = sensor_data_calculate();  //计算完成,获得结果
                xQueueSend(xQueueSensorData, &Get_data, portMAX_DELAY); // 把计算结果发送给LVGL任务C
        }
        vTaskDelay(pdMS_TO_TICKS(10));
}


//////////任务C
static void vTask_C_LVGL(void* pvParameters)  //显示任务
{
         SemaphoreHandle_t xMutexlvglsec = xSemaphoreCreateMutex();
        xSemaphoreGive(xMutexlvglsec);                              
        lv_init();                                             
        lv_port_disp_init();                                    
        lv_port_indev_init();                                    
        sensor_data_display_ui();    //主界面的按钮UI函数
       for(;;)
      {
        if(xSemaphoreTake(xMutexlvglsec,portMAX_DELAY) == pdTRUE)  //线程安全互斥锁
        {
            lv_timer_handler();
            xSemaphoreGive(xMutexlvglsec);
        }
        vTaskDelay(pdMS_TO_TICKS(5));
    }
}


//主界面的按钮UI函数,按下按钮进入显示UI子界面,同时产生点击回调事件,在回调函数main_screen_btn_cb中通知B任务开始计算  
void sensor_data_display_ui(void)
{
     main_screen_button();  //按钮UI
}

//如果按下按钮,则进入回调函数
static void main_screen_btn_cb((lv_event_t* e)
{
     start_screen_display_ui();                 //进入显示子界面
     xTaskNotifyGive(xHandleTask_B);   //发任务通知给B,通知开始计算
}


//进入显示子界面start_screen_display_ui()后,立即启动一个5ms的定时器,在定时器回调函数中(如下)接收B任务计算好的结果进行显示
static void  timer_receivedata_5ms_cb(lv_timer_t* e)
{
      sGetSensorData_t GeteDataAll;
      if(xQueueReceive(xQueueSensorData, &GeteDataAll, pdMS_TO_TICKS(5))==pdTRUE)  //等待来自任务B的计算数据,pdMS_TO_TICKS(5)换成过porMAX_DELAY以及0,都没有改善
      {
                lv_display();  //接收完毕,LVGL开始刷新显示
           xTaskNotifyGive(xHandleTask_B);  //一帧显示完毕,再发个通知给任务B,持续进行计算和显示
      }
}




以上是就是一个完整的显示流程,按照你所说,有可能没释放CPU权限,但是我按照自己的理解测试过很多释放权限的方法,但不知道对不对,请硬汉哥帮我看一下,还有哪里需要优化,感谢
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
119430
QQ
发表于 2025-10-7 12:26:08 | 显示全部楼层

可以考虑修改下实现方案,这种方式可以把计算好的数据先存入FIFO,然后GUI任务需要展示从里面读取就行。
回复

使用道具 举报

51

主题

103

回帖

256

积分

高级会员

积分
256
 楼主| 发表于 2025-10-9 14:14:34 | 显示全部楼层
eric2013 发表于 2025-10-7 12:26
可以考虑修改下实现方案,这种方式可以把计算好的数据先存入FIFO,然后GUI任务需要展示从里面读取就行。

感谢指导,我在研究研究
回复

使用道具 举报

16

主题

73

回帖

121

积分

初级会员

积分
121
发表于 2025-10-9 18:01:34 来自手机 | 显示全部楼层
这种rtos环境下queue和fifo什么时候使用,之前用ThreadX一个queue有32bit,传串口数据太浪费了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-11-22 04:11 , Processed in 0.039710 second(s), 24 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表