📄 7_2_2_p246.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 + -