MPU6500 电子防抖 (EIS) 推流例程 — 技术架构文档
📅 2026/7/23 11:01:30
👁️ 阅读次数
📝 编程学习
硬件平台: HI3516CV610 + MPU6500 MEMS 6轴惯性传感器
核心功能: 视频编码 + 实时电子防抖 (EIS) + RTSP 推流
目录
- 系统总览
- 维度1: 完整执行流程
- 维度2: 关键子流程图解
- 维度3: 数据流全貌
- 维度4: 配置链
- 附录: 源码文件索引
1. 系统总览
1.1 双线程异构架构
┌─────────────────────────────────────────────────────────────────────────────┐ │ myvenc_eis 系统架构 │ │ │ │ Thread 1: main (视频管线, 30fps) Thread 2: gyro_eis (实时采集, 1kHz) │ │ ┌────────────────────────────────┐ ┌────────────────────────────────┐ │ │ │ SENSOR → VI → VPSS → VENC │ │ MPU6500 (GPIO 模拟 I2C) │ │ │ │ ↑ EIS补偿注入 │ │ │ │ │ │ │ VPSS chn0: 2560×1440 H.265 │◄──────┼───┤ eis_process_sample() │ │ │ │ VPSS chn1: 1080P H.264 │ │ │ clamp→deadzone→Kalman │ │ │ │ │ │ │ →integral→LPF→pixel_map │ │ │ │ → sample_comm_get_stream │ │ │ │ │ │ │ → RTSP(8554) / 本地文件 │ │ └── last_comp (mutex 保护) │ │ │ └────────────────────────────────┘ └────────────────────────────────┘ │ │ │ │ 线程安全: eis_context.data_mutex 保护 采集线程(写) 与 视频线程(读) 无竞争 │ └─────────────────────────────────────────────────────────────────────────────┘1.2 物理硬件连接
HI3516CV610 MPU6500 ┌──────────────┐ ┌──────────────┐ │ IOCFG_BASE │ │ pin 23: SCL ├── GPIO1_4 (0x11130004) │ (0x11130000) │ │ pin 24: SDA ├── GPIO1_5 (0x11130000) │ GPIO1_BASE │ │ pin 9: AD0 ├── GND → I2C addr=0x68 │ (0x11091000) │ │ pin 8: VCC ├── 3.3V └──────────────┘ │ pin 7: nCS ├── VCC (I2C模式) └──────────────┘ - GPIO1_4(SCL) 始终输出; GPIO1_5(SDA) 方向切换模拟开漏 - 内部上拉 ~50kΩ 替代外部上拉电阻; 需 root 权限运行 (/dev/mem)1.3 源文件分工
| 文件 | 行数 | 职责 |
|---|---|---|
myvenc_eis.c | 1075 | 主程序: 双线程管理、视频编码管线、RTSP、命令行解析 |
mpu6500_eis.c | 743 | EIS 算法: 卡尔曼滤波、死区、限幅、积分、LPF 分离、像素补偿 |
mpu6500_eis.h | 509 | EIS 接口: 数据结构 (kalman/lpf/姿态/补偿)、API 声明 |
mpu6500_i2c.c | 981 | I2C 驱动: GPIO 模拟 I2C、寄存器读写、物理量换算 |
mpu6500_i2c.h | 392 | I2C 接口: 寄存器宏定义、设备句柄、API 声明 |
2. 维度1: 完整执行流程
2.1 main() 顶级调用链
main() [myvenc_eis.c:957] │ ├─ 阶段1: 命令行解析 [L964-987] │ argc=1 → 本地文件 | argc=2 → RTSP推流(g_rtsp_enable=1) │ ├─ 阶段2: 注册信号处理 [L990-992] │ SIGINT/SIGTERM → g_sample_venc_exit=TD_TRUE │ ├─ 阶段3: 创建 RTSP 服务 [L994-1015] (g_rtsp_enable==1时) │ create_rtsp_demo(8554) → create_rtsp_session(H264+H265) │ rtsp_do_event 循环 5s 等待客户端连入 │ ├─ ★ 阶段4: 启动 EIS 子系统 [L1029-1036] │ └─ start_gyro_eis() [L253] │ ├─ mpu6500_init() [mpu6500_i2c.c:743] │ │ ├─ gpio_i2c_init() 映射 IOCFG + GPIO1 → 用户空间 │ │ ├─ PWR_MGMT_1 ← 0x80 硬件复位 (等待 100ms) │ │ ├─ PWR_MGMT_1 ← 0x01 唤醒 + PLL 时钟源 │ │ ├─ PWR_MGMT_2 ← 0x00 使能全部 6 轴 │ │ ├─ WHO_AM_I → 0x70 通信验证 │ │ ├─ GYRO_CONFIG ← ±1000°/s 量程 + sensitivity=32.8 │ │ ├─ ACCEL_CONFIG ← ±4g 量程 + sensitivity=8192 │ │ ├─ CONFIG ← DLPF_98Hz 硬件低通 (2.8ms 延迟) │ │ └─ SMPLRT_DIV ← 0 ODR = 1kHz │ │ │ ├─ eis_init() [mpu6500_eis.c:292] │ │ ├─ 保存传感器参数: fov_h/v_deg, image_w/h │ │ ├─ 派生计算: sample_dt=0.001s, margin_x=img_w/10 │ │ ├─ 初始化卡尔曼 3轴: x_est=0, p_est=1, Q/R 写入 │ │ ├─ 初始化 LPF 3轴: α=dt/(dt+τ)=0.001/0.501≈0.002 │ │ └─ pthread_mutex_init() │ │ │ └─ pthread_create(gyro_eis_thread) │ └─ sched_setscheduler(SCHED_FIFO, prio=50) │ ├─ 阶段5: 启动视频编码管线 [L1039] │ └─ sample_venc_normal() [L900] │ ├─ sample_venc_online_wrap_start_sys_vi_vpss() │ │ ├─ sys_init() → VB 缓冲池 + VI-VPSS Online 模式 │ │ ├─ vi_init() → 启动 VI pipe0 采集 │ │ ├─ start_vpss() → VPSS grp0 + early_line=height/2 + chn1 low_delay │ │ └─ vi_bind_vpss() → VI→VPSS 绑定 │ │ │ ├─ sample_venc_normal_start_encode() [L564] │ │ ├─ get_gop_mode() 用户选 NormalP/DualP/SmartP │ │ ├─ get_rc_mode() 用户选 CBR/VBR/ABR/AVBR/... │ │ ├─ venc_start(chn0, H.265, GOP=30) │ │ ├─ vpss_bind_venc(chn0) │ │ ├─ venc_start(chn1, H.264, GOP=15) │ │ ├─ vpss_bind_venc(chn1) │ │ └─ venc_start_get_stream() → 阻塞接收码流 │ │ │ └─ 等待用户按两次 Enter 退出 │ ├─ 阶段6: 停止 EIS [L1041-1046] │ print_eis_status() → stop_gyro_eis() │ ├─ g_sample_venc_exit = TRUE → 通知线程退出 │ ├─ pthread_join(gyro_thread) │ ├─ eis_deinit() → 销毁 mutex │ └─ mpu6500_deinit() → 睡眠模式 + munmap GPIO/IOCFG │ ├─ 阶段7: 清理 RTSP [L1049-1057] │ rtsp_del_session() × 2 + rtsp_del_demo() │ └─ 阶段8: 输出统计 [L1060-1074] printf(samples=%llu, errors=%llu, EIS=%s)2.2 线程启动时序
时间 → ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ main: mpu6500_init(~100ms) → eis_init(<1ms) → pthread_create(gyro_thread) → SYS/VI/VPSS init (~200ms) → VENC init (~50ms) → ★ VI→VPSS→VENC 管线开始, gyro 线程已在 1kHz 后台运行 → getchar() 阻塞等待退出 gyro: sched_setscheduler(SCHED_FIFO,50) → while(!exit){read_phy→process_sample→nanosleep}2.3 安全退出链
Ctrl+C / 两次 Enter → g_sample_venc_exit = TRUE → 并行: 主: VPSS-VENC 解绑 → VENC stop → VI-VPSS 解绑 → VPSS stop → VI stop → SYS exit gyro: while(!exit) 退出循环 → return NULL → pthread_join(gyro_thread) → eis_deinit() + mpu6500_deinit() + rtsp 清理3. 维度2: 关键子流程图解
3.1 EIS 防抖核心 — 6步滤波流水线 (1kHz)
输入: 三轴角速度 (gx,gy,gz °/s) + timestamp (μs) ═══════════════════════════════════════════════════════════════════════════ Step 1: clamp_gyro() — 限幅 ±300°/s │ │ 判定: IF |ω| > 300 → 截断为 ±300 │ 区域: [-300,300]=手持运动正常范围, 超出=冲击/跌落→截断 │ 数据: ω_raw → [clamp] → ω_clamped │ ▼ Step 2: apply_dead_zone() — 死区过滤 threshold=0.5°/s │ │ 判定: IF |ω| < 0.5 → 置零 (MPU6500 典型零漂 ±0.5°/s) │ ELSE: ω = |ω| − 0.5 (去偏置) │ 不设死区后果: 每60秒漂30°, 补偿失效 │ 数据: ω_clamped → [dead_zone] → ω_clean │ ▼ Step 3: kalman_1d_update() — 卡尔曼最优估计 Q=0.001,R=0.15 │ │ 预测: x_pred=x_est; p_pred=p_est+Q │ 增益: K=p_pred/(p_pred+R)≈0.05 │ 修正: x_est+=K×(z−x_pred); p_est=(1-K)×p_pred │ 含义: 新测量仅5%权重, 历史估计95%, 高频噪声大幅削弱 │ 状态: kf->x_est 更新, kf->p_est 更新 (3轴独立) │ 数据: ω_clean → [Kalman] → fx (滤波后角速度 °/s) │ ▼ Step 4: 矩形积分 — 角速度 → 角度 (▲ mutex lock 开始) │ │ d_pitch=fx×0.001s; total.pitch+=d_pitch (累加) │ dt=1ms 时矩形积分误差可忽略 │ 状态: angle_state.total.{pitch,roll,yaw}_deg 累加 │ 数据: fx → [integral×dt] → d_pitch → [累加] → total_angle │ ▼ Step 5: lpf_1d_update() — 有意运动分离 τ=0.5s, α≈0.002 │ │ intentional(k)=α×total(k)+(1−α)×intentional(k−1) │ jitter=total−intentional │ │ 频率判定 (fc≈0.32Hz): │ 0.1 Hz — 缓慢 pan → 有意运动 (不补偿) │ 2-8 Hz — 手持微抖 → 抖动 (完全补偿) │ >15 Hz — 传感器噪声 → 卡尔曼已滤除 │ │ 三态关系 (恒定+1°/s, Pitch): │ t=100ms: total=0.1° intent≈0.0002° jitter≈0.1° │ t=500ms: total=0.5° intent≈0.005° jitter≈0.495° │ 5Hz抖动手: total≈0, intent≈0, jitter≈0 (LPF滤除) │ │ 状态: intentional/jitter 更新 │ 数据: total_angle → [LPF] → {intentional, jitter} │ ▼ Step 6: 像素映射 + 裁切限幅 — 补偿输出 (▲ mutex unlock) │ │ shift_x_degree=−jitter_yaw×1.0 (反向补偿) │ shift_y_degree=−jitter_pitch×1.0 │ shift_x_pixel=shift_x_degree/fov_h×img_w clamp(±margin_x) │ 例: jitter_yaw=0.5°, fov=90°, w=2560 → shift_x≈14 px │ │ 状态: last_comp 全部字段写入 (timestamp, valid=TRUE) │ ▼ 输出: eis_compensation {shift_x_pixel, shift_y_pixel, valid, timestamp} ═══════════════════════════════════════════════════════════════════════════3.2 I2C 通信 — GPIO 模拟时序
一次 14字节突发读取 (设备 0x68, 起始寄存器 0x3B, ~100kHz): START → ADDR 0xD0(W) 等ACK → REG 0x3B 等ACK → RESTART → ADDR 0xD1(R) 等ACK → 读14字节(前13字节ACK,末字节NACK) → STOP 总耗时 ≈ 795μs (@100kHz I2C) SDA 开漏模拟: 输出0: DATA&=~(1<<5) → DIR|=(1<<5) 先写0再切输出→拉低 输出1: DIR&=~(1<<5) 切输入→内部上拉~50kΩ拉高 读取: DIR&=~(1<<5) → return (DATA>>5)&1 输入模式读pin GPIO 寄存器映射: IOCFG SDA: 0x11130000 → GPIO1_5 配置为 GPIO 模式 + 上拉 IOCFG SCL: 0x11130004 → GPIO1_4 配置为 GPIO 模式 + 上拉 GPIO1 DATA: 0x11091000 (word[0]=数据, word[256]=方向)3.3 MPU6500 初始化 — 寄存器配置状态机
mpu6500_init() 逐级上电 [mpu6500_i2c.c:743] [未知] → gpio_i2c_init() → [/dev/mem mmap IOCFG + GPIO1 + 总线IDLE] → PWR_MGMT_1←0x80+100ms → [复位完成, MEMS起振] → PWR_MGMT_1←0x01+10ms → [唤醒, PLL锁定, PWR_MGMT_2←0x00全轴使能] → WHO_AM_I→0x70 → [I2C通信验证OK] → GYRO_CONFIG←0x10 → [陀螺仪 ±1000°/s, sensitivity=32.8 LSB/(°/s)] → ACCEL_CONFIG←0x08 → [加表 ±4g, sensitivity=8192 LSB/g] → CONFIG←0x02 → [DLPF 98Hz, 2.8ms延迟 — 防抖第0级硬件滤波] → SMPLRT_DIV←0 → [ODR=1000Hz, sample_dt=1ms] → INT_ENABLE←0x01 → [数据就绪中断使能] → initialized=TRUE ★ 设备进入运行状态3.4 GOP/RC 模式选择 — 用户交互分支
sample_venc_normal_start_encode() [myvenc_eis.c:564] get_gop_mode(): '0'=NormalP | '1'=DualP | '2'=SmartP get_rc_mode(): 'c'=CBR | 'v'=VBR | 'b'=ABR | 'a'=AVBR | 'x'=CVBR | 'q'=QVBR | 'f'=FIXQP sample_venc_set_video_param(): chn0 H.265: frame_rate=30, gop=30, stats_time=2 chn1 H.264: frame_rate=30, gop=15, stats_time=24. 维度3: 数据流全貌
4.1 防抖数据形态转换链 (MEMS → 像素)
┌──────────────────────────────────────────────────────────────────────────┐ │ 层级 载体 格式 吞吐/频率 │ ├──────────────────────────────────────────────────────────────────────────┤ │ L0: MEMS 物理角速度信号 模拟电压 内部8kHz采样 │ │ │ + DLPF 硬件低通 (98Hz) │ │ L1: I2C buf[0..13] 14字节 大端序16-bit 0.8ms/次 @100kHz │ │ │ 寄存器 0x43-0x48 = GYRO_X/Y/Z[15:0] │ │ L2: Raw mpu6500_raw_data td_s16×7 1000 Hz │ │ │ {ax,ay,az,temp,gx,gy,gz} 例: gx=0xF830=-2000 LSB │ │ L3: Phy mpu6500_phy_data td_float °/s 1000 Hz │ │ │ gx_dps = raw.gx / 32.8 例: -2000/32.8=-60.9 °/s │ │ L4: filt fx, fy, fz td_float °/s 1000 Hz │ │ │ Kalman 滤波后角速度 例: -60.9→≈-58.2 │ │ L5: angle d_pitch = fx × 0.001 td_float 度 1000 Hz │ │ │ total.pitch += d_pitch 例: d=0.0582°, 累加 │ │ L6: sep {total, intentional, jitter} td_float 度 1000 Hz │ │ │ jitter = total−intentional 角度三态 │ │ L7: px eis_compensation td_s32 像素 30 fps (读出) │ │ │ shift_px=jitter/fov×img 例: 0.5°/90°×2560≈14 px │ │ │ clamp(shift_px, ±margin) │ └────────┴───────────────────────────────────────────────────────────────┘4.2 视频数据流 (硬件管线)
SENSOR (MIPI CSI-2) │ Bayer RAW 10b, 2560×1440@30fps, ~138 MB/s ▼ VI pipe0 (ISP: AE/AWB/AF/NR, RAW→YUV NV12, Online 模式) │ YUV420SP, ~165 MB/s ▼ VPSS grp0 (online_wrap 零拷贝, early_line=height/2 帧中断) │ ├─ chn0: 2560×1440 NV12 (SEG_COMPACT) → VENC chn0: H.265, GOP=30 │ ★ EIS 补偿在此注入 (crop offset) H.265 bitstream ~1.5 MB/s │ └─ chn1: 1920×1080 NV12 → VENC chn1: H.264, GOP=15 (chn1 low_delay: 200行, ~6.6ms) H.264 bitstream ~1.5 MB/s │ sample_comm_get_stream_from_one_channl() │ ┌─────────────────────┴───────────────────┐ RTSP推流 本地存储 rtsp_tx_video() → rtp_tx_data() fwrite(.h264/.h265) TCP send() → VLC 客户端4.3 关键吞吐特征
| 环节 | 数据格式 | 单次量 | 频率 | 带宽 |
|---|---|---|---|---|
| MIPI CSI-2 | Bayer RAW 10b | 4.6 MB/frame | 30 fps | ~138 MB/s |
| VI→VPSS | YUV420SP NV12 | 5.5 MB/frame | 30 fps | ~165 MB/s |
| VPSS→VENC chn0 | NV12 SEG_COMPACT | ~3.7 MB/frame | 30 fps | ~110 MB/s |
| VPSS→VENC chn1 | NV12 1080P | ~3.1 MB/frame | 30 fps | ~93 MB/s |
| VENC→RTSP | H.265/H.264 | ~50 KB/frame | 30 fps | ~1.5 MB/s |
| MPU6500 I2C | 14 bytes raw | 14 B/次 | 1000 Hz | ~14 KB/s |
| EIS 补偿 | eis_compensation | 40 B | 30 fps | ~1.2 KB/s |
5. 维度4: 配置链
5.1 配置参数全景图
════════════════════════════════════════════════════════════════════════════ 【编译期常量】— 宏定义, 编译后固定 ────────────────────────────────────────────────────────────────────────── 常量 值 作用域 ────────────────────────────────────────────────────────────────────────── BIG_STREAM_SIZE PIC_2560X1440 主码流分辨率 SMALL_STREAM_SIZE PIC_1080P 子码流分辨率 GYRO_SAMPLE_HZ 1000 陀螺仪采样频率 KALMAN_Q 0.001 卡尔曼过程噪声 KALMAN_R 0.15 卡尔曼观测噪声 LPF_TAU_SEC 0.5 有意运动 LPF 时间常数 LENS_FOV_H_DEG 90.0 水平视场角 LENS_FOV_V_DEG 55.0 垂直视场角 MPU6500_GYRO_STATIC_THRESH 0.5 °/s 死区阈值 (防零漂) MPU6500_GYRO_MAX_VALID 300 °/s 限幅上限 (防冲击) MPU6500_I2C_ADDR 0x68 I2C 地址 GPIO1_BASE_ADDR 0x11091000 PL061 基址 IOCFG_SDA_ADDR 0x11130000 SDA 引脚复用 IOCFG_SCL_ADDR 0x11130004 SCL 引脚复用 I2C_HALF_PERIOD_US 5 μs I2C 半周期 → 100kHz I2C_RESET_DELAY_MS 100 ms 复位稳定时间 I2C_PLL_DELAY_MS 10 ms PLL 锁定时间 ════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════ 【运行时初始化参数】— main() 传入函数, 写入 ctx/dev ────────────────────────────────────────────────────────────────────────── 传递函数 目标字段 硬件寄存器 ────────────────────────────────────────────────────────────────────────── mpu6500_init() 实参: MPU6500_GYRO_FS_1000 → dev->gyro_fs GYRO_CONFIG[4:3] → gyro_sensitivity=32.8 MPU6500_ACCEL_FS_4G → dev->accel_fs ACCEL_CONFIG[4:3] → accel_sensitivity=8192 MPU6500_DLPF_98HZ → dev->dlpf_cfg CONFIG[2:0] GYRO_SMPLRT_DIV=0 → dev->smplrt_div SMPLRT_DIV → ODR=1000/(1+0)=1kHz eis_init() 实参 [myvenc_eis.c:279]: LENS_FOV_H_DEG=90 → ctx->fov_h_deg — LENS_FOV_V_DEG=55 → ctx->fov_v_deg — 2560, 1440 → ctx->image_w/h — KALMAN_Q=0.001 → ctx->kalman_q → kf->q KALMAN_R=0.15 → ctx->kalman_r → kf->r LPF_TAU_SEC=0.5 → ctx->lpf_tau_sec → α=dt/(dt+τ) GYRO_SAMPLE_HZ=1000 → ctx->sample_dt=0.001 → 积分步长 sample_venc_set_video_param() [myvenc_eis.c:503]: chn0: frame_rate=30, gop=30, H.265 → VENC chn0 参数 chn1: frame_rate=30, gop=15, H.264 → VENC chn1 参数 rc_mode (用户选择: CBR/VBR/...) → VENC RC 参数 gop_mode (用户选择: NormalP/DualP/SmartP) → VENC GOP 参数 ════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════ 【派生计算值】— 运行时从上述参数衍生, 每次调用时引用 ────────────────────────────────────────────────────────────────────────── 派生值 公式 使用者 ────────────────────────────────────────────────────────────────────────── ctx->sample_dt=0.001s 1.0/1000 eis_process_sample:积分Δt lpf_alpha≈0.002 0.001/(0.001+0.5) lpf_1d_update: 有意运动α ctx->margin_x=256 image_width/10 像素补偿 clamp 上限 ctx->margin_y=144 image_height/10 像素补偿 clamp 上限 ctx->stab_strength=1.0 硬编码 补偿强度缩放 gyro_sensitivity=32.8 查表 {FS→LSB/(°/s)} 物理量换算: raw/LSB→°/s ════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════ 【运行时硬编码】— 代码中直接写死 ────────────────────────────────────────────────────────────────────────── 位置 值 含义 ────────────────────────────────────────────────────────────────────────── sched_param.sched_priority 50 采集线程实时优先级 create_rtsp_demo(8554) 8554 RTSP 服务端口 wait loop cnt 50×100ms=5s 等待 VLC 连入 early_line height/2 帧中断提前行数 g_delay_loops 400 I2C 半周期 ~5μs@1GHz ════════════════════════════════════════════════════════════════════════════5.2 配置生效时序
时间 ──────────────────────────────────────────────────────────────────→ [编译期] [初始化期] [运行期] KALMAN_Q=0.001 → ctx->kalman_q ────────→ kf->q (每1ms调用 kalman_1d_update) KALMAN_R=0.15 → ctx->kalman_r ────────→ kf->r LPF_TAU=0.5 → ctx->lpf_tau ────────→ α=dt/(dt+τ) (每1ms) FOV_H/V=90/55 → ctx->fov_h/v ────────→ shift_px = deg/fov×res (每1ms) SAMPLE_HZ=1000 → ctx->sample_dt ────────→ d_pitch = fx×dt (每1ms) STATIC_THRESH [纯常量] ────────→ apply_dead_zone(0.5) (每1ms) MAX_VALID=300 [纯常量] ────────→ clamp_gyro(300) (每1ms) I2C_ADDR=0x68 → dev->i2c_addr ────────→ i2c_transfer_gpio() (每1ms) GYRO_FS=1000 → dev→gyro_fs ────────→ sensitivity=32.8 LSB/(°/s) → GYRO_CONFIG←0x10 DLPF=98Hz → dev→dlpf_cfg ────────→ CONFIG←0x02 → 硬件LPF生效 → CONFIG←0x025.3 调优参数指南
| 参数 | 默认值 | 增大效果 | 减小效果 | 推荐范围 |
|---|---|---|---|---|
KALMAN_Q | 0.001 | 响应更快, 噪声增加 | 更平滑, 跟踪滞后 | 0.0005-0.005 |
KALMAN_R | 0.15 | 更平滑, 变化迟钝 | 更贴近原始, 噪声大 | 0.05-0.5 |
LPF_TAU_SEC | 0.5 | 更多运动判为"有意"(不补) | 更多运动判为"抖动"(补) | 0.2-1.0 |
死区STATIC_THRESH | 0.5°/s | 更多弱信号忽略 | 零漂可能通过 | 0.3-1.0 |
限幅MAX_VALID | 300°/s | 容忍更剧烈 | 更保守 | 200-500 |
stab_strength | 1.0 | — | 减弱稳像效果 | 0.8-1.0 |
附录: 源码文件索引
| 文件 | 关键函数/结构体 | 行号 |
|---|---|---|
| myvenc_eis.c | main()— 总入口 | 957 |
start_gyro_eis()— EIS 子系统启动 | 253 | |
gyro_eis_thread()— 1kHz 采集循环 | 163 | |
stop_gyro_eis()— EIS 子系统停止 | 310 | |
sample_venc_normal()— 视频管线主流程 | 900 | |
sample_venc_online_wrap_start_sys_vi_vpss()— SYS/VI/VPSS启动 | 830 | |
sample_venc_online_wrap_start_vpss()— VPSS low_delay | 785 | |
sample_venc_normal_start_encode()— 编码器启动+GOP/RC选择 | 564 | |
sample_venc_set_video_param()— 编码参数设置 | 503 | |
| mpu6500_eis.c | eis_init()— EIS 配置入口, 参数写入 ctx | 292 |
eis_process_sample()— 6步滤波流水线 | 467 | |
eis_get_compensation()— 线程安全读取补偿值 | 686 | |
eis_reset()— 滤波器状态重置 | 712 | |
kalman_1d_init()/update()— 卡尔曼滤波 | 95 / 131 | |
lpf_1d_init()/update()— 有意运动 LPF | 162 / 184 | |
clamp_gyro()— 限幅上限判定 | 253 | |
apply_dead_zone()— 死区下限判定 | 231 | |
| mpu6500_eis.h | kalman_1d— 单轴卡尔曼结构体 | 186 |
lpf_1d— 单轴 LPF 结构体 | 232 | |
eis_angle_state— 三态角度 (total/intentional/jitter) | 282 | |
eis_compensation— 补偿输出 (像素+角度) | 310 | |
eis_context— 全局上下文 (所有配置+状态+锁) | 338 | |
| API 声明 — eis_init/deinit/process_sample/get_compensation/reset | 440-502 | |
| mpu6500_i2c.c | mpu6500_init()— 硬件初始化 (11步寄存器链) | 743 |
gpio_i2c_init()— GPIO 映射 + 引脚复用 | 564 | |
mpu6500_read_raw()— 14字节突发读取 | 916 | |
mpu6500_convert_to_phy()— 原始值→物理量 | 955 | |
mpu6500_read_phy()— 组合接口 (raw+convert) | 970 | |
i2c_transfer_gpio()— 组合读写传输 | 446 | |
i2c_write_byte()/i2c_read_byte()— 单字节收发 | 348 / 398 | |
sda_high()/sda_low()/sda_read()— GPIO开漏模拟 | 143-161 | |
| mpu6500_i2c.h | 寄存器地址宏 (0x19~0x75) | 73-105 |
| GPIO 基地址宏 (IOCFG, GPIO1) | 147-167 | |
mpu6500_gyro_fs_e量程枚举 + sensitivity | 194-199 | |
mpu6500_dlpf_eDLPF 枚举 | 219-227 | |
mpu6500_raw_data/mpu6500_phy_data数据结构 | 246-258 | |
mpu6500_dev设备句柄 | 273-288 |
编程学习
技术分享
实战经验