linux下关于中断的驱动. 求助求助

defoecn 2010-05-18 06:59:57
static int request_irqs(void)
{
struct key_info *k;
int i;
for (i = 0; i < sizeof key_info_table / sizeof key_info_table[1]; i++)
{
k = key_info_table + i;
//set_external_irq(k->irq_no, EXT_BOTH_EDGES, GPIO_PULLUP_DIS);
set_irq_type(k->irq_no, IRQT_BOTHEDGE);
if (request_irq(k->irq_no, &buttons_irq, SA_INTERRUPT, DEVICE_NAME,i))
{
//printk("irq request failed by %d \n");
return -1;
}
}
printk("irq request successfully!\n");
return 0;
}

static void free_irqs(void)
{
struct key_info *k;
int i;
for (i = 0; i < sizeof key_info_table / sizeof key_info_table[1]; i++)
{
k = key_info_table + i;
free_irq(k->irq_no, buttons_irq);
}
}
static int button_init(void)
{
int ret,i;
dev_t devno = MKDEV(button_major,0);
ret = register_chrdev_region(devno, 1, "button");
if(ret)
return ret;
button_p = kmalloc(sizeof(button_dev), GFP_KERNEL);
if(!button_p)
{
ret = -ENOMEM;
goto fail;
}

memset(button_p, 0, sizeof(button_dev));

button_setup(button_p, 0);
for(i=0;i<4;i++)
{
s3c2410_gpio_cfgpin(led_table[i].gpio, led_table[i].gpio_status);
s3c2410_gpio_setpin(led_table[i].gpio, 1);
printk("led%d initialized!\n",i+1);
}
ret = request_irqs();
if(ret)
{
printk(DEVICE_NAME " can't request irqs\n");
goto fail;
}
printk("int request ok!\n");
return 0;
fail:
unregister_chrdev_region(devno, 1);
return ret;
}

static void button_exit(void)
{
cdev_del(&button_p->cdev);
kfree(button_p);
unregister_chrdev_region(MKDEV(button_major,0), 1);
free_irqs();
}
上面是部分程序.
问题是, 先insmod 这个模块, 执行正常, 然后rmmod 这个模块. 不重启, 再insmod 出错,
提示是:
button can't request irqs
insmod: cannot insert './key.ko': Operation not permitted

请教 是free_irq没有成功吗? 还是什么别的原因?

另外 ,关于创建文件节点的问题, 以前移植过一个linux2.4的led驱动(无cdev结构), 在insmod之前要自己手动创建文件节点. 这次的驱动带了cdev结构, 所以不需要创建设备节点就能正常工作... 是因为有了cdev结构才不需要创建设备节点吗?

多谢指教.
...全文
230 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
defoecn 2010-05-27
  • 打赏
  • 举报
回复
问题解决:
free_irqs 失败.
因为dev_id参数传递错误. 编译的时候出现了一个警告, 就是关于这个内容.
现在问题解决, 警告也没有了. 可以rmmod, 然后再insmod 呵呵. 多谢各位.
soon 2010-05-22
  • 打赏
  • 举报
回复
我前几天才写了一个基于Linux内核中的驱动模块,如果楼感兴趣的话可以发给你。不过我是应用LED做为验证的工具。‘
我的邮箱: sw_2006.1230@163.com
IamGooday 2010-05-22
  • 打赏
  • 举报
回复
关于第二个问题:是这样的,这个接口函数会在自行创建设备节点。
zhongliangzhihou 2010-05-22
  • 打赏
  • 举报
回复
出错很可能是在request_irqs()中,调用request_irq()函数失败造成的。请将该函数的返回值打印出来。该函数的返回值可以告诉你注册中断失败的错误号。具体错误号可以参考request_irq()的源码
defoecn 2010-05-21
  • 打赏
  • 举报
回复
求教.
曹大夯 2010-05-21
  • 打赏
  • 举报
回复
1. button_setup()是什么函数,在moudule_init时候被调用?
2. 由于你是在request_irqs()函数返回失败后,打印的“button can't request irqs”。请在request_irqs()中打印更详细的信息。
3. 出错很可能是在request_irqs()中,调用request_irq()函数失败造成的。请将该函数的返回值打印出来。该函数的返回值可以告诉你注册中断失败的错误号。具体错误号可以参考request_irq()的源码。

21,597

社区成员

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

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