小松之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 指针赋值为 ...
随机推荐
- 【c语言】 模拟实现库函数的atoi函数
// 模拟实现库函数的atoi函数 #include <stdio.h> #include <string.h> #include <assert.h> #incl ...
- oc2---类
// main.m // 第一个OC类,OC中的类其实本质就是一个结构体, 所以p这个指针其实就是指向了一个结构体,创建一个对象就是创建一个结构体指针, #import <Foundation/ ...
- git分支演示
https://learngitbranching.js.org https://github.com/pcottle/learnGitBranching no demo模式可以随便玩 https:/ ...
- Swift - 可编辑表格样例(可直接编辑单元格中内容、移动删除单元格)
(本文代码已升级至Swift3) 本文演示如何制作一个可以编辑单元格内容的表格(UITableView). 1,效果图 (1)默认状态下,表格不可编辑,当点击单元格的时候会弹出提示框显示选中的内容 ...
- SwiftUI 官方教程(二)
SwiftUI 官方教程(二) 2. 自定义 Text View 为了自定义 view 的显示,我们可以自己更改代码,或者使用 inspector 来帮助我们编写代码. 在构建 Landmarks 的 ...
- Open CASCADE Technology(OCCT)概述
OCCT模块结构图 基础类: Foundation Classes module underlies all other OCCT classes; 模型数据: Modeling Data modul ...
- Oracle获取alter.log的方法
10g下:可以在 admin\{sid}\pfile文件下的init.ora文件中找到以下内容:audit_file_dest = C:\ORACLE\PRODUCT\10.2.0\ADMIN\ORC ...
- 函数的arguments
1.arguments a.只能在函数内部被访问. b.arguments是一个伪数组(有下标索引,可以存放多个值,但是他里面没有数组的方法.) c.arguments里面存的是什么?函数的实际参数传 ...
- 在AndroidManifest(清单文件)中注册activity(活动)及配置主活动、更改App图标、App名称、修改隐藏标题栏
打开app/src/main/AndroidManifest. <?xml version="1.0" encoding="utf-8"?> < ...
- python爬虫:读取PDF
下面的代码可以实现用python读取PDF,包括读取本地和网络上的PDF. pdfminer下载地址:https://pypi.python.org/packages/source/p/pdfmine ...