linux 驱动编程

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux 驱动编程相关的知识,希望对你有一定的参考价值。

本人最近刚学linux驱动编程,想在自己的电脑上面测试一下,就找了个程序练练,但是编译不能通过,求高手解答,谢了!!附上我的程序

驱动模块源程序 chdev_test.c
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/fs.h>
MODULE_LICENSE("GPL");

#define MAJOR_NUM 200
#define DEVICE_NAME "chdev_test"

static ssize_t chdev_test_read(struct file *filp, char *, size_t , loff_t *);
static ssize_t chdev_test_write(struct file *filp, char *, size_t , loff_t *);

static int chdev_test_var = 0;

static struct file_operations chdev_test_fops =

read: chdev_test_read,
write: chdev_test_write,
;

static ssize_t chdev_test_read(struct file *filp, char *buf, size_t count,
loff_t *f_pos)

if(copy_to_user(buf,&chdev_test_var,sizeof(int)))

return -EFAULT;

return sizeof(int);


static ssize_t chdev_test_write(struct file *filp, char *buf, size_t count,
loff_t *f_pos)

if(copy_from_user(&chdev_test_var,buf,sizeof(int)))

return -EFAULT;

return sizeof(int);


static int __init chdev_test_init(void)

int reg;
reg=register_chrdev(MAJOR_NUM, DEVICE_NAME, &chdev_test_fops);
if(reg)

printk("regisrer fail!\n");

else

printk("regisrer success!\n");

return reg;


static void __exit chdev_test_exit(void)

int reg;
reg=unregister_chrdev(MAJOR_NUM, DEVICE_NAME);
if(reg)

printk("unregisrer fail!\n");

else

printk("unregisrer success!\n");



module_init(chdev_test_init);
module_exit(chdev_test_exit);

Makefile程序:
obj-m := chdev_test.o
KERNELDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules

可是运行make编译不能通过,因此后面的操作就无法进行,下面是我编译出错的画面,请高手帮我看看。

fricy@fricy-virtual-machine:~/文档$ make
make -C /lib/modules/2.6.38-12-generic/build M=/home/fricy/文档 modules
make[1]: 正在进入目录 `/usr/src/linux-headers-2.6.38-12-generic'
CC [M] /home/fricy/文档/chdev_test.o
/home/fricy/文档/chdev_test.c:19:5: warning: initialization from incompatible pointer type
/home/fricy/文档/chdev_test.c: In function ‘chdev_test_read’:
/home/fricy/文档/chdev_test.c:25:5: error: implicit declaration of function ‘copy_to_user’
/home/fricy/文档/chdev_test.c: In function ‘chdev_test_write’:
/home/fricy/文档/chdev_test.c:35:5: error: implicit declaration of function ‘copy_from_user’
/home/fricy/文档/chdev_test.c: In function ‘chdev_test_exit’:
/home/fricy/文档/chdev_test.c:60:8: error: void value not ignored as it ought to be
make[2]: *** [/home/fricy/文档/chdev_test.o] 错误 1
make[1]: *** [_module_/home/fricy/文档] 错误 2
make[1]:正在离开目录 `/usr/src/linux-headers-2.6.38-12-generic'
make: *** [default] 错误 2
fricy@fricy-virtual-machine:~/文档$

驱动我没有写过。不过可以给你些方法。

换gcc编译一下。然后GDB调试跟踪。虚拟机有没有装好开发包。
参考技术A /home/fricy/文档/chdev_test.c: In function ‘chdev_test_read’:
/home/fricy/文档/chdev_test.c:25:5: error: implicit declaration of function ‘copy_to_user’
/home/fricy/文档/chdev_test.c: In function ‘chdev_test_write’:
/home/fricy/文档/chdev_test.c:35:5: error: implicit declaration of function ‘copy_from_user’
看报错内容,首先copy_to_user’ copy_from_user’这两个函数没声明,又没具体实现,所以error了
参考技术B 错误很简单,就是找不到copy_from_user和copy_to_user这两个函数。: implicit declaration of function ‘copy_to_user’是说这个符号使用了隐式的声明,也就是找不到这两个函数的显示声明,也就是找不到这俩函数~
因为copy_from_user和copy_to_user这两个函数名字偶尔有变化,具体需要看你使用内核版本的情况.你可以去/usr/src/下面找你引用copy_to_user和copy_from_user这两个函数所在的头文件,在头文件中确定具体的函数名称。一般来所,可能会是:__copy_to_user、__copy_from_user等,反正是略有变化。内核版本之间API经常有变化,因此编写驱动程序时最好不要随意变动内核,可能下个版本中你所看到的API都不存在了或者处理方式都发生变化了 。

为了检索的方便,建议你去lxr.linux.no,在你对应的内核版本中检索这两个函数名称,然后确定函数名是什么....也不排除你所使用发行版的内核自行修改了内核。

因此,最好是去kernel.org下载一个未修改的内核,然后在系统中编译并使用这个内核,这样就可以排除不同发行版本对内核的修改.然后不要随意变动内核版本
参考技术C 驱动开发,很爽嘛,我也想学习的,可惜啊,时间不多了,以后要工作,时间更少了,我学习的是内核,

嵌入式Linux-C01 嵌入式LinuxC语言编程的概念

拿嵌入式 Linux 硬件平台下的软件开发来说,我们大可将编程分为三种,分别为裸机编程、 Linux 驱动编程以及 Linux 应用编程。

裸机编程:

一般把没有操作系统支持的编程环境称为裸机编程环境,譬如单片机上的编程开发,编写直接在硬件上运行的程序,没有操作系统支持;

Linux 驱动编程:

Linux 驱动编程指的是基于内核驱动框架开发驱动程序, 驱动开发工程师通过调用 Linux 内核提供的接口完成设备驱动的注册, 驱动程序负责底层硬件操作相关逻辑, 如果学习过 Linux 驱动开发的读者,想必对此并不陌生;

Linux 应用编程:

Linux 应用编程(系统编程)则指的是基于 Linux 操作系统的应用编程,在应用程序中通过调用系统调用 API 完成应用程序的功能和逻辑, 应用程序运行于操作系统之上。通常在操作系统下有两种不同的状态:

内核态和用户态:

内核态和用户态,应用程序运行在用户态、而内核则运行在内核态。

系统调用和库函数:

系统调用是内核直接向应用层提供的应用编程接口, 譬如 open、 write、read、 close 等

库函数也就是 C 语言库函数, C 语言库是应用层使用的一套函数库, 在 Linux 下,通常以动态

以上是关于linux 驱动编程的主要内容,如果未能解决你的问题,请参考以下文章

嵌入式Linux-C01 嵌入式LinuxC语言编程的概念

深入浅出Linux 设备驱动编程

linux c 编程 ------ 通过设备节点调用驱动

4412开发板Linux系统编程实战-字符设备控制

驱动编程思想之初体验 --------------- 嵌入式linux驱动开发之点亮LED

at91 linux 4.1.0下dts驱动编程模型