基于S3C2440的嵌入式Linux驱动——DS18B20温度传感器(添加使用platform总线机制)

本文介绍了如何在基于S3C2440的嵌入式系统上实现DS18B20温度传感器的Linux驱动,包括原始的字符设备驱动代码和使用platform总线机制修正多进程访问问题的驱动代码。详细展示了驱动注册、设备操作函数及应用程序接口。驱动代码经过平台设备驱动的改进,解决了多进程访问的问题。
摘要由CSDN通过智能技术生成

此代码为本人原创。该代码仍有不完善之处,有可能还要再次修改!仅供参考!

若有错误、疑问和意见请留言,非常感谢!

该驱动程序基于TQ2440开发板,内核2.6.30。

驱动程序比较简单,使用字符设备来实现。要注意的是在模拟DS18B20的总线时序时,处理器不能抢占当前线程从而造成时序错乱,因此使用了自旋锁来禁止处理器抢占。

代码比较简单,所以代码注释也比较少。如果有不明白的请参考DS18B20的datasheet以及<<Linux设备驱动程序>>的第三章。

1. 驱动代码一

NOTE:请使用驱动代码二,代码一不支持多进程访问。

[cpp]  view plain copy
  1. //using cdev to create device  
  2. #include <linux/module.h>  
  3. #include <linux/kernel.h>  
  4. #include <linux/fs.h>  
  5. #include <linux/init.h>  
  6. #include <linux/delay.h>  
  7. #include <asm/irq.h>  
  8. #include <mach/regs-gpio.h>  
  9. #include <mach/hardware.h>  
  10. #include <linux/device.h>  
  11. #include <linux/kdev_t.h>  
  12. #include <linux/cdev.h>  
  13. #include <linux/spinlock.h>  
  14. #include <linux/mutex.h>  
  15. #include <asm/uaccess.h>  
  16.   
  17. #define DEVICE_NAME "ds18b20"  
  18. #define SKIP_ROM 0xcc  
  19. #define CONVERT_T 0x44  
  20. #define READ_SCRATCHPAD 0xbe  
  21. #define DQ  S3C2410_GPB5  
  22.   
  23. MODULE_LICENSE("GPL");  
  24.   
  25. static struct ds18b20_info  
  26. {  
  27.     struct mutex    ds18b20_mutex;  
  28.     spinlock_t  ds18b20_spinlock;         
  29.   
  30. };  
  31.   
  32. static int ds18b20_init_work(struct ds18b20_info *dsin)  
  33. {  
  34.     char n;  
  35.     unsigned long flag;  
  36.   
  37.     spin_lock_irqsave(&dsin->ds18b20_spinlock,flag);  
  38.     s3c2410_gpio_setpin(DQ, 1);  
  39.     udelay(70);  
  40.     s3c2410_gpio_setpin(DQ, 0);  
  41.     udelay(500);  
  42.     s3c2410_gpio_setpin(DQ, 1);  
  43.     udelay(70);  
  44.     n = s3c2410_gpio_getpin(DQ);  
  45.     if(n == 1)  
  46.         n = -1;  
  47.     udelay(80);  
  48.     spin_unlock_irqrestore(&dsin->ds18b20_spinlock, flag);  
  49.     return n;  
  50. }  
  51.   
  52. static void ds18b20_write_byte(unsigned char data, struct ds18b20_info *dsin){  
  53.     unsigned char i;  
  54.     unsigned long flag;  
  55.       
  56.     spin_lock_irqsave(&dsin->ds18b20_spinlock,flag);  
  57.     for (i = 0; i < 8; i++){  
  58.         s3c2410_gpio_setpin(DQ, 0);  
  59.         udelay(10);  
  60.         s3c2410_gpio_setpin(DQ, (data&0x01)? 1:0);  
  61.         udelay(40);  
  62.         s3c2410_gpio_setpin(DQ, 1);  
  63.         data >>= 1;  
  64.         udelay(1);  
  65.     }  
  66.     spin_unlock_irqrestore(&dsin->ds18b20_spinlock, flag);  
  67. }  
  68.   
  69. static unsigned char ds18b20_read_byte(struct ds18b20_info *dsin){  
  70.     unsigned char i, value= 0;  
  71.     unsigned long flag;  
  72.       
  73.     spin_lock_irqsave(&dsin->ds18b20_spinlock,flag);  
  74.     for(i = 0; i < 8; i++){  
  75.         value >>= 1;  
  76.         s3c2410_gpio_setpin(DQ, 0);     //pull low  
  77.         s3c2410_gpio_setpin(DQ, 1);     //pull high  
  78.         if (s3c2410_gpio_getpin(DQ))    //read  
  79.         {  
  80.             value |= 0x80;  
  81.         }  
  82.         udelay(40);  
  83.     }  
  84.     spin_unlock_irqrestore(&dsin->ds18b20_spinlock, flag);  
  85.     return value;  
  86. }  
  87.   
  88. static int ds18b20_open(struct inode *inode, struct file *file)  
  89. {  
  90.     struct ds18b20_info *dsin = kmalloc(sizeof(* dsin), GFP_KERNEL);  
  91.       
  92.     if(dsin == NULL){  
  93.         printk("No memory for ds18b20\n");  
  94.         return -ENOENT;  
  95.     }  
  96.     memset(dsin, 0, sizeof(*dsin));  
  97.     file->private_data = dsin;  
  98.     spin_lock_init(&dsin->ds18b20_spinlock);  
  99.     mutex_init(&ds
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值