Linux 驱动之 SPI 子系统
Linux SPI 驱动框架
对于 SPI 的驱动框架与 I2C 是大致一致的,也分为两层,控制器驱动程序层叫 spi_controller ,主要提供 transfer 函数,进行 spi 协议的收发。
另一层是设备驱动层,基于 spi_bus_type,在 driver 里则使用 spi_read、spi_writer 等函数,最终也会调用到 controller->transfer 函数进行发送接收。
对于 SPI 的驱动框架与 I2C 是大致一致的,也分为两层,控制器驱动程序层叫 spi_controller ,主要提供 transfer 函数,进行 spi 协议的收发。
另一层是设备驱动层,基于 spi_bus_type,在 driver 里则使用 spi_read、spi_writer 等函数,最终也会调用到 controller->transfer 函数进行发送接收。
流程如下:
下图:白色背景表示"主→从",灰色背景表示"从→主"
以 arm64 为例,内核启动如下:
1 | __HEAD |
在开启 UEFI 支持时,add x13, x18, #0x16 这个 code 实际上是为了满足 EFI 格式的”MZ”头。如果使用 UEFI 来启动 kernel, 会识别出来并走 UEFI 启动的流程,如果是普通的启动过程如使用 uboot 的 booti 进行引导,那么第一条指令就是一条 dummy 指令,第二条就跳转到 stext 运行了。
seq_file 只是在普通文件 read 中加入了内核缓冲的功能,从而实现顺序多次遍历读取大数据量的简单接口,seq_file 一般只提供只读接口。
1 | struct seq_operations { |
当电机采用 id=0 的控制策略,这种控制方法忽略了磁阻转矩的作用,电磁转钜方程如下:
转矩分为永磁转矩 Tr 和磁阻转矩 Tm,而 id=0 只剩下 Tr。这会导致电流的利用率不高,系统的效率降低。所以 id=0 的控制比较适用于隐极式电机(Ld=Lq),而对于凸极式电机并不最优,所以需要重新考虑控制策略。
将左手的食指,中指和拇指伸直,使其在空间内相互垂直。食指方向代表磁场的方向(从
N 级到 S
级),中指代表电流的方向(从正极到负极),那拇指所指的方向就是受力的方向。可用于判断安培力(运动导体所受到的力)和洛伦兹力(运动电荷所受的力)。
伸开右手,使拇指与其余四个手指垂直,并且都与手掌在同一平面内;让磁感线垂直于手心进入,并使拇指指向导线运动方向,这时四指所指的方向就是感应电流的方向。用于判断导体在做切割磁场时产生的电流方向。
openshoe 是一种通过惯性测量元件 (IMU) 来对运动进行积分以得到路径的控制算法。算法的核心是 ZUPT(零速度更新算法),在只有 IMU 惯性测量元件的情况下获得路径只能通过对加速度积分得到速度,再将速度对时间进行积分得到路径,这里如果不能对积分得到的速度进行有效的校正那么这个速度误差会时刻对时间进行积分,导致路径完全失效,因此必须采取有效手段及时对速度误差进行校正以得到较为准确的路径信息,ZUPT 就是一种基于检测零速度进行路径积分校正的算法。该算法的关键是对零速度的准确检测。
openshoe 采用广义似然检测算法对零速度进行检测,以判断 IMU 是否处于静止状态。
要理解广义似然检测原理需要先熟悉几个概率论中相关的概念,详细如下:
对于理想的 IMU 三轴加速度计两两正交,构成一个正交的三轴直角坐标系,加速度计每一轴单独测量该轴的加速度,而陀螺仪则测量该轴的角速度。在实际的真实 IMU 中由于制造工艺的误差,三个坐标轴不可能完全两两正交,加速度计与陀螺仪的坐标系也不会完全重合,并且单个传感器也不是完全精确的。在实际器件中将数字输出量转化为实际物理量的 scale 参数在不同轴上是不同的,但是设备生产商都会提供一个默认的 scale 参数用于转换所有轴的数据,而且数字量的输出还会受到零偏(传感器在静止情况下也会有微小量的输出)的影响,这些就是造成 IMU 传感器的系统误差。
我们取实际器件的加速度计坐标系为 AF, 陀螺仪坐标系为 GF,根据 AF 和 GF 分别建立对应的正交坐标系 AOF 和 GOF,其建立约束为
对于 GOF 的建立约束与 AOF
的约束类比建立。最后再建立一个正交机体坐标系 BF,BF 通常与 AF 和 GF
之间有一个小角度的偏差。在非正交坐标系(AF 或
GF)中测量得到的物理量