文件路径:书附光盘\6应用例程\6Linux\driver\01_demo\demo.c
文件内容:
1.定义设备名- DEMO
#ifdef MODULE //需要编译为模块
#include <linux/module.h>
#ifdef CONFIG_DEVFS_FS
#include <linux/devfs_fs_kernel.h>
#endif
#include <linux/init.h> //初始化相关头文件
#include <linux/kernel.h> //与printk()等函数有关的头文件
#include <linux/slab.h> //与kmalloc()等函数有关的头文件
#include <linux/fs.h> //与文件系统有关的头文件everything...
#include <linux/errno.h> //错误代码处理头文件error codes
#include <linux/types.h> //数据类型头文件size_t
#include <linux/proc_fs.h> //与进程调度相关的头文件
#include <linux/fcntl.h> //O_ACCMODE
#include <linux/poll.h> //COPY_TO_USER
#include <asm/system.h> //cli(), *_flags
#define DEVICE_NAME "DEMO" //定义虚拟设备的名称为DEMO
#define DEMORAW_MINOR 1
#define DEMO_Devfs_path "demo/0"
//定义全局变量
static int demoMajor = 0;
static int MAX_BUF_LEN=1024; //定义缓冲区最大长度
static char drv_buf[1024]; //内核定义一缓冲区
static int WRI_LENGTH=0;
2.static void do_write()
/************************************************************************************
名称:do_write()
功能:将数组drv_buf[]内容逆序重排,用于被demo_write()调用。
入口参数: 排序前数据存于数组drv_buf[],数组drv_buf[]为全局变量。
出口参数: 排序后数据存于数组drv_buf[]。
************************************************************************************/
static void do_write(void)
{
int i;
int len = WRI_LENGTH; //WRI_LENGTH值来自demo_write()函数
char tmp;
for(i = 0; i < (len>>1); i++,len--){
tmp = drv_buf[len-1];
drv_buf[len-1] = drv_buf[i]; //对drv_buf[]数组进行逆序排列
drv_buf[i] = tmp;}}
3.demo_write()
/************************************************************************************
名称:demo_write()
功能:对应于应用层write系统调用。
将应用层用户定义缓冲区中数据复制到内核缓冲区drv_buf[]。
调用do_write()函数对数组drv_buf[]进行逆序排列。
入口参数: *filp 操作设备文件的ID,指向用户程序test_demo.c中打开的设备。
*buffer 应用层用户定义缓冲区的起始地址
count 应用层用户定义缓冲区的长度
出口参数: 返回排序数组长度
************************************************************************************/
static ssize_t demo_write(struct file *filp,const char *buffer, size_t count)
{
if(count > MAX_BUF_LEN) //数据<1024,越界保护
count = MAX_BUF_LEN;
copy_from_user(drv_buf , buffer, count); //复制用户buffer到内核空间drv_buf
WRI_LENGTH = count;
printk("user write data to driver\n"); //输出提示行
do_write(); //调用排序函数
return count;}
4.demo_read
/************************************************************************************
名称:demo_read()
功能:对应于应用层read系统调用。
将内核缓冲区drv_buf[]中数据复制到应用层用户定义的缓冲区中。
入口参数: *filp 操作设备文件的ID,指向用户程序test_demo.c中打开的设备。
*buffer 应用层用户定义缓冲区的起始地址
count 应用层用户定义缓冲区的长度
*ppos 用户在文件中进行存储操作的位置
出口参数: 返回排序数组长度
************************************************************************************/
static ssize_t demo_read(struct file *filp, char *buffer, size_t count, loff_t *ppos)
{
if(count > MAX_BUF_LEN)
count=MAX_BUF_LEN;
copy_to_user(buffer, drv_buf,count); //内核排列后的drv_buf传递给用户buffer
printk("user read data from driver\n"); //输出提示行
return count;}
5.demo_ioctl
/************************************************************************************
名称:demo_ioctl()
功能:对应于应用层ioctl系统调用。
展示对用户空间传递过来的命令的处理过程
入口参数: *filp操作设备文件的ID,指向用户程序test_demo.c中打开的设备。
cmd 来自应用层参数
arg 来自应用传递过来的参数列表
出口参数: 正确返回0 ,错误命令返回default 的提示内容
************************************************************************************/
static int demo_ioctl(struct inode *inode, struct file *file,unsigned int cmd, unsigned long arg)
{
switch(cmd){ //对来自应用层参数的处理
case 1:printk("runing command 1 \n");break;
case 2:printk("runing command 2 \n");break;
default:
printk("error cmd number\n");break;}
return 0;}
6.demo_open
//**********************************************************************
名称:static void demo_open()
功能:定义设备文件打开函数,对应于应用层open系统调用
入口参数: 设备文件节点,可附加参数(如O_RDWR表示以即读也写方式访问被打开文件)
出口参数: 无
**********************************************************************/
static int demo_open(struct inode *inode, struct file *file)
{
printk(KERN_DEBUG" device open sucess!\n");
return 0;}
7.demo_release
//**********************************************************************
名称:static void demo_ release ()
功能:设备文件释放函数,对应用应用层close系统调用,
入口参数: 设备文件节点
出口参数: 无
**********************************************************************/
static int demo_release(struct inode *inode, struct file *filp)
{
printk(KERN_DEBUG "device release\n");
return 0;}
8.demo_fops
//**********************************************************************
名称:demo_fops 设备文件结构
功能: 设备驱动文件结构体
关联系统操作write、read、ioctl、open、release与实体函数
**********************************************************************/
static struct file_operations demo_fops = {
owner: THIS_MODULE,
write: demo_write,
read:demo_read,
ioctl: demo_ioctl,
open: demo_open,
release: demo_release}
9.demo_init (register)
//**********************************************************************
名称:static void demo_init ()
功能:设备注册函数,通过register_chrdev向内核字符设备链表注册该字符设备
入口参数: 无
出口参数: 无
**********************************************************************/
static int __init demo_init(void)
{
int ret;
ret = register_chrdev(0, DEVICE_NAME, &pxa270_fops);
if (ret < 0) {
printk(DEVICE_NAME "can't get major number\n");
return ret;}
demoMajor=ret;
return 0;}
10.demo_ exit (unregister)
//**********************************************************************************
名称:static void demo_ exit()
功能:设备注销函数,通过unregister_chrdev 向内核字符设备链表注销该字符设备
入口参数: 无
出口参数: 无
************************************************************************************/
#ifdef MODULE
static void __exit demo_exit(void)
{
unregister_chrdev(demoMajor, DEVICE_NAME);
}
module_exit(demo_exit);
#endif
11.Module_
module_init(demo_init); //模块初始化
MODULE_LICENSE("Dual BSD/GPL"); //版权信息
#endif //MODULE