写了个键盘驱动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吗?谢谢
首先你没有说你的编译环境是什么,是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的信息。
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这类调试工具吗?
谢谢
关于交叉编译的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
关于第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(),更深就要用硬件调试了,用示波器看它的波形了
hzcpig()
-----------
int register_chrdev_region(dev_t first, unsigned int count, char *name);
void cdev_init(struct cdev *cdev, struct file_operations *fops);
谢谢你,请解释一下各个参数什么意思以及该怎么使用!
qq群:29468069
linux技术驱动讨论专用群,欢迎前往讨论学习.
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就是你驱动的文件操作索引。