以下均是在X86平台下编辑,操作,运行

以下均是在X86平台下编辑,操作,运行

编写好驱动,通过挂载的方法将驱动程序挂载到内核里面,大致步骤如下:

:  1>建立以.c为后缀的c语言程序文件 (里面包含了设备名及设备号等)

2>建立Makefile文件(作用是通过make来产生设备文件*.ko文件,里面可以建立自己的平台所需的设备文件如:arm).make 产生相应的设备文件

: 要在/dev下建立相应的设备结点(设备名),insomd *.ko命令将相应的驱动设备文件挂载到内核中.

:编写测试文件(.c文件)用来测试内核是否已近成功挂载到内核.(编写好相应的测试文件后,gcc –o Filename Filename.c(测试文件名) 来产生相应的可执行文件).

:如果设备驱动挂载成功,当执行测试文件(./Filename)时会产生相应的结果.

 

:可能用到的相关命令:

1.       lsmod:列出内核已经载入模块的专题.

输出:

Module(模块名)            size(大小)            used by (..使用)

2.       demop:分析可加载模块的依赖性,生成modules.dep文件和映射文件

3.       uname –r   显示内核版本(在编写Makefile时使用到)

4.       modprobe : linux 内核添加和删除模块(相关参数请查看man帮助文档)

5.       modinfo:显示内核模块的信息.

6.       insmod: linux内核中加载一个模块,用法:insmod  [filename] [module options…]

7.       rmmod: 删除内核中的模块, 用法: rmmod [-f,w,s,v]       [modulename]

8.       dmesg: 显示内核缓冲区,内核的各种信息,内核启动时的信息会写入到/var/log/.

 

.例子1:

第一步:增加头文件和宏定义

#include

#include

#include

#include

#include

#include

 

第二步:添加与字符设备定义及注册有关的数据成员

//定义设备名称

#define DEVICE_NAME "test"        //设备名

#define BUF_SIZE       1024

static char tmpbuf[BUF_SIZE];

 

//定义主次设备号

static unsigned int TestMajor=0;                     //

static unsigned int TestMinor=0;                     //

 

 

static struct cdev *test_cdev;

static dev_t dev;

 

第三步:增加open/release函数

 

static int test_chardev_open(struct inode *inode,struct file *file)

{

    printk("open major=%d, minor=%d\n", imajor(inode),

                                     iminor(inode));

       return 0;

}

 

static int test_chardev_release(struct inode *inode,struct file *file)

{

      printk("close major=%d,minor=%d\n",imajor(inode), 

                                      iminor(inode));

       return 0;

}

 

第四步:增加read函数

static ssize_t test_chardev_read(struct file *file,char __user *buf,

                            size_t const count,loff_t *offset)

{

       if(count < BUF_SIZE)

       {

              if(copy_to_user(buf,tmpbuf,count))

              {

                printk("copy to user fail \n");

               return -EFAULT;

              }

       }else{

              printk("read size must be less than %d\n", BUF_SIZE);

              return -EINVAL;

}

       *offset += count;

              return count;

}

 

 

第五步:增加write函数

static ssize_t test_chardev_write(struct file *file, const char __user  *buf,size_t const count,loff_t *offset)

{

       if(count < BUF_SIZE)

       {

              if(copy_from_user(tmpbuf,buf,count))

              {

                printk("copy from user fail \n");

               return -EFAULT;

               }

       }else{

      

              printk("size must be less than %d\n", BUF_SIZE);

              return -EINVAL;

}           

       *offset += count;

       return count;

}

 

第六步:添加增加file_operations 成员

 

static struct file_operations chardev_fops={

       .owner = THIS_MODULE,

       .read = test_chardev_read,

       .write = test_chardev_write,

       .open = test_chardev_open,

       .release = test_chardev_release,

};

 

第七步:在模块的入口添加设备的设备号获取及设备注册

static int __init chrdev_init(void)

{      

int result;

 

if(TestMajor)

{

        dev=MKDEV(TestMajor,TestMinor);//创建设备编号

        result=register_chrdev_region(dev,1,DEVICE_NAME);

} else {

        result=alloc_chrdev_region(&dev,TestMinor,1,DEVICE_NAME);

        TestMajor=MAJOR(dev);

}

if(result<0)

{

        printk(KERN_WARNING"LED: cannot get major %d \n",TestMajor);

        return result;

}

 

test_cdev=cdev_alloc();

cdev_init(test_cdev,&chardev_fops);

//test_cdev->ops=&chardev_fops;

test_cdev->owner=THIS_MODULE;

result=cdev_add(test_cdev,dev,1);

if(result)

        printk("<1>Error %d while register led device!\n",result);

 

return 0;

}

 

第八步:在模块的出口函数增加设备设备号释放及设备注销函数

 

       unregister_chrdev_region(MKDEV(TestMajor,TestMinor),1);

       cdev_del(test_cdev);

 

第九步:编译并加载该模块

 

 

第十步:根据设备号的设置,在文件系统中建立对应的设备节点

    #mknod /dev/test  c  XXX  XX

 

例子2:

驱动文件:

#include

#include

#include

#include

#include

#include

 

#define DEVICENAME  "ccccc"

 

unsigned int major=221;

unsigned int minor=0;

struct cdev *abc;

dev_t dev;

static char bufrh[1024]="read success!";

 

static int aaaaa_open(struct inode *inodep, struct file *filep)

{

       printk("read success!\n");

      return 0;

}

 

int aaaaa_release(struct inode *inodep, struct file *filep)

{

      return 0;

}

static ssize_t aaaaa_read (struct file *filep, char __user *buf, size_t  count, loff_t *offset)

{

       if(copy_to_user(buf, bufrh, 1))

              {

                     printk("copy_to_user fail!\n");

              }

       return 0;

}

 

ssize_t aaaaa_write (struct file *filep, const char __user *buf,  size_t count, loff_t *offse)

{

       printk("write!\n");

       return 0;

}

 

 

static const struct  file_operations  fops = {

       .owner = THIS_MODULE,

       .open = aaaaa_open,

       .release = aaaaa_release,

       .read = aaaaa_read,

       .write = aaaaa_write,

      

      

};

 

 

 

 

static int __init aaaaa_init(void)

{

       int a;

       dev=MKDEV(major, minor);

       a=register_chrdev_region(dev, 1, DEVICENAME);

        

       abc=cdev_alloc();

       abc->owner=THIS_MODULE;

       cdev_init(abc, &fops);

      

       cdev_add(abc, dev, 1);

 

      

       return 0;

}

 

static void __exit  aaaaa_cleanup(void)

{

       cdev_del(abc);

       unregister_chrdev_region(dev, 1);

}

 

module_init(aaaaa_init);

module_exit(aaaaa_cleanup);

MODULE_LICENSE("GPL ");

 

 

Makefile文件:

 

obj-m += firstqd.o(相应设备文件名)

 

KERDIR = /usr/src/linux-headers-2.6.32-24-generic

#KERDIR=/home/linux2.6/linux  #arm骞冲彴

PWD=$(shell pwd)

 

modules:

       $(MAKE) -C $(KERDIR) M=$(PWD)  modules

 

pc:

       gcc -o fristqd firstqd.c

arm:

       arm-linux-gcc -o fristqd firstqd.c

 

clean:

        rm -rf *.o *~core *.depend *.cmd *.ko *.mod.c *.tmp_versions

 

 

 

测试文件(test.c):

 

 

#include

#include

#include

 

char buf[1024];

char bufw[1024]="write success";

int main()

{

      int fd,m,n;

      fd=open("/dev/aaa",O_RDWR);

      if (fd)

        {

            m=read(fd,buf,100);

            printf("read kernel:%s\n",buf);

 

            n=write(fd,bufw,10);

         }

      //printf("ni hao");

      return  0;

}

你可能感兴趣的:(LINUX)