Linux驱动程序编写演示 编制驱动代码.doc
文本预览下载声明
Linux驱动程序编写演示 编制驱动代码
本文参考有关驱动程序设计资料的思路,动态申请一段内存做为对一个字符设备的模拟,即内存=字符设备,使用C语言实现2个函数段:初始化函数和卸载函数。采用GNU make命令对其进行编译,得到test_driver.ko文件,这就是我们所需要的驱动模块,这个模块可以动态加载,也可以动态卸载。
编译器使用GUN ARM gcc Compiler,这可以在环境变量中设置ARCH=arm,CROSS_COMPILE=/opt/gcc-4.1.2-glibc-2.5-nptl-3/arm-none-linux-gnueabi/bin/arm-none-linux-gnueabi-(说明:这个是本人主机上的编译器路径,需要根据具体的交叉编译工具设置情况给出来),也可以在编制Makefile文件时,在语句中指定,语句相同,放在Makefile文件的开始处。本人采用的是在环境变量中设置的方式。
一、头文件包含内容
/*linux内核提供的头文件,具体定义的数据结构及内核API函数,可打开他们查阅*/
#include linux/types.h
#include linux/init.h
#include linux/module.h
#include linux/kernel.h
#include linux/fs.h
#include linux/cdev.h
#include asm/uaccess.h
/*针对test_driver.c的自定义头文件,里面是结构和对上层的接口函数定义*/
#includetest_driver.h
二、C语言驱动代码
代码:
struct DEMO_dev
{
struct cdev cdev;
};
l简单说明:
struct cdev cdev是内核提供的字符设备数据结构,在我们自己的设备结构中包含它,实时上就是一个面向对象设计方法的继承概念:基于内核字符设备,继承父类中的公共属性并定义自己的特有属性。这样,我们自己的字符设备,就具有了所有字符设备的公共特征。这个思想非常重要,我们自己的驱动程序不能脱离开内核的支持。
因此,上面的简单结构,就实现了自定义的字符设备。struct cdev cdev数据结构定义在linux/cdev.h中。完整路径是:kernel-imx/include/linux/cdev.h,kernel-imx是本人内核源码的顶层目录名,这和每台机器arm for linux的源码路径有关。
也可以直接使用:struct cdev*my_cdev方法直接定义一个自己的字符设备。
---
struct file_operations DEMO_fops={
.owner=THIS_MODULE,
.llseek=DEMO_llseek,
.read=DEMO_read,
.write=DEMO_write,
.ioctl=DEMO_ioctl,
.open=DEMO_open,
.release=DEMO_release,
};
l简单说明:
struct file_operations是在kernel-imx/include/linux/types.h中定义的数据结构,其作用就是针对我们的设备,给上层的系统调用提供设备操作方法。这些方法包括对设备的:open,write,read,ioctl,seek,close等。具体的方法,可查阅linux系统调用所提供的函数库。在应用层,程序员可以使用这些系统调用实现对我们设备的必要操作。我们使用这个数据结构,直接定义了自己的设备操作方法:struct file_operations DEMO_fops,这个定义非常清楚:基于struct file_operations定义我们自己设备的操作对象DEMO_fops,并完成DEMO_fops的初始化。这个对象中的每个域对应着固定的方法,这是不能变的。对于不是用的方法,可以用NULL填写,或者不填,不填NULL的时候,必须要对域的名称赋值,见上面的填写方法。
---
/*定义我们自己的设备对象*/
struct DEMO_dev*DEMO_devices;
/*我们的设备被引用的次数,或者叫引用计数器*/
static unsigned char demo_inc=0;
/*分配一段无符号整数的字节内存,大小256个字节,用来在内核空间和用户空间传递数据*/
static u8 demoBuffer[256];
/*以下代码时具体的驱动过程*/
/*初始化函数DEMO_init_module*/
int DEMO_init_module(void)
{
int result;
dev_t dev=0;
/*使用MKDEV宏,把主设备号和次设备号转变为d
显示全部