编写好驱动,通过挂载的方法将驱动程序挂载到内核里面,大致步骤如下:

一:  1>建立以.c为后缀的c语言程序文件 (里面包含了设备名及设备号等)

2>建立Makefile文件(作用是通过make来产生设备文件*.ko文件,里面可以建立自己的平台所需的设备文件如:arm等).make 产生相应的设备文件

二: 要在/dev下建立相应的设备结点(设备名),用insomd *.ko命令将相应的驱动设备文件挂载到内核中.

三:编写测试文件(.c文件)用来测试内核是否已近成功挂载到内核.(编写好相应的测试文件后,用gcc –o Filename Filename.c(测试文件名) 来产生相应的可执行文件).

四:如果设备驱动挂载成功,当执行测试文件(./Filename)时会产生相应的结果.

五:可能用到的相关命令:

1.       lsmod:列出内核已经载入模块的专题.

输出:

Module(模块名)            size(大小)            used by (被..使用)

2.       demop:分析可加载模块的依赖性,生成modules.dep文件和映射文件

3.       uname –r   显示内核版本(在编写Makefile时使用到)

4.       modprobe : linux 内核添加和删除模块(相关参数请查看man帮助文档)

5.       modinfo:显示内核模块的信息.

6.       insmod: 向linux内核中加载一个模块,用法:insmod  [filename] [module options…]

7.       rmmod: 删除内核中的模块, 用法: rmmod [-f,w,s,v]       [modulename]

8.       dmesg: 显示内核缓冲区,内核的各种信息,内核启动时的信息会写入到/var/log/下.

六.例子

第一步:增加头文件和宏定义

#include

#include

#include

#include

#include

#include

第二步:添加与字符设备定义及注册有关的数据成员

//定义设备名称

#define DEVICE_NAME "test" //设备名

#define BUF_SIZE 1024

static char tmpbuf[BUF_SIZE];

//定义主次设备号

static unsigned int TestMajor=0; //主

static unsigned int TestMinor=0; //次

static struct cdev *test_cdev;

static dev_t dev;

第三步:增加open/release函数

static int test_chardev_open(struct inode *inode,struct file *file)

{

printk("open major=%d, minor=%d\n", imajor(inode),

iminor(inode));

return 0;

}

static int test_chardev_release(struct inode *inode,struct file *file)

{

printk("close major=%d,minor=%d\n",imajor(inode),

iminor(inode));

return 0;

}

第四步:增加read函数

static ssize_t test_chardev_read(struct file *file,char __user *buf,

size_t const count,loff_t *offset)

{

if(count < BUF_SIZE)

{

if(copy_to_user(buf,tmpbuf,count))

{

printk("copy to user fail \n");

return -EFAULT;

}

}else{

printk("read size must be less than %d\n", BUF_SIZE);

return -EINVAL;

}

*offset += count;

return count;

}

第五步:增加write函数

static ssize_t test_chardev_write(struct file *file, const char __user *buf,size_t const count,loff_t *offset)

{

if(count < BUF_SIZE)

{

if(copy_from_user(tmpbuf,buf,count))

{

printk("copy from user fail \n");

return -EFAULT;

}

}else{

printk("size must be less than %d\n", BUF_SIZE);

return -EINVAL;

}

*offset += count;

return count;

}

第六步:添加增加file_operations 成员

static struct file_operations chardev_fops={

.owner = THIS_MODULE,

.read = test_chardev_read,

.write = test_chardev_write,

.open = test_chardev_open,

.release = test_chardev_release,

};

第七步:在模块的入口添加设备的设备号获取及设备注册

static int __init chrdev_init(void)

{

int result;

if(TestMajor)

{

dev=MKDEV(TestMajor,TestMinor);//创建设备编号

result=register_chrdev_region(dev,1,DEVICE_NAME);

} else {

result=alloc_chrdev_region(&dev,TestMinor,1,DEVICE_NAME);

TestMajor=MAJOR(dev);

}

if(result<0)

{

printk(KERN_WARNING"LED: cannot get major %d \n",TestMajor);

return result;

}

test_cdev=cdev_alloc();

cdev_init(test_cdev,&chardev_fops);

//test_cdev->ops=&chardev_fops;

test_cdev->owner=THIS_MODULE;

result=cdev_add(test_cdev,dev,1);

if(result)

printk("<1>Error %d while register led device!\n",result);

return 0;

}

第八步:在模块的出口函数增加设备设备号释放及设备注销函数

unregister_chrdev_region(MKDEV(TestMajor,TestMinor),1);

cdev_del(test_cdev);

第九步:编译并加载该模块

第十步:根据设备号的设置,在文件系统中建立对应的设备节点

$mknod /dev/test  c  XXX(主设备号)  XX(次设备号)

完整例子

驱动文件

#include

#include

#include

#include

#include

#include

#define DEVICENAME "ccccc"

unsigned int major=221;

unsigned int minor=0;

struct cdev *abc;

dev_t dev;

static char bufrh[1024]="read success!";

static int aaaaa_open(struct inode *inodep, struct file *filep)

{

printk("read success!\n");

return 0;

}

int aaaaa_release(struct inode *inodep, struct file *filep)

{

return 0;

}

static ssize_t aaaaa_read (struct file *filep, char __user *buf, size_t count, loff_t *offset)

{

if(copy_to_user(buf, bufrh, 1))

{

printk("copy_to_user fail!\n");

}

return 0;

}

ssize_t aaaaa_write (struct file *filep, const char __user *buf, size_t count, loff_t *offse)

{

printk("write!\n");

return 0;

}

static const struct file_operations fops = {

.owner = THIS_MODULE,

.open = aaaaa_open,

.release = aaaaa_release,

.read = aaaaa_read,

.write = aaaaa_write,

};

static int __init aaaaa_init(void)

{

int a;

dev=MKDEV(major, minor);

a=register_chrdev_region(dev, 1, DEVICENAME);

abc=cdev_alloc();

abc->owner=THIS_MODULE;

cdev_init(abc, &fops);

cdev_add(abc, dev, 1);

return 0;

}

static void __exit aaaaa_cleanup(void)

{

cdev_del(abc);

unregister_chrdev_region(dev, 1);

}

module_init(aaaaa_init);

module_exit(aaaaa_cleanup);

MODULE_LICENSE("GPL ");

Makefile文件

obj-m += firstqd.o(相应设备文件名)

KERDIR = /usr/src/linux-headers-2.6.32-24-generic #x86平台

PWD=$(shell pwd)

modules:

$(MAKE) -C $(KERDIR) M=$(PWD) modules

pc:

gcc -o fristqd firstqd.c

arm:

arm-linux-gcc -o fristqd firstqd.c

clean:

rm -rf *.o *~core *.depend *.cmd *.ko *.mod.c *.tmp_versions

用户空间测试代码

#include

#include

#include

char buf[1024];

char bufw[1024]="write success";

int main()

{

int fd,m,n;

fd=open("/dev/aaa",O_RDWR);

if (fd)

{

m=read(fd,buf,100);

printf("read kernel:%s\n",buf);

n=write(fd,bufw,10);

}

//printf("ni hao");

return 0;

}

linux字符驱动头文件路径,Linux 字符设备驱动例子相关推荐

  1. window、linux、mac 文件路径禁止字符, 路径长度【全网总结】

    参考: https://9to5answer.com/what-characters-are-forbidden-in-windows-and-linux-directory-names https: ...

  2. linux的库文件路径,Linux下的库文件搜索路径

    对于以压缩包发布的软件,在它的目录下通常都有一个配置脚本configure,它的作用确定编译参数(比如头文件位置.连接库位置等),然后生成Makefile以编译程序.可以进入该软件的目录,执行&quo ...

  3. linux 函数 创建文件路径,linux中创建文件和文件夹的方法

    linux中创建文件和文件夹的方法 发布时间:2020-06-12 19:32:19 来源:亿速云 阅读:174 作者:鸽子 首先说一下touch 创建文件的命令,touch可以用于创建二进制文件,用 ...

  4. linux的trace文件路径,linux系统分析工具之Blktrace(十)

    Blktrace简介: blktrace是一个针对Linux内核中块设备I/O层的跟踪工具,用来收集磁盘IO信息中当IO进行到块设备层(block层,所以叫blk trace)时的详细信息(如IO请求 ...

  5. linux trace 进程 文件路径,linux panic 问题定位

    详细描述出现kernel panic时的处理过程. 最直接.简单的方法,查看panic时的调用栈,根据打印的出错函数及文件行数,找到panic的位置,再详细处理. 有时候会出现错误的调用栈,此时必须查 ...

  6. linux蓝牙接收文件路径,Linux 蓝牙系列(3) 蓝牙传输文件测试

    Andrew Huang 蓝牙文件传送协议 标准是采用OPP协议(应该Obex文件传输相关协议,手机界面很多用这个术语),另外还支持FTP传输,但这个需要额外软件支持.一般是ObexFtp的移植版本, ...

  7. linux nginx ssl 文件路径,linux – 如何将SSL证书从Apache服务器传输到NGINX服务器

    您需要复制以下文件: > SSL_Certificate.crt > SSL_Certificate.key 从APACHE SSL配置路径到NGINX服务器配置路径. 现在打开您正在保护 ...

  8. qt linux 添加库文件路径,linux下qt使用第三方库的那些事

    开发库查看工具:$sudo apt-get install pkg-config 很多时候我们并不知道自己电脑有没有这个库,所以我们可以使用这个工具来查看自己有哪些工具,或者哪些工具没有.同时,qma ...

  9. qt linux 添加库文件路径,Linux下Qt调用共享库文件.so

    jvm--4垃圾收集 6. 垃圾收集GC (1)当需要排查各种内存溢出,内存泄漏等问题,当GC成为系统达到更高性能的瓶颈时,我们就需要对这些自动化的GC进行监控和调节. (2)PC计数器.本地方法栈. ...

最新文章

  1. A - 棋盘问题 POJ - 1321(dfs)
  2. C++动态数组再总结
  3. 高一计算机组装,高中生计算机组装与维护,呼市新华互联网学校
  4. 安卓使用JNI-NDK
  5. 做ppt用的小插图_如何用PPT做随机抽奖?
  6. 【转】交织容积重建技术:基本原理与临床价值
  7. Python写出一个字节,一个YouTube,我用Python怎么了!
  8. bzoj 1076 奖励关 状压+期望dp
  9. html css 时钟,css3时钟
  10. 在LUA中使用异步IO的思考
  11. itextpdf生成表格的常见用法
  12. Python实现最小二乘法曲线拟合
  13. openbmc开发29:开关机管理
  14. 蓝桥杯 2015 javaB组 校赛
  15. 电脑坏了怎么把硬盘的mysql数据恢复_硬盘坏了怎么恢复数据?
  16. html鼠标拖动变换大小案例,js实现鼠标拖拽缩放div实例代码_哒哒_前端开发者
  17. .NET/C# — EXCEL文件内容添加到数据库中
  18. IPHONE绑定武大邮箱的一些坑
  19. 软体尚方宝剑(Silver Bullet)何在﹖
  20. 多策略融合的改进麻雀搜索算法

热门文章

  1. [Machine Learning] logistic函数和softmax函数
  2. Javascript 笔记与总结(2-11)暴力操作节点
  3. ftp在命令行状态下下载跟上传东西
  4. CCNA综合实验配置
  5. VS2010(VS2008)下安装配置OpenCV
  6. MapInfo导入.TAB和.mws的方法
  7. 小程序获取form_id 与 小程序获取openid
  8. 2017中国电商峰会共话“一带一路”网上商机
  9. [剑指offer]8.重建二叉树
  10. 对tableView三种计算动态行高方法的分析