嵌入式学习4--混杂设备驱动
作者:互联网
混杂设备驱动主要用于一些功能简单的器件,将之整合到一起,major为10,minor一般为动态分配,其实实际的还是字符设备驱动。
比常规字符设备驱动更好的地方就是在于它简化了编写过程,将一些步骤整合到了一起,使代码更加简洁,可读性更高,也便于维护和移植。
以下代码为超声波传感器的驱动代码
1.超声波SRF05传感器,在这里只用了Vcc、Trig、Echo、GND四个脚
A.Vcc 接5V电源
B.Trig接主板输出端,主要是发送启动信号
C.Echo接输入端,主要检测这个脚传回来的值进行距离计算
D.GND接地
使用注意:如果带电操作,一定要保证先接地,否则极易损坏器件
2.时序图
A.触发信号为至少维持20uS的高电平信号,需要控制Trig引脚来做启动
B.模块会发出8个40KHz的脉冲信号,并检测回波
C.如果有回波,就输出回响信号,回响信号会通过Echo引脚检测,检测到后做相应的处理
D.计算的公式为
3.以下为驱动代码,Linux驱动代码需要从下向上看
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <mach/platform.h>
#include <linux/errno.h>
#include <linux/input.h>
#include <linux/cdev.h>
#include <linux/miscdevice.h>
#include <linux/gpio.h>
#include <asm/uaccess.h>
#define DEVICE_NAME "ultra_drv"
#define GPIOC_CFG_ULTRA_TRIG (PAD_GPIO_B + 28) //Trig引脚
#define GPIOC_CFG_ULTRA_ECHO (PAD_GPIO_B + 29) //Echo引脚
static int echo_data_in(void)
{
gpio_direction_input(GPIOC_CFG_ULTRA_ECHO); //设置为输入引脚
return gpio_get_value(GPIOC_CFG_ULTRA_ECHO); //检测当前电平
}
static int ultra_read_data(void)
{
unsigned int time_cnt = 0;
unsigned int distance = 0;
int ret = 0;
ret = echo_data_in();
if(ret){
while(echo_data_in() && ((time_cnt++) < 50000)) //如果返回的是高电平代表有回波信号,开始记录高电平持续时间
{
udelay(10);
}
distance = ((time_cnt * 3) / 2); //当Echo拉低的时候,代码测距完成,开始计算
}
return (distance);
}
int ultra_drv_open(struct inode *inode, struct file *filp)
{
printk("<4>" "ultra drv open\n");
return 0;
}
ssize_t ultra_drv_read(struct file *filp, char __user *user_buf, size_t size, loff_t *offset)
{
int ret = 0;
unsigned int distance = 0;
if(size != 4)
return -EINVAL;
gpio_direction_output(GPIOC_CFG_ULTRA_TRIG, 1); //启动信号,控制Trig引脚拉高
udelay(20); //至少维持10uS的高电平
gpio_set_value(GPIOC_CFG_ULTRA_TRIG, 0); //拉低Trig引脚,启动成功
distance = ultra_read_data(); //开始检测Echo是否有回波信号
ret = copy_to_user((int *)user_buf, &distance, sizeof(distance)); //将检测到的距离copy到用户空间,通过read读取到
return 0;
}
static struct file_operations ultra_drv_fops = { //文件操作集
.owner = THIS_MODULE,
.open = ultra_drv_open,
.read = ultra_drv_read
};
static struct miscdevice ultra_drv_miscdev = { //混杂设备
.minor = MISC_DYNAMIC_MINOR, //动态分配minor(此设备号)
.name = DEVICE_NAME, //设备名,使用open打开的就是这个名字
.fops = &ultra_drv_fops //文件操作集
};
static int __init ultra_drv_init(void)
{
int ret = 0;
gpio_free(GPIOC_CFG_ULTRA_TRIG); //野路子,避免内核中已经有功能使用该引脚,先释放掉
ret = gpio_request(GPIOC_CFG_ULTRA_TRIG, "ultra_drv"); //释放后再申请给我们使用
if(ret < 0){
printk("<4>" "gpio_request %s %d fail\n", DEVICE_NAME, GPIOC_CFG_ULTRA_TRIG);
return ret;
}
ret = misc_register(&ultra_drv_miscdev); //注册混杂设备
if(ret < 0){
printk("<4>" "misc_register fail\n");
return ret;
}
printk("<4>" "ultra drv init\n");
return 0;
}
static void __exit ultra_drv_exit(void)
{
gpio_free(GPIOC_CFG_ULTRA_TRIG);
misc_deregister(&ultra_drv_miscdev);
printk("<4>" "ultra drv exit\n");
}
module_init(ultra_drv_init);
module_exit(ultra_drv_exit);
MODULE_AUTHOR("ayl0521@sina.com"); //如有问题,可邮件探讨
MODULE_DESCRIPTION("ultrasonic drv");
MODULE_LICENSE("GPL");
标签:ULTRA,include,混杂,int,ret,drv,嵌入式,驱动,ultra 来源: https://blog.csdn.net/origina1s/article/details/89477569