小松之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 指针赋值为 ...
随机推荐
- Oracle 使用sqlnet.ora/trigger限制/允许某IP或IP段访问指定用户
Oracle 使用sqlnet.ora/trigger限制/允许某IP或IP段访问指定用户 学习了:http://blog.itpub.net/28602568/viewspace-2092858/ ...
- 在java中,怎样跳出当前的多重循环?
</pre>直接用break ;详细举比例如以下:<p></p><p></p><p></p><pre name ...
- 在Windows 8.1系统上配置免安装版mysql-5.6.21-winx64
1.到官网上下载MySQL 下载地址为:http://cdn.mysql.com/Downloads/MySQL-5.6/mysql-5.6.21-winx64.zip 2.解压文件到D盘 当然你可以 ...
- luogu2054 洗牌 同余方程
题目大意 对于扑克牌的一次洗牌是这样定义的,将一叠N(N为偶数)张扑克牌平均分成上下两叠,取下面一叠的第一张作为新的一叠的第一张,然后取上面一叠的第一张作为新的一叠的第二张,再取下面一叠的第二张作为新 ...
- html5 初探
html5是越来越火了.小小菜鸟也来学习学习. 相比于之前的几个版本,HTML5提供了更加丰富的多媒体标签使得音乐,视频的播放不用再借助于flah了.不过暂时各浏览器间样式还是有差别. 除此之外,表单 ...
- struts的工作流程
- 一个请求过来,走前端控制器StrutsPrepareAndExecuteFilter -前端控制器是一个过滤器,过滤器中的核心方法是doFilter(),doFilter方法中首先处 ...
- [Pulgin] 利用swfupload实现java文件批量上传
URL:http://blog.csdn.net/xuweilinjijis/article/details/8876305 之前在网上找过很多相关资料,很多所谓的批量上传都是忽悠人的,真正的批量上传 ...
- D - Knight Tournament(set)
Problem description Hooray! Berl II, the king of Berland is making a knight tournament. The king has ...
- C#使用SqlTransaction事务回滚与SqlBulkCopy批量插入数据
C#中批量处理数据,有时候因为一条记录导致整个批量处理失败.这时候肯能会导致数据不全等问题,这时候我们可以使用SqlTransaction来进行事务回滚,即是要么全部成功要么全部不成功.如下代码 // ...
- 关于电脑安装新硬盘,出现无法是识别设备,03F0问题解答。
问题说明:在添加新的硬盘,切确定硬盘没有坏的情况下,无法识别出新的硬盘. 解决方案: 1.检查bios系统里的安全模式,是否处于开启中.因为在windows 8.1以上的版本中,不开启的情况下只能读取 ...