您的位置 首页 电子

当主函数与中止函数同享变量问题

当时开发的一个产品,一项功能是在通电后播放40秒的语音.测试时发现,大约通电70-80次就有一次播放时间不够40秒就提前停止。当时以为复位有…

其时开发的一个产品,一项功用是在通电后播映40秒的语音.
测验时发现,大约通电70-80次就有一次播映时刻不行40秒就提早中止。
其时认为复位有问题,换了复位片,没好。又先后换了CPU,语音芯片,还有电源,都没有好转。排除了硬件芯片原因导致的此现象.
后来又从软件中查找原因。重复查找软件逻辑,也没发现问题。后来偶尔发现在主while里添加很多延时后,稳定性进步。
简直不再出现问题。可是我仍是觉得不对劲,用了两天时刻总算找到了原因。由于这是公司的程序,所以不能贴源码。
我把其他程序都省略,只把犯错的程序大约写一下。我们看看能找到问题吗?
unsigned int ms_counter;
void T0()
{
//定时器程序每100毫秒中止一次,程序略
if (ms_counter<1000) ms_counter++;
}
void main(void)
{
//初始化定时器程序每100毫秒中止一次,程序略
unsigned char tt;
ms_counter=0;
tt=0;//用tt操控只响一次
while(1)
{
if (ms_counter<400)
{
if (tt==0)
{
tt=1;
Sound_on();
}
}
else
{
Sound_off();
}
//其他程序
//。。。。。。
}
}

高手们不要笑,菜鸟们坐好
问题出在ms_counter不到400时,程序提早执行了Sound_off();
原因剖析:if (ms_counter<400)中的ms_counter是两字节的整型,并且在中止里有增一操作。
这就有一种过错的或许
if (ms_counter<400)//被编译器翻译成以下句子
+0000007C:E9E0LDIR30,0x90Load immediate
+0000007D:E0F1LDIR31,0x01Load immediate
+0000007E:164ECPR4,R30Compare
+0000007F:065FCPCR5,R31Compare with carry
+00000080:F428BRCC+0x05Branch if carry cleared
在ms_counter==255时R4是255R5是0

CPR4,R30;这时R4是255
留意!如果在这两条句子中心产生了中止ms_counter增一今后R4是0R5是1
CPCR5,R31;这时R5是1

简略的说是由于在整型数增一进位的时分,又遭到中止的影响。
原本正确值0x00ff或0x0100(ms_counter),
实践过错值0x01ff(ms_counter)先判别低位时低位是FF,中止后判别高位时高位是01
ms_counter在255时被误认为511(0x01ff)导致提示音提早封闭。

主函数中止函数共用变量时,或许产生:
1.主函数对变量的读-写,或许形成中止函数对变量的读-写无效。
如:当主函数刚刚把变量读入到内部寄存器时,还未再回写到变量中时,产生中止,中止中改写了变量。当中止回来时,主函数将值再回写到变量中。形成中止函数对变量的改写无效。
2.多字节变量读取过错。
如:当变量的其间一个字节读入到寄存器中时,产生中止,中止中改写了变量值。当中止回来时,变量的其他字节持续被读入到寄存器中,形成新旧字节组合过错。

主函数与中止函数同享变量问题相似两个线程同享资源的问题,怎么处理同享资源抵触是体系结构设计的要害
处理方法
1.volatile正确运用.
2.留意临界段(或原子操作).(写变量时,关中止,写完后再开)

操作体系中对这种问题有另一种处理办法,即引进一个与ms_counter相同类型的暂时变量:
unsigned int tmp_counter;

在运用ms_counter做判别前作如下操作:
do {
tmp_counter = ms_counter;
while (tmp_counter != ms_counter);

然后运用tmp_counter替代ms_counter进行判别,这样能够确保逃避楼主所述问题。

一般说来,volatile用在如下的几个当地:
1)、中止服务程序中修正的供其它程序检测的变量需求加volatile;

2)、多使命环境下各使命间同享的标志应该加volatile;
3)、存储器映射的硬件寄存器一般也要加volatile阐明,由于每次对它的读写都或许由不同含义;

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/qiche/dianzi/276724.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部