FL2440—基于platform 模型的DS18B20驱动实例

来源:互联网 发布:java 时间段 拆分 编辑:程序博客网 时间:2024/06/06 08:33

目录(?)[-]

  1. 基于platform 模型的DS18B20驱动实例
    1. 单总线通信协议时序理解
      1. 初始化序列复位和存在脉冲
      2. 读写时序
        1. 写时序
        2. 读时序
      3. DS18B20温度值获取原理
      4. 驱动程序测试程序
      5. 编译测试
      6. 遇到的问题及解决

基于platform 模型的DS18B20驱动实例

通过前面的学习了解到DS18B20是基于单总线协议靠一个单线端口与CPU通信实现数据传输,关于单总线设备之前接触的比较少,这次通过学习编写DS18B20的驱动,总算对这种通信协议有了多一点的了解。

单总线通信协议时序理解

初始化序列——复位和存在脉冲

这里写图片描述

如图为DS18B20的单总线通信协议的初始化序列时序,DS18B20的所有通信都由由复位脉冲组成的初始化序列开始。该初始化序列由主机发出,后跟由DS18B20发出的存在脉冲(presence pulse)。当发出应答复位脉冲的存在脉冲后,DS18B20通知主机它在总线上并且准备好操作了。 
在初始化步骤中,总线上的主机通过拉低单总线至少480μs来产生复位脉冲。然后总线主机释放总线并进入接收模式。 当总线释放后,5kΩ的上拉电阻把单总线上的电平拉回高电平。当DS18B20检测到上升沿后等待15到60us,然后以拉低总线60-240us的方式发出存在脉冲。

读写时序

写时序

这里写图片描述 
由以上的时序图可知,总线主机使用写“1”时间隙向DS18B20写入逻辑1,使用写“0”时间隙向DS18B20写入逻辑0.所有的写时隙必须有最少60us的持续时间,相邻两个写时隙必须要有最少1us的恢复时间。两种写时隙都通过主机拉低总线产生。为产生写1时隙,在拉低总线后主机必须在15μs内释放总线。在总线被释放后,由于5kΩ上拉电阻的作用,总线恢复为高电平。为产生写0时隙,在拉低总线后主机必须继续拉低总线以满足时隙持续时间的要求(至少60μs)。 在主机产生写时序后,DS18B20会在其后的15到60us的一个时间窗口内采样单总线。在采样的时间窗口内,如果总线为高电平,主机会向DS18B20写入1;如果总线为低电平,主机会向DS18B20写入0。

读时序

这里写图片描述 
DS18B20只有在主机发出读暂存器命令 [BEh]或温度转换命令T [44h]后,主机才会产生读时隙以便DS18B20提供所需数据。在主机产生读时序后,DS18B20开始发送0或1到总线上。DS18B20让总线保持高电平的方式发送1,以拉低总线的方式表示发送0.当发送0的时候,DS18B20在读时序的末期将会释放总线,总线将会被上拉电阻拉回高电平(也是总线空闲的状态)。DS18B20输出的数据在下降沿(下降沿产生读时隙)产生后15us后有效。因此,主机释放总线和采样总线等动作要在15μs内完成。

DS18B20温度值获取原理

这里写图片描述 
DS18B20的测温原理如图2所示,图中低温度系数晶振的振荡频率受温度的影响很小[1],用于产生固定频率的脉冲信号送给减法计数器1,高温度系数晶振随温度变化其震荡频率明显改变,所产生的信号作为减法计数器2的脉冲输入,图中还隐含着计数门,当计数门打开时,DS18B20就对低温度系数振荡器产生的时钟脉冲后进行计数,进而完成温度测量。计数门的开启时间由高温度系数振荡器来决定,每次测量前,首先将-55 ℃所对应的基数分别置入减法计数器1和温度寄存器中,减法计数器1和温度寄存器被预置在-55 ℃所对应的一个基数值。减法计数器1对低温度系数晶振产生的脉冲信号进行减法计数,当减法计数器1的预置值减到0时温度寄存器的值将加1,减法计数器1的预置将重新被装入,减法计数器1重新开始对低温度系数晶振产生的脉冲信号进行计数,如此循环直到减法计数器2计数到0时,停止温度寄存器值的累加,此时温度寄存器中的数值即为所测温度。

驱动程序&&测试程序

下面是自己参考ds18b20的datasheet以及前辈们的博客编写的驱动和测试程序:

  • 驱动程序:s3c_plat_ds18b20.c
/********************************************************************************* *      Copyright:  (C) 2017 Li Wanneng<liwjng@gmail.com> *                  All rights reserved. * *       Filename:  s3c_ds18b20.c *    Description:  This file is driver for s3c_ds18b20 *                  *        Version:  1.0.0(04/24/2017) *         Author:  Li Wanneng <liwjng@gmail.com> *      ChangeLog:  1, Release initial version on "04/24/2017 07:34:17 PM" *                  ********************************************************************************/#include<linux/module.h>#include<linux/kernel.h>#include<linux/fs.h>#include<linux/init.h>#include<linux/delay.h>#include<linux/gpio.h>#include<linux/types.h>#include<asm/irq.h>#include<mach/regs-gpio.h>#include<mach/hardware.h>#include<linux/device.h>#include<linux/kdev_t.h>#include<linux/cdev.h>#include<linux/errno.h>#include<asm/uaccess.h>#include<linux/platform_device.h>#define DRV_AUTHOR                "Li Wanneng<liwjng@gmail.com>"#define DRV_DESC                  "S3C_DS18B20 driver"#define DISABLE                   0/* Driver version */#define DRV_MAJOR_VER             1#define DRV_MINOR_VER             0#define DRV_REVER_VER             0/* Set major static */#define DEV_NAME                 "s3c_ds18b20"/* dynamic major by default  */#ifndef DEV_MAJOR#define DEV_MAJOR                 0#endif#define DQ S3C2410_GPG(0)  #define INPUT S3C2410_GPIO_INPUT  #define OUTPUT S3C2410_GPIO_OUTPUT static int debug = DISABLE;static int dev_major = DEV_MAJOR;static int dev_minor = 0;struct ds18b20_device{    struct s3c_ds18b20_platform_data *data;    struct class *dev_class;    struct cdev cdev;} ds18b20_device;static struct s3c_ds18b20_platform_data{    unsigned int gpio;    unsigned int is_open_drain:1;};static struct s3c_ds18b20_platform_data s3c_ds18b20_data = {    .gpio = S3C2410_GPG(0),    .is_open_drain = 0,};/* Reset W1-ds18b20 and read presence pluse */static unsigned int w1_ds18b20_reset(void){    int err;    s3c2410_gpio_cfgpin(DQ, OUTPUT);    s3c2410_gpio_pullup(DQ, 0);    s3c2410_gpio_setpin(DQ, 1);    udelay(10);    s3c2410_gpio_setpin(DQ, 0);    udelay(600);    s3c2410_gpio_setpin(DQ, 1);    udelay(60);    s3c2410_gpio_cfgpin(DQ, INPUT);    udelay(400);    err = s3c2410_gpio_getpin(DQ);    return err;}/* w1 write bit */static unsigned int w1_ds18b20_write(unsigned char data){    unsigned int i;    s3c2410_gpio_cfgpin(DQ, OUTPUT);    for (i = 0; i < 8; i++)    {        s3c2410_gpio_setpin(DQ, 0);        udelay(5);        if (data & 0x01)        {            s3c2410_gpio_setpin(DQ, 1);            udelay(60);        }        else            udelay(60);        data >>= 1;        s3c2410_gpio_setpin(DQ, 1);        udelay(1);    }    return 2;}/* w1 read byte */static unsigned int w1_ds18b20_read(void){    unsigned int i;    unsigned char data = 0x00;    for (i = 0; i < 8; i++)    {        s3c2410_gpio_cfgpin(DQ, OUTPUT);        s3c2410_gpio_setpin(DQ, 1);        udelay(1);        s3c2410_gpio_setpin(DQ, 0);        udelay(2);        s3c2410_gpio_setpin(DQ, 1);        s3c2410_gpio_cfgpin(DQ, INPUT);        data >>= 1;        if (0 != s3c2410_gpio_getpin(DQ))            data |= 0x80;        udelay(60);    }    return data;}static ssize_t ds18b20_read(struct file *filp, char __user * buf, size_t count, loff_t * f_pos){    unsigned char Data[2] = { 0x00, 0x00 };    unsigned long err;    /* Enable temperature conversion*/    if ((w1_ds18b20_reset()) <= 0)    {        printk(KERN_ERR "ds18b20 reset fail!\n");        return -1;    }    w1_ds18b20_write(0xcc);/* Skip ROM command. */    w1_ds18b20_write(0x44);/* Initiates temperature conversion*/    /* Read temperature value.*/    if ((w1_ds18b20_reset()) <= 0)    {        printk(KERN_ERR "ds18b20 reset fail!\n");        return -1;    }    w1_ds18b20_write(0xcc);/* Skop ROM commond. */    w1_ds18b20_write(0xbe);/* Read Scratchpad. */    Data[0] = w1_ds18b20_read();/* Read low byte */    Data[1] = w1_ds18b20_read();/* Read high byte */    w1_ds18b20_reset();    err = copy_to_user(buf, Data, sizeof(Data));    return err ? -EFAULT : count;}static int ds18b20_release(struct inode *inode, struct file *file){    return 0;}static int ds18b20_open(struct inode *inode, struct file *file){    int flag = 0;    struct ds18b20_device *pdev;    struct s3c_ds18b20_platform_data *pdata;    /* debug */    printk(KERN_INFO"ds18b20_open.\n");    pdev = container_of(inode->i_cdev,struct ds18b20_device, cdev);    pdata = pdev->data;    file->private_data = pdata;    flag = w1_ds18b20_reset();    if (flag)    {        printk(KERN_INFO "open ds18b20 successful!\n");    }    else        printk("open ds18b20 failed!\n");    return 0;}static struct platform_device s3c_ds18b20_device = {    .name = "s3c_ds18b20",    .id = -1,    .dev = {            .platform_data = &s3c_ds18b20_data,            },};static struct file_operations ds18b20_fops = {    .owner = THIS_MODULE,    .open = ds18b20_open,    .read = ds18b20_read,    .release = ds18b20_release,};static int s3c_ds18b20_probe(struct platform_device *dev){    struct s3c_ds18b20_platform_data *pdata = dev->dev.platform_data;    int result = 0;    dev_t devno;    /* Alloc the device for driver */    if (0 != dev_major)    {        devno = MKDEV(dev_major, dev_minor);        result = register_chrdev_region(devno, 1, DEV_NAME);    }    else    {        result = alloc_chrdev_region(&devno, dev_minor, 1, DEV_NAME);        dev_major = MAJOR(devno);    }    /* debug */    printk(KERN_INFO "major is %d.\n",dev_major);    /* Alloc for device major failure */    if (result < 0)    {        printk("%s driver can't get major %d\n", DEV_NAME, dev_major);        return result;    }    /*  Initialize ds18b20 structure and register cdev */    memset(&ds18b20_device, 0, sizeof(ds18b20_device));    ds18b20_device.data = dev->dev.platform_data;    cdev_init(&(ds18b20_device.cdev), &ds18b20_fops);    ds18b20_device.cdev.owner = THIS_MODULE;    result = cdev_add(&(ds18b20_device.cdev), devno, 1);    /* debug */    printk(KERN_INFO "result is %d.\n",result);    if (result)    {        printk(KERN_NOTICE "error %d add %s device", result, DEV_NAME);        goto ERROR;    }    ds18b20_device.dev_class = class_create(THIS_MODULE, DEV_NAME);    if (IS_ERR(ds18b20_device.dev_class))    {        printk("%s driver create class failture\n", DEV_NAME);        result = -ENOMEM;        goto ERROR;    }    device_create(ds18b20_device.dev_class, NULL, devno, NULL, DEV_NAME);    printk("S3C %s driver version %d.%d.%d initiliazed.\n", DEV_NAME, DRV_MAJOR_VER, DRV_MINOR_VER,           DRV_REVER_VER);    return 0;  ERROR:    printk("S3C %s driver version %d.%d.%d install failure.\n", DEV_NAME, DRV_MAJOR_VER,           DRV_MINOR_VER, DRV_REVER_VER);    cdev_del(&(ds18b20_device.cdev));    unregister_chrdev_region(devno, 1);    return result;}static int s3c_ds18b20_remove(struct platform_device *dev){    dev_t devno = MKDEV(dev_major, dev_minor);    cdev_del(&(ds18b20_device.cdev));    device_destroy(ds18b20_device.dev_class, devno);    class_destroy(ds18b20_device.dev_class);    unregister_chrdev_region(devno, 1);    printk("%s driver removed\n", DEV_NAME);    return 0;}static struct platform_driver s3c_ds18b20_driver = {    .probe = s3c_ds18b20_probe,    .remove = s3c_ds18b20_remove,    .driver = {               .name = "s3c_ds18b20",               .owner = THIS_MODULE,               },};static int __init s3c_ds18b20_init(void){    int ret = 0;    ret = platform_device_register(&s3c_ds18b20_device);    if (ret)    {        printk(KERN_ERR "%s:%d: Can't register platform device %d\n", __FUNCTION__, __LINE__, ret);        goto fail_reg_plat_dev;    }    ret = platform_driver_register(&s3c_ds18b20_driver);    if (ret)    {        printk(KERN_ERR "%s:%d: Can't register platform driver %d\n", __FUNCTION__, __LINE__, ret);        goto fail_reg_plat_drv;    }    return 0;  fail_reg_plat_dev:    return ret;  fail_reg_plat_drv:    platform_driver_unregister(&s3c_ds18b20_driver);    return ret;}static void s3c_ds18b20_exit(void){    platform_driver_unregister(&s3c_ds18b20_driver);    platform_device_unregister(&s3c_ds18b20_device);}module_init(s3c_ds18b20_init);module_exit(s3c_ds18b20_exit);module_param(debug, int, S_IRUGO);module_param(dev_major, int, S_IRUGO);module_param(dev_minor, int, S_IRUGO);MODULE_AUTHOR(DRV_AUTHOR);MODULE_DESCRIPTION(DRV_DESC);MODULE_LICENSE("GPL");MODULE_ALIAS("platform:S3C_DS18B20");
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280
  • 281
  • 282
  • 283
  • 284
  • 285
  • 286
  • 287
  • 288
  • 289
  • 290
  • 291
  • 292
  • 293
  • 294
  • 295
  • 296
  • 297
  • 298
  • 299
  • 300
  • 301
  • 302
  • 303
  • 304
  • 305
  • 306
  • 307
  • 308
  • 309
  • 310
  • 311
  • 312
  • 313
  • 314
  • 315
  • 316
  • 317
  • 318
  • 319
  • 320
  • 321
  • 322
  • 323
  • 324
  • 325
  • 326
  • 327
  • 328
  • 329
  • 330
  • 331
  • 332
  • 333
  • 334
  • 335
  • 336
  • 337
  • 338
  • 339
  • 340
  • 341
  • 342
  • 343
  • 344
  • 345
  • 346
  • 347
  • 348
  • 349
  • 350
  • 351
  • 352
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280
  • 281
  • 282
  • 283
  • 284
  • 285
  • 286
  • 287
  • 288
  • 289
  • 290
  • 291
  • 292
  • 293
  • 294
  • 295
  • 296
  • 297
  • 298
  • 299
  • 300
  • 301
  • 302
  • 303
  • 304
  • 305
  • 306
  • 307
  • 308
  • 309
  • 310
  • 311
  • 312
  • 313
  • 314
  • 315
  • 316
  • 317
  • 318
  • 319
  • 320
  • 321
  • 322
  • 323
  • 324
  • 325
  • 326
  • 327
  • 328
  • 329
  • 330
  • 331
  • 332
  • 333
  • 334
  • 335
  • 336
  • 337
  • 338
  • 339
  • 340
  • 341
  • 342
  • 343
  • 344
  • 345
  • 346
  • 347
  • 348
  • 349
  • 350
  • 351
  • 352
  • Makefile
[lwn@localhost ds18b20]$ vim Makefile  LINUX_SRC?=~/myfl2440/kernel/linux-lwn-3.0.1CROSS_COMPILE=/opt/dl/buildroot-2012.08/ARM920t/usr/bin/arm-linux-obj-m := s3c_plat_ds18b20.omodules:    @make -C $(LINUX_SRC) M=`pwd` modules    @make cleanclean:    rm -f  *.ko.* *.o *mod.c *.order *.symvers
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 测试程序:test_ds18b20.c
 /********************************************************************************* *      Copyright:  (C) 2017 Li Wanneng<liwjng@gmail.com> *                  All rights reserved. * *       Filename:  test_ds18b20.c *    Description:  This file used for test ds18b20 driver *                  *        Version:  1.0.0(04/26/2017) *         Author:  Li Wanneng <liwjng@gmail.com> *      ChangeLog:  1, Release initial version on "04/26/2017 03:19:52 PM" *                  ********************************************************************************/#include <stdio.h>#include <stdlib.h>  #include <sys/types.h>  #include <sys/stat.h>  #include <fcntl.h>  #include <unistd.h>  #include <errno.h>  /******************************************************************************** *  Description: *   Input Args: *  Output Args: * Return Value: ********************************************************************************/int main(int argc, char **argv){    int fd;    int data = 0;    unsigned char result[2];    float temperature = 0;    fd = open("/dev/s3c_ds18b20", O_RDWR | O_NONBLOCK);    if (fd < 0)    {        printf("user:open s3c_ds18b20 failed.\n");        printf("user_Message : %s\n", strerror(errno));         return -1;    }    while (1)    {        int ret = 0;        usleep(100);        ret = read(fd, result, sizeof(result));        if (ret != 2)        {            printf("read wrong\n");            exit(0);        }        data = (int)result[1];        data <<= 8;        data = data | result[0];        temperature = data * 0.0625;        printf("Temperature = %.2f\n", temperature);        fflush(stdout);        sleep(1);    }    close(fd);    return 0;}                               /* ----- End of main() ----- */
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70

编译&&测试

完成上述的驱动和测试程序的编写,对于驱动程序基于上述makefile使用make命令编译生成ko文件,对于测试程序使用gcc交叉编译生成可执行二进制文件test,然后使用tftp将其下载到开发板测试。

  • 编译生成驱动文件和测试文件 
    这里写图片描述
  • 开发板测试温度 
    这里写图片描述

遇到的问题及解决:

1.Q:在测试驱动程序的时候,一直打不开设备节点,读取文件失败。提示错误信息:No such device or address。 
A:通过调试发现,在ds18b20_open(struct inode *inode, struct file *file)函数中没有对参数file赋值。于是赶紧添加了下面三行代码,重新编译之后驱动程序可以运行了。

pdev = container_of(inode->i_cdev,struct ds18b20_device, cdev);pdata = pdev->data;file->private_data = pdata;
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

2.Q:执行测试程序的时候出现以下错误信息:

WARNING: at drivers/gpio/gpiolib.c:101 gpio_ensure_requested+0x54/0xd4()autorequest GPIO-192Modules linked in: s3c_plat_ds18b20[<c002d508>] (unwind_backtrace+0x0/0xf0) from [<c003a9ac>] (warn_slowpath_common+0x48/0x60)[<c003a9ac>] (warn_slowpath_common+0x48/0x60) from [<c003aa58>] (warn_slowpath_fmt+0x30/0x40)[<c003aa58>] (warn_slowpath_fmt+0x30/0x40) from [<c01fad00>] (gpio_ensure_requested+0x54/0xd4)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

A:经查阅资料以及警告信息(autorequest GPIO-192)得知是因为gpio冲突,联想到前两天添加了内核自带的ds18b20驱动,可能是两个驱动都同时使用了同一个GPIO管脚,于是我在make manuconfig中取消内核对于ds18b20驱动的选项,重新编译内核。最终问题得到了解决。

参考文章: 
http://www.cnblogs.com/wangyuezhuiyi/archive/2012/10/12/2721839.html 
http://blog.csdn.net/u010944778/article/details/48058433 
在此感谢两位网友的文章给予的帮助和启发

0
原创粉丝点击