中断处理程序里的等待机制出错

nedshannon 2007-07-15 10:36:13
我编写了一个AT91RM9200平台下使用armlinux的设备驱动,主要功能是在中断程序里面读外设FPGA产生的数据,然后通过read系统调用传给用户空间,特殊一点的地方是外设需要由我自己启动。这里贴出有关的几个程序:
驱动部分:
// 全局变量声明
wait_queue_head_t mywq;
unsigned char f_rcv_over; //外设数据接收完标志
//驱动回调函数
static ssize_t my_read(struct file *filp,char *buffer,size_t count,loff_t *ppos)
{
(*(u32*)AIC_ICCR_VA) = (0x1<<myFpgaMobile_IrqNum);//清AT91中断标志
writew(0x0000,FPGA_DATA_VA[0]); //启动外设,使之产生数据
enable_irq(myFpgaMobile_IrqNum);//允许AT91接收中断
wait_event_interruptible(mywq,(f_rcv_over==1));//阻塞读进程,等待唤醒
f_rcv_over=0;
copy_to_user(buffer,mydata,count);//向用户空间传输数据
}

void my_IrqHandler(int irq,void *dev_id, struct pt_regs *regs)//中断处理程序
{ //关中断及接收FPGA产生的数据
....
//数据接收完并存放于mydata数组中,以下设置标志并唤醒被阻塞的读进程
f_rcv_over=1;
wake_up_interruptible(&mywq);
}

static int init_module(void) //驱动模块初始化程序
{ ......
init_waitqueue_head(&mywq);//初始化等待队列
......
}

用户应用程序部分:
void main(void)
{ ......
read(fpga_dev,mydata_buffer,data_length); //fpga_dev是外设的描述符
for(i=0;i<data_length;i++)
printf("0x%x,"mydada_buffer[i]);
......
}

程序编译能通过,现在每次中断处理程序运行到wake_up_interruptible(&mywq)一句是就会出错,程序完全死掉,同时中断程序接收数据的速度也很慢。如果不使用等待机制,改成如下的形式,程序工作正常,且中断接收处理也很快:
static ssize_t my_read(struct file *filp,char *buffer,size_t count,loff_t *ppos)
{
(*(u32*)AIC_ICCR_VA) = (0x1<<myFpgaMobile_IrqNum);//清AT91中断标志
writew(0x0000,FPGA_DATA_VA[0]); //启动外设,使之产生数据
enable_irq(myFpgaMobile_IrqNum);//允许AT91接收中断
while(1){
if(f_rcv_over==1) break;
}
f_rcv_over=0;
copy_to_user(buffer,mydata,count);//向用户空间传输数据
}

void my_IrqHandler(int irq,void *dev_id, struct pt_regs *regs
{ //关中断及处理接收到的数据
....
//数据接收完,并存放于mydata数组中,以下设置数据接收完标志
f_rcv_over=1;
}

请问,为什么使用等待机制不能正常工作呢?起初怀疑跟我的头文件有关系,但后来检查了又好像不是这个原因。头文件列出如下:
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/devfs_fs_kernel.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/mm.h>
#include <linux/ioport.h>
#include <linux/interrupt.h>
#include <linux/tqueue.h>
#include <linux/wait.h>
#include <asm/system.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
#include <linux/types.h>
#include <linux/ioctl.h>
...全文
159 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
nedshannon 2009-01-08
  • 打赏
  • 举报
回复
已经解决,问题源于采用的内核版本和编译器版本不一致。内核是2.4.19, 编译器用的arm-gcc3.3.2 。 改为 2.95.3可以解决
nedshannon 2007-07-16
  • 打赏
  • 举报
回复
按照《linux设备驱动程序》,这两个函数的写法都没错,编译是能通过的
Great_Bug 2007-07-16
  • 打赏
  • 举报
回复
wait_event_interruptible(mywq,(f_rcv_over==1));//阻塞读进程,等待唤醒

init_waitqueue_head(&mywq);//初始化等待队列

------
一个传对象,一个传地址,会否是其中一个有问题?
Great_Bug 2007-07-16
  • 打赏
  • 举报
回复
不懂,学习...

21,595

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 驱动开发/核心开发
社区管理员
  • 驱动开发/核心开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧