驱动开发入手手册1

1、驱动

顾名思义,是驱使硬件动起来的设备;

种类:

1)、裸机驱动:需求分析,查看原理图,查看芯片手册,再而编写驱动程序;

2)、系统驱动:需求分析,查看原理图,查看芯片手册,设备树文件,编写对应的驱动模块,安装到linux内核中;

2、应用程序和驱动程序的区别?

从加载方式来看:应用程序是主动加载,驱动程序是被动加载;

从执行空间来看:应用程序是用户运行,驱动程序是内核来运行;

从执行权限来看:应用程序的执行权限低,驱动程序的执行权限高;

从程序的影响来看:应用程序的影响低,驱动程序的影响高;

从函数来源来看:应用程序可以是自定义的,库里自带的,也可以是来自系统调用的,驱动程序可以是自定义的,也可以是内核函数里面的。

3、模块

3.1、驱动模块:能够单独命名并且独立完成一定功能的程序语句的集合(程序代码和数据结构);

注意:、一个驱动模块就是一个完整的外设驱动程序。驱动模块被安装到linux内核中,当该驱动模块对应的设备要工作时,该驱动模块被调用。

3.2、如何写一个驱动模块?

test.c--->int main()

hello.c--->int main()

模块初始化函数:int  函数名1(void)

模块清除函数: void 函数名2(void)

模块加载函数:module_init(函数名1)--->sudo insmod hello.ko

模块退出函数:module_exit(函数名2)-->sudo rmmod hello.ko

遵守GPL规范:MODULE_LICENSE("GPL");

linux3.14源码+hello.c-->uImage

hello.c-->hello.ko--->安装到Linux内核中

3.3、如何编译驱动模块

gcc   arm-none-linux-gnueabi-gcc

分两种情况:

1) 若想要驱动在ubuntu上测试,那么使用编译ubuntu内核的makefile去编译驱动代码

2 若想要驱动在开发板的uImage上测试,那么使用编译linux3.14内核的Makefile去编译驱动程序。

Makefile如下:

ifeq ($(KERNELRELEASE),)

KERNELDIR ?= /lib/modules/$(shell uname -r)/build   

PWD := $(shell pwd)

modules:

$(MAKE) -C $(KERNELDIR) M=$(PWD) modules//进入/lib/modules/3.5.0-23-generic/build下执行Makefile,将PWD路径下的代码编译成一个hello.o

else

obj-m := hello.o  //将hello.o链接成hello.ko

endif

clean:

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

3.4、将驱动模块安装到Linux内核中

sudo insmod  hello.ko-->将驱动模块hello.ko安装到linux内核中

lsmod-->查看当前系统中所有已加载的驱动模块

dmesg |tail-->查看内核缓存区尾部10行的打印信息

dmesg |tail -20-->查看内核缓存区尾部20行的打印信息

modinfo hello.ko-->查看驱动模块hello.ko的所有信息描述

sudo rmmod hello.ko-->将hello.ko去内核中移除

3.5、将一个驱动代码分成两个文件

hello.c-->hello_init.c/hello_exit.c-->hello_init.o/hello_exit.o-->hello.ko

Makefile:

ifeq ($(KERNELRELEASE),)

KERNELDIR ?= /lib/modules/$(shell uname -r)/build   

PWD := $(shell pwd)

modules:

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

//进入/lib/modules/3.5.0-23-generic/build下执行Makefile,将PWD路径下的代码编译成一个hello.o

else

obj-m := hello.o  //将hello.o链接成hello.ko

hello-objs=hello_init.o hello_exit.o   (新增)

endif

4、模块传参

应用程序传参:./test 1.txt 2.txt

应用程序接收传参:Int main(int argc,char *argv[])

驱动程序传参:sudo insmod hello.ko gtest=100

驱动程序接收传参:1)全局变量  int gtest  2)声明该全局变量支持shell终端的传参值

如何声明:  

module_param(name, type, perm)

name:参数名,既是外部参数名,又是内部参数名

type:参数的数据类型

perm:访问权限,0644。0表示该参数在文件系统中不可见

module_param_string(name, string, len, perm)

name:参数名,外部参数名

string:内部参数名

len:数组的长度

perm:访问权限,0644。0表示该参数在文件系统中不可见

module_param_array(name, type, nump, perm)

name:数组参数名,既是外部参数名,又是内部参数名

type:参数的数据类型

nump:终端传给数组的实际元素个数(指针变量)

perm:访问权限,0644。0表示该参数在文件系统中不可见

测试步骤:

1) make--->hello.ko

2) sudo insmod hello.ko gtest=100

3) dmesg |tail   ---->查看gtest的值

4) cd /sys/module/hello/parameters

ls  -l

cat gtest--->100?

sudo chmod 777 gtest

echo 80 > gtest

cat gtest---->80?

5) sudo rmmod hello.ko

dmesg |tail

5 符号导出

5.1 什么是符号?

主要是指全局变量和函数

5.2 为什么要导出符号?

linux内核采用的是以模块化的形式管理内核代码。内核中的每个模块之间是相互独立的,也就是说A模块的全局变量和函数,B模块是无法访问的。若B模块想要使用A模块已有的符号,那么必须将A模块中的符号做符号导出,导出到模块符号表中,然后B模块将导出的符号表添加到自己的目录下,之后就可以在自己的代码中使用符号了。

5.3 如何导出符号?

Linux内核给我们提供了两个宏,用作符号导出

EXPORT_SYMBOL(符号)

EXPORT_SYMBOL_GPL(符号)

EXPORT_SYMBOL_GPL(gtest)

EXPORT_SYMBOL_GPL(func)

5.4 示例

A模块:导出符号--》导出到了本地符号表中(Module.symvers)

Module.symvers内容:

Addr---------------->符号名-------》模块名--------------》导出符号的宏

0x8f21315d   

gtest /home/farsight/2022/22071/driver/day1/module_symbol/moduleA_export/hello EXPORT_SYMBOL_GPL

0xd1a68ac8   

func /home/farsight/2022/22073/driver/day1/module_symbol/moduleA_export/hello EXPORT_SYMBOL_GPL

B模块:使用符号;B模块:使用导出的符号:1)将A模块导出的符号表拷贝到B模块的目录下 2) 在B模块中外部声明要使用的符号,然后使用之

注意:安装驱动模块时,先安装符号导出模块,再安装使用符号的模块;卸载时,先卸载使用符号的模块,再卸载导出符号的模块

注意:linux内核有两类符号表:

第一种:用户自定义模块导出的符号表,这些符号保存在本模块目录下的Module.symvers---》本地符号表

第二种:全局符号表 /proc/kallsyms

sudo cat /proc/kallsyms |grep printk

c15cd833

int (*pFunc)(const char *format,...)=0xc15cd833

pFunc("hellotest");

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一条小白码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值