小松之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 指针赋值为 ...
随机推荐
- Spring boot 前后台分离项目 怎么处理spring security 抛出的异常
最近在开发一个项目 前后台分离的 使用 spring boot + spring security + jwt 实现用户登录权限控制等操作.但是 在用户登录的时候,怎么处理spring securi ...
- Js计算指定日期
function DateAdd(interval,number,date) { /* * 功能:实现VBScript的DateAdd功能. * 参数:interval,字符串表达式,表示要添加的时间 ...
- 【微信小程序】:小程序,新场景
前言: 我们频繁进入的地方,是场景. 手机.是场景:浏览器.是场景.事实上,微信,也是场景-- 微信要做的是占领很多其它用户时间.占领很多其它应用场景.占领很多其它服务入口.这是商业本质想去垄断要做的 ...
- ios自己定义类(UIView)代码生成简单的UITableViewCell
因为一个项目中有大量的UITableViewCell须要书写,样式几乎相同都是 文字介绍:显示内容 这种. 自己又懒得写UITableViewCell类嫌不是必需:在方法tableView:cellF ...
- ftk学习记(label篇)
[ 声明:版权全部,欢迎转载,请勿用于商业用途. 联系信箱:feixiaoxing @163.com] 还是接着上面的一篇博文. 之前以前答应过大家,让大家看一下最简单的ftk程序是怎么执行的.所以 ...
- poj1753,Flip Game,ArrayDeque<Node>
Flip Game Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 30449 Accepted: 13232 Descr ...
- Mysql经常使用函数汇总
一. 聚合函数 1.1 求和函数-----SUM() 求和函数SUM( )用于对数据求和.返回选取结果集中全部值的总和. 语法:SELECT SUM(column_name) FROM table_n ...
- 固定管线shader编写:基本属性
欢迎转载!转载时请注明出处:http://write.blog.csdn.net/postedit/50753008 shader 部分介绍: properties:属性部分 material:材质部 ...
- crm高速开发之OrganizationService
这是主要的开发模式: /* 创建者:菜刀居士的博客 * 创建日期:2014年07月06号 */ namespace Net.CRM.OrganizationService { using ...
- iOS10 推送通知 UserNotifications
简介 新框架 获取权限 获取用户设置 注册APNS,获取deviceToken 本地推送流程 远程推送流程 通知策略(Category+Action) 附件通知 代理回调 简介 iOS10新增了Use ...