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 ...
随机推荐
- API指南----application
<application android:allowTaskReparenting=["true" | "false"] android:allow ...
- JAVA多线程二
Thread.Join() join()函数表示等待当前线程结束,然后返回. public final synchronized void join(long millis) throws Inter ...
- HTTP协议的状态码
对于Web编程人员来说,熟悉了解HTTP协议的状态码是很有必要的,很多时侯可能根据HTTP协议的状态码很快就能定位到错误信息!今天整理了一下所有HTTP状态码. HTTP状态码(HTTP Status ...
- 【转】linux下cpio命令使用
转自:http://www.51testing.com/html/32/498132-816949.html 功能说明:备份文件. 补充说明:cpio是用来建立,还原备份档的工具程序,它可以加入,解开 ...
- LR之录制SQL脚本
1.选择协议 ①MS SQL serve ②ODBC 一般情况下选ODBC 2.录制步骤
- 让pre标签自动换行示例代码
pre 元素可定义预格式化的文本.被包围在 pre 元素中的文本通常会保留空格和换行符.而文本也会呈现为等宽字体. <pre> 标签的一个常见应用就是用来表示计算机的源代码.对于技术博客经 ...
- 用ASP.Net写一个发送ICQ信息的程序
用ASP.Net写一个发送ICQ信息的程序 这里我给大家提供一个很实用的例子,就是在线发送ICQ信息.想一想我们在网页上直接给朋友发送ICQ信息,那是多么美妙的事情啊.呵呵,在吹牛啊,其实ICQ本来就 ...
- 数往知来 JavaScript<十三>
一.javaScript 语法:大小写敏感,弱类型(所有类型都用var进行引导.声明) 写在<script></script>标签里 不可以放在title里 var num= ...
- fork()函数
现代操作系统提供的三种构造并发程序的方法: •进程 一个进程实体包括:代码段,数据段, 进程控制块 fork()函数:通过系统调用创建一个与原来一模一样的子线程,[用来处理请求信号,而父进程继续一直处 ...
- CISCO ASA 防火墙 IOS恢复与升级
在IOS被误清除时的处理办法: 1.从tftp上的ios启动防火墙 防火墙启动后 ,按“ESC”键进入监控模式 rommon #2> ADDRESS=192.168.1.116 rommon # ...