驱动终于写完了,这是我的项目的最后一个驱动,虽然还有wifi的驱动,但是由于时间关系,决定就拿内核自带的wifi驱动改一改算了,今天为大家献上超声波测距模块的驱动,希望大家能够喜欢,发了这个之后就是项目了,所以这是最后一个驱动。
硬件平台:OK210;
os :Linux2.6.35.7
驱动类型:hc_sr04
驱动程序如下:
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- //#include
- #define MEM_MAGIC 'h' //»ÃÊý
- #define HC1_START _IO(MEM_MAGIC , 0)
- #define HC1_END _IO(MEM_MAGIC , 1)
- #define HC2_START _IO(MEM_MAGIC , 2)
- #define HC2_END _IO(MEM_MAGIC , 3)
- static int major;
- static struct class *led_class;
- static unsigned long *gpio_con;
- static unsigned long *gpio_data;
- static int pin1, pin2;
- struct timespec now;
- char flag=0;
- unsigned long data[2]={0,0};
- unsigned long s=0,ns=0;
- long getnstime()
- {
- getnstimeofday(&now);
- }
- static struct resource hc_sr04_resources[] = {
- [0] = {
- .start = 0xE0200C40,
- .end = 0xE0200C44 - 1,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = 2,
- .end = 2,
- .flags = IORESOURCE_IRQ,
- },
- [2] = {
- .start = 3,
- .end = 3,
- .flags = IORESOURCE_IRQ,
- }
- };
- //static struct timer_list key_timer;
- static irqreturn_t gpio_keys_isr(int irq, void *dev_id)
- {
- if(flag==0)
- {
- flag = 1;
- getnstime();
- s = now.tv_sec;
- ns = now.tv_nsec;
- //printk("interrupt type is rising n");
- }
- else
- {
- flag = 0;
- data[0] = 0;
- data[1] = 0;
- getnstime();
- data[0] = now.tv_sec-s;
- if(data[0])
- data[1]= data[0]*1000000000+now.tv_nsec-ns;
- else
- data[1] =now.tv_nsec-ns;
- //printk("interrupt type is falling !!!!!!!!! nn");
- }
- return IRQ_HANDLED;
- }
- static ssize_t hc_sr04_read (struct file *file, char __user *buff, size_t size, loff_t *loff)
- {
- copy_to_user(buff,data,sizeof(data));
- flag=0; //¶ÁÍêºó½«flagÇåÁ㣬ȷ±£Ï´ÎÄÜ׼ȷÅжÏÖжϱßÑØ
- return size;
-
-
- }
- static void hc_sr04_release(struct device *dev)
- {
-
- printk("%sn", __func__);
- }
- static struct platform_device hc_sr04_device = {
- .name = "hc_sr04s",
- .num_resources = ARRAY_SIZE(hc_sr04_resources),
- .resource = hc_sr04_resources,
- .dev = {
- .release = hc_sr04_release,
- }
- };
- static int hc_sr04_open(struct inode *inode, struct file *file)
- {
- char irq=0;
- *gpio_con &= ~((0xf << (pin1 * 4)) | (0xf << (pin2 * 4)));
- *gpio_con |= (1 << (pin1 * 4)) | (0xf << (pin2 * 4));
- irq = gpio_to_irq(S5PV210_GPH2(3));
- request_irq(irq, gpio_keys_isr, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING ,0,(void *)0);
- return 0;
- }
- static int hc_sr04_close(struct inode *inode, struct file *file)
- {
- char irq=0;
- irq = gpio_to_irq(S5PV210_GPH2(3));
- free_irq(irq, (void *)0);
- //del_timer(&key_timer);
- return 0;
- }
- static long hc_sr04_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
- {
- switch (cmd) {
- case HC1_START:
-
- *gpio_data |= (1 << pin1);
- udelay(50);
- *gpio_data &= ~(1 << pin1);
- break;
- case HC1_END:
- //*gpio_data &= ~(1 << pin1);
- break;
- case HC2_START:
- //*gpio_data |= (1 << pin2);
- break;
- case HC2_END:
- //*gpio_data &= ~(1 << pin2);
- break;
- default:
- return -1;
- };
- return 0;
- }
- static struct file_operations hc_sr04_fops = {
- .open = hc_sr04_open,
- .read = hc_sr04_read,
- .release = hc_sr04_close,
- .unlocked_ioctl = hc_sr04_ioctl,
- };
- static int hc_sr04_probe(struct platform_device *dev)
- {
- struct resource *res;
-
- major = register_chrdev(0, "hc_sr04s", &hc_sr04_fops);
- led_class = class_create(THIS_MODULE, "hc_sr04s");
- device_create(led_class, NULL, MKDEV(major, 0), NULL, "hc_sr04s");
- res = platform_get_resource(dev, IORESOURCE_MEM, 0);
- gpio_con = ioremap(res->start, res->end - res->start + 1);
- gpio_data = gpio_con + 1;
- res = platform_get_resource(dev, IORESOURCE_IRQ, 0);
- pin1 = res->start;
- res = platform_get_resource(dev, IORESOURCE_IRQ, 1);
- pin2 = res->start;
- return 0;
- }
- static int hc_sr04_remove(struct platform_device *dev)
- {
- iounmap(gpio_con);
- device_destroy(led_class, MKDEV(major, 0));
- class_destroy(led_class);
- unregister_chrdev(major, "hc_sr04s");
-
- return 0;
- }
- static struct platform_driver hc_sr04_driver = {
- .probe = hc_sr04_probe,
- .remove = hc_sr04_remove,
- .driver = {
- .name = "hc_sr04s",
- },
- };
- static int hc_sr04_init(void)
- {
- platform_device_register(&hc_sr04_device);
- platform_driver_register(&hc_sr04_driver);
- return 0;
- }
- static void hc_sr04_exit(void)
- {
- platform_driver_unregister(&hc_sr04_driver);
- platform_device_unregister(&hc_sr04_device);
- }
- module_init(hc_sr04_init);
- module_exit(hc_sr04_exit);
- MODULE_LICENSE("GPL");
下面是makefile文件
- obj-m := hc_sr04.o
- KDIR := /my_dir/linux-smart210/
- all:
- make -C $(KDIR) M=$(PWD) modules CROSS_COMPILE=arm-linux- ARCH=arm
- clean:
- rm -f *.ko *.o *.mod.o *.mod.c *.symvers *.bak *.order
驱动程序经过测试能够正常使用,测距精度在2cm~4m范围内可达一毫米,由于驱动程序不是很复杂,具体的应用程序请大家仔细阅读驱动程序。
接下来的时间小弟会为大家跟上项目“基于arm的泊车导航系统”。