2.制作第一个驱动程序

驱动框架

先讲解驱动框架,然后写出first_drv驱动程序,来打印一些信息
写出first_drv驱动程序需要以下几步:

  1. 写出驱动程序first_drv_openfirst_drv_write
  2. 需要定义file_operations结构体来封装驱动函数first_drv_openirst_drv_write

对于字符设备来说,常用file_operations以下几个成员:
这里写图片描述

  1. 写驱动的first_drv_init 入口函数来调用alloc_chrdevregion函数,用以动态获得设备编号(存于cdev中)。
  2. 模块加载函数,通过函数 cdev_init(cdev,fops)将设备与操作绑定,然后通过cdev_add(cdev,num,count)函数将该结构信息通知给内核。
  3. 通过module_init()来修饰first_drv_init入口函数,使内核知道有这是模块初始化函数。
  4. 写驱动的first_drv_exit出口函数,调用这个unregister_chrdev_region()函数卸载,
  5. 通过module_exit()来修饰出口函数
  6. 模块许可证声明, 最常见的是以MODULE_LICENSE( "GPL v2" )来声明

#编写步骤

1. 首先创建first_drv.c文件

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <asm/irq.h>
#include <asm/arch/regs-gpio.h>
#include <asm/hardware.h>
#include <asm/uaccess.h>
#include <asm/io.h>
 
/*1写出驱动程序first_drv_open first_drv_write */

/*  inode结构表示具体的文件,file结构体用来追踪文件在运行时的状态信息。*/
static int first_drv_open(struct inode *inode, struct file  *file)
{
   printk(“first_drv_open\n”);      //打印,在内核中打印只能用printk()
   return 0;
}

/*参数filp为目标文件结构体指针,buffer为要写入文件的信息缓冲区,count为要写入信息的长度,ppos为当前的偏移位置,这个值通常是用来判断写文件是否越界*/

static ssize_t first_drv_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos)
{
  printk(“first_drv_write\n”);      //打印,在内核中打印只能用printk()
   return 0;
}

/*2定义file_operations结构体来封装驱动函数first_drv_open first_drv_write */
 static struct file_operations first_drv_fops = {
    .owner  =   THIS_MODULE,     //被使用时阻止模块被卸载
    .open   =   first_drv_open,      
    .write   =   first_drv_write,   
  };

/*4写first_drv_init入口函数来调用这个register_chrdev()注册函数*/
int first_drv_init(void)
{
   /*3 register_chrdev注册字符设备,并设置major=111*/
  /*如果设置major为0,表示由内核动态分配主设备号,函数的返回值是主设备号*/
register_chrdev (111, “first_drv”, &first_drv_fops); //111:主设备号,”first_drv”:设备名
/*
register_chrdev作用:在VFS虚拟文件系统中找到字符设备,然后通过主设备号找到内核数组里对应的位置,最后将设备名字和fops结构体填进去
*/
   return 0;
}

/*5 module_init修饰入口函数*/
module_init(first_drv_init);

/*6 写first_drv_exit出口函数*/
void first_drv_exit(void)
{
unregister_chrdev (111, “first_drv”);  //卸载驱动,只需要主设备号和设备名就行 
}

/*7 module_exit修饰出口函数*/
module_exit(first_drv_exit);

/*8许可证声明, 描述内核模块的许可权限,如果不声明

LICENSE,模块被加载时,将收到内核被污染 (kernel tainted)的警告。*/
MODULE_LICENSE( "GPL v2" );

2. 编写Makefile文件

KERNEL_VERSION :=$(shell uname -r)
KERNEL_MODULES :=/lib/modules/$(KERNEL_VERSION)/build
obj-m += first_drv.o

 all:
          make -C $(KERNEL_MODULES) M=$(PWD) modules 

3. make 编译

4. 装卸与卸载

使用insmod,rmmod进行装载,卸载

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值