一片实际驱动的彻底分析

来源:互联网 发布:淘宝店铺头像怎么设置 编辑:程序博客网 时间:2024/05/30 04:29

//#include #include #include #include #include #include #include #include #include #include #include #include #include #include #define DEVICE_NAME "TEM"#define tp_MAJOR  232unsigned char sdata;unsigned char xiaoshu1;unsigned char xiaoshu2;unsigned char xiaoshu;void tmreset (void){      s3c_gpio_cfgpin(S3C64XX_GPE(0), S3C_GPIO_SFN(1));gpio_set_value(S3C64XX_GPE(0), 1);udelay(100);gpio_set_value(S3C64XX_GPE(0), 0);udelay(600);gpio_set_value(S3C64XX_GPE(0), 1);udelay(100);s3c_gpio_cfgpin(S3C64XX_GPE(0), S3C_GPIO_SFN(0));}  void tmwbyte (unsigned char dat){                       unsigned char j;s3c_gpio_cfgpin(S3C64XX_GPE(0), S3C_GPIO_SFN(1));for (j=1;j<=8;j++)      { gpio_set_value(S3C64XX_GPE(0), 0); udelay(1); if((dat&0x01)==1){gpio_set_value(S3C64XX_GPE(0), 1);     }   else {}udelay(60);gpio_set_value(S3C64XX_GPE(0), 1);udelay(15);dat = dat >> 1;}  gpio_set_value(S3C64XX_GPE(0), 1);} unsigned char tmrbyte (void){   unsigned char i,u=0;      for (i=1;i<=8;i++)      {s3c_gpio_cfgpin(S3C64XX_GPE(0), S3C_GPIO_SFN(1));gpio_set_value(S3C64XX_GPE(0), 0); udelay(1);u >>= 1; gpio_set_value(S3C64XX_GPE(0), 1);s3c_gpio_cfgpin(S3C64XX_GPE(0), S3C_GPIO_SFN(0)); if( gpio_get_value(S3C64XX_GPE(0)))    u=u|0x80;udelay(60);  }  return (u);   }void DS18B20PRO(void)         {    unsigned char a,b; tmreset();         udelay(420);tmwbyte(0xcc);        tmwbyte(0x44);      mdelay(750);tmreset ();    udelay(400);tmwbyte (0xcc);  tmwbyte (0xbe);  a = tmrbyte ();b= tmrbyte ();sdata = a/16+b*16;   }static ssize_t  s3c6410_18b20_read(struct file *filp, char *buf, size_t len, loff_t *off){DS18B20PRO();*buf=sdata;return 1;}static struct file_operations s3c6410_18b20_fops = {.owner = THIS_MODULE,.read = s3c6410_18b20_read,};static struct cdev cdev_18b20;static int __init s3c6410_18b20_init(void){int result;dev_t devno = MKDEV(tp_MAJOR,0);struct class *tem_class;result = register_chrdev_region(devno,1,DEVICE_NAME);if(result){printk(KERN_NOTICE "Error %d register 18b20",result);return result;}     cdev_init(&cdev_18b20,&s3c6410_18b20_fops);result = cdev_add(&cdev_18b20,devno,1);if(result){printk(KERN_NOTICE "Error %d adding 18b20",result);return result;}tem_class = class_create(THIS_MODULE, "tem_class");device_create(tem_class, NULL, MKDEV(tp_MAJOR, 0), "ds18b20","TEM%d", 0);return 0;}static void __exit s3c6410_18b20_exit(void){cdev_del(&cdev_18b20);unregister_chrdev_region(MKDEV(tp_MAJOR,0),1);}module_init(s3c6410_18b20_init);module_exit(s3c6410_18b20_exit);MODULE_LICENSE("GPL");

上面是所有的代码下面进行实际分析

这个驱动是一个真实的驱动程序

程序的一开始从 init开始分析

1分配设备号

2注册设备号{

绑定了设备名 和这个分配的设备号在内核里面

}

当然上面这个驱动仔细分析一下有可多不合理的 地方 不合适的地方 能凑合工作  但是绝对不能商用上项目

因为这个本身就是开发板购买时候提供的一个例子  仅能演示切勿照抄

3字符设备的 初始化{

绑定设备结构和fop(给这个静态原始的躯体附上灵魂)

}

4添加设备到内核{

把被赋予灵魂的字符设备结构贴上标号和名字

}

5创建设备接点{

有意思的 地方在这

tem_class = class_create(THIS_MODULE, "tem_class");
device_create(tem_class, NULL, MKDEV(tp_MAJOR, 0), "ds18b20","TEM%d", 0);

第一行创建了这个类 为什么这种方式呢是因为为了迎合 总线 设备 驱动的模型   内核的一个和管理机制有兴趣可以深入研究

第二行就是mknod 的作用 前2个参数同样是为了迎合或者说是衔接总线设备驱动模型  后面的是正经的跟以前的 手工mknod用的

dev_t 就不多说了  设备号呗 TEM%d  后面的参数就是跟printf一样 格式化输出 输出的 这个东西就是在设备目录下要操作的 东西

也就是在应用程序里面进行当做一个文件打开 操作的 到此为止 驱动完成任务

}

 

 

原创粉丝点击