代码示例_中断
?
?
?
//頭文件 #include <linux/init.h> #include <linux/module.h> #include <linux/fs.h> #include <linux/device.h> #include <linux/slab.h> #include <linux/gpio.h> #include <linux/cdev.h> #include <linux/interrupt.h> #include <linux/input.h>#include <asm/io.h> #include <asm/string.h> #include <asm/uaccess.h> #include <asm-generic/ioctl.h>#define LED_NUM_ON _IOW('L',0x1122,int) #define LED_NUM_OFF _IOW('L',0x3344,int) #define LED_ALL_ON _IO('L',0x1234) #define LED_ALL_OFF _IO('L',0x5678)//定義一個按鍵的數據包 struct button_event{int code; //按鍵的名稱---鍵值:KEY_DOWNint value; //按鍵的狀態---按下:1,松開:0 };//面向對象編程----設計設備的類型 struct s5pv210_button{//unsigned int major; dev_t devno;struct class * cls;struct device * dev;struct cdev *cdev;unsigned int irqno;struct button_event event;int data; }; struct s5pv210_button *button_dev;//實現中斷處理函數--------當觸發中斷時會被執行 irqreturn_t button_irq_svc(int irqno, void *dev) {int value;printk("--------^_^ %s------------\n",__FUNCTION__);//獲取按鍵信息value = gpio_get_value(S5PV210_GPH0(1));//判斷是按下還是松開if(value){//松開printk("kenel:keydown up!\n");button_dev->event.code = KEY_DOWN;button_dev->event.value = 0;}else{//按下printk("kenel:keydown pressed!\n");button_dev->event.code = KEY_DOWN;button_dev->event.value = 1;}return IRQ_HANDLED; }//實現設備操作接口 int button_open(struct inode *inode, struct file *filp) {printk("--------^_^ %s------------\n",__FUNCTION__);return 0; } ssize_t button_read(struct file *filp , char __user *buf , size_t size, loff_t *flags) {int ret;printk("--------^_^ %s------------\n",__FUNCTION__);//將內核數據轉換為用戶空間數據ret = copy_to_user(buf,&button_dev->event,size);if(ret > 0){printk("copy_to_user error!\n");return -EFAULT;}//將數據返回給應用空間后,清空數據包memset(&button_dev->event,0,sizeof(button_dev->event));return size; }ssize_t button_write(struct file *filp, const char __user *buf, size_t size, loff_t *flags) {printk("--------^_^ %s------------\n",__FUNCTION__);return size; }long button_ioctl(struct file *filp, unsigned int cmd , unsigned long args) {printk("--------^_^ %s------------\n",__FUNCTION__);return 0; }int button_close(struct inode *inode, struct file *filp) {printk("--------^_^ %s------------\n",__FUNCTION__);return 0; }static struct file_operations fops = {.open = button_open,.read = button_read,.write = button_write,.unlocked_ioctl = button_ioctl,.release = button_close, };//加載函數和卸載函數 static int __init button_init(void) //加載函數-----在驅動被加載時執行 {int ret;printk("--------^_^ %s------------\n",__FUNCTION__);//0,實例化設備對象//參數1 ---- 要申請的空間的大小//參數2 ---- 申請的空間的標識button_dev = kzalloc(sizeof(struct s5pv210_button),GFP_KERNEL);if(IS_ERR(button_dev)){printk("kzalloc error!\n");ret = PTR_ERR(button_dev);return -ENOMEM;}//1,申請設備號-----新方法 #if 0//靜態申請設備號button_dev->major = 256;ret = register_chrdev_region(MKDEV(button_dev->major,0),1,"button_drv");if(ret < 0){printk("register_chrdev_region error!\n");ret = -EINVAL;goto err_kfree;} #else//動態申請設備號ret = alloc_chrdev_region(&button_dev->devno,0,1,"button_drv");if(ret < 0){printk("register_chrdev_region error!\n");ret = -EINVAL;goto err_kfree;} #endif//創建cdev//申請cdev的空間button_dev->cdev = cdev_alloc();if(IS_ERR(button_dev->cdev)){ printk("button_dev->cdev error!\n");ret = PTR_ERR(button_dev->cdev);goto err_unregister;}//初始化cdev的成員cdev_init(button_dev->cdev,&fops);//將cdev加入到內核中----鏈表ret = cdev_add(button_dev->cdev,button_dev->devno,1);//2,創建設備文件-----/dev/buttonbutton_dev->cls = class_create(THIS_MODULE,"button_cls");if(IS_ERR(button_dev->cls)){printk("class_create error!\n");ret = PTR_ERR(button_dev->cls);goto err_cdev_del;}button_dev->dev = device_create(button_dev->cls,NULL,button_dev->devno,NULL,"button");if(IS_ERR(button_dev->dev)){printk("device_create error!\n");ret = PTR_ERR(button_dev->dev);goto err_class;}//3,硬件初始化---申請中斷button_dev->irqno = IRQ_EINT(1);ret = request_irq(button_dev->irqno,button_irq_svc,IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING,"eint-keydown",NULL);if(ret != 0){printk("request_irq error!\n");ret = -EBUSY;goto err_device;}return 0;err_device:device_destroy(button_dev->cls,button_dev->devno); err_class:class_destroy(button_dev->cls);err_cdev_del:cdev_del(button_dev->cdev);err_unregister:unregister_chrdev_region(button_dev->devno,1);err_kfree:kfree(button_dev);return ret;}static void __exit button_exit(void) //卸載函數-----在驅動被卸載時執行 {printk("--------^_^ %s------------\n",__FUNCTION__);free_irq(button_dev->irqno,NULL);device_destroy(button_dev->cls,button_dev->devno);class_destroy(button_dev->cls);cdev_del(button_dev->cdev);unregister_chrdev_region(button_dev->devno,1);kfree(button_dev); }//聲明和認證 module_init(button_init); module_exit(button_exit); MODULE_LICENSE("GPL");?
?
?
?
?
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <sys/ioctl.h> #include <linux/input.h>//定義一個按鍵的數據包 struct button_event{int code; //按鍵的名稱---鍵值:KEY_DOWNint value; //按鍵的狀態---按下:1,松開:0 };int main(void) {int fd;int ret;struct button_event event;fd = open("/dev/button",O_RDWR);if(fd < 0){perror("open");exit(1);}while(1){bzero(&event,sizeof(event));ret = read(fd,&event,sizeof(event));if(ret < 0){perror("read");exit(1);}if(event.code == KEY_DOWN){if(event.value)printf("按下了下鍵!\n");elseprintf("松開了下鍵!\n");}sleep(1);}close(fd);return 0; }#include <stdio.h> #include <string.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <sys/ioctl.h> #include <linux/input.h>//定義一個按鍵的數據包 struct button_event{int code; //按鍵的名稱---鍵值:KEY_DOWNint value; //按鍵的狀態---按下:1,松開:0 };int main(void) {int fd;int ret;struct button_event event;fd = open("/dev/button",O_RDWR);if(fd < 0){perror("open");exit(1);}while(1){bzero(&event,sizeof(event));ret = read(fd,&event,sizeof(event));if(ret < 0){perror("read");exit(1);}if(event.code == KEY_DOWN){if(event.value)printf("按下了下鍵!\n");elseprintf("松開了下鍵!\n");}sleep(1);}close(fd);return 0; }?
?
?
?
?
#指定內核源碼路徑 KERNEL_DIR = /home/farsight/s5pv210/kernel/linux-3.0.8 CUR_DIR = $(shell pwd) MYAPP = testall:#讓make進入內核源碼編譯,同時將當前目錄中的c程序作為內核模塊一起編譯make -C $(KERNEL_DIR) M=$(CUR_DIR) modulesarm-none-linux-gnueabi-gcc -o $(MYAPP) $(MYAPP).cclean:#刪除上面編譯生成的文件make -C $(KERNEL_DIR) M=$(CUR_DIR) cleanrm -rf $(MYAPP)install:cp *.ko $(MYAPP) /opt/rootfs/drv_module#指定當前目錄下哪個文件作為內核模塊編 obj-m = button_drv.o?
轉載于:https://www.cnblogs.com/panda-w/p/10991402.html
總結
- 上一篇: UVa LA 4253 UVa 142
- 下一篇: 第五章 初始jQuery