小松之LINUX 驱动学习笔记(二)
这两天一直在看字符驱动那块,后来从网上找啦几个例子,自己编译啦下,安装啥的都挺正常,就是用测试程序测试的时候总出问题,现在找到一个能测试的代码,自己先看看和原来的那个代码有啥不同,后面会继续更新,说下到底是啥问题导致驱动不能用。先附上能用代码的链接,这里先谢谢作者:
http://blog.chinaunix.net/uid-22666248-id-3052861.html
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h> #include <linux/cdev.h>
#include <linux/device.h>
#include <linux/slab.h>//kmalloc
#include <linux/vmalloc.h>//vmalloc()
#include <linux/types.h>//ssize_t
#include <linux/fs.h>//file_operaiotns
#include <linux/uaccess.h>//copy_from_user #define MEM_MALLOC_SIZE 4096 ////缓冲区大小
#define MEM_MAJOR 240 ////主设备号
#define MEM_MINOR 0 char *mem_spvm = NULL; ////缓冲区指针,指向内存区
struct cdev *mem_cdev = NULL; //字符设备对象指针
struct class *mem_class = NULL; //设备类指针 static int __init mem_init(void);
static void __exit mem_exit(void);
static int mem_open(struct inode *inode,struct file *filp);
static int mem_release(struct inode *inode, struct file *filp);
static ssize_t mem_read(struct file *filp,char __user *buf,size_t count,loff_t *fpos);
static ssize_t mem_write(struct file *filp, char __user *buf,size_t count ,loff_t *fops); static const struct file_operations mem_fops={
.owner = THIS_MODULE,
.open = mem_open,
.release = mem_release,
.read = mem_read,
.write = mem_write,
}; static int __init mem_init(void)
{
int ret;
//创建设备号 主次设备号
int devno = MKDEV(MEM_MAJOR,MEM_MINOR);
printk("mem_init initial...\n"); //开辟内核内存缓冲区
mem_spvm = (char *)vmalloc(MEM_MALLOC_SIZE);
if(mem_spvm == NULL)
{
printk("vmalloc mem_spvm error\n");
return -ENOMEM;//
} //
mem_cdev = cdev_alloc();
if(mem_cdev == NULL)
{
printk("cdev_alloc error\n");
return -ENOMEM;
}
cdev_init(mem_cdev,&mem_fops);
mem_cdev->owner = THIS_MODULE;
ret = cdev_add(mem_cdev,devno,);//将字符设备键入内核系统
if(ret)
{
cdev_del(mem_cdev);
mem_cdev = NULL;
printk("cdev_add error\n");
return -;
} //
mem_class = class_create(THIS_MODULE,"ywx_class_char");
if(IS_ERR(mem_class))
{
printk("class_create error..\n");
return -;
}
device_create(mem_class,NULL,MKDEV(MEM_MAJOR,MEM_MINOR),NULL,"ywx_device_char"); printk("init finished..\n");
return ;
} static void __exit mem_exit(void)
{
printk("mem_exit starting..\n");
if(mem_cdev != NULL)
cdev_del(mem_cdev);
printk("cdev_del ok\n"); device_destroy(mem_class,MKDEV(MEM_MAJOR,MEM_MINOR));
class_destroy(mem_class); if(mem_spvm != NULL)
vfree(mem_spvm); printk("vfree ok\n");
printk("mem_exit finished..\n");
} static int mem_open(struct inode *inode,struct file *filp)
{
printk("open vmalloc space..\n");
try_module_get(THIS_MODULE);//模块引用计数器自加
printk("open vamlloc space ok..\n");
return ;
}
static int mem_release(struct inode *inode, struct file *filp)
{
printk("close vmalloc space..\n");
module_put(THIS_MODULE);//模块引用计数器自减
return ;
}
static ssize_t mem_read(struct file *filp,char __user *buf,size_t count,loff_t *fpos)
{
int ret = -;
char *tmp;
printk("copy data to the user space\n");
tmp = mem_spvm;
if(count > MEM_MALLOC_SIZE)
count = MEM_MALLOC_SIZE;
if(tmp != NULL)//将内核数据写入到用户空间
ret = copy_to_user(buf,tmp,count);
if(ret == )
{
printk("read copy data success\n");
return count;
}
else
{
printk("read copy data error\n");
return ;
}
}
static ssize_t mem_write(struct file *filp, char __user *buf,size_t count ,loff_t *fops)
{
int ret = -;
char *tmp;
printk("read data from the user space.\n");
tmp = mem_spvm;
if(count > MEM_MALLOC_SIZE)
count = MEM_MALLOC_SIZE;
if(tmp != NULL)
ret = copy_from_user(tmp,buf,count);
if(ret == )
{
printk("write copy data success.\n");
return count;
}
else
{
printk("write copy data error.\n");
return ;
}
} MODULE_LICENSE("GPL");
module_init(mem_init);
module_exit(mem_exit);
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>//memset() int main(int argc, char *argv[])
{
int fd,cnt;
char buf[];
int i;
printf("char device testing..\n");
fd = open("/dev/ywx_device_char",O_RDWR);
if(fd == )
{
printf("open failed.\n");
return ;
} printf("input the data for kernel:");
scanf("%s",buf);
cnt = write(fd,buf,);
if(cnt == )
printf("write error\n"); printf("clear buf,and will read from kernel...\n");
for(i=;i<;i++)
buf[i] = ;//32 =" " cnt = read(fd,buf,);
if(cnt > )
printf("read data from kernel is:%s\n",buf);
else
printf("read data error\n");
close(fd);
printf("close app..\n");
return ;
}
运行的时候用root用户运行,可以看到/dev目录下有设备节点,然后运行test文件,可以看到能运行。
make;sudo insmod xxx.ko; sudo ./app
小松之LINUX 驱动学习笔记(二)的更多相关文章
- 小松之LINUX 驱动学习笔记(一)
		
本篇主要是讲解驱动开发的基础知识以及一些环境配置方面的问题. 下面是一个hello world的简单的模块代码,很简单./*********************** 模块的简单例子* author ...
 - 小松之LINUX驱动学习笔记之模块间函数调用通讯
		
1. 符号导出函数 EXPORT_SYMBOL() EXPORT_SYMBOL标签内定义的函数对全部内核代码公开,不用修改内核代码就可以在您的内核模块中直接调用. EXPORT_SYMBOL_GPL( ...
 - 小松之LINUX 驱动学习笔记(开篇)
		
时间对每个人都是公平的,就看你怎么对待他.每天多努力一点,未来就会轻松一点.作为一名北漂,感受着首都的压力,也曾萌生过逃离北上广的想法,但是,最后我最终还是选择留下来,随着年龄的增长,我已经没有那么多 ...
 - linux 驱动学习笔记01--Linux 内核的编译
		
由于用的学习材料是<linux设备驱动开发详解(第二版)>,所以linux驱动学习笔记大部分文字描述来自于这本书,学习笔记系列用于自己学习理解的一种查阅和复习方式. #make confi ...
 - Linux内核学习笔记二——进程
		
Linux内核学习笔记二——进程 一 进程与线程 进程就是处于执行期的程序,包含了独立地址空间,多个执行线程等资源. 线程是进程中活动的对象,每个线程都拥有独立的程序计数器.进程栈和一组进程寄存器 ...
 - linux驱动学习(二) Makefile高级【转】
		
转自:http://blog.csdn.net/ghostyu/article/details/6866863 版权声明:本文为博主原创文章,未经博主允许不得转载. 在我前一篇写的[ linux驱动学 ...
 - Linux 驱动学习笔记05--字符驱动实例,实现一个共享内存设备的驱动
		
断断续续学驱动,好不容易有空,做了段字符驱动的例子.主要还是跟书上学习在此记录下来,以后说不定能回过头来温故知新. 首先上驱动源码 gmem.c: /************************* ...
 - linux 驱动学习笔记04--简单驱动
		
首先贴代码helloworld.c和Makefile /************************************************************************ ...
 - linux 驱动学习笔记03--Linux 内核的引导
		
如图所示为 X86 PC 上从上电/复位到运行 Linux 用户空间初始进程的流程.在进入与 Linux相关代码之间,会经历如下阶段. ( 1 ) 当系统上电或复位时, CPU 会将 PC 指针赋值为 ...
 
随机推荐
- JSTL函数标签
			
tld 文件代码 <?xml version="1.0" encoding="UTF-8" ?> <taglib xmlns="ht ...
 - ArcGIS Python实现Modis NDVI批量化月最大合成
			
最大合成法(MVC)能够在Envi中的Band Math中进行,式子是B1>B2,可是无法批量化.本文实如今ArcGIS中利用Python代码批量进行,例如以下: 用到的Modis NDVI数据 ...
 - hdoj--1045--Fire Net(二分图)
			
Fire Net Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total S ...
 - C# List<T>转成DataTable
			
//将List<T>转成DataTable public static DataTable ToDataTable(List<T> collection) ...
 - 外观模式(Facade)C++实现
			
外观模式 意图: 为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一系统更加容易使用. 适用性: 1.在设计初期阶段,应该要有意识的将不同的两个层分离,比如经典的三层架 ...
 - React安装 脚手架create-react-app安装步骤及问题
			
create-react-app 是来自于 Facebook的脚手架,通过该命令我们无需配置就能快速构建 React 开发环境. 安装步骤: 1.先装脚手架 PS:第一次装直接在打开CMD默认 ...
 - vue-router  原理解析
			
“更新视图但不重新请求页面”是前端路由原理的核心之一,
 - Paint、Canvas.1
			
Canvas 方法详解 1:translate(float dx, float dy) /**** 移动canvas的原点到(dx,dy),默认为(0,0) */ public void transl ...
 - 电商物流仓储WMS业务流程
			
电商物流仓储WMS业务流程 SKU是什么意思? 一文详解电商仓储管理中SKU的含义 从货品角度看,SKU是指单独一种商品,其货品属性已经被确定.只要货品属性有所不同,那么就是不同的SKU. PO信息 ...
 - WP - 控件基础-按钮控件
			
Button:HyperlinkButton:RepeatButton:ToggleButton 1.Button: <button content="Button" ...