驱动开发框架学习1

文章介绍了Linux模块化编程的基本结构,包括入口和出口函数,并提到了两种将模块代码编译进内核的方法。接着,讨论了注册字符设备驱动的过程,强调了设备号在驱动标识中的重要性,以及应用层如何通过设备文件访问驱动。最后,提到了自动创建设备文件的机制以及传统字符设备驱动的局限性。
摘要由CSDN通过智能技术生成

1.模块化编程

按照Linux规定模块的形式添加代码

#include <linux/init.h>
#include <linux/module.h>

MODULE_LICENSE("GPL v2");

static int hello_init(void) //入口函数
{
	printk("Hello linux module init!\n");
	return 0;
}

static void  hello_exit(void)//出口函数
{
	printk("Hello linux module exit!\n");
}

module_init(hello_init);//告诉linux模块入口函数,加载模块代码到操作系统的时候会调用
module_exit(hello_exit);//告诉linux模块出口函数,从操作系统中卸载模块代码的时候调用

Makefile的编写

思想:
Linux 内核源码的编译系统可以编译我们编写的模块代码
		 
第一种(产品发布):
将自己编写的代码,拷贝到Linux内核源码树下,然后配置编译,编译进内核
		 			
第二种(驱动调试):
自己编写Makefile,然后使用Linux内核的编译系统,编译自己的模块代码
		 			 
问:Linux内核的编译系统在哪里?
答:
<1>Linux内核源码下的Makefile
注意:
你的Linux内核源码必须已经根据自己所开发的平台进行了配置

[1]修改了Makefile,指定了开发工具链
[2]已经使用Linux内核默认配置文件进行了配置
		 	 	  		 	 	  
<2>ubuntu系统自带的Linux内核编译系统(pc机,x86)
/lib/modules/3.13.0-32-generic/build/Makefile
		
		 	    
问:如何在自己编写的Makefile中使用Linux内核的编译系统
答:make  -C  linux内核编译系统的路径  M=需要编译的模块代码路径  modules

make 调用当前目录下的Makefile-----------切换到------------>linux内核编译系统的路径Makefile
                

ifeq ($(KERNELRELEASE),)

KERNEL_BUILD=/lib/modules/$(shell uname -r)/build  记录Linux内核的编译系统路径
MODULE_PATH =$(shell pwd) 记录模块代码的路径

module:
	$(MAKE) -C $(KERNEL_BUILD) M=$(MODULE_PATH) modules 
	make    -C /lib/modules/$(shell uname -r)/build  M=记录模块代码的路径   modules

clean:
	$(MAKE) -C $(KERNEL_BUILD) M=$(MODULE_PATH) clean
	
else
	obj-m = hello_module.o
endif	

Makefile调用图

 2.注册字符设备

七 写字符设备驱动,驱动需要包含哪些信息

1.设备号
       |
       |
2.struct cdev
       |
       |
       | 
3.一组函数接口 -----> struct file_operations

LED驱动----字符设备驱动注册

1.应用层的进程如何访问底层的驱动程序
  字符设备或块设备,我们可以通过设备文件(属性信息中包含的设备号)来找到底层驱动程序
  
---------------------------------------------------------------------------------------
驱动的标识:设备号

12bit(主设备号) + 20bit(次设备号) = 32bit

主设备号:标识一类设备
次设备号:为了区分同类型设备的不同设备
----------------------------------------------------------------------------------------
问:Linux内核有那么多驱动程序,如何才能确定自己需要访问的驱动程序?
答:通过设备文件中包含的设备号信息 

问:Linux内核中,如何描述描述文件?
答:<1>struct inode 描述文件属性信息(文件类型,权限,大小,修改时间,设备号[设备文件])
   <2>struct file  描述一个打开的文件(打开的方式,文件偏移量,...)
	   [注意:只要打开一次文件,就会分配一次]
	   

问:应用层访问底层字符设备驱动的过程?
答:open---->设备文件
							 struct inode:设备号
							 				--------->struct cdev
							 				             它的一个成员记录操作硬件设备的函数接口
														 (struct file_operations)
							 				
	 
	 寻找成功之后:(.probe的实现。cdev_init就可以把自己写的操作硬件接口放到虚拟文件系统对象当中去)
	 struct inode 结构体记录struct cdev这个结构体首地址
	 struct file  结构体记录struct file_operations这个结构体首地址

问:写字符驱动,需要做什么?
答:<1>struct cdev:Linux 针对字符设备的通用描述
		  
		struct  led_device{
			struct cdev cdev;//通用的字符设备描述
			...
		};
		需要给自己设计的结构体分配空间
		  
	<2>提供硬件设备的操作函数接口
	 	struct file_operations 结构体做填充  
	 	需要将这个结构体的首地址记录在struct cdev结构体中
	 	  	  
	<3>申请一个空闲的设备号
	 
	<4>使用设备号,将struct cdev这个结构体添加到系统中去 

 3.自动创建设备文件

 自动创建设备文件

1.驱动程序必须导出设备号信息
2.捕获设备号信息的程序,帮我们创建设备文件
  <1>devtmpfs 在内核启动的时候,它就会运行,在内核空间(可以通过make menuconfig去掉这个功能)
  <2>udev     应用程序,功能强大
  <3>mdev     应用程序,它是udev简化版本

4.传统字符设备缺点

驱动与设备未分离,而且写的比较死,可移植性差,原因:驱动中包含了特定平台的硬件信息,如果是其他平台,硬件信息会有差异,所以
驱动无法直接使用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值