有没有人遇到过F1C200S运行LVGL随机卡死的?我的系统在移植LVGL之前连夜跑过无限memtest循环,没有出现死机的问题。
最近移植了LVGL,并启用了看门狗,设置为1秒,然后主线程里面每隔100ms喂一次狗。现在开始出现随机的重启,时间在20分钟到两小时不等。
我看了一下,系统里面只有四个任务在运行,主线程,图形线程,通信线程和一个内核定时器。
主线程就是循环延时喂狗,图形线程就是每隔10ms刷一次lv_task_handler(),通信线程就是循环非阻塞poll stdin。
所有延时都是基于以下函数实现的:
void sleep(int ms)
{
clock_t tend=clock()+ms*1000;
while(likely(clock()<tend)) task_yield();
}
系统是XBoot,非抢占,所以任何线程没有及时放开资源都会导致整个系统锁死。
讲道理这个函数每一次wrap around需要50万年(最大值是2^64,单位是us)。
其他的地方我想不到会出问题了,除非lvgl那两个函数会锁死。
咋办?
离线
clock()是啥?觉得这种sleep的实现效果很飘忽。
离线
clock()是啥?觉得这种sleep的实现效果很飘忽。
内核时钟,上电清零。原版内核的sleep实现更惨,就是循环,烧cpu周期,完全卡死别的线程。
不过你这么一问倒是给我点了一道,很有可能是nice值和调度器算法的锅。
我应该试着把串口线程的nice值调高点,目前main是0,串口是-5,图形是5。我把串口nice调成0试试。
离线
内核时钟,上电清零。原版内核的sleep实现更惨,就是循环,烧cpu周期,完全卡死别的线程。
不过你这么一问倒是给我点了一道,很有可能是nice值和调度器算法的锅。
我应该试着把串口线程的nice值调高点,目前main是0,串口是-5,图形是5。我把串口nice调成0试试。
bug解决了吗?
离线
bug解决了吗?
代码重写了,原来的三线程让我合到一起了。一个timer任务更新lvgl的tick,其他的任务都做到main_task里面了。
反正ARM9主频高,刷新一下花不了太长时间,从串口的角度看应该是没有延迟的。
而且就算我分了三个线程,XBoot的协程机制也没法保证串口的实时性。无论如何我都得等当前任务忙完了才能切换线程。
所以我干脆把每次刷新的buffer大小改小,借以减少lvgl的线程粒度,然后把三个任务放一起做,给串口高一点的优先级(如果串口buffer不读完不进行下一步操作)。
这样我的最坏延迟就是刷屏幕的几分之一花的时间,只要保证这个时间里面串口buffer不爆炸就好了。
F1C200S有64字节的硬件串口buffer,外加stdio的4096字节,总共4160字节。算上开始位和停止位,共41600符号。
在115.2k的波特率,传输41600符号需要361毫秒。我的刷屏代码咋的也不能这么慢吧。
离线
最开始分线程就是典型的先入为主,想的很好,但是完全忽略了XBoot是非抢占式的,而且buffer远大于需求等等事实,典型的通常怎么好就怎么搞而脱离现状。
离线
应该也是偏离了xboot原来的定位,本来他就不是一个多线程的,非要分多线程就造成无法预知的bug,像你上面所说协调好自己的任务在一个线程就行了,且屏幕也不一定是时时全屏刷新的呀,只刷内容改变部分也是很快的。
离线