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 ...
随机推荐
- PHP中的session
来自博客园 1.初始化(使用session前都要使用,一个页面用一个就可以了) session_start(); 2.保存 $_SESSION[$sessionName]=$value; (value ...
- 解决 winform 界面对不齐 z
一个winform的程序,本机上界面对得很齐,到一到客户的机器上就惨不忍睹,一番研究后搞定: 1. AutoScaleMode = None 2. BackgroundImageLayout = No ...
- reCAPTCHA 简单分析
CAPTCHA项目是Completely Automated Public Turing Test to Tell Computers and Humans Apart (全自动区分计算机和人类的图灵 ...
- js中location.search、split()HTML5中localStorage
1. location.search在客户端获取Url参数的方法 location.search是从当前URL的?号开始的字符串 如:http://www.baidu.com/s?wd=baidu&a ...
- Yii1 控制前端载入文件
Yii::app()->clientScript->registerCssFile(CSS_URL.'reset.css'); Yii::app()->clientScript-&g ...
- 【转】内网yum源搭建
我们内网yum要玩的话,先加hosts,然后找运维要CentOS_base.repo这个文件,然后yum clean all && yum makecache ========== ...
- URAL-1997 Those are not the droids you're looking for 二分匹配
题目链接:http://acm.timus.ru/problem.aspx?space=1&num=1997 题意:记录了n个人进出门的时间点,每个人在房子里面待的时间要么小于等于a,要么大于 ...
- 轻松学习Linux之进程监视与管理
前后台进程转换-1 前后台进程转换-2 本文出自 "李晨光原创技术博客" 博客,谢绝转载!
- Cocos2d-x项目移植到WP8小记
Cocos2d-x项目移植到WP8小记 作者: K.C. 日期: 10/24/2013 Date: 2013-10-24 00:33 Title: Cocos2d-x项目移植到WP8小记 Tags: ...
- POJ 3177 Redundant Paths POJ 3352 Road Construction
这两题是一样的,代码完全一样. 就是给了一个连通图,问加多少条边可以变成边双连通. 去掉桥,其余的连通分支就是边双连通分支了.一个有桥的连通图要变成边双连通图的话,把双连通子图收缩为一个点,形成一颗树 ...