移植wouoUI到stm32 freertos上遇到的bug
寄寄boy233
编辑于 2024年04月20日 17:35
收录于文集
共1篇

    wouoUI是B站up @音游玩的人​ 开源的一款ui框架,基于u8g2库。这个框架特别之处在于其优雅和顺滑的用户界面设计。原始版本是使用STM32F103C8T6开发板,并采用Arduino IDE开发,本文在wouoUI的分支项目 https://gitee.com/henrycrh/stm32-f103-rct6_-wouo-ui 基础上将标准库改为了hal库,并引入了freertos。

    今天在移植的过程中发现了一个bug,当我按下EC11旋转编码器按键时,不会执行按下按键的操作,而是执行上一次的按键或者旋钮操作。

bug演示gif

之后经过Debug发现,在按键扫描函数中,当程序运行到btn.pressed = true之后,btn.id 被赋值之前,

按键扫描函数

如果发生了任务调度切换到主页面交互处理函数中,此时btn.pressed已经在按键扫描任务中被置1,但btn.id因为任务调度并没有更新,仍是上一次的交互操作,此时则会出现上文所述的bug。

这个bug就是一个经典的实时操作系统中任务调度和共享资源的问题,可以使用freertos提供的mutex互斥锁、信号量、事件组标志来解决。本文仅讨论使用mutex解决此bug的方法。

首先我们在cubemx中创建一个mutex

添加btnmutex

生成好代码之后,在按键扫描函数的btn.pressed被赋值之前给btnmutex上锁,在btn.id被赋值之后释放互斥锁,下图所示

修改的按键扫描函数

接下来继续给ui交互处理进行同样的操作,但是不能在main_proc这个主页面交互处理函数中修改,因为其他页面也需要进行互斥操作,所以在ui_proc这个全局ui处理函数中修改,在执行各页面处理函数之前上锁,处理结束之后再释放即可。如下图所示

修改后的全局ui处理函数

进行上述修改之后即可使用EC11旋转编码器进行正常的ui操作。

修改后演示gif