实在没辙了,按键驱动,麻烦大家,请指点一下,附代码~~ 谢谢

发布于 2022-09-18 18:21:55 字数 11774 浏览 18 评论 0

实在没辙了,按键驱动,麻烦大家,请指点一下,附代码~~ 谢谢
一个很简单的 按键驱动, 搞了三天也insmod不上去.... 电脑上输入insmod **.ko 后, 直接就死机了......
系统:Redhat 2.6.18
代码如下:

  1. #include <linux/module.h>
  2. #include <linux/types.h>
  3. #include <linux/fs.h>
  4. #include <linux/mm.h>
  5. #include <linux/errno.h>
  6. #include <linux/sched.h>
  7. #include <linux/init.h>
  8. #include <linux/cdev.h>
  9. #include <linux/interrupt.h>
  10. #include <asm/io.h>
  11. #include <asm/system.h>
  12. #include <asm/uaccess.h>
  13. #include <asm-arm/irq.h>
  14. #include <asm-arm/arch-s3c2410/irqs.h>
  15. #include <asm-arm/arch-s3c2410/regs-gpio.h>
  16. #include <asm-arm/arch-s3c2410/hardware.h>
  17. #define DEVICE_NAME "mini_buttons"
  18. #define BUTTONS_NUM 6
  19. #define MAX_BUTTONS_BUF 16
  20. #define BUTTONS_MAJOR 252
  21. #define BUTTONSTATUS_DOWNX 0
  22. #define BUTTONSTATUS_DOWN 1
  23. #define BUTTONSTATUS_UP 2
  24. #define BUTTONS_TIMER_DELAY (HZ/50)
  25. #define BUTTONS_TIMER_DELAY1 (HZ/10)
  26. static int buttons_major = BUTTONS_MAJOR;
  27. struct buttons_dev
  28. {
  29. struct cdev cdev;
  30. unsigned int buttonStatus[BUTTONS_NUM];
  31. unsigned char buf[MAX_BUTTONS_BUF];
  32. unsigned int head,tail;
  33. wait_queue_head_t wq;
  34. };
  35. static struct buttons_dev *buttons_devp;
  36. static struct buttons_info
  37. {
  38. unsigned int irq_no;
  39. unsigned int gpio_port;
  40. unsigned int buttons_no;
  41. }buttons_info_tab[BUTTONS_NUM] =
  42. {
  43. {IRQ_EINT8,S3C2410_GPG0,1},
  44. {IRQ_EINT11,S3C2410_GPG3,2},
  45. {IRQ_EINT13,S3C2410_GPG5,3},
  46. {IRQ_EINT14,S3C2410_GPG6,4},
  47. {IRQ_EINT15,S3C2410_GPG7,5},
  48. {IRQ_EINT19,S3C2410_GPG11,6},
  49. };
  50. static struct timer_list buttons_timer[BUTTONS_NUM];
  51. void __iomem * virt_GPGCON;
  52. void __iomem * virt_GPGDAT;
  53. void __iomem * virt_SRCPND;
  54. void __iomem * virt_INTMSK;
  55. void __iomem * virt_INTPND;
  56. void __iomem * virt_EINTPEND;
  57. void __iomem * virt_EINTMASK;
  58. void __iomem * virt_EXTINT1;
  59. void __iomem * virt_EXTINT2;
  60. static int buttons_open(struct inode *inode,struct file *filp);
  61. static int buttons_release(struct inode *inode,struct file *filp);
  62. static ssize_t buttons_read(struct file *filp,char __user *buf,
  63. size_t size,loff_t *ppos);
  64. static struct file_operations buttons_fops =
  65. {
  66. .owner = THIS_MODULE,
  67. .open = buttons_open,
  68. .release = buttons_release,
  69. .read = buttons_read,
  70. // .write = buttons_write,
  71. };
  72. static void buttons_ioremap(void)
  73. {
  74. virt_INTPND=ioremap(0x4a000010,4);
  75. virt_EINTPEND=ioremap(0x560000a8,4);
  76. virt_SRCPND=ioremap(0x4a000000,4);
  77. // virt_EXTINT0=ioremap(0x56000088,4);
  78. virt_EXTINT1=ioremap(0x5600008c,4);
  79. virt_EXTINT2=ioremap(0x56000090,4);
  80. virt_GPGDAT=ioremap(0x56000064,4);
  81. virt_EINTMASK=ioremap(0x560000a4,4);
  82. virt_INTMSK=ioremap(0x4a000008,4);
  83. virt_GPGCON=ioremap(0x56000060,4);
  84. }
  85. static void buttons_iounmap(void)
  86. {
  87. iounmap(&virt_INTPND);
  88. iounmap(&virt_EINTPEND);
  89. iounmap(&virt_SRCPND);
  90. // iounmap(&virt_EXTINT0);
  91. iounmap(&virt_EXTINT1);
  92. iounmap(&virt_EXTINT2);
  93. iounmap(&virt_GPGDAT);
  94. iounmap(&virt_EINTMASK);
  95. iounmap(&virt_INTMSK);
  96. iounmap(&virt_GPGCON);
  97. }
  98. static void buttons_enable_irq(void)
  99. {
  100. unsigned int value;
  101. iowrite32((1<<5),virt_SRCPND);
  102. iowrite32((1<<5),virt_INTPND);
  103. value = ioread32(virt_INTMSK);
  104. value &= ~(1<<5);
  105. iowrite32(value,virt_INTMSK);
  106. value = 0;
  107. value |= (1<<8)|(1<<11)|(1<<13)|(1<<14)|(1<<15)|(1<<19);
  108. iowrite32(value,virt_EINTPEND);
  109. value = ioread32(virt_EINTMASK);
  110. value &= ~((1<<8)|(1<<11)|(1<<13)|(1<<14)|(1<<15)|(1<<19));
  111. iowrite32(value,virt_EINTMASK);
  112. }
  113. static void buttons_enable_irq_again(void)
  114. {
  115. unsigned int value;
  116. value = 0;
  117. value = ioread32(virt_INTPND);
  118. if(value = (1<<5))
  119. {
  120. iowrite32((1<<5),virt_SRCPND);
  121. iowrite32((1<<5),virt_INTPND);
  122. value = ioread32(virt_EINTPEND);
  123. if(value = (1<<8))
  124. {
  125. iowrite32(value,virt_EINTPEND);
  126. }else if(value = (1<<11))
  127. {
  128. iowrite32(value,virt_EINTPEND);
  129. }else if(value = (1<<13))
  130. {
  131. iowrite32(value,virt_EINTPEND);
  132. }else if(value = (1<<14))
  133. {
  134. iowrite32(value,virt_EINTPEND);
  135. }else if(value = (1<<15))
  136. {
  137. iowrite32(value,virt_EINTPEND);
  138. }else if(value = (1<<19))
  139. {
  140. iowrite32(value,virt_EINTPEND);
  141. }
  142. }
  143. }
  144. static void buttons_lowlevel(void)
  145. {
  146. unsigned int value;
  147. value = 0;
  148. value &= ~((7<<0)|(7<<12)|(7<<20)|(7<<24)|(7<<28));
  149. iowrite32(value,virt_EXTINT1);
  150. value &= ~(7<<12);
  151. iowrite32(value,virt_EXTINT2);
  152. }
  153. static int buttons_open(struct inode *inode,struct file *filp)
  154. {
  155. filp->private_data = buttons_devp;
  156. buttons_devp->head = buttons_devp->tail =0;
  157. return 0;
  158. }
  159. static int buttons_release(struct inode *inode,struct file *filp)
  160. {
  161. return 0;
  162. }
  163. static ssize_t buttons_read(struct file *filp,char __user *buf,
  164. size_t size,loff_t *ppos)
  165. {
  166. int ret;
  167. retry:if(buttons_devp->head != buttons_devp->tail)
  168. {
  169. // buf = buttons_devp->buf[buttons_devp->tail];
  170. ret = copy_to_user(buf,(void *)buttons_devp->buf[buttons_devp->tail],sizeof(unsigned char));
  171. (buttons_devp->tail)++;
  172. if(buttons_devp->tail == MAX_BUTTONS_BUF)
  173. {
  174. buttons_devp->tail = 0;
  175. }
  176. }else{
  177. __set_current_state(TASK_INTERRUPTIBLE);
  178. if(filp->f_flags & O_NONBLOCK)
  179. {
  180. return -EAGAIN;
  181. }
  182. schedule();
  183. if(signal_pending(current))
  184. {
  185. return -ERESTARTSYS;
  186. }
  187. goto retry;
  188. }
  189. return ret;
  190. }
  191. static int is_buttons_down(unsigned long data)
  192. {
  193. int key = data;
  194. unsigned long ret;
  195. void __iomem * base = S3C24XX_GPIO_BASE(buttons_info_tab[key].gpio_port);
  196. unsigned long offs = S3C2410_GPIO_OFFSET(buttons_info_tab[key].gpio_port);
  197. ret = __raw_readl(base + 0x04) & (1 << offs);
  198. if(ret == 0)
  199. return 1;
  200. else
  201. return 0;
  202. }
  203. static void buttons_event(int data)
  204. {
  205. int key = data;
  206. buttons_devp->buf[buttons_devp->head] = buttons_info_tab[key].buttons_no;
  207. (buttons_devp->head)++;
  208. if(buttons_devp->head == MAX_BUTTONS_BUF)
  209. buttons_devp->head = 0;
  210. wake_up_interruptible(&buttons_devp->wq);
  211. }
  212. static void buttons_timer_func(unsigned long data)
  213. {
  214. int key = data;
  215. if(is_buttons_down(key))
  216. {
  217. if(buttons_devp->buttonStatus[key] == BUTTONSTATUS_DOWNX)
  218. {
  219. buttons_devp->buttonStatus[key] == BUTTONSTATUS_DOWN;
  220. buttons_event(key);
  221. buttons_timer[key].expires = jiffies + BUTTONS_TIMER_DELAY1;
  222. add_timer(&buttons_timer[key]);
  223. }else{
  224. buttons_timer[key].expires = jiffies + BUTTONS_TIMER_DELAY1;
  225. add_timer(&buttons_timer[key]);
  226. }
  227. }else{
  228. buttons_devp->buttonStatus[key] == BUTTONSTATUS_UP;
  229. enable_irq(buttons_info_tab[key].irq_no);
  230. }
  231. }
  232. static irqreturn_t buttons_eint_func(int irq,void *dev_id,struct pt_regs *regs)
  233. {
  234. int key = dev_id;
  235. disable_irq(buttons_info_tab[key].irq_no);
  236. buttons_enable_irq_again();
  237. buttons_devp->buttonStatus[key] = BUTTONSTATUS_DOWNX;
  238. buttons_timer[key].expires = jiffies + BUTTONS_TIMER_DELAY;
  239. add_timer(&buttons_timer[key]);
  240. }
  241. static int request_irqs(void)
  242. {
  243. int i,ret;
  244. buttons_lowlevel();
  245. for(i = 0;i < sizeof(buttons_info_tab)/sizeof(buttons_info_tab[1]);i++)
  246. {
  247. set_irq_type(buttons_info_tab[i].irq_no,IRQT_LOW);
  248. ret = request_irq(buttons_info_tab[i].irq_no,buttons_eint_func, SA_INTERRUPT,DEVICE_NAME,i);
  249. if(ret)
  250. return - EINVAL;
  251. }
  252. return 0;
  253. }
  254. static int buttons_setup_cdev(struct buttons_dev *dev,int index)
  255. {
  256. int err,devno = MKDEV(buttons_major,index);
  257. cdev_init(&dev->cdev,&buttons_fops);
  258. dev->cdev.owner = THIS_MODULE;
  259. dev->cdev.ops = &buttons_fops;
  260. err = cdev_add(&dev->cdev,devno,1);
  261. if(err)
  262. printk(KERN_NOTICE "Error %d adding",err);
  263. buttons_enable_irq();
  264. request_irqs();
  265. /***** IOREMAP *****/
  266. buttons_ioremap();
  267. return 0;
  268. }
  269. static int __init buttons_init(void)
  270. {
  271. int i,result;
  272. dev_t devno = MKDEV(buttons_major,0);
  273. if(buttons_major)
  274. result = register_chrdev_region(devno,1,DEVICE_NAME);
  275. else{
  276. result = alloc_chrdev_region(&devno,0,1,DEVICE_NAME);
  277. buttons_major = MAJOR(devno);
  278. }
  279. if(result)
  280. return result;
  281. buttons_devp->head = buttons_devp->tail = 0;
  282. for(i = 0;i < BUTTONS_NUM;i++)
  283. buttons_devp->buttonStatus[i] = BUTTONSTATUS_UP;
  284. for(i = 0;i < BUTTONS_NUM;i++)
  285. setup_timer(&buttons_timer[i],buttons_timer_func,i);
  286. init_waitqueue_head(&(buttons_devp->wq));
  287. buttons_setup_cdev(buttons_devp,0);
  288. return 0;
  289. }
  290. module_init(buttons_init);
  291. static void __exit buttons_exit(void)
  292. {
  293. int i;
  294. // for(i = 0;i < sizeof(buttons_info_tab)/sizeof(buttons_info_tab[i]);i++)
  295. buttons_iounmap();
  296. for(i = 0;i < sizeof(buttons_info_tab)/sizeof(buttons_info_tab[i]);i++)
  297. free_irq(buttons_info_tab[i].irq_no,i);
  298. cdev_del(&buttons_devp->cdev);
  299. for(i = 0;i < BUTTONS_NUM;i++)
  300. del_timer(&buttons_timer[i]);
  301. unregister_chrdev_region(MKDEV(buttons_major,0),1);
  302. }
  303. module_exit(buttons_exit);
  304. MODULE_LICENSE("Dual BSD/GPL");
  305. MODULE_AUTHOR("bejoey_pro");

复制代码

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

じ违心 2022-09-25 18:21:55

设置一堆printk(KERN_INFO "point x\n");

这样的~ 看看加载到第几步死机吧~

而且最好用个虚拟机来试试~ 这样死机也不用重启~

那片花海 2022-09-25 18:21:55

原帖由 superfight 于 2009-4-12 10:54 发表
设置一堆printk(KERN_INFO "point x\n");

这样的~ 看看加载到第几步死机吧~

而且最好用个虚拟机来试试~ 这样死机也不用重启~

他的平台应该是s3c24××  不是pc把。所以系统:Redhat 2.6.18 没有用。

最好是增加printk。    检查中断是否一直在中断。(set_irq_type(buttons_info_tab.irq_no,IRQT_LOW);)

伴我心暖 2022-09-25 18:21:55

这句话有问题吧,buttons_devp->head = buttons_devp->tail = 0;
buttons_devp申请空间了么?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文