请教几个嵌入式linux驱动的问题!谢谢!

yu1981666   2007-5-19 15:26 楼主
写了个键盘驱动key_scan.c,
1.请问想编译成key_scan.o该在Makefile中怎么写编译语句?谢谢。
2.int register_chrdev(unsigned int major, const char *name, struct file_operations *fops);函数的参数 name该用什么?是key_scan吗?它与mknod的第一个参数有什么关系?
3.想调试这个驱动,ARM9通过串口在超级终端上能看见printk输出的信息,该怎么做?是不是要使用GDB?如果是,又该怎么使用呢?在ARM9上能使用GDB吗?谢谢

回复评论 (8)

首先你没有说你的编译环境是什么,是Linux到ARM的交叉编译么。
还有你的编译内核是2.4还是2.6也没说,差别还是挺大的。

2.4中编译成.o文件,2.6中编译成.ko文件。

第1个问题,与交叉编译链相关,你没说。

第2个问题,与内核版本相关,不过看这个申明:
int register_chrdev(unsigned int major, const char *name, struct file_operations *fops);
name应该就是要向 /proc/device里写入的设备名称,也就是你之后mknod的参数。

第3个问题,通过串口连接的超级终端能直接看到printk的信息。
点赞  2007-5-19 17:33
hzcpig() ,谢谢你!
----------------------
1.用arm-linux-gcc(2.95.3)交叉编译工具,内核(2.6)。
2.如果是mknod 的第一个参数,那么请问发生如下情况怎么处理呢?
mknod /dev/test0 c 200 0
mknod /dev/test1 c 200 1
相同主设备号,不同次设备号,建了两国设备文件,那么register_chrdev()的第二个参数用什么呢?
3.需要使用GDB这类调试工具吗?
谢谢
点赞  2007-5-19 19:03
关于交叉编译的Makefile,我给你一个 ppc-linux-gcc 的,你改相应的编译链应该就可以了
CROSS_COMPILE=/home/guys/starwave-ppc/staging_dir_powerpc/bin/powerpc-linux-uclibc-

CC = $(CROSS_COMPILE)gcc
LD = $(CROSS_COMPILE)ld
RM = rm

KMOD = mypcf8563
INC = myi2c

LINUX = /home/guys/starwave-ppc/build_powerpc/linux

SYS_INC = /home/guys/starwave-ppc/staging_dir_powerpc/bin/../lib/gcc/powerpc-linux-uclibc/3.4.6/include

CINCS = -I . -I include -I inc -I $(LINUX)/include -I $(LINUX)/arch/ppc \
        -I $(LINUX)/arch/ppc/include

CFLAG = -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
                 -fno-strict-aliasing -fno-common -ffreestanding -O2 \
             -fomit-frame-pointer -Iarch/ppc -msoft-float -pipe -ffixed-r2 \
                 -mmultiple -mstring -Wa,-maltivec -Wdeclaration-after-statement

DFLAGS = -DMODULE -DKBUILD_BASENAME=$(KMOD) -DKBUILD_MODNAME=$(KMOD)

CFLAGS = -m32 -Wp,-MD,.$(KMOD).o.d \
                 -nostdinc -isystem $(SYS_INC) \
                 -D__KERNEL__ $(CINCS) $(CFLAG)

SRCS = $(KMOD).mod.o $(KMOD).o $(INC).o

OBJS = $(SRCS)

all: $(KMOD)
        @echo "Look for $<.ko please"

%.o: %.c
        $(CC) $(CFLAGS) $(DFLAGS) -c -o $@ $<

$(KMOD): $(SRCS)
        $(LD) -m elf32ppc -r -o $@.ko $(KMOD).mod.o $(KMOD).o $(INC).o

clean:
        $(RM) -f $(OBJS) *.o *.ko
点赞  2007-5-19 22:45
关于第2个问题
register_chrdev()是2.4内核注册设备的老方法,而你用的是2.6内核,建议用
int register_chrdev_region(dev_t first, unsigned int count, char *name);
void cdev_init(struct cdev *cdev, struct file_operations *fops);

这种2.6推荐的方法注册设备。

mknod 一个已经被占用了设备号的设备肯定是要出错的,通常不会直接去mknod,而是通过脚本之类的东西读取/proc/devices里面记录的设备号,然后建立设备节点.如:

major=$(awk "\\$2==\"$module\" {print \\$1}" /proc/devices)
mknod /dev/${device} c $major 0


关于第3个问题

驱动调试的软件方法通常有:
1. 用打印调试(printk)
2. 使用 /proc 文件系统调试
3. 用strace 命令观察调试
4. 使用kgdb 调试

你的情况是交叉编译,感觉用kgdb调试的可能性不大,主要还是printk(),更深就要用硬件调试了,用示波器看它的波形了
点赞  2007-5-19 22:53
hzcpig()
-----------
int register_chrdev_region(dev_t first, unsigned int count, char *name);
void cdev_init(struct cdev *cdev, struct file_operations *fops);
谢谢你,请解释一下各个参数什么意思以及该怎么使用!
点赞  2007-5-20 19:55
qq群:29468069
linux技术驱动讨论专用群,欢迎前往讨论学习.
点赞  2007-5-23 14:34
mark
点赞  2007-5-23 17:08
int register_chrdev_region(dev_t first, unsigned int count, char *name);

first 是你要分配的起始设备编号. count 是你请求的连续设备编号的总数. name 是应当连接到这个编号范围的设备的名子; 它会出现在 /proc/devices 和 sysfs 中.

void cdev_init(struct cdev *cdev, struct file_operations *fops);

cdev 结构嵌入一个你自己的设备特定的结构,fops就是你驱动的文件操作索引。
点赞  2007-5-23 22:40
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复