大头
Table_bottom

标签云
Table_bottom

分类
Table_bottom

日历
二月
28293031123
45678910
11121314151617
18192021222324
252627282912
Table_bottom

评论
Table_bottom

留言
Table_bottom

微博
Table_bottom

热门文章
Table_bottom

随机文章
Table_bottom

豆瓣上谁关注这里
Table_bottom

链接
Table_bottom

搜索栏
Table_bottom

RSS
RSS Link
Table_bottom

功能
Table_bottom

页面
Table_bottom

计数器
464646
Table_bottom

访客统计
Table_bottom

存档
Table_bottom

又是被优先级问题折腾了三天

loveisbug posted @ 2010年1月21日 03:14 in 工作 with tags debug 反思 , 1780 阅读

因为换用了一颗第三方前面板芯片,需要把第三方提供的驱动合到我们的系统里。上周整合好驱动,前面板的四个8段显示正常,按键有问题。

前面板排插5根pin分别是:data,clock,3.3V电压,接地,IR。

驱动是这样读取键值的(SomePanel_Read()):先写一个命令字,然后读一个byte,判断读回byte的第6位,如果是1,认为是有按键按下,送出键值;如果是0,认为不是有效键值,返回0。

u_int8 SomePanel_Read( void )
{
	u_int8 keycode = 0;
	
	SomePanel_Start(); 
	SomePanel_WrByte((u_SomePanel_GET_KEY>>7)&0x2E|0x01|0x40);
	keycode=SomePanel_RdByte();
	SomePanel_Stop();
	if(keycode&0x40 ==0)
		keycode = 0;
	return keycode;
}

task的while(1)循环里,调用SomePanel_Read()读取键值,如果是0,稍微sleep一会,再调用SomePanel_Read()读键值;如果不是0,处理处理,填好按键key结构,放到缓存队尾,再继续读。

很简单的流程,出问题了。

前面板排插和JTAG复用,无法单步调试,只能用串口打印调试。在while(1)读回键值后如果不是0,打印输出该键值。

开电后,没有按键按下,却一直送出键值。

送出的键值第6位并不是1。是一个无效键值。

按下某个按键后,能读出一个有效键值,然后又不停地送出另一个无效键值。每一个按键按下后都会送出一个不一样的无效键值。这些无效键值被放到的缓存中,于是乱套。

咨询第三方工程师,先建议我们调整SomePanel_RdByte()中拉高拉底data pin和clock pin中间的delay。增加和减少延时都没有效果。

再咨询,又建议我们把3.3V电压改为5V。也是没有效果。

量波形也没有帮助,data pin上一直有波形,没错,循环里一直很在读。只不过第6位是0的无效键值应该不会被送出啊。但它们确实送出来了。我们都觉得很奇怪。

被这个问题困扰了两天,无解。

终于,今天,在又一次又一次阅读相关的驱动代码后,找到问题所在,修改SomePanel_Read()函数后,正常。

u_int8 SomePanel_Read( void )
{
	u_int8 keycode = 0;
	
	SomePanel_Start(); 
	SomePanel_WrByte((u_SomePanel_GET_KEY >> 7) & 0x2E | 0x01 | 0x40);
	keycode = SomePanel_RdByte();
	SomePanel_Stop();
	if((keycode & 0x40) == 0)
		keycode = 0;
	return keycode;
}

又是依赖运算符优先级出了错。

不知道为什么正式发布的驱动程序里居然会有这样的问题。

其他方案里用这颗芯片也会出问题,现象可能会是丢键值,按很多下按键都没有反应,不按了突然又噌噌噌连续响应。

写程序时还是不要太相信自己对优先级的记忆,靠括号很靠谱。


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter