ARM&Linux 下驱动开发第三节
#include<linux/init.h>
#include<linux/module.h>
#include<linux/kernel.h>
#include <linux/poll.h> /* COPY_TO_USER */
#include<linux/errno.h>
#include <linux/cdev.h>
#include <linux/slab.h> #define DEV_NAME "rwtest"
#define DEV_NUM 2
#define DEV_MEM_SIZE 4096 static int major=;
//static int MAX_BUF_LEN=1024;
static char drv_buffer[][];
//static char drv_buf0[1024];
//static char drv_buf1[1024];
//static int WRI_LENGTH=0;
struct cdev cdev;
struct mem_dev * mem_devp; /*璁惧缁撴瀯浣撴寚閽?/ /*mem璁惧鎻忚堪缁撴瀯浣?/
struct mem_dev
{
char *data;
unsigned long size;
}; /***********鍐欏叆*************************/
static ssize_t dx_write(struct file *filp, const char __user *buffer, size_t size, loff_t * ppos)
{
unsigned long p=*ppos;
unsigned int count =size;
int ret=;
char * data=filp->private_data ;
//struct mem_dev *dev = filp->private_data; /*鑾峰緱璁惧缁撴瀯浣撴寚閽?/
//struct mem_dev *dev=&mem_devp[0];/*鑾峰緱璁惧缁撴瀯浣撴寚閽? [0]*/
printk("data:::%s\n",data);
if(p>=DEV_MEM_SIZE)return ;
if(count>DEV_MEM_SIZE-p)
{
count=DEV_MEM_SIZE-p;
}
printk("write p::%ld\n",p);
/*浠庤繃鎴风┖闂村啓鍏ユ暟鎹?/
if(copy_from_user(data + p,buffer,count))
{
ret=-EFAULT;
}
else
{
*ppos +=count;
ret=count;
printk(KERN_INFO "written %d bytes from %ld\n",count,p);
}
printk("write:%s\n",(char *)(filp->private_data+p));
printk("write buffer:%s\n",buffer);
return count;
}
/**************************************璇诲彇***********************************************/
static ssize_t dx_read(struct file *filp, char __user *buffer, size_t size, loff_t *ppos)
{
//鏂囦欢璇诲彇浣嶇疆
unsigned long p=*ppos;
unsigned int count =size;//瑕佽鍙栫殑,澶у皬
int ret=;
char * data=filp->private_data ;
//struct mem_dev *dev = filp->private_data; /*鑾峰緱璁惧缁撴瀯浣撴寚閽?/
//struct mem_dev *dev=&mem_devp[0];/*鑾峰緱璁惧缁撴瀯浣撴寚閽? [0]*/ if(p>=DEV_MEM_SIZE)
return ;
if(count>DEV_MEM_SIZE-p)
{
count=DEV_MEM_SIZE-p;
}
printk("read p::%ld\n",p);
/*浠庢暟鎹鍒扮敤鎴风┖闂?*/
if(copy_to_user(buffer,data + p,count))
{
ret=-EFAULT;
}
else
{
*ppos +=count;
ret=count;
printk(KERN_INFO "written %d bytes from %ld\n",count,p);
}
printk("read:%s\n",(char *)(filp->private_data));
printk("read buffer:%s\n",buffer);
return count;
}
//===========================鎵撳紑=========================================
static int dx_open(struct inode *inode, struct file *filp)
{
//printk("device open sucess!\n");
//struct mem_dev *dev;
/*鑾峰彇娆¤澶囧彿*/
int num = MINOR(inode->i_rdev); if (num >= DEV_NUM)
return -ENODEV;
//dev = &mem_devp[num];
//dev = drv_buffer[num];
printk("num:%d\n",num);
/*灏嗚澶囨弿杩扮粨鏋勬寚閽堣祴鍊肩粰鏂囦欢绉佹湁鏁版嵁鎸囬拡*/
filp->private_data = drv_buffer[num];
filp->f_pos +=strlen(drv_buffer[num]);
printk("open:%s\n",(char *)filp->private_data);
return ;
}
/**********************************release***************************************************/
static int dx_release(struct inode *inode, struct file *filp)
{
printk("device release\n");
return ;
} static loff_t dx_llseek(struct file *filp, loff_t offset, int whence)
{
loff_t newpos; switch(whence) {
case : /* SEEK_SET */
newpos = offset;//鏂囦欢寮€濮嬩綅缃姞鍋忕Щ閲? break;
case : /* SEEK_CUR */
newpos = filp->f_pos + offset;//褰撳墠鎸囬拡浣嶇疆鍔犲亸绉婚噺
break;
case : /* SEEK_END */
newpos = DEV_MEM_SIZE - + offset;//鏂囦欢鏈熬鍔犲亸绉婚噺(鏈€鍚庝竴浣嶄负'\0')
break;
default: /* can't happen */
return -EINVAL;
}
if ((newpos<) || (newpos>DEV_MEM_SIZE))
return -EINVAL;
filp->f_pos = newpos;
return newpos;
} //===============缁撴瀯浣?椹卞姩鍚勫睘鎬?=========
static struct file_operations file_opt = {
.owner= THIS_MODULE,
.llseek= dx_llseek,
.write= dx_write,
.read= dx_read,
.open= dx_open,
.release=dx_release,
};
//----------------------------------------------------------------------
static int __init qudong_init(void)
{
int ret;
ret = register_chrdev(, DEV_NAME, &file_opt);
if(ret<)
{
printk(DEV_NAME " can't get major number\n");
return ;
}
major=ret;
printk("dx module major number is %d\n", ret);
return ;
}
//-----------------------------------------------------------------------
static void __exit qudong_exit(void)
{
/*娉ㄩ攢璁惧*/
cdev_del(&cdev);
//kfree(mem_devp); /*閲婃斁璁惧缁撴瀯浣撳唴瀛?/
unregister_chrdev_region(MKDEV(major,),);/*閲婃斁璁惧鍙?/
printk("exit\n");
}
module_init(qudong_init);
module_exit(qudong_exit);
MODULE_LICENSE("GPL");/*浣跨敤鏉冮檺*/
MODULE_AUTHOR("Made in China <china@hotmail.com>");/*浣滆€?/
MODULE_DESCRIPTION("s3c6410 Hypervisor Filesystem");/*鐗堟湰*/
测试代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include<string.h>
int main()
{
int fd0=;
int fd1=;
int ret=;
char bufw[]={'\0'};
char bufr[]={'\0'};
char bufw1[]={'\0'};
char bufr1[]={'\0'};
fd0=open("/dev/rw0",O_RDWR);
if(fd0<)
{
perror("open error\n");
return ;
}
fd1=open("/dev/rw1",O_RDWR);
if(fd1<)
{
perror("open error\n");
return ;
}
printf("Please input string:\n");
scanf("%s",bufw);
ret=write(fd0,bufw,strlen(bufw));
if(ret<)
{
perror("write bufw error\n");
return ;
}
printf("burw====%s\n",bufw);
printf("Please input string:\n");
scanf("%s",bufw1);
ret=write(fd1,bufw1,strlen(bufw1));
if(ret<)
{
perror("write bufw1 error\n");
return ;
}
printf("burw1====%s\n",bufw1);
int num0=strlen(bufw);
printf("num0:%d\n",num0);
lseek(fd0,-(num0),SEEK_CUR);
//lseek(fd0,0,SEEK_CUR);
ret=read(fd0,bufr,);
if(ret<)
{
perror("read bufr error\n");
return ;
}
printf("bufr====%s\n",bufr);
int num1=strlen(bufw1);
printf("num1:%d\n",num1);
lseek(fd1,-(num1),SEEK_CUR);
//lseek(fd1,0,SEEK_SET);
ret=read(fd1,bufr1,);
if(ret<)
{
perror("read bufr1 error\n");
return ;
}
printf("bufr1====%s\n",bufr1); close(fd0);
close(fd1);
return ;
}
Makefile文件:
## Makefile template. obj-m := qudong.o
UNAME := $(shell uname -r)
PWD := $(shell pwd)
ADVMOD := qudong defualt:
@make -C /lib/modules/$(UNAME)/build SUBDIRS=$(PWD) modules clean:
@rm -f *.o
@rm -f *.ko
@rm -f *.mod.c
@rm -f .*.cmd
@rm -rf .tmp_versions
#endif
ARM&Linux 下驱动开发第三节的更多相关文章
- ARM&Linux 下驱动开发第一节(小试牛刀)
#include<linux/init.h> #include<linux/module.h> static int __init hello_init(void) { pri ...
- ARM&Linux 下驱动开发第二节
驱动文件:qudong.c,make生成qudong.ko文件,烧录到ARM板上 #include<linux/init.h> #include<linux/module.h> ...
- Linux设备驱动开发环境的搭建(转)
经过两周的摸索,终于对Linux设备驱动开发有了个初步的认识,下面对Linux设备驱动开发环境的搭建做个小结,以方便自己以后查询,同时也能给同道的初学者一点帮助. 刚接触Linux设备驱动时,初学者往 ...
- 《Linux设备驱动开发具体解释(第3版)》进展同步更新
本博实时更新<Linux设备驱动开发具体解释(第3版)>的最新进展. 2015.2.26 差点儿完毕初稿. 本书已经rebase到开发中的Linux 4.0内核,案例多数基于多核CORTE ...
- Hasen的linux设备驱动开发学习之旅--时钟
/** * Author:hasen * 參考 :<linux设备驱动开发具体解释> * 简单介绍:android小菜鸟的linux * 设备驱动开发学习之旅 * 主题:时钟 * Date ...
- 移植ARM linux下远程连接工具dropbear
移植ARM linux下远程连接工具dropbear 原文地址:http://www.cnblogs.com/NickQ/p/9010529.html 移植zlib 下载地址:https://gith ...
- 《Linux设备驱动开发具体解释(第3版)》(即《Linux设备驱动开发具体解释:基于最新的Linux 4.0内核》)网购链接
<Linux设备驱动开发具体解释:基于最新的Linux 4.0内核> china-pub spm=a1z10.3-b.w4011-10017777404.30.kvceXB&i ...
- Linux 设备驱动开发 —— platform设备驱动应用实例解析
前面我们已经学习了platform设备的理论知识Linux 设备驱动开发 —— platform 设备驱动 ,下面将通过一个实例来深入我们的学习. 一.platform 驱动的工作过程 platfor ...
- Linux下c开发 之 线程通信(转)
Linux下c开发 之 线程通信(转) 1.Linux“线程” 进程与线程之间是有区别的,不过Linux内核只提供了轻量进程的支持,未实现线程模型.Linux是一种“多进程单线程”的操作系统.Linu ...
随机推荐
- Java并发编程-synchronized
多线程的同步机制对资源进行加锁,使得在同一个时间,只有一个线程可以进行操作,同步用以解决多个线程同时访问时可能出现的问题.同步机制可以使用synchronized关键字实现.synchronized关 ...
- MAC OSX 驱动操作
mac ox系统的驱动安装常规操作:下载到 *.kext 的驱动以后,都可以直接把它拖到 /System/Library/Extensions/ 下替换掉原来的文件.替换了以后,还需要修复权限才能够正 ...
- OpenERP 7.0 中文报表PDF乱码(WindowsXP)
OpenERP默认安装输出的PDF中文报表都是一些方块: 此问题可以通过oecn_base_fonts模块解决: 更多关于oecn_base_fonts的信息请参考: 1. OpenERPv7.0 中 ...
- 二级指针的作用及用途 .xml
pre{ line-height:1; color:#9f1d66; background-color:#e1e1e1; font-size:16px;}.sysFunc{color:#5d57ff; ...
- C++标准转换运算符 --四种
具体归纳如下: reinterpret_cast 函数将一个类型的指针转换为另一个类型的指针. 这种转换不用修改指针变量值存放格式(不改变指针变量值),只需在编译时重新解释指针的类型就可做到.rein ...
- 【脚本语言对比】BASH,PERL以及PYTHON
据说: BASH能调用linux的应用程序,这是其最大的优点,也是其最大的缺点. PERL那复杂的语法确实看得让人想吐. python很优美,但是据说对正则的支持不够,没有perl强大. 总结一下学习 ...
- C语言基础(不断更新)
1.memcpy. memmove.memccpy的区别 字符串函数功能查询 memcpy要求源串和目的串不能重叠 memccpy:copy直至遇到由参数指定的ch. memmove: 源串和目的串可 ...
- 验证dictionary重复键
if (dict.ContainsKey("sadsa")) { }
- 让git忽略ignore所有文件,只对某些文件进行版本控制
*.c !frob_*.c !custom.c 或者:*!*/ # 这个的意思是不忽略目录.否则目录被忽略了之后,它里面的所有文件都忽略了!*.c!*.cc!*.cpp!*.cxx 也就是先忽略所有文 ...
- MYSQL数据库性能调优之四:解决慢查询--索引
为什么索引能够提高查询速度?没有索引 检索数据的方式是从头到尾一条一条挨着匹配,这是慢的根本原因:索引类型BTREE:二叉树类型,原理图如下:对表创建一个二叉树,记录中间数据的物理磁盘地址,二叉树检索 ...