我们的电子表产品有一个墨水屏,整个系统使用Dialog14585芯片来驱动,每秒都会尝试刷新屏幕。墨水屏有一个特点是,就算是断电了,屏幕还是能正常显示出内容的。中间有几次发现,屏幕彻底不动了,看起来是程序死机了,但是蓝牙仍然正常工作,说明没有死机。
开始找问题。我设计的应用架构,是通过一个全局的timer来驱动各种测温湿度、刷新屏幕、存储数据和更新广播内容等逻辑的,这个timer必须要在进入sleep的时候仍然有效,但是14585芯片上只提供了2个Timer,一般用于PWM之类的,但是这两个Timer跑起来功耗很大(相对的)。这里的话,使用了内核的timer,叫做ke_timer。sdk的描述是 “This module implements the functions used for managing kernel timers.”,这个timer的特点是跟随内核一起跑的,休眠的时候也能生效。关键是,功耗相对于芯片上的两个Timer模块几乎不计。然后,细心体贴的Dialog提供了一个app_easy_timer的文件,让这个timer的使用变得极为方便。
然后,这个timer有几个特别重要的地方需要注意,不然就是一个超级大坑。
一个是这个timer是随着BT内核一起启动的,BT的初始化没有完成之前,使用这个timer无效。具体的在应用上需要注意的就是,不可以在 app_on_init 的时候调用,必须在app_on_db_init_complete 之后。
另一个问题是,内核提供的这个Timer可以计时的长度是有上限的,源文件中给出的描述是Max timer delay 41943sec (4194300 * 10ms),大约11.6小时。大多数时候不需要这么长时间的delay,但是难保有失心疯的...
然后,真正的深坑来了,这是个很容易