完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
扫一扫,分享给好友
|
|
|
|
百度了一下,凑了一段代码出来,直接在nanopi-neo里面make出gpio_int.ko模块。
/*---------------------------- gpio_int.c -----------------------*/ #include #include #include #include #include #include #include #include #include #include static unsigned int gpio_num=203; //--linux num. for GP11 unsigned int int_num=0;//--interrupter number static struct work_struct int_wq; //--work queue for INT handler low part static void enable_int_wq(struct work_struct *data) { printk(KERN_INFO"Entering work_queue and start msleep....n"); msleep_interruptible(3000); printk(KERN_INFO"Re-enable irq now....n"); enable_irq(int_num); } static irqreturn_t int_handler(int irq, void *dev_id) { printk(KERN_INFO "------ gpio_to_irq(PG11) triggered! -----n"); printk(KERN_INFO "Disable irq ...n"); disable_irq_nosync(int_num); //--!!!Must NOT use disable_irq() anyway,it's cause deadloop and will crash the kernel //----- irq handler low part ------- schedule_work(&int_wq); return IRQ_HANDLED; } static int register_gpio_irq(void) { int int_result=0; int_result=request_irq(int_num,int_handler,IRQF_TRIGGER_RISING,"GPIO_INT_Midas",(void *)&gpio_num); if(int_result != 0) { printk(KERN_EMERG "--- GPIO request irq failed! ---n"); } return int_result; } static int __init gpio_int_init(void) { int ret=-1; printk(KERN_INFO"------ Start init gpio_int -----n"); gpio_set_value(gpio_num,0); gpio_direction_input(gpio_num); //-set gpio direction int_num=gpio_to_irq(gpio_num); if(int_num>0) printk(KERN_INFO "------ gpio_to_irq(PG11):%d -----n",int_num); else return -1; ret=register_gpio_irq(); if(ret!= 0) { printk(KERN_EMERG "----- register_gpio_irq() failed! ----n"); return -1; } else //---init wor-queue for irq-handler low part INIT_WORK(&int_wq,enable_int_wq); return 0; } static void __exit gpio_int_exit(void) { if(int_num > 0) free_irq(int_num,(void *)&gpio_num); //---!!! void *dev_id MUST be presented,even no IRQF_SHARED flag in request_irq() printk(KERN_EMERG "------ gpio interrupt test exit -----n"); } module_init(gpio_int_init); module_exit(gpio_int_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Linux"); MODULE_DESCRIPTION("gpio-int-test"); /*---------------------------- END -----------------------*/ |
|
|
|
|
|
|
|
但是有个问题,disable_irq_nosync()好像并不能关闭硬件中断,在关闭irq期间产生的中断标记位似乎都被记录下来了,当再次enable_irq()的时候,就会再次触发中断程序的执行....
|
|
|
|
本帖最后由 midaszhou 于 2017-7-24 13:58 编辑
忘了在中断处理程序中先清理中断标记和关闭硬中断了. 还有,把PGIO设置成PULL_DOWN就可以不用外部拉低了。不过对于Multi-Driving SELECT还是没搞懂... |
|
|
|
加了一个蜂鸣器,每一次中断会触发蜂鸣器鸣叫,期间此中断被关闭。 尽管是一个很傻的功能,但是用来学习和理解GPIO中断却也不错.... |
|
|
|
|
|
|
|
midaszhou 发表于 2017-7-24 13:13 你驱动makefile怎么写的,分享下吧,怎么在neo上直接编译驱动 |
|
|
|
本帖最后由 midaszhou 于 2017-7-31 15:49 编辑
很简单的 obj-m := gpio_int.o PWD := $(shell pwd) K_DIR := /works/linux all: $(MAKE) -C $(K_DIR) M=$(PWD) modules clean: $(MAKE) -C $(K_DIR) M=$(PWD) clean 我把官方的linux11.4源码放在nanopi-neo的 /works/linux 下编译了下。nanopi-neo这个环境真的是学习LINUX的好地方! |
|
|
|
|
|
|
|
midaszhou 发表于 2017-7-24 13:13 我按着上面的方法试过了,确实是没有清除中断标志位。但是,我不知道怎么清除,请指教。 |
|
|
|
只有小组成员才能发言,加入小组>>
369个成员聚集在这个小组
加入小组NanoPi m3适合刷什么系统,刚接触玩,我刷了一个比较卡
5426 浏览 1 评论
7163 浏览 1 评论
4766 浏览 1 评论
【NanoPC-T4试用体验】4、手把手教你从单片机移植驱动到ARM Linux上
7723 浏览 1 评论
【NanoPC-T4试用体验】NanoPC-T4控制步进电机
24577 浏览 1 评论
NanoPi m3适合刷什么系统,刚接触玩,我刷了一个比较卡
5427浏览 1评论
428浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-17 00:20 , Processed in 8.588943 second(s), Total 91, Slave 82 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号