linux下的IIC
linux的IIC体系结构Linux的IIC体系结构分为3个组成部分,分别是IIC核心、IIC总线驱动和IIC设备驱动!
(1)IIC核心
提供了IIC总线驱动与IIC设备驱动的注册、注销方法和与具体IIC控制器无关的代码,该部分用来管理IIC总线驱动与IIC设备驱动。
(2)IIC总线驱动
IIC总线驱动是适配器(IIC控制器)的驱动程序,包含了适配器(IIC控制器)的数据描述结构i2c_adapter、通信方法数据结构i2c_algorithm、控制适配器产生通信时序的函数。
(3)IIC设备驱动
是具体IIC设备的驱动,因为不同的IIC设备可能有不同的读写时序要求,比如at24cxx读写需要发送16位地址,而tmp75只需要8位地址即可。IIC设备驱动通过i2c_algorithm通信方法驱动适配器驱动程序去访问具体的IIC设备。
体系结构
架构层次分类 第一层:提供i2c adapter的硬件驱动,探测、初始化i2c adapter(如申请i2c的io地址和中断号),驱动soc控制的i2c adapter在硬件上产生信号(start、stop、ack)以及处理i2c中断。图 ...
SPI驱动
SPI
SPI 控制器驱动程序SPI 主机驱动就是 SOC 的 SPI 控制器驱动,SPI 控制器不用关心设备的具体功能,它只负责把上层协议驱动准备好的数据按 SPI 总线的时序要求发送给 SPI 设备,同时把从设备收到的数据返回给上层的协议驱动,因此,内核把 SPI 控制器的驱动程序独立出来。
SPI 控制器驱动负责控制具体的控制器硬件,诸如 DMA 和中断操作等等,因为多个上层的协议驱动可能会通过控制器请求数据传输操作,所以,SPI 控制器驱动同时也要负责对这些请求进行队列管理,保证先进先出的原则。
申请必要的硬件资源,比如中断、DMA 通道、DMA 内存缓冲区等等
配置 SPI 控制器的工作模式和参数,使之可以和相应的设备进行正确的数据交换
向通用接口层提供接口,使得上层的协议驱动可以通过通用接口层访问控制器驱动
配合通用接口层,完成数据消息队列的排队和处理,直到消息队列变空为止
SPI 主机驱动的核心就是申请 spi_master,然后初始化 spi_master,最后向 Linux 内核注册spi_master。
12345678spi_alloc_master ...
IIC驱动
IIC驱动框架Linux内核将 I2C 驱动分为两部分:①、 I2C 总线驱动, I2C 总线驱动就是 SOC 的 I2C 控制器驱动,也叫做 I2C 适配器驱动。②、 I2C 设备驱动, I2C 设备驱动就是针对具体的 I2C 设备而编写的驱动。
IIC驱动也是借用platform思想,将设备和总线进行分离,但是IIC有自己的总线,所以就不用使用虚拟总线。
I2C 总线驱动重点是 I2C 适配器(也就是 SOC 的 I2C 接口控制器)驱动,这里要用到两个重要的数据结构: i2c_adapter 和 i2c_algorithm, Linux 内核将 SOC 的 I2C 适配器(控制器)抽象成 i2c_adapter, i2c_adapter 结构体定义在 include/linux/i2c.h 文件中。
1234567891011121314151617181920212223498 struct i2c_adapter {499 struct module *owner;500 unsigned int class; /* classes to al ...
RTC驱动
Linux 内核中 RTC 驱动调用流程
Linux 内核将 RTC 设备抽象为 rtc_device 结构体,因此 RTC 设备驱动就是申请并初始化rtc_device,最后将 rtc_device 注册到 Linux 内核里面,这样 Linux 内核就有一个 RTC 设备了 。
当 rtc_class_ops 准备好以后需要将其注册到 Linux 内核中,这里我们可以使用rtc_device_register函数完成注册工作。此函数会申请一个rtc_device并且初始化这个rtc_device,最后向调用者返回这个 rtc_device,此函数原型如下:
1234567struct rtc_device *rtc_device_register(const char *name, //设备名字 struct device *dev, //设备 const struct rtc_class_ops *ops,//RTC 底层驱 ...
lcd驱动
Framebuffer在 Linux 中应用程序最终也是通过操作 RGB LCD 的显存来实现在 LCD 上显示字符、图片等信息。 因为虚拟内存的存在,驱动程序设置的显存和应用程序访问的显存要是同一片物理内存。
Framebuffer 诞生了, Framebuffer 翻译过来就是帧缓冲,简称 fb 。fb 是一种机制,将系统中所有跟显示有关的硬件以及软件集合起来,虚拟出一个 fb 设备。帧缓冲是linux系统中的一种显示驱动接口,它将显示设备(比如LCD)进行抽象、屏蔽了不同显示设备硬件的实现,对应用层抽象为一块显示内存(显存),它允许上层应用程序直接对显示缓冲区进行读写操作,而用户不关心物理显存的位置等具体细节,这些都由Framebuffer设备驱动来完成。
显示设备被称为 FrameBuffer 设备(帧缓冲设备),所以 LCD 显示屏自然而言就是 FrameBuffer 设备。 FrameBuffer 设备对应的设备文件为/dev/fbX(X 为数字, 0、 1、 2、 3 等) , Linux下可支持多个 FrameBuffer 设备,最多可达 32 个, ...
input驱动
Input子系统input 就是输入的意思,因此 input 子系统就是管理输入的子系统,和 pinctrl、 gpio 子系统一样,都是 Linux 内核针对某一类设备而创建的框架。比如按键输入、键盘、鼠标、触摸屏等等这些都属于输入设备,为此 input 子系统分为 input 驱动层、 input 核心层、 input 事件处理层,最终给用户空间提供可访问的设备节点。
驱动部分包含三个部分:驱动层,核心层,事件层驱动层:输入设备的具体驱动程序,比如按键驱动程序,向内核层报告输入内容。核心层:承上启下,为驱动层提供输入设备注册和操作接口。通知事件层对输入事件进行处理。事件层:主要和用户空间进行交互。
注册input_dev在使用 input 子系统的时候我们只需要注册一个 input 设备即可, input_dev 结构体表示 input设备
1234567891011121314151617181920121 struct input_dev {122 const char *name;123 const char *phys;124 const char *uni ...
MISC设备驱动
MISC驱动所有的 MISC 设备驱动的主设备号都为 10,不同的设备使用不同的从设备号。 MISC 设备会自动创建 cdev,不需要像手动创建,因此采用 MISC 设备驱动可以简化字符设备驱动的编写。 需要向 Linux 注册一个 miscdevice 设备
1234567891011struct miscdevice { int minor; /* 子设备号 */ const char *name; /* 设备名字 */ const struct file_operations *fops; /* 设备操作集 */ struct list_head list; struct device *parent; struct device *this_device; const struct attribute_group **groups; const char *nodename; umode_t mode;};
Linux 系统已经预定义了一些 MISC 设备的子设备号,这些预定义的子设备号定义在include/linux/miscdev ...
设备树下的platform设备驱动
设备树下的platform驱动在使用设备树的时候,设备的描述被放到了设备树中,因此 platform_device 就不需要我们去编写了,我们只需要实现 platform_driver 即可 。
1.创建设备树中设备节点platform 总线需要通过设备节点的 compatible 属性值来匹配驱动! 以led设备为例子:
123456789gpioled{ #address-cells = <1>; #size-cells = <1>; compatible = "atkalpha-gpioled";//匹配的属性 pinctrl-names = "default"; pinctrl-0 = <&pinctrl_led>; led-gpio = <&gpio1 3 GPIO_ACTIVE_LOW>; status = "okay";};
2.编写platform驱动时候要注意兼容属性在使用设备树的时 ...
platform设备驱动
驱动框架传统驱动框架假如现在有三个平台 A、 B 和 C,这三个平台(这里的平台说的是 SOC)上都有 MPU6050 这个 I2C接口的六轴传感器
每种平台下都有一个主机驱动和设备驱动,主机驱动肯定是必须要的,毕竟不同的平台其 I2C 控制器不同。但是右侧的设备驱动就没必要每个平台都写一个,因为不管对于那个 SOC 来说, MPU6050 都是一样,通过 I2C 接口读写数据就行了,只需要一个 MPU6050 的驱动程序即可。
分离后的驱动框架
相当于将设备信息从设备驱动中剥离开来,驱动使用标准方法去获取到设备信息(比如从设备树中获取到设备信息),然后根据获取到的设备信息来初始化设备。 这样就相当于驱动只负责驱动,设备只负责设备,想办法将两者进行匹配即可。这个就是 Linux 中的总线(bus)、驱动(driver)和设备(device)模型,也就是常说的驱动分离。
platformplatform总线paltform是一种虚拟的总线,用于管理外设资源内存资源中断资源。在硬件上有USB-BUS总线,PCI-BUS总线,这是在物理设备上实际存在的总线。USB-BUS管理USB ...
经典滤波算法
1.限幅滤波法(程序判断滤波法)方法:确定两次采样允许的最大偏差值,如果本次值与上次值之差<=A,则本次有效,反之>A,则本次值无效,放弃本次值,上次代替本次值。
优点:克服偶然误差造成的干扰
缺点:无法抑制周期性干扰,平滑度差
核心内容:
12345678910#define A 10char value;char filter(){ char new_value; new_value = get_ad(); if ( ( new_value - value > A ) || ( value - new_value > A ) return value; else return new_value;}
eg:
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152#include "stdio.h"#define A 4float data_number[] = { ...