当前位置: 代码迷 >> 驱动开发 >> 请问几个嵌入式linux驱动的有关问题!多谢
  详细解决方案

请问几个嵌入式linux驱动的有关问题!多谢

热度:34   发布时间:2016-04-28 11:10:58.0
请教几个嵌入式linux驱动的问题!谢谢!
写了个键盘驱动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的信息。
------解决方案--------------------
关于交叉编译的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(),更深就要用硬件调试了,用示波器看它的波形了
------解决方案--------------------
qq群:29468069
linux技术驱动讨论专用群,欢迎前往讨论学习.
------解决方案--------------------
mark
------解决方案--------------------
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就是你驱动的文件操作索引。