⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 7_2_2_p246.txt

📁 键盘ledlcd的3个驱动程序,以WORD的格式打开,有设计思想,步骤,框图,为你学习带来方便
💻 TXT
字号:
4.模块化驱动程序框架
模块化驱动程序框架如下:

#define MODULE
#include<linux/module.h>
int init_module(void)
{
  printk("<1>Hello...\n");
  return 0;
 }
void cleanup_module(void)
{
  printk("<1>Goodbye...\n");
}

    其中init_module()在运行insmod命令后由系统调用,完成驱动模块的初始化工作。
cleanup_module()在运行rmmod命令后由系统调用,完成驱动模块的卸载时的清除工作。

5.字符设备的例子
   下面的例子包括样例模块化驱动程序、测试程序、Makefile文件和模块化驱动的操作步骤。
(1)DEMO驱动程(demo_drv.c)
/***********************************************************************
     演示如何设计一个字符驱动程序
***********************************************************************/
#include<linux/kernel.h>
#include<linux/module.h>
#include<linux/init.h>
#include<linux/errno.h>
#include<linux/sched.h>
#define DEMO_MAJOR   125
#define COMMAND1      1
#define COMMAND2      2
/******************************************************************
           函数声明 
 ******************************************************************/
static int demo_init(void);
static int demo_open(struct inode *inode,struct file *file);
static int demo_close(struct inode *inode,struct file *file);
static ssize_t demo_read(struct file *file,char *buf,size_t count,loff_t *offset);
static int demo_ioctl(struct inode *inode,struct file *file,unsigned int cmd,unsigned long arg);
static void demo_cleanup(void);
/**********************************************************************
     全局变量定义
***********************************************************************/
int demo_param = 9;
static int demo_initialized = 0;
static volatile int demo_flag = 0;
static struct file_operations demo_fops={
#if LINUX_KERNEL_VERSION>=KERNEL_VERSION(2,4,0)
    owner:      THIS_MODULE,
#endif
    llseek:     NULL,
    read:       demo_read,     /* 读数据 */
    write:      NIULL,         /* 写数据 */
    ioctl:      demo_ioctl,    /* 控制模块的设置 */
    open:       demo_open,     /* 在任何操作前打开模块 */
    release:    demo_close     /* 操作后关闭模块 */
};

static int demo_init(void){
    int i;
    /* 确定模块以前未初始化 */
    if (demo_initialized == 1)
        return 0;
    /* 分配并初始化所以数据结构为缺省状态 */
    i=register_chrdev(DEMO_MAJOR,"demo_drv",&demo_fops);
    if(i<0){
      printk(KERN_CRIT"DEMO:i = %d\n",i);
      return -EIO;
    }
    printk(KERN_CRIT"DEMO:demo_drv registerred successsfully:)=\n");
    /* 请求中断 */
    demo_initialized = 1;
    return 0;
}

static int demo_open(struct inode *inode, struct file *file)
{
   if(demo_flag==1)  
     {  /* 检查驱动忙否 */
        return -1;
     }
   /* 可以初始化一些内部数据结构 */
   printk(KERN_CRIT"DEMO:demo device open\n");
   MOD_INC_USE_COUNT;
   demo_flag =1;
   return 0;
}

static int demo_close(struct inode *inode,struct file *file)
{
   if(demo_flag == 0)
     {
        return 0;
     }
   /* 可以删除一些内部数据结构 */
   printk(KERN_CRIT"DEMO:demo device close\n");
   MOD_DEC_USE_COUNT;
   demo_flag = 0;
   return 0;
}

static ssize_t demo_read(struct file *file,char *buf,size_t count,loff_t *offset)
{  /* 检查是否已有线程在读数据,返回error */
   //DEMO_RD_LOCK;
   printk(KERN_CRIT"DEMO:demo is reading,demo_param = %d\n",demo_param);
   //DEMO_RD_UNLOCK;
   /* 通常返回成功读到的数据 */
   return 0;
}

static int demo_ioctl(struct inode *inode,struct file *file,unsigned int cmd,unsigned long arg)
{
   if(cmd == COMMAND1)
     {
       printk(KERN_CRIT"DEMO:set command COMMAND1\n");
       return 0;
     }
   if(cmd == COMMAND2)
     {
       printk(KERN_CRIT"DEMO:set command COMMAND2\n");
       return 0;
     }

     printk(KERN_CRIT"DEMO:set command WRONG\n");
     return 0;
}

static void demo_cleanup(void)
{ /* 确保要清掉的模块是已初始化的 */
   if(demo_initialized == 1)
     { /* 禁止中断 */
       /* 释放该模块的中断服务程序 */
       unregister_chrdev(DEMO_MAJOR,"demo_drv");
       demo_initialized =0;
       printk(KERN_CRIT"DEMO:demo device is cleanup\n");
     }
    return;
}

/*************************************************************************
      初始化/清除模块
***********************************************************************/
#ifdef MODULE
MODULE_AUTHOR("DEPART 901");
MODULE_DESCRIPTION("DEMO driver");
MODULE_PARM(demo_param,"i");
MODULE_PARM(demo_param,"parameter sent to driver");
int init_module(void){
   return demo_init();
}
void cleanup_module(void){
   demo_cleanup();
}
#endif

(2)应用程序(test.c)
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <linux/rtc.h>
#include <linux/ioctl.h>
#define COMMAND1    1
#define COMMAND2    2
main()
{
   int fd;
   int i;
   unsigned long data;
   int retval;
   fd = open("./demo_drv",O_RDONLY);
   if(fd==-1)
     {
        perror("open");
        exit(-1);
      }
   retval = ioctl(fd,COMMAND1,0);
   if(retval==-1)
     {
       perror("ioctl");
       exit(-1);
     }
    for(i=0;i<3;i++)
      {
         retval=read(fd,&data,sizeof(unsigned long));
         if(retval==-1)
           {
              perror("read");
              exit(-1);
            }
       }
     close(fd);
}

(3)Makefile 文件(makefile)

INCLUDE=/user/linux/include
EXTRA_CFLAGS=-D_KERNEL_-DMODULE-I$(INCLUDE)-02-Wall-0
all:demo.o test
demo.o:demo_drv.c
  gcc $((CFLAGS)$(EXTRA_CFLAGS)-c demo_drv.c-o demo.o
test:test.c
	gcc -g test.c-o test
clean:
	rm -rf demo.o
	rm -rf test
(4)模块化驱动的操作步骤(step.txt)

make clean
make
mknod demo_drv c 125 0
lsmod
insmod demo.o
lsmod
./test
rmmod demo
insmod demo.o demo_param=8
lsmod
./test
rmmod demo
rm demo_drv -rf
make clean

		
    






  

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -