驱动编译问题!
从网上下了个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输出模式
s3c2410_gpio_cfgpin(DS18B20_PIN, DS18B20_PIN_OUTP);
// 向18B20发送一个上升沿,并保持高电平状态约100微秒
s3c2410_gpio_setpin(DS18B20_PIN, HIGH);
udelay(100);
// 向18B20发送一个下降沿,并保持低电平状态约600微秒
s3c2410_gpio_setpin(DS18B20_PIN, LOW);
udelay(600);
// 向18B20发送一个上升沿,此时可释放DS18B20总线
s3c2410_gpio_setpin(DS18B20_PIN, HIGH);
udelay(100);
// 以上动作是给DS18B20一个复位脉冲
// 通过再次配置GPIOB1引脚成输入状态,可以检测到DS18B20是否复位成功
s3c2410_gpio_cfgpin(DS18B20_PIN, DS18B20_PIN_INP);
// 若总线在释放后总线状态为高电平,则复位失败
if(s3c2410_gpio_getpin(DS18B20_PIN))
{
printk("DS18b20 reset failed.\r\n");
return 1;
}
return 0;
}
void DS18b20_write_byte (BYTE byte)
{
BYTE i;
// 配置GPIOB1为输出模式
s3c2410_gpio_cfgpin(DS18B20_PIN, DS18B20_PIN_OUTP);
// 写“1”时隙:
// 保持总线在低电平1微秒到15微秒之间
// 然后再保持总线在高电平15微秒到60微秒之间
// 理想状态: 1微秒的低电平然后跳变再保持60微秒的高电平
//
// 写“0”时隙:
// 保持总线在低电平15微秒到60微秒之间
// 然后再保持总线在高电平1微秒到15微秒之间
// 理想状态: 60微秒的低电平然后跳变再保持1微秒的高电平
for (i = 0; i < 8; i++)
{
s3c2410_gpio_setpin(DS18B20_PIN, LOW);
udelay(1);
if(byte & HIGH)
{
// 若byte变量的D0位是1,则需向总线上写“1”
// 根据写“1”时隙规则,电平在此处翻转为高
s3c2410_gpio_setpin(DS18B20_PIN, HIGH);
}
else
{
// 若byte变量的D0位是0,则需向总线上写“0”
// 根据写“0”时隙规则,电平在保持为低
s3c2410_gpio_setpin(DS18B20_PIN, LOW);
}
// 电平状态保持60微秒
udelay(60);
s3c2410_gpio_setpin(DS18B20_PIN, HIGH);
udelay(15);
byte >>= 1;
}
s3c2410_gpio_setpin(DS18B20_PIN, HIGH);
}
BYTE DS18b20_read_byte (void)
{
BYTE i = 0;
BYTE byte = 0;
// 读“1”时隙:
// 若总线状态保持在低电平状态1微秒到15微秒之间
// 然后跳变到高电平状态且保持在15微秒到60微秒之间
// 就认为从DS18B20读到一个“1”信号
// 理想情况: 1微秒的低电平然后跳变再保持60微秒的高电平
//
// 读“0”时隙:
// 若总线状态保持在低电平状态15微秒到30微秒之间
// 然后跳变到高电平状态且保持在15微秒到60微秒之间
// 就认为从DS18B20读到一个“0”信号
// 理想情况: 15微秒的低电平然后跳变再保持46微秒的高电平
for (i = 0; i < 8; i++)
{
s3c2410_gpio_cfgpin(DS18B20_PIN, DS18B20_PIN_OUTP);
s3c2410_gpio_setpin(DS18B20_PIN, LOW);
udelay(1);
byte >>= 1;
s3c2410_gpio_setpin(DS18B20_PIN, HIGH);
s3c2410_gpio_cfgpin(DS18B20_PIN, DS18B20_PIN_INP);
// 若总线在我们设它为低电平之后若1微秒之内变为高
// 则认为从DS18B20处收到一个“1”信号
// 因此把byte的D7为置“1”
if (s3c2410_gpio_getpin(DS18B20_PIN))
byte |= 0x80;
udelay(60);
}
return byte;
}
void DS18b20_proc(void)
{
while(DS18b20_reset());
udelay(120);
DS18b20_write_byte(0xcc);
DS18b20_write_byte(0x44);
udelay(5);
while(DS18b20_reset());
udelay(200);
DS18b20_write_byte(0xcc);
DS18b20_write_byte(0xbe);
data[0] = DS18b20_read_byte();
data[1] = DS18b20_read_byte();
}
static ssize_t s3c2440_18b20_read(struct file *filp, char *buf, size_t len, loff_t *off)
{
DS18b20_proc();
buf[0] = data[0];
buf[1] = data[1];
return 1;
}
static struct file_operations s3c2440_18b20_fops =
{
.owner = THIS_MODULE,
.read = s3c2440_18b20_read,
};
static int __init s3c2440_18b20_init(void)
{
if (register_chrdev(DEV_MAJOR, DEV_NAME, &s3c2440_18b20_fops) < 0)
{
printk(DEV_NAME ": Register major failed.\r\n");
return -1;
}
devfs_mk_cdev(MKDEV(DEV_MAJOR, 0),S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, DEV_NAME);
while(DS18b20_reset());
}
static void __exit s3c2440_18b20_exit(void)
{
devfs_remove(DEV_NAME);
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 编辑 ] 你这些
#define DS18B20_PIN S3C2410_GPB1
#define DS18B20_PIN_OUTP S3C2410_GPB1_OUTP
#define DS18B20_PIN_INP S3C2410_GPB1_INP
定义不太对吧
回复 #2 dreamice 的帖子
我也不知道,它这里就这样写的,好像是使用GPB1口进行数据通讯的。不过我整了个Makefile,然后能生成.o和.ko文件了但没.bin
使用insmode *.o insmode *.ko insmode * 都不好使
没法加载。我看其他的资料好像.o.ko就可以加载了,为什么这个不行
我是将开发板的内核在虚拟机上编译了一遍,然后用make能生成.o.ko文件,但编译内核是出现过一些warning。
.o文件生成.bin文件使用什么命令,参数是什么?交叉编译下!
回复 #3 SKY_MASTER 的帖子
是insmod,不是insmode啊。回复 #4 dreamice 的帖子
噢!是我笔误,输命令时没错。不好意思!
页:
[1]