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

📄 11linux.txt

📁 Linux系统中
💻 TXT
字号:
1、   程序清单
//      MyDev.c      2000年2月7日编写
#ifndef __KERNEL__
# define __KERNEL__  //按内核模块编译
#endif
#ifndef MODULE
# define MODULE        //设备驱动程序模块编译
#endif
#define DEVICE_NAME ”MyDev”
#define OPENSPK 1
#define CLOSESPK 2
//必要的头文件
#include <linux/module.h>    //同kernel.h,最基本的内核模块头文件
#include <linux/kernel.h> //同module.h,最基本的内核模块头文件
#include <linux/sched.h> //这里包含了进行正确性检查的宏
#include <linux/fs.h>   //文件系统所必需的头文件
#include <asm/uaccess.h> //这里包含了内核空间与用户空间进行数据交换时的
函数宏
#include <asm/io.h>   //I/O访问
int my_major=0;         //主设备号
static int Device_Open=0;
static char Message[]=”This is from device driver”;
char *Message_Ptr;
int my_open(struct inode *inode, struct file *file)
{//每当应用程序用open打开设备时,此函数被调用
printk (”\ndevice_open(%p,%p)\n”, inode, file);
if (Device_Open)
return -EBUSY;   //同时只能由一个应用程序打开
Device_Open++;
MOD_INC_USE_COUNT;  //设备打开期间禁止卸载
return 0;
}
static void my_release(struct inode *inode, struct file *file)
{//每当应用程序用close关闭设备时,此函数被调用
printk (”\ndevice_release(%p,%p)\n”, inode, file);
Device_Open –;
MOD_DEC_USE_COUNT;  //引用计数减1
}
ssize_t my_read (struct file *f,char *buf,int size,loff_t off)
{//每当应用程序用read访问设备时,此函数被调用
int bytes_read=0;
#ifdef DEBUG
printk(”\nmy_read is called. User buffer is %p,size is %d\n”,buf,size);
#endif
if (verify_area(VERIFY_WRITE,buf,size)==-EFAULT)
return -EFAULT;
Message_Ptr=Message;
while(size && *Message_Ptr)
{
if(put_user(*(Message_Ptr++),buf++))  //写数据到用户空间
return -EINVAL;
size –;
bytes_read++;
}
return bytes_read;
}
ssize_t my_write (struct file *f,const char *buf, int size,loff_t off)
{//每当应用程序用write访问设备时,此函数被调用
int i;
unsigned char uc;
#ifdef DEBUG
printk(”\nmy_write is called. User buffer is %p,size is %d\n”,buf,size);
#endif
if (verify_area(VERIFY_WRITE,buf,size)==-EFAULT)
return -EFAULT;
printk(”\nData below is from user program:\n”);
for (i=0;i<size;i++)
if(!get_user(uc,buf++)) //从用户空间读数据
printk(”%02x ”,uc);
return size;
}
int my_ioctl(struct inode *inod,struct file *f,unsigned int arg1,
unsigned int arg2)
{//每当应用程序用ioctl访问设备时,此函数被调用
#ifdef DEBUG
printk(”\nmy_ioctl is called. Parameter is %p,size is %d\n”,arg1);
#endif
switch (arg1)
{
case OPENSPK:
printk(”\nNow,open PC’s speaker.\n”);
outb(inb(0×61)|3,0×61); //打开计算机的扬声器
break;
case CLOSESPK:
printk(”\nNow,close PC’s speaker.”);
outb(inb(0×61)&0xfc,0×61);//关闭计算机的扬声器
break;
}
}

struct file_operations my_fops = {
NULL,     /* lseek */
my_read,
my_write,
NULL,
NULL,
my_ioctl,
NULL,
my_open,
my_release,
/* nothing more, fill with NULLs */
};
int init_module(void)
{//每当装配设备驱动程序时,系统自动调用此函数
int result;
result = register_chrdev(my_major,DEVICE_NAME,&my_fops);
if (result < 0) return result;
if (my_major == 0)
my_major = result;
printk(”\nRegister Ok. major-number=%d\n”,result);
return 0;
}
void cleanup_module(void)
{//每当卸载设备驱动程序时,系统自动调用此函数
printk(”\nunload\n”);
unregister_chrdev(my_major, DEVICE_NAME);
}

2、   设备  驱动程序设计
Linux设备分为字符设备、块设备和网络设备。字符设备是不需要缓冲而直接读写的设备,如串口、键盘、鼠标等,本例就是字符设备驱动程序;块设备的访问通常需要缓冲来支持,以数据块为单位来读写,如磁盘设备等;网络设备是通过套接字来访问的特殊设备。
1) 设备驱动程序和内核与应用程序的接口
无论哪种类型的设备,Linux都是通过在内核中维护特殊的设备控制块来与设备驱动程序接口的。在字符设备和块设备的控制块中,有一个重要的数据结构file_operations,该结构中包含了驱动程序提供给应用程序访问硬件设备的各种方法,其定义如下(参见fs.h):
struct file_operations {
loff_t (*llseek) (struct file *, loff_t, int);    //响应应用程序中lseek调
用的函数指针
ssize_t (*read) (struct file *, char *, size_t, loff_t *);
//响应应用程序中read调用的函数指针
ssize_t (*write) (struct file *, const char *, size_t, loff_t *);
//响应应用程序中write调用的函数指针
int (*readdir) (struct file *, void *, filldir_t); //响应应用程序中
readdir调用的函数指针
unsigned int (*poll) (struct file *, struct poll_table_struct *);
//响应应用程序中select调用的函数指针
int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned
long);
//响应应用程序中ioctl调用的函数指针
int (*mmap) (struct file *, struct vm_area_struct *);
//响应应用程序中mmap调用的函数指针
int (*open) (struct inode *, struct file *);  //响应应用程序中open调
用的函数指针
int (*flush) (struct file *);
int (*release) (struct inode *, struct file *); //响应应用程序中close
调用的函数指针
int (*fsync) (struct file *, struct dentry *);
int (*fasync) (int, struct file *, int);
int (*check_media_change) (kdev_t dev);
int (*revalidate) (kdev_t dev);
int (*lock) (struct file *, int, struct file_lock *);
};

⌨️ 快捷键说明

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