免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3791 | 回复: 4
打印 上一主题 下一主题

驱动编译问题! [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-08-01 16:57 |只看该作者 |倒序浏览
从网上下了个DS18B20传感器的驱动程序(2.6.29),但编译时出错,使用其他的驱动代码也有问题。以前没接触过嵌入式,不知道怎么解决!编译驱动时需要注意些什么?

我用的是虚拟机上装的Linux AS 4, 内核2.6.9-22.EL,编译器是4.3.1的

程序如下:

#include <linux/config.h>
#include <linux/module.h>  

#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/devfs_fs_kernel.h>
#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <asm/irq.h>
#include <asm/arch/regs-gpio.h>
#include <asm/hardware.h>
typedef unsigned char BYTE;
#define DS18B20_PIN   S3C2410_GPB1
#define DS18B20_PIN_OUTP S3C2410_GPB1_OUTP
#define DS18B20_PIN_INP   S3C2410_GPB1_INP
#define HIGH 1
#define LOW 0
#define DEV_NAME "DS18B20"
#define DEV_MAJOR 232
static BYTE data[2];
// DS18B20复位函数

BYTE DS18b20_reset (void)
{
// 配置GPIOB0输出模式

&nbsp;s3c2410_gpio_cfgpin(DS18B20_PIN, DS18B20_PIN_OUTP);
// 向18B20发送一个上升沿,并保持高电平状态约100微秒

&nbsp;s3c2410_gpio_setpin(DS18B20_PIN, HIGH);
&nbsp;udelay(100);
// 向18B20发送一个下降沿,并保持低电平状态约600微秒

&nbsp;s3c2410_gpio_setpin(DS18B20_PIN, LOW);
&nbsp;udelay(600);
// 向18B20发送一个上升沿,此时可释放DS18B20总线

&nbsp;s3c2410_gpio_setpin(DS18B20_PIN, HIGH);
&nbsp;udelay(100);
// 以上动作是给DS18B20一个复位脉冲

// 通过再次配置GPIOB1引脚成输入状态,可以检测到DS18B20是否复位成功

&nbsp;s3c2410_gpio_cfgpin(DS18B20_PIN, DS18B20_PIN_INP);
// 若总线在释放后总线状态为高电平,则复位失败

&nbsp;if(s3c2410_gpio_getpin(DS18B20_PIN))
&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;printk("DS18b20 reset failed.\r\n");
&nbsp;&nbsp;&nbsp;return 1;
&nbsp;&nbsp;}
&nbsp;return 0;
}
void DS18b20_write_byte (BYTE byte)
{
&nbsp;BYTE i;
// 配置GPIOB1为输出模式

&nbsp;s3c2410_gpio_cfgpin(DS18B20_PIN, DS18B20_PIN_OUTP);
// 写“1”时隙:

//     保持总线在低电平1微秒到15微秒之间

//     然后再保持总线在高电平15微秒到60微秒之间

//     理想状态: 1微秒的低电平然后跳变再保持60微秒的高电平

//

// 写“0”时隙:

//     保持总线在低电平15微秒到60微秒之间

//     然后再保持总线在高电平1微秒到15微秒之间

//     理想状态: 60微秒的低电平然后跳变再保持1微秒的高电平

&nbsp;for (i = 0; i < 8; i++)
&nbsp;{
&nbsp;&nbsp;s3c2410_gpio_setpin(DS18B20_PIN, LOW);
&nbsp;&nbsp;udelay(1);
&nbsp;&nbsp;if(byte & HIGH)
&nbsp;&nbsp;{
// 若byte变量的D0位是1,则需向总线上写“1”

// 根据写“1”时隙规则,电平在此处翻转为高

&nbsp;&nbsp;&nbsp;s3c2410_gpio_setpin(DS18B20_PIN, HIGH);
&nbsp;&nbsp;}
&nbsp;&nbsp;else
&nbsp;&nbsp;{
// 若byte变量的D0位是0,则需向总线上写“0”

// 根据写“0”时隙规则,电平在保持为低

&nbsp;&nbsp;&nbsp;s3c2410_gpio_setpin(DS18B20_PIN, LOW);
&nbsp;&nbsp;}
// 电平状态保持60微秒

&nbsp;&nbsp;udelay(60);
&nbsp;&nbsp;s3c2410_gpio_setpin(DS18B20_PIN, HIGH);
&nbsp;&nbsp;udelay(15);
&nbsp;&nbsp;byte >>= 1;
&nbsp;}
&nbsp;s3c2410_gpio_setpin(DS18B20_PIN, HIGH);
}
BYTE DS18b20_read_byte (void)
{
&nbsp;BYTE i = 0;
&nbsp;BYTE byte = 0;
// 读“1”时隙:

//     若总线状态保持在低电平状态1微秒到15微秒之间

//     然后跳变到高电平状态且保持在15微秒到60微秒之间

//      就认为从DS18B20读到一个“1”信号

//     理想情况: 1微秒的低电平然后跳变再保持60微秒的高电平

//

// 读“0”时隙:

//     若总线状态保持在低电平状态15微秒到30微秒之间

//     然后跳变到高电平状态且保持在15微秒到60微秒之间

//     就认为从DS18B20读到一个“0”信号

//     理想情况: 15微秒的低电平然后跳变再保持46微秒的高电平

&nbsp;for (i = 0; i < 8; i++)
&nbsp;{
&nbsp;&nbsp;s3c2410_gpio_cfgpin(DS18B20_PIN, DS18B20_PIN_OUTP);
&nbsp;&nbsp;s3c2410_gpio_setpin(DS18B20_PIN, LOW);
&nbsp;&nbsp;udelay(1);
&nbsp;&nbsp;byte >>= 1;
&nbsp;&nbsp;s3c2410_gpio_setpin(DS18B20_PIN, HIGH);
&nbsp;&nbsp;s3c2410_gpio_cfgpin(DS18B20_PIN, DS18B20_PIN_INP);
// 若总线在我们设它为低电平之后若1微秒之内变为高

// 则认为从DS18B20处收到一个“1”信号

// 因此把byte的D7为置“1”

&nbsp;&nbsp;if (s3c2410_gpio_getpin(DS18B20_PIN))
&nbsp;&nbsp;&nbsp;byte |= 0x80;
&nbsp;&nbsp;&nbsp;udelay(60);
&nbsp;}
&nbsp;return byte;
}
void DS18b20_proc(void)
{
&nbsp;while(DS18b20_reset());
&nbsp;udelay(120);
&nbsp;DS18b20_write_byte(0xcc);
&nbsp;DS18b20_write_byte(0x44);
&nbsp;udelay(5);
&nbsp;while(DS18b20_reset());
&nbsp;udelay(200);
&nbsp;DS18b20_write_byte(0xcc);
&nbsp;DS18b20_write_byte(0xbe);
&nbsp;data[0] = DS18b20_read_byte();
&nbsp;data[1] = DS18b20_read_byte();
}
static ssize_t s3c2440_18b20_read(struct file *filp, char *buf, size_t len, loff_t *off)
{
&nbsp;DS18b20_proc();
&nbsp;buf[0] = data[0];
&nbsp;buf[1] = data[1];
&nbsp;return 1;
}
static struct file_operations s3c2440_18b20_fops =
{
&nbsp;.owner = THIS_MODULE,
&nbsp;.read = s3c2440_18b20_read,
};
static int __init s3c2440_18b20_init(void)
{
&nbsp;if (register_chrdev(DEV_MAJOR, DEV_NAME, &s3c2440_18b20_fops) < 0)
&nbsp;{
&nbsp;&nbsp;printk(DEV_NAME ": Register major failed.\r\n");
&nbsp;&nbsp;return -1;
&nbsp;}
&nbsp;devfs_mk_cdev(MKDEV(DEV_MAJOR, 0),S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, DEV_NAME);
&nbsp;while(DS18b20_reset());
}
static void __exit s3c2440_18b20_exit(void)
{
&nbsp;devfs_remove(DEV_NAME);
&nbsp;unregister_chrdev(DEV_MAJOR, DEV_NAME);
}
module_init(s3c2440_18b20_init);
module_exit(s3c2440_18b20_exit);


使用了 arm-linux-gcc -DKEREL -DMODULE -I/usr/include -c DS18B20.c  命令
(-o 也是一样)

出现如下错误:

DS18B20.c:255: warning: "struct file" declared inside parameter list
DS18B20.c:255: warning: its scope is only this definition or declaration, which is probably not what you want
DS18B20.c:269: error: variable `s3c2440_18b20_fops' has initializer but incomplete type
DS18B20.c:273: error: unknown field `owner' specified in initializer
DS18B20.c:273: error: `__this_module' undeclared here (not in a function)
DS18B20.c:273: warning: excess elements in struct initializer
DS18B20.c:273: warning: (near initialization for `s3c2440_18b20_fops')
DS18B20.c:275: error: unknown field `read' specified in initializer
DS18B20.c:275: warning: excess elements in struct initializer
DS18B20.c:275: warning: (near initialization for `s3c2440_18b20_fops')
DS18B20.c: In function `s3c2440_18b20_init':
DS18B20.c:293: error: `S_IFCHR' undeclared (first use in this function)
DS18B20.c:293: error: (Each undeclared identifier is reported only once
DS18B20.c:293: error: for each function it appears in.)
DS18B20.c:293: error: `S_IRUSR' undeclared (first use in this function)
DS18B20.c:293: error: `S_IWUSR' undeclared (first use in this function)
DS18B20.c:293: error: `S_IRGRP' undeclared (first use in this function)
DS18B20.c: At top level:
DS18B20.c:269: error: storage size of `s3c2440_18b20_fops' isn't known

这是什么错误,是路径有问题?但是我找不到内核的路径,/usr/src/kernels/ 文件夹里有三个,-I后写哪个都出现更长的错误
所以我就用了 /usr/include 这里大部分头文件都有

有些头文件我搜索了没有找到
#include <linux/devfs_fs_kernel.h> 但这个在那三个核中都有

#include <asm/arch/regs-gpio.h>
#include <asm/hardware.h>这两个都没找到

需要自己再编译一遍内核吗?
这个错误该怎么改啊?查查其他的资料也没解决。希望大家帮忙!

[ 本帖最后由 dreamice 于 2009-8-5 17:58 编辑 ]

论坛徽章:
3
金牛座
日期:2014-06-14 22:04:062015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:49:45
2 [报告]
发表于 2009-08-05 17:59 |只看该作者
你这些
#define DS18B20_PIN   S3C2410_GPB1
#define DS18B20_PIN_OUTP S3C2410_GPB1_OUTP
#define DS18B20_PIN_INP   S3C2410_GPB1_INP
定义不太对吧

论坛徽章:
0
3 [报告]
发表于 2009-08-08 13:25 |只看该作者

回复 #2 dreamice 的帖子

我也不知道,它这里就这样写的,好像是使用GPB1口进行数据通讯的。


不过我整了个Makefile,然后能生成.o和.ko文件了但没.bin
使用insmode *.o   insmode *.ko insmode * 都不好使
没法加载。我看其他的资料好像.o.ko就可以加载了,为什么这个不行
我是将开发板的内核在虚拟机上编译了一遍,然后用make能生成.o.ko文件,但编译内核是出现过一些warning。
.o文件生成.bin文件使用什么命令,参数是什么?交叉编译下!

论坛徽章:
3
金牛座
日期:2014-06-14 22:04:062015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:49:45
4 [报告]
发表于 2009-08-08 15:58 |只看该作者

回复 #3 SKY_MASTER 的帖子

是insmod,不是insmode啊。

论坛徽章:
0
5 [报告]
发表于 2009-08-08 16:02 |只看该作者

回复 #4 dreamice 的帖子

噢!
是我笔误,输命令时没错。不好意思!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP