linux device driver —— 字符设备
现在对linux设备驱动还没有什么认识,跟着书上敲了一个字符驱动,这里把代码贴一下.
测试环境是 Ubuntu 16.04 64bit
驱动程序:
#include <linux/fs.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/cdev.h>
#include <linux/uaccess.h>
#define CDEVDEMO_MAJOR 0
#define BUFFER_SIZE 512
static int cdevdemo_major = CDEVDEMO_MAJOR;
static char msgbuff[BUFFER_SIZE];
void cdevdemo_exit(void);
int cdevdemo_init(void);
MODULE_LICENSE("Dual BSD/GPL");
module_param(cdevdemo_major,int,S_IRUGO);
//注册初始化方法
module_init(cdevdemo_init);
//注册退出方法
module_exit(cdevdemo_exit);
struct cdev *my_cdev;
ssize_t cdev_write(struct file *, const char __user *, size_t, loff_t *);
ssize_t cdev_read (struct file *, char __user *, size_t, loff_t *);
int cdev_open (struct inode *,struct file *);
int cdev_release (struct inode *,struct file *);
struct file_operations my_fops = {
.owner = THIS_MODULE,
.open = cdev_open,
.release = cdev_release,
.read = cdev_read,
.write = cdev_write,
};
void init_cdev(void)
{
int ret;
my_cdev = cdev_alloc();
my_cdev->owner = THIS_MODULE;
my_cdev->ops = &my_fops;
//添加字符设备
ret = cdev_add(my_cdev,MKDEV(cdevdemo_major,),);
)
{
printk(KERN_NOTICE "=== cdev_add fail");
}
printk(KERN_NOTICE "=== init_cdev finish");
}
int __init cdevdemo_init(void)
{
int ret;
dev_t devno;
printk(KERN_NOTICE "=== cdevdemo_init 0");
devno = MKDEV(cdevdemo_major,);
if(cdevdemo_major)
{
printk(KERN_NOTICE "=== cdevdemo_init try register");
ret = register_chrdev_region(devno,,"cdevdemo");
}else
{
printk(KERN_NOTICE "=== cdevdemo_init auto register");
ret = alloc_chrdev_region(&devno,,,"cdevdemo");
cdevdemo_major = MAJOR(devno);
}
)
{
printk(KERN_NOTICE "=== cdevdemo_init register fail");
return ret;
}
init_cdev();
printk(KERN_NOTICE "=== cdevdemo_init finish");
;
}
void __exit cdevdemo_exit(void)
{
printk (KERN_NOTICE "=== cdevdemo_exit");
//去除字符设备
cdev_del(my_cdev);
unregister_chrdev_region(MKDEV(cdevdemo_major,),);
}
ssize_t cdev_write(struct file *filp, const char __user *buf, size_t count, loff_t *offp)
{
int ret;
printk(KERN_NOTICE "=== cdev_write");
ret = copy_from_user(msgbuff,buf,count%BUFFER_SIZE);
)
{
printk(KERN_NOTICE "=== cdev_write copy_from_user fail %d",ret);
return -EFAULT;
}
msgbuff[count] = '-';
msgbuff[count+] = '-';
msgbuff[count+] = 'k';
msgbuff[count+] = 'e';
msgbuff[count+] = 'r';
msgbuff[count+] = 'n';
msgbuff[count+] = 'e';
msgbuff[count+] = 'l';
msgbuff[count+] = '\0';
printk(KERN_NOTICE "--- cdev_write : %s",msgbuff);
return count%BUFFER_SIZE;
}
ssize_t cdev_read (struct file *filp, char __user *buf, size_t count, loff_t *offp)
{
int ret;
printk(KERN_NOTICE "=== cdev_read");
ret = copy_to_user(buf,msgbuff,count%BUFFER_SIZE);
)
{
printk(KERN_NOTICE "=== cdev_read copy_to_user fail %d",ret);
return -EFAULT;
}
printk(KERN_NOTICE "--- cdev_read :%s",msgbuff);
return count%BUFFER_SIZE;
}
int cdev_open (struct inode *inode,struct file *filp)
{
printk(KERN_NOTICE "=== cdev_open");
;
}
int cdev_release (struct inode *inode,struct file *filp)
{
printk(KERN_NOTICE "=== cdev_release");
;
}
Makefile
ifneq ($(KERNELRELEASE),)
mymodule-objs := cdev
obj-m := cdev.o
else
PWD := $(shell pwd)
KVER ?= $(shell uname -r)
KDIR := /lib/modules/$(KVER)/build
all:
$(MAKE) -C $(KDIR) M=$(PWD)
clean:
rm -rf *.cmd *.o *.mod.c *.ko .tmp_versions
endif
install.sh
#!/bin/bash
module="cdev"
device="cdev"
name="cdevdemo"
insmod $module.ko
]
then
exit
fi
major=$(awk "{if(\$2==\"$name\"){print \$1}}" /proc/devices)
/dev/$device
uninstall.sh
#!/bin/bash
module="cdev"
device="cdev"
file="/dev/$device"
if [ -e $file ]
then
rm -rf /dev/$device
echo 'rm device'
fi
echo 'rm module'
/sbin/rmmod $module
测试程序
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
int main(void)
{
int fd,ret;
] = "hello I'm from user";
] = {};
fd = open("/dev/cdev",O_RDWR);
)
{
puts("open fail");
;
}
ret = write(fd,buff,strlen(buff));
printf("write ret :%d\n",ret);
ret = read(fd,rbuff,);
printf("read ret :%d\n%s",ret,rbuff);
;
}
运行结果:
write ret : read ret : hello I'm from user--kernel
linux device driver —— 字符设备的更多相关文章
- Linux驱动设计——字符设备驱动(一)
Linux字符设别驱动结构 cdev结构体 struct cdev { struct kobject kobj; struct module *owner; const struct file_ope ...
- linux device driver —— 环形缓冲区的实现
还是没有接触到怎么控制硬件,但是在书里看到了一个挺巧妙的环形缓冲区实现. 此环形缓冲区实际为一个大小为bufsize的一维数组,有一个rp的读指针,一个wp的写指针. 在数据满时写进程会等待读进程读取 ...
- Linux Device Driver 学习(1)
Linux Device Driver 学习(1) 一.搭建虚拟机开发环境 1.选择虚拟机VirtualBox,官网下载.deb包安装: VirtualBox Linux 5.1.6 下载fedora ...
- how to write your first linux device driver
how to write your first linux device driver 0. environment-ubuntu 1804 64bit 1. apt-get install linu ...
- linux driver ------ 字符设备驱动 之 “ 创建设备节点流程 ”
在字符设备驱动开发的入门教程中,最常见的就是用device_create()函数来创建设备节点了,但是在之后阅读内核源码的过程中却很少见device_create()的踪影了,取而代之的是device ...
- Linux Device Driver && Device File
catalog . 设备驱动程序简介 . I/O体系结构 . 访问设备 . 与文件系统关联 . 字符设备操作 . 块设备操作 . 资源分配 . 总线系统 1. 设备驱动程序简介 设备驱动程序是内核的关 ...
- 【Linux驱动】字符设备驱动
一.linux系统将设备分为3类:字符设备.块设备.网络设备.使用驱动程序: 1.字符设备:是指只能一个字节一个字节读写的设备,不能随机读取设备内存中的某一数据,读取数据需要按照先后数据.字符设备是面 ...
- 手把手教Linux驱动3-之字符设备架构详解,有这篇就够了
一.Linux设备分类 Linux系统为了管理方便,将设备分成三种基本类型: 字符设备 块设备 网络设备 字符设备: 字符(char)设备是个能够像字节流(类似文件)一样被访问的设备,由字符设备驱动程 ...
- Linux学习 :字符设备框架
一.系统功能框架: U-boot : 启动内核 linux kernel: 启动应用 应用: open,read,write 都是通过C库实现,汇编就相当于swi val,引发中断,通过系统调用接口在 ...
随机推荐
- iOS:等待控件
定义: @interface ViewController () { UIActivityIndicatorView *testActivityIndicator; } 实例化,开始旋转: -(voi ...
- LightOj_1284 Lights inside 3D Grid
题目链接 题意: 给一个X * Y * Z 的立方体, 每个单位立方体内都有一盏灯, 初始状态是灭的, 你每次操作如下: 1)选择一个点(x1, y1, z1) 再选择一个点(x2, y2, ...
- nutch-1.7 编译
转载自:http://peigang.iteye.com/blog/1563288 从nutch-.3开始 本地抓取(单击) 和 分布式抓取(集群)所使用的配置文件和命令单独分开. 资源:下载地址:h ...
- SAAS相关技术要点
这篇文章本来是我们开发组内部用的一个小文档.因为我们公司以前没有做SAAS的经验,就成立了一个小组做一做这方面的技术前探,我是成员之一.这篇文档想从宏观的层面把开发一个SAAS应用所要用到的技术点稍微 ...
- LED七彩变色灯的制作
LED变色灯是一种新型灯泡.它的外形与一般乳白色白炽灯泡相同,但点亮后会自动按一定的时间间隔变色.循环地发出青.黄.绿.紫.蓝.红.白色光.它适用于家庭生日派对.节日聚会.过节过年,给节日添加欢乐气氛 ...
- 使用Git将本地代码上传到GitHub
#1注册GitHub账号 *1)到https://github.com/注册GitHub账号 #2在GitHub上建立GitHub仓库 *1)登录后点击右下方的"new repository ...
- 【HDOJ】1829 A Bug's Life
并查集变型.题意就是x与y是互斥的,下列是否数据是否可保证x-y是否均为互斥. #include <cstdio> #include <cstring> #define MAX ...
- 怒刷BZOJ记录(二)1038~10xx
我实在是太弱了...不滚粗只能刷BZOJ了...这里来记录每天刷了什么题吧. 2015-8-13: 正式开始! 1030[JSOI2007]文本生成器 | ...
- 浅谈Redis及其安装配置
一.Redis的介绍 二.Redis的安装配置 三.Redis的配置文件说明 四.Redis的简单操作 简介: Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型. ...
- dede织梦跨频道调用指定栏目文章的解决方法
很久没有写技术类的文章了,这次这个标题写的- 呃, 有一点儿纠结. 事情是这样的,刚刚回答了一个百度问答上的问题,这个问题的大体意思是,有一个图片栏目,内含3个子栏目,分别为图片栏目1.2和3,另有三 ...