espressif / esp-bsp

Board support components for Espressif development boards
Other
141 stars 76 forks source link

Unable to delete or suspend task that has lvgl_port_lock(0); calls in it. (BSP-441) #276

Closed wreyford closed 1 month ago

wreyford commented 4 months ago

I have a situation where multiple RTOS tasks are running. Some of these are waiting on queues for data, eg RSSI, Batt Voltage Date Time to name a few, These queues then will update icons or display data on the screen.

Obviously this will require lvgl api's, thus these visual updates in the tasks are wrapped in lvgl_port_lock(), and lvgl_port_unlock().

Due to the recursive mutex nature, only the actual task can release the lvlg_port_lock, that it took.

I need to suspend or delete such tasks, as for instance in one of my cases - a critical battery shutdown. At that point I don't know if the task(s) are actually holding the mutex when I call vTaskDelete of vTaskSuspend. This results in all sorts of crashes.

How do you propose this is properly managed under your current recursive mutex.

igrr commented 4 months ago

There are multiple solutions to this problem. The one I like to use is to delegate all the UI updates to one task in the system, and then send messages to this task from other tasks. One way to do this without creating additional tasks is to use esp_event. All the tasks which generate events can send these events to the esp_event dispatcher task. Event handlers will be executed from the dispatcher task, performing necessary actions (such as updating the UI).

In the event of a shutdown, typically you don't need to worry about the esp_event task, you can enter deep sleep or power down the system without first deleting this task.

wreyford commented 4 months ago

Thx @igrr for your advice. I see that under the hood the esp_event uses tasks that are created with queues and stack space, priorities and core affinities. This is more or less my approach too. But the tasks calling the lvgl_port_lock be they wrapped by esp_event or my rtos tasks are all in tasks, so there is no true way of knowing in a large system, what tasks, or events are running, thus what mutexes are held. I will put some more thought into it, and appreciate you excellent advice.

sukesh-ak commented 2 months ago

@wreyford You can fix this issue just from LVGL.

Use Observer from lvgl 9.0 which is very powerful and flexible. https://docs.lvgl.io/master/others/observer.html

If you are on lvlg 8.x there was lv_msg which is now deprecated and replaced by Observer above. I have used lv_msg before in my project called ESP32-TUX

VojtechBartoska commented 2 months ago

@wreyford Can this ticket be closed as answered? Thanks

wreyford commented 1 month ago

Thx for valuable advice.