一、字符驱动框架

问:应用程序open、read、write如何找到驱动程序的open、read、write函数?

答:应用程序的open、read、write是在C库里面实现的,它里面通过swi val指令去触发一个异常,这个异常就会进入到内核空间,在内核的异常处理函数里面有根据我们传入的val来决定调用system_open还是system_read、system_write函数,这些函数根据我们打开不同的文件、不同的文件就有不同的属性(例如设备类型(字符设备还是块设备还是网络设备)、主设备号),根据这些属性找到更底层的驱动程序。

问:什么是主设备号,什么是次设备号

答:Linux主设备号用来区分不同硬件设备类型,如LED和串口之间的区别;
Linux次设备号用来区分不同硬件设备,如串口1和串口2之间的区别;

问:通过什么样的方法来找到驱动程序的open函数

答:通过一个注册函数+设备节点

注册函数如下(旧的注册函数,新的以后再说):

register_chrdev(unsigned int major, const char * name, const struct file_operations * fops)

参数1:主设备号(重要)

参数2:名字(不重要)

参数3:file_operations结构体(重要)

设备节点:

可以手工创建也可以自动创建,这里暂且只说手工创建

mknod  /dev/xxx  c  252  0

创建一个名为/dev/xxx的设备节点,c表示字符设备节点,252是主设备号,0是次设备号。

问:应用程序一般是由main函数开始执行,那么驱动程序一般是先执行什么?

答:通过一个宏,指定驱动程序的入口函数,当装载驱动时就会执行入口函数。

例如:module_init(first_drv_init);  //用于修饰入口函数

自然地,驱动程序的出口函数,则是在卸载驱动时就会执行出口函数。

例如:module_exit(first_drv_exit);  //用于修饰出口函数

驱动源程序如下:

#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <linux/module.h>int major;
static int first_drv_open(struct inode * inode, struct file * filp)
{printk("first_drv_open\n");return 0;
}
static int first_drv_write(struct file * file, const char __user * buffer, size_t count, loff_t * ppos)
{printk("first_drv_write\n");return 0;
}/* File operations struct for character device */
static const struct file_operations first_drv_fops = {.owner        = THIS_MODULE,.open     = first_drv_open,.write      = first_drv_write,
};/* 驱动入口函数 */
static int first_drv_init(void)
{/* 主设备号设置为0表示由系统自动分配主设备号 */major = register_chrdev(0, "first_drv", &first_drv_fops);return 0;
}/* 驱动出口函数 */
static void first_drv_exit(void)
{unregister_chrdev(major, "first_drv");
}module_init(first_drv_init);  //用于修饰入口函数
module_exit(first_drv_exit);  //用于修饰出口函数    MODULE_AUTHOR("LWJ");
MODULE_DESCRIPTION("Just for Demon");
MODULE_LICENSE("GPL");  //遵循GPL协议

Makefile源码如下:

ifneq ($(KERNELRELEASE),)obj-m := first_drv.oelseKDIR := /home/opt/EmbedSky/linux-2.6.30.4all:make -C $(KDIR) M=$(PWD) modules ARCH=arm CROSS_COMPILE=arm-linux-
clean:rm -f *.ko *.o *.mod.o *.mod.c *.symversendif

测试程序如下:

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>int main(void){int fd;int val = 1;fd = open("/dev/xxx",O_RDWR);    //打开名为  /dev/xxx  的设备节点if(fd < 0){printf("open error\n");}write(fd,&val,4);return 0;
}

开发板上的测试步骤如下:

[WJ2440]# insmod first_drv.ko
[WJ2440]# ./first_test
open error                    //没有创建设备节点
[WJ2440]# cat proc/devices
Character devices:1 mem4 /dev/vc/04 tty5 /dev/tty5 /dev/console5 /dev/ptmx7 vcs10 misc13 input14 sound29 fb81 video4linux89 i2c90 mtd
116 alsa
128 ptm
136 pts
180 usb
188 ttyUSB
189 usb_device
204 tq2440_serial
252 first_drv                //我们创建的字符设备,主设备号252
253 usb_endpoint
254 rtcBlock devices:
259 blkext7 loop8 sd31 mtdblock65 sd66 sd67 sd68 sd69 sd70 sd71 sd
128 sd
129 sd
130 sd
131 sd
132 sd
133 sd
134 sd
135 sd
179 mmc
[WJ2440]# mknod /dev/xxx c 252 0        //手动创建一个字符设备节点
[WJ2440]# ls -l /dev/xxx
crw-r--r--    1 root     root      252,   0 Jan  1 20:49 /dev/xxx
[WJ2440]# ./first_test                 //有设备节点后成功我们的应用程序运行了
first_drv_open
first_drv_write
[WJ2440]#

本文参考:

https://blog.csdn.net/lwj103862095/article/details/17468587

linux字符驱动之概念介绍相关推荐

  1. Linux字符驱动开发学习总结

    linux驱动编写(虚拟字符设备编写) 昨天我们说了一些简单模块编写方法,但是终归没有涉及到设备的编写内容,今天我们就可以了解一下相关方面的内容,并且用一个实例来说明在linux上面设备是如何编写的. ...

  2. [Linux字符驱动] DIDO 74HC595实现遥控遥信功能

    项目中经常会使用YK和YX功能,DI操作,简单来说就是外部输入高电平,软件检测信号就为1:外部信号输入低电平,软件检测信号就为0:依据这样的设计,我们来看一下字符驱动该如何完成. 下面介绍一种有IO控 ...

  3. 嵌入式linux led驱动有几种写法,嵌入式Linux字符驱动LED灯设计

    一.任务要求 完成一个字符IO口驱动,在开发板上该IO口对应LED灯.该驱动程序通过控制IO口的高低电平来控制亮灭.同时要写一个应用层的测试程序,用来测试驱动程序.我的测试程序为myled_test. ...

  4. Linux字符驱动开发

    Linux字符驱动简介 字符设备驱动简介 举个栗子 file_operations 结构体 字符设备驱动开发步骤 驱动模块的加载和卸载 字符设备的注册和注销 添加 LICENSE 和作者信息 Linu ...

  5. 关于linux字符驱动中read函数filp->f_pos 和 loff_t *ppos的关系

    在学习linux 字符驱动的时候会有这样的困惑 比如我们实现一个字符驱动的读函数,如下 static ssize_t globalmem_read(struct file *filp, char __ ...

  6. linux驱动基础开发1——linux 设备驱动基本概念-转

    学习linux设备驱动首先我们必须明确以下几个概念,为我们接下来学习linux驱动打下坚实的基础: 应用程序.库.内核.驱动程序的关系 设备类型 设备文件.主设备号与从设备号 驱动程序与应用程序的区别 ...

  7. Linux字符驱动设备开发

    一.基础知识 参考博客:18 linux字符设备驱动之设备号_jklinux的博客-CSDN博客 创建设备驱动的目的,通常是让用户程序来调用.一般我们使用字符设备文件来提供接口,使用户进程可以访问操作 ...

  8. linux字符驱动之点亮LED

    上一节中,我们讲解了如何自动创建设备节点,这一节我们在上一节的基础上,实现点亮LED. 上一节文章链接:https://blog.csdn.net/qq_37659294/article/detail ...

  9. Linux字符驱动中动态分配设备号与动态生成设备节点

    在编写Linux内核驱动程序的时候,如果不动态生成设备号的话,需要自己手动分配设备号,有可能你分配的设备号会与已有设备号相同而产生冲突.因此推荐自动分配设备号.使用下面的函数: int alloc_c ...

最新文章

  1. 都996了,需求还是没法按时交付,怎么办?
  2. 有关计算机组装的书,计算机组装实习报告书.doc
  3. Java 设计模式之外观模式
  4. 深入理解Javascript之执行上下文(Execution Context)
  5. SAP Spartacus pageSlot一览
  6. bat kafka启动_windows下搭建Kafka,并通过命令窗口收发消息
  7. 重学TCP协议(3) 端口号及MTU、MSS
  8. 团队第一阶段冲刺——第七天
  9. 计算机视觉基础-图像处理 Task06 边缘检测
  10. 一次http请求中的信息
  11. java打包后找不到图片路径,解决Vue项目打包后打开index.html页面显示空白以及图片路径错误的问题...
  12. bypy更换绑定的百度云盘账户
  13. Java--Files
  14. 【笔记】设计模式 | 5种设计模式笔记整理
  15. 文件夹如何去除SVN的标记符号
  16. cad渐变线怎么画_CAD中怎么填充距离渐变的线条???
  17. 什么是价值投资?(Value Investing)
  18. 232电平和TTL电平
  19. ckeditor提交时判断是否为空
  20. python语句--条件语句

热门文章

  1. Gradle中的buildScript,gradle wrapper,dependencies等一些基础知识
  2. Linux基础之命令练习Day2-useradd(mod,del),groupadd(mod,del),chmod,chown,
  3. webpack基础入门
  4. axios 参数为payload的解决方法
  5. input type:text输入框点击输入,文字消失
  6. 如何解决EDM邮件营销中的图片难题
  7. php关联数组和哈希表,php遍历哈希表及关联数组的实例代码
  8. html鼠标事件没反应,鼠标有时候点击没反应怎么解决
  9. python菜鸟教程split_Python split()方法
  10. Oracle 常用的一些函数