




已阅读5页,还剩5页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Driverdemo源代码分析模块驱动源代码demo.c如下,其中的demo_read,demo_write函数完成驱动的读写接口功能,do_write函数实现将用户写入的数据逆序排列,通过读取函数读取转换后的数据。这里只是演示接口的实现过程和内核驱动对用户的数据的处理。Demo_ioctl函数演示ioctl调用接口的实现过程。#ifdef MODULE#include #ifdef CONFIG_DEVFS_FS#include #endif#include /*初始化相关头文件*/#include /*与 printk()等函数有关的头文件 */#include /*与 kmalloc()等函数有关的头文件*/#include /* 与文件系统有关的头文件everything. */#include /* 错误代码处理头文件error codes */#include /*数据类型头文件 size_t */#include /*与进程调度相关的头文件*/#include /* O_ACCMODE */#include /* COPY_TO_USER */#include /* cli(), *_flags */#define DEVICE_NAMEUP-TECH DEMO /*该驱动的设备名*/#define DEMORAW_MINOR 1#define DEMO_Devfs_path demo/0static int demoMajor = 0;static int MAX_BUF_LEN=1024; /*定义一缓冲区最大长度*/static char drv_buf1024; /*定义一缓冲区*/static int WRI_LENGTH=0;/* 名称:static void do_write()* 功能:逆序排列缓冲区数据* 入口参数:无* 出口参数:无*/static void do_write()int i;int len = WRI_LENGTH;char tmp;for(i = 0; i 1); i+,len-)tmp = drv_buflen-1;drv_buflen-1 = drv_bufi; /*对drv_buf数组进行逆序排列*/drv_bufi = tmp;/* 名称:demo_write()* 功能:对应用户空间的write系统调用,从用户空间拷贝给定长度缓冲区数据到内核空间* 入口参数:*filp 操作设备文件的ID,*buffer对应用户空间的缓冲区的起始地址,count用户空间数据缓冲区长度 * 出口参数:返回用户空间数据缓冲区长度 */static ssize_t demo_write(struct file *filp,const char *buffer, size_t count) if(count MAX_BUF_LEN)count = MAX_BUF_LEN;copy_from_user(drv_buf , buffer, count); /*从用户空间拷贝缓冲区数据到内核空间的关键函数,把用户空间的buffer数据传递给drv_buf数组*/ WRI_LENGTH = count;printk(user write data to drivern);do_write(); /*对drv_buf数组进行逆序排列*/return count;/* 名称:demo_ read()* 功能:对应用户空间的read系统调用,从内核空间拷贝给定长度缓冲区数据到用户空间* 入口参数:*filp 操作设备文件的ID,*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; /*涉及内核buffer与用户空间buffer传输匹配的问题,可让学生考虑为什么这样处理*/copy_to_user(buffer, drv_buf,count); /*从内核空间拷贝缓冲区数据到用户空间的关键函数,把内核空间经过逆序排列后的drv_buf数组传递给用户空间的buffer数组*/ printk(user read data from drivern);return count;/* 名称:demo_ioctl()* 功能:对应用户空间的ioctl系统调用,对用户空间传递过来的命令进行swith判断,并进行相应处理,本函数只对用户空间传递过来的1,2做简单的处理,打印一条信息,该信息可以在var/log/messages文件尾查阅到* 入口参数:*filp 操作设备文件的ID,cmd对应用户空间的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 numbern);break;return 0;/* 名称:static void demo_open ()* 功能:设备文件打开函数,对应用户空间open系统调用,* 入口参数:设备文件节点* 出口参数:无*/static int demo_open(struct inode *inode, struct file *file) printk(KERN_DEBUG device open sucess!n); return 0;/* 名称:static void demo_open ()* 功能:设备文件释放函数,对应用户空间close系统调用,* 入口参数:设备文件节点* 出口参数:无*/static int demo_release(struct inode *inode, struct file *filp) printk(KERN_DEBUG device releasen); return 0;/* 名称:demo_fops设备文件结构* 功能: 设备驱动文件结构体*/static struct file_operations demo_fops = owner:THIS_MODULE,write:demo_write,read:demo_read,ioctl:demo_ioctl,open:demo_open,release:demo_release,;/* 名称:static void demo_init ()* 功能:设备注册函数,通过devfs_register向设备文件系统/dev目录下注册设备,通过register_chrdev向内核字符设备链表注册该字符设备* 入口参数:无* 出口参数:无*/static int _init demo_init(void)int ret;ret = register_chrdev(0, DEVICE_NAME, &demo_fops);if (ret 0) printk(DEVICE_NAME cant get major numbern); return ret; demoMajor=ret; #ifdef CONFIG_DEVFS_FSdevfs_mk_cdev(MKDEV(demoMajor, DEMORAW_MINOR), S_IFCHR|S_IRUSR|S_IWUSR|S_IRGRP, DEMO_Devfs_path); #endif return 0;/* 名称:static void demo_ exit ()* 功能:设备注销函数,通过unregister_chrdev向内核字符设备链表注销该字符设备* 入口参数:无* 出口参数:无*/#ifdef MODULEstatic void _exit demo_exit(void)#ifdef CONFIG_DEVFS_FS devfs_remove(DEMO_Devfs_path);#endifunregister_chrdev(demoMajor, DEVICE_NAME);module_exit(demo_exit);#endif/*/module_init(demo_init);MODULE_LICENSE(Dual BSD/GPL);#endif / MODULE参考Makefile如下:TARGET = test_demoCROSS_COMPILE = arm-linux- CC = $(CROSS_COMPILE)gccSTRIP = $(CROSS_COMPILE)strip#CFLAGS = -O2ifeq ($(KERNELRELEASE),) # Assume the source tree is where the running kernel was built # You should set KERNELDIR in the environment if its elsewhere KERNELDIR ?=/home/sprife/kernel/linux-2.6.24.4 /*给ARM编译的驱动内核源代码所在的路径*/# KERNELDIR ?= /usr/src/kernels/2.6.9-42.EL-smp-i686/ /*给PC编译的驱动内核源代码所在的路径*/ # The current directory is passed to sub-makes as argument PWD := $(shell pwd) all: $(TARGET) modules $(TARGET): $(CC) -o $(TARGET) $(TARGET).cmodules: $(MAKE) -C $(KERNELDIR) M=$(PWD) modulesmodules_install: $(MAKE) -C $(KERNELDIR) M=$(PWD) modules_installclean: rm -rf *.o * core .depend .*.cmd *.ko *.mod.c .tmp_versions $(TARGET).PHONY: modules modules_install cleanelse # called from kernel build system: just declare what our modules are obj-m := demo.oendif其中的:#KERNELDIR = /home/sprife/kernel/linux-2.6.24.4#CROSS_COMPILE= arm -linux-两行宏变量定义用于使用arm -linux-gcc编译器编译驱动,适用于经典2410平台。默认使用gcc编译器,使用X86 PC平台。用户测试程序test_demo.c代码如下:#include #include #include void showbuf(char *buf);int MAX_LEN=32;int main()int fd;int i,j,k;char buf255;for(i=0; iMAX_LEN; i+)bufi=i;fd=open(/dev/demo/0,O_RDWR); if(fd 0)printf(#DEMO device open fail#n);return (-1);printf(write %d bytes data to /dev/demo n,MAX_LEN);showbuf(buf);write(fd,buf,MAX_LEN);printf(Read %d bytes data from /dev/demo n,MAX_LEN);read(fd,buf,MAX_LEN);showbuf(buf);ioctl(fd,1,NULL);ioctl(fd,4,NULL);close(fd);void showbuf(char *buf)int i,j=0;for(i=0;iMAX_LEN;i+)if(i%4 =0)printf(n%4d: ,j+);printf(%4d ,bufi);printf(n*n);Driverdemo实验步骤一感性认识的实验步骤:在Linux PC机上进行1修改Makefile文件两个地方a.注释CROSS_COMPILE = arm-linux-这一行b.修改KERNELDIR ?= /usr/src/kernels/2.6.9-42.EL-smp-i686/ make clean;make 生成demo.ko2. 用insmod 命令插入设备驱动rootvm-dev demo_driver#insmod demo.korootvm-dev 01_moddriver# cat /proc/devices Character devices: 1 mem 4 /dev/vc/0 4 tty 4 ttyS 5 /dev/tty 5 /dev/console 5 /dev/ptmx 6 lp 7 vcs 10 misc 13 input 14 sound 29 fb 36 netlink 89 i2c116 alsa128 ptm136 pts162 raw180 usb253 UP-TECH DEMO254 vmci Block devices: 1 ramdisk 2 fd3用mknod命令建立demo设备节点rootvm-dev demo_driver#mkdir /dev/demorootvm-dev demo_driver#mknod /dev/demo/0 c 253 04 运行测试程序 rootvm-dev demo_driver#./test_demowrite 32 bytes data to /dev/mydemo 0: 0 1 2 3 1: 4 5 6 7 2: 8 9 10 11 3: 12 13 14 15 4: 16 17 18 19 5: 20 21 22 23 6: 24 25 26 27 7: 28 29 30 31 *Read 32 bytes data from /dev/mydemo 0: 31 30 29 28 1: 27 26 25 24 2: 23 22 21 20 3: 19 18 17 16 4: 15 14 13 12 5: 11 10 9 8 6: 7 6 5 4 7: 3 2 1 0 *5删除设备节点rootvm-dev demo_driver#rm -f /dev/demo二完善代码部分1分析Makefile文件,把为PC linux编写的Makefile文件改写为为ARM开发平台编写的Makefile文件a.去掉注释CROSS_COMPILE = arm-linux-这一行b.修改KERNELDIR ?= /home/hq/kernel/linux-2.6.24.4(开发板的内核目录) 三、编译驱动模块及测试程序1按第二部分完善代码后,用make命令编译驱动和测试程序qianzglocalhost demo$make armv4l-unknown-linux-gcc -c -I. -Wall -O -D_KERNEL_ -DMODULE -I/arm2410dev/kernel-2410dev/include demo.c -o demo.odemo.c:108: warning: initialization from incompatible pointer typearmv4l-unknown-linux-gcc -c -I. -Wall -O -D_KERNEL_ -DMODULE -I/arm2410dev/kernel-2410de
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 辅警调解业务知识培训课件
- 中国银行2025六盘水市秋招面试典型题目及参考答案
- 交通银行2025武汉市笔试英文行测高频题含答案
- 中国银行2025保山市结构化面试15问及话术
- 2025年3D打印技术的个性化定制优势
- 2025海洋塑料污染的源头控制
- 2025行业数字化转型挑战与对策-1
- 2025应急管理行业创新发展报告
- 邮储银行2025黄山市秋招半结构化面试题库及参考答案
- 交通银行2025威海市数据分析师笔试题及答案
- DL∕T 514-2017 电除尘器 标准
- IPO申报财务三年又一期会计报表模板(单体式)
- 急性胰腺炎抗凝治疗
- 媒介素养概论 课件 刘勇 第0-4章 绪论、媒介素养-新闻评论
- 美慧树课件教材培训
- 09J202-1 坡屋面建筑构造(一)-1
- 研发人员工时统计表
- 沙盘游戏在自闭症中的运用课件
- 桥梁施工过程中的安全检查要点
- 护士长竞聘晋升述职报告模板(含内容)
- 二年级科学上册跨学科项目化学习案例做一个小鸟餐厅
评论
0/150
提交评论