zlg

您所在的位置:网站首页 gpio0:2 zlg

zlg

#zlg| 来源: 网络整理| 查看: 265

[(112条消息) (一)初识Linux驱动_hanp_linux的博客-CSDN博客_linux驱动学习](https://blog.csdn.net/hanp_linux/article/details/90441869)

操作系统:多任务并发、独立内存空间

Linux模块 Linux应用程序 (1)运行空间 内核空间 用户空间 (2)入口函数 模块加载函数 main函数 (3)库 内核源码库(内核include目录) 用户空间的库/usr/lib (4)释放 必须释放(装载和卸载) 要求释放 (5)段错误危害 可能导致整个系统崩溃 危害小,不会影响系统 Makefile格式: #定义一些变量,增加代码的阅读性和扩展性 #`uname -r`这种写法就是执行uname -r这个shell命令,从而构造这个绝对路径,因为每个人的计算机的绝对路径都不一样,这样提高通用性,对于我的主机,这个路径相当于/lib/modules/4.4.0-31-generic/build KERNEL_PATH := /home/vmuser/M3568_zy_source/half_open/kernel PWD := $(shell pwd) # CROSS_COMPILE := /home/vmuser/M3568_zy_source/half_open/prebuilts/gcc/linux-x86/aarch64/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu- #这个名字表示:要生产的模块的名字,最终会生成hello.ko MODULE_NAME := hello #表示要生成hello.ko要依靠中间文件hello.o kbuild系统会将源码hello.c编译成hello.o obj-m := $(MODULE_NAME).o #当执行make命令默认会寻找第一个目标,即all all: $(MAKE) ARCH=arm64 -C $(KERNEL_PATH) M=$(PWD) #执行make clean要执行的操作,将编译生成的中间文件删掉 clean: rm -rf .*.cmd *.o *.mod.c *.order *.symvers disclean: rm -rf .*.cmd *.o *.mod.c *.order *.symvers *.ko

ARCH=arm64记得要加上,否则会默认编译x86版本,报错。

hello world #include #include static int intarg = 100; static int hello_init(void) { printk("hello world ! you tell me the [%d] \r\n", intarg); return 0; } static void hello_exit(void) { printk("bye world !\r\n"); } MODULE_LICENSE("GPL"); MODULE_AUTHOR("Zihao.Hu"); MODULE_DESCRIPTION("This is a hello description"); // MODULE_INFO("This is a hello info"); module_init(hello_init); module_exit(hello_exit); module_param(intarg, int, 0600); MODULE_PARM_DESC(intary, "is A interger"); 相关api说明: /* 现有一个驱动hello.ko */ module_param(变量名,数据类型,0600权限) //传递参数。可以在驱动中使用,用户层可以在 /sys/module/hello(驱动名)/parameters/变量名 查看 // 不对 #include //对

(113条消息) fatal error: asm/system.h: No such file or directory 以及 linux/autoconf.h、asm/uaccess.h 报错的解决方法_mochih的博客-CSDN博客_asm/system.h

不要打印用户层传过来的字符串指针,不然可能会崩溃

container_of: /**

container_of - cast a member of a structure out to the containing structure @ptr: the pointer to the member.已知结构体成员的地址 @type: the type of the container struct this is embedded in.要获取的结构体的类型 @member: the name of the member within the struct.已知结构体成员的名字 */

C99 先定义

/proc/device // 查看设备号分配情况

/sys/class // 查看类节点

/dev/? //设备节点

bus_dev_drv模型 --> i2c/spi/platform等总线模型

struct bus_type platform_bus_type = { .name = "platform", .dev_groups = platform_dev_groups, .match = platform_match, //用来匹配platform_device和对应的platform_driver .uevent = platform_uevent, .pm = &platform_dev_pm_ops, }; struct platform_device { const char *name; //platform_device的名字 int id; bool id_auto; struct device dev; //表示platform_driver是继承于(用面向对象思想,不严谨,但便于理解)device_driver u32 num_resources; // 用来描述硬件资源的数量 struct resource *resource; // 结构体数组,用来描述具体的硬件资源 /* struct resource { resource_size_t start; resource_size_t end; const char *name; unsigned long flags; //IORESOURCE_MEM(地址资源) IORESOURCE_IO(IO ports资源) IORESOURCE_IRQ(中断资源) unsigned long desc; struct resource *parent, *sibling, *child; }; */ const struct platform_device_id *id_entry; char *driver_override; /* Driver name to force a match */ /* MFD cell pointer */ struct mfd_cell *mfd_cell; /* arch specific additions */ struct pdev_archdata archdata; }; struct platform_driver { int (*probe)(struct platform_device *); //如何platform总线探测到它下面挂的某个driver和device匹配,那么就会调用对应的drv下面的probe函数 int (*remove)(struct platform_device *); void (*shutdown)(struct platform_device *); int (*suspend)(struct platform_device *, pm_message_t state); int (*resume)(struct platform_device *); struct device_driver driver; //表示platform_driver是继承于(用面向对象思想,不严谨,但便于理解)device_driver const struct platform_device_id *id_table; bool prevent_deferred_probe; }; 设备树

4.x以后的kernel,不用platform_device了,改用设备树(设备树在platform_device优先级之上)

必须要有compatible,匹配后执行probe

a = "hello world"; #字符串 b = ; #int c = ;#数组int

#include

I2C

通过设备树(devicetree)创建i2c_client

@i2c-0 {//表示这个i2c_client所依附的adapter是i2c-0 //对应i2c_client的name = "invensense,mpu6050" compatible = "invensense,mpu6050"; //对应i2c_client的addr = 0x69 -- 从机设备的地址 reg = ; //对应i2c_client的irq interrupts = ; }; struct i2c_client { unsigned short flags; //标志位 (读写) unsigned short addr; //7位的设备地址(低7位) 对应reg char name[I2C_NAME_SIZE]; //设备的名字,用来和i2c_driver匹配 对应compatible struct i2c_adapter *adapter; //依附的适配器(adapter),适配器指明所属的总线(i2c0/1/2_bus) struct device dev; //继承的设备结构体 int irq; //设备申请的中断号 对应interrupt struct list_head detected; //已经被发现的设备链表 }; regulator子系统配置

有时候我们需要一个上电就要输出高电平的IO,一般用于电源使能

显然不能在应用层中调用gpio系统输出,这样太慢了;同样的,led子系统也太慢了,通常需要上电几秒后才能启动。

我们需要通过regulator-gpio在加载内核kernel时就能输出高电平

配置说明文档:

GPIO controlled regulators regulator-max-microvolt Required properties: - compatible : Must be "regulator-gpio". - regulator-name : Defined in regulator.txt as optional, but required // 在应用层中根据regulator-name定位 here. - states : Selection of available voltages and GPIO configs. if there are no states, then use a fixed regulator // 选择可用电压和 Optional properties: - enable-gpio : GPIO to use to enable/disable the regulator. // 使能regulator-gpio的gpio - gpios : GPIO group used to control voltage. // gpio组 - gpios-states : gpios pin's initial states array. 0: LOW, 1: HIGH. defualt is LOW if nothing is specified. // 初始状态,默认逻辑低 - startup-delay-us : Startup time in microseconds. // 启动时间,微秒级 - enable-active-high : Polarity of GPIO is active high (default is low). // 极性是否高激活?(默认低激活) - regulator-type : Specifies what is being regulated, must be either "voltage" or "current", defaults to voltage. - vin-supply : Input supply name. Any property defined as part of the core regulator binding defined in regulator.txt can also be used. Example: mmciv: gpio-regulator { compatible = "regulator-gpio"; regulator-name = "mmci-gpio-supply"; regulator-min-microvolt = ; regulator-max-microvolt = ; regulator-boot-on; enable-gpio = ; gpios = ; states = ; startup-delay-us = ; enable-active-high; vin-supply = ; };

设备树配置例子:

vcc3v3_603: vcc3v3-603 { compatible = "regulator-fixed"; regulator-name = "pw3V3"; regulator-boot-on; regulator-always-on; regulator-min-microvolt = ; regulator-max-microvolt = ; enable-active-high; gpio = ; /* vin-supply = ; */ pinctrl-names = "default"; pinctrl-0 = ; };


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3