现在对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 —— 字符设备的更多相关文章

  1. Linux驱动设计——字符设备驱动(一)

    Linux字符设别驱动结构 cdev结构体 struct cdev { struct kobject kobj; struct module *owner; const struct file_ope ...

  2. linux device driver —— 环形缓冲区的实现

    还是没有接触到怎么控制硬件,但是在书里看到了一个挺巧妙的环形缓冲区实现. 此环形缓冲区实际为一个大小为bufsize的一维数组,有一个rp的读指针,一个wp的写指针. 在数据满时写进程会等待读进程读取 ...

  3. Linux Device Driver 学习(1)

    Linux Device Driver 学习(1) 一.搭建虚拟机开发环境 1.选择虚拟机VirtualBox,官网下载.deb包安装: VirtualBox Linux 5.1.6 下载fedora ...

  4. 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 ...

  5. linux driver ------ 字符设备驱动 之 “ 创建设备节点流程 ”

    在字符设备驱动开发的入门教程中,最常见的就是用device_create()函数来创建设备节点了,但是在之后阅读内核源码的过程中却很少见device_create()的踪影了,取而代之的是device ...

  6. Linux Device Driver && Device File

    catalog . 设备驱动程序简介 . I/O体系结构 . 访问设备 . 与文件系统关联 . 字符设备操作 . 块设备操作 . 资源分配 . 总线系统 1. 设备驱动程序简介 设备驱动程序是内核的关 ...

  7. 【Linux驱动】字符设备驱动

    一.linux系统将设备分为3类:字符设备.块设备.网络设备.使用驱动程序: 1.字符设备:是指只能一个字节一个字节读写的设备,不能随机读取设备内存中的某一数据,读取数据需要按照先后数据.字符设备是面 ...

  8. 手把手教Linux驱动3-之字符设备架构详解,有这篇就够了

    一.Linux设备分类 Linux系统为了管理方便,将设备分成三种基本类型: 字符设备 块设备 网络设备 字符设备: 字符(char)设备是个能够像字节流(类似文件)一样被访问的设备,由字符设备驱动程 ...

  9. Linux学习 :字符设备框架

    一.系统功能框架: U-boot : 启动内核 linux kernel: 启动应用 应用: open,read,write 都是通过C库实现,汇编就相当于swi val,引发中断,通过系统调用接口在 ...

随机推荐

  1. [python]文本处理1.2

    1.0初步完成了文本截取需要信息的处理 1.1 修复了格式所造成的遗漏字符 1.2 去除了遗漏字符中的多余字符 bug-文本test14 有遗漏字符 bug-修复的遗漏字符中含有\n 未被识别为换行符

  2. go 语言与循环

    package main import "fmt" type Employee struct{name string; age int} func displayName(e *E ...

  3. CSS样式的优先级

    1.相同权值情况下,CSS样式的优先级总结来说,就是--就近原则(离被设置元素越近优先级别越高): 内联样式表(标签内部)> 嵌入样式表(当前文件中)> 外部样式表(外部文件中). 2.权 ...

  4. matlab操作之--读取指定文件夹下的“指定格式”文件

    %% 正负样本所在folder fext='*.png';%要读取的文件格式 positiveFolder='F:\课题\Crater detection\machingLearning\Positi ...

  5. matlab读取指定路径下的图像

    利用matlab读取指定路径下的图像 %% 读入指定路径imgFolder下的图像imgName imgFolder = 'F:\博\快盘\图像+数据\images\文章实验图'; %指定路径 img ...

  6. 掌握C++基础

    以下是笔者在ubuntu系统下编译运行通过的一些反应c++基础特性的例子,包括类,结构体,构造函数,析构函数,函数的重载,this指针,类的继承,虚函数,函数的覆盖和隐藏等.(由于格式问题代码中的乱码 ...

  7. 几个字符串的误区,以及setlocale函数的使用

    转自 http://www.blogjava.net/baicker/archive/2007/08/09/135642.html 转自 http://witmax.cn/character-enco ...

  8. QPixmap有缓冲区的

    我想qt 中QPixmap这个类大家都很熟悉,它可以很简单的在标签上贴图:例如: QPixmap p; p.load("1.png"): label->setPixmap(p ...

  9. JVM参数配置大全

    前阵子遇到几个面试题都是关于对Java内存控制的,因此从网上找到这篇文章,希望自己对Java的内存分配有重新的认识 /usr/local/jdk/bin/java -Dresin.home=/usr/ ...

  10. [转帖]自动调整TextView字体大小以适应文字长度

    package com.test.android.textview; import android.content.Context; import android.graphics.Paint; im ...