ounhue
驱动牛犊
驱动牛犊
  • 注册日期2006-08-15
  • 最后登录2010-01-26
  • 粉丝0
  • 关注0
  • 积分4分
  • 威望31点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:2304回复:5

新手问题:2.6.26 中断下的奇怪问题

楼主#
更多 发布于:2010-01-22 11:46

使用 2.6.26 内核 在 ks8695x 遇到了下面的问题:


int g_nAlloc=0, g_nFree=0;
int hw_isr0(...)
{
...

    spin_lock(&g_nsLock);
    if( ((g_nAlloc+1)%250) != g_nFree ) {
        g_nAlloc = (g_nAlloc+1)%250 ;
    }

    barrier();

    if( g_nFree != g_nAlloc ) {
        g_nFree = (g_nFree+1)%250;
    }

    spin_unlock(&g_nsLock);

...
}


上述函数通过GPIO 口响应一个外部硬中断,可以确定 g_nAlloc g_nFree 只在上面的代码中涉及到,且我确定中断源只有一个。现在问题是,上述函数经过数次执行后,g_nAlloc g_nFree 的值【有时候】会出现不等的情况!可是在应用层下跑都是正常的。开始听说乱序执行可能导致类似问题,因此用了 barrier(),但好像没什么改善。我是新手,各位前辈有什么建议没有?
cyliu
论坛版主
论坛版主
  • 注册日期2003-06-13
  • 最后登录2014-04-11
  • 粉丝5
  • 关注0
  • 积分1238分
  • 威望2531点
  • 贡献值0点
  • 好评度577点
  • 原创分14分
  • 专家分10分
沙发#
发布于:2010-01-22 12:35
g_nAlloc g_nFree 的值【有时候】会出现不等的情况  这是什么意思?

走走看看开源好 Solaris vs Linux
ounhue
驱动牛犊
驱动牛犊
  • 注册日期2006-08-15
  • 最后登录2010-01-26
  • 粉丝0
  • 关注0
  • 积分4分
  • 威望31点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2010-01-22 14:44

g_nAlloc 和 g_nFree 有时候不相等的意思是, 由于响应中断,hw_isr0() 可能会被调用若干次,响应完这若干次中断后(中断由我主动触发),我会打印两者的值,发现他们的值并不是期望中的相等,而是有时候打印出来是不相等的。在应用程序或内核线程中测试从来都是相等的,跟想象的一样。
cyliu
论坛版主
论坛版主
  • 注册日期2003-06-13
  • 最后登录2014-04-11
  • 粉丝5
  • 关注0
  • 积分1238分
  • 威望2531点
  • 贡献值0点
  • 好评度577点
  • 原创分14分
  • 专家分10分
地板#
发布于:2010-01-22 15:20
由于可能数据在缓存中和内存中数据不一致,在读前最好保证这两个变量都写内存了,然后存内存中读取.
走走看看开源好 Solaris vs Linux
ounhue
驱动牛犊
驱动牛犊
  • 注册日期2006-08-15
  • 最后登录2010-01-26
  • 粉丝0
  • 关注0
  • 积分4分
  • 威望31点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2010-01-22 16:24
【由于可能数据在缓存中和内存中数据不一致,在读前最好保证这两个变量都写内存了,然后存内存中读取.】

我刚写驱动,不是太清楚怎么做到保证两个变量都写内存,并从内存读取?是把变量定义为 volatile 吗? 这种方法我尝试了,效果也是不明显的。请版主指教。

cyliu
论坛版主
论坛版主
  • 注册日期2003-06-13
  • 最后登录2014-04-11
  • 粉丝5
  • 关注0
  • 积分1238分
  • 威望2531点
  • 贡献值0点
  • 好评度577点
  • 原创分14分
  • 专家分10分
5楼#
发布于:2010-01-23 13:51
指的就是volatile .

如果这样不解决,最好把使用此变量的地方的代码提出来,否则没有办法看
走走看看开源好 Solaris vs Linux
游客

返回顶部