字元裝置字驅動理解(二)實現點亮一個燈
阿新 • • 發佈:2020-12-20
點亮一個燈的過程:
1.首先寫出字元裝置驅動的框架
2. 在open 函式中初始化各個引腳的內容
3. 在write函式中點亮燈
我們首先先寫出字元裝置的框架:如下面程式所示:
#include <linux/module.h> #include <linux/kernel.h> #include <linux/fs.h> #include <linux/init.h> #include <linux/delay.h> #include <linux/irq.h> #include <asm/uaccess.h> #include<asm/irq.h> #include <asm/io.h> #include <asm/arch/regs-gpio.h> #include <asm/hardware.h> #include <linux/poll.h> static struct class *forthdrv_class; static struct class_device *forthdrv_class_dev; volatile unsigned long *gpfcon; volatile unsigned long *gpfdat; volatileunsigned long *gpgcon; volatile unsigned long *gpgdat; static int forth_drv_open(struct inode *inode, struct file *file) { printk("this is the open function\r\n"); return 0; } ssize_t forth_drv_read(struct file *file, char __user *buf, size_t size, loff_t *ppos) { printk("this is the read function\r\n"); return 0; } static struct file_operations sencod_drv_fops = { .owner = THIS_MODULE, /* ����һ���꣬�������ģ��ʱ�Զ�������__this_module���� */ .open = forth_drv_open, .read = forth_drv_read, }; int major; static int forth_drv_init(void) { major = register_chrdev(0, "forth_drv", &sencod_drv_fops); forthdrv_class = class_create(THIS_MODULE, "forth_drv"); forthdrv_class_dev = class_device_create(forthdrv_class, NULL, MKDEV(major, 0), NULL, "buttons"); /* /dev/buttons */ return 0; } static void forth_drv_exit(void) { unregister_chrdev(major, "forth_drv"); return 0; } module_init(forth_drv_init); module_exit(forth_drv_exit); MODULE_LICENSE("GPL");
然後我們新增硬體的設定:
#include <linux/module.h> #include <linux/kernel.h> #include <linux/fs.h> #include <linux/init.h> #include <linux/delay.h> #include <linux/irq.h> #include <asm/uaccess.h> #include <asm/irq.h> #include <asm/io.h> #include <asm/arch/regs-gpio.h> #include <asm/hardware.h> #include <linux/poll.h> static struct class *forthdrv_class; static struct class_device *forthdrv_class_dev; volatile unsigned long *gpfcon = NULL; volatile unsigned long *gpfdat = NULL; static int forth_drv_open(struct inode *inode, struct file *file) { printk("this is the open function\r\n"); *gpfcon |= (1<<8); *gpfcon &= ~(1<<9); return 0; } ssize_t forth_drv_write (struct file *file, const char __user *buf, size_t count, loff_t *ppos) { int val; copy_from_user(&val, buf, count); if(val == 1) { *gpfdat &= ~((1<<4) | (1<<5) | (1<<6)); } else { *gpfdat |= (1<<4) | (1<<5) | (1<<6); } return 0; } ssize_t forth_drv_read(struct file *file, char __user *buf, size_t size, loff_t *ppos) { printk("this is the read function\r\n"); return 0; } static struct file_operations sencod_drv_fops = { .owner = THIS_MODULE, /* ����һ���꣬�������ģ��ʱ�Զ�������__this_module���� */ .open = forth_drv_open, .read = forth_drv_read, .write = forth_drv_write, }; int major; static int forth_drv_init(void) { major = register_chrdev(0, "forth_drv", &sencod_drv_fops); forthdrv_class = class_create(THIS_MODULE, "forth_drv"); forthdrv_class_dev = class_device_create(forthdrv_class, NULL, MKDEV(major, 0), NULL, "buttons"); /* /dev/buttons */ gpfcon = ioremap(0x56000050, 16); //remap the IO address to virsual linux address gpfdat = gpfcon + 1; return 0; } static void forth_drv_exit(void) { unregister_chrdev(major, "forth_drv"); iounmap(gpfcon); class_destroy(forthdrv_class); } module_init(forth_drv_init); module_exit(forth_drv_exit); MODULE_LICENSE("GPL");
這個程式碼很簡單 慢慢看就行了。