在智能硬件、车载终端、工业平板等嵌入式设备中,Android 系统的显示与交互体验直接影响产品竞争力。液晶屏(LCD/MIPI-DSI)、触摸屏(I2C/USB)和摄像头(CSI/USB)的驱动适配是核心环节,涉及硬件接口、内核驱动、HAL 层实现及系统集成。本文将系统梳理三大外设的适配流程,结合代码示例与调试技巧,助力开发者高效完成硬件兼容性开发。
常见接口:
MIPI-DSI:高速串行接口,适用于高分辨率屏(如 1080P/4K),需确认屏参数(时序、分辨率、色深)。
RGB/LVDS:并行接口,需匹配电平标准(如 TTL/LVDS)和时序(HSYNC/VSYNC)。
SPI/I2C:低速接口,仅用于小尺寸屏(如 OLED 字符屏)。
关键参数:在 device tree 中配置 display-timings 节点,示例:
device tree
display-timings
dtsdisplay-timings { native-mode = <&timing0>; timing0: timing { hactive = <1920>; vactive = <1080>; hfront-porch = <88>; hback-porch = <48>; hsync-len = <44>; vfront-porch = <4>; vback-porch = <23>; vsync-len = <5>; clock-frequency = <148500000>; }; };
DRM/KMS 框架:现代 Android 推荐使用 Direct Rendering Manager(DRM)驱动,支持多屏同步与硬件加速。
注册 DRM 设备:在 drivers/gpu/drm/ 下实现 struct drm_driver,绑定到 platform_device。
drivers/gpu/drm/
struct drm_driver
platform_device
实现 Modesetting:通过 drm_mode_create_dumb() 分配帧缓冲区,drm_mode_set_crtc() 配置显示时序。
drm_mode_create_dumb()
drm_mode_set_crtc()
Legacy FrameBuffer:旧设备可能使用 fbdev 框架,需实现 struct fb_ops 中的 fb_check_var()、fb_set_par() 等函数。
fbdev
struct fb_ops
fb_check_var()
fb_set_par()
SurfaceFlinger 服务:在 hardware/libhardware/modules/gralloc/ 中实现 gralloc_module_t,分配 GPU 可访问的内存缓冲区。
hardware/libhardware/modules/gralloc/
gralloc_module_t
HDMI/DP 热插拔:通过 uevent 监听接口状态,动态调整显示配置(如 /sys/class/switch/hdmi/state)。
uevent
/sys/class/switch/hdmi/state
电阻屏:通过 AD 转换 获取坐标,需实现 input_report_abs() 上报 ABS_X/ABS_Y。
AD 转换
input_report_abs()
ABS_X
ABS_Y
电容屏:支持多点触控,需上报 ABS_MT_POSITION_X/ABS_MT_POSITION_Y 及 BTN_TOUCH 事件。
ABS_MT_POSITION_X
ABS_MT_POSITION_Y
BTN_TOUCH
协议支持:
I2C 接口:常见于 FT5x06、GT9xx 等芯片,需实现 i2c_driver 并注册 input_dev。
i2c_driver
input_dev
USB 接口:如 HID 协议设备,直接使用 usbhid 驱动。
usbhid
注册输入设备:
cstruct input_dev *input_dev = input_allocate_device();input_dev->name = "gt9xx_ts";input_dev->id.bustype = BUS_I2C;input_set_abs_params(input_dev, ABS_X, 0, 1080, 0, 0); // X 轴范围input_set_abs_params(input_dev, ABS_Y, 0, 1920, 0, 0); // Y 轴范围input_set_capability(input_dev, EV_KEY, BTN_TOUCH); // 触摸按键input_register_device(input_dev);
中断处理:在 probe() 函数中请求中断(如 request_threaded_irq()),读取触摸数据并上报事件。
probe()
request_threaded_irq()
多点触控协议:确保上报事件符合 A-Touch 或 B-Touch 协议(通过 getevent -l 验证)。
A-Touch
B-Touch
getevent -l
校准工具:使用 tslib 或自定义工具生成校准矩阵,保存至 /etc/pointercal 文件供系统读取。
tslib
/etc/pointercal
CSI 接口:通过 MIPI CSI-2 连接摄像头模组(如 OV5640、IMX335),需配置:
时钟树:在 device tree 中设置 clocks 和 clock-names(如 mclk)。
clocks
clock-names
mclk
电源管理:通过 regulator 框架控制 DVDD/AVDD/DOVDD 供电。
regulator
DVDD
AVDD
DOVDD
USB 摄像头:使用 uvcvideo 驱动,自动识别 UVC 协议设备。
uvcvideo
UVC
注册视频设备:
cstruct video_device *vdev = video_device_alloc();vdev->release = camera_release;vdev->fops = &camera_fops; // 实现 .open/.read/.ioctl 等vdev->ioctl_ops = &v4l2_ctrl_ioctl_ops;video_register_device(vdev, VFL_TYPE_GRABBER, 0); // 注册为 /dev/video0
支持格式与分辨率:在 struct v4l2_fmtdesc 中声明支持的格式(如 V4L2_PIX_FMT_YUYV),并通过 VIDIOC_S_FMT 协商分辨率。
struct v4l2_fmtdesc
V4L2_PIX_FMT_YUYV
VIDIOC_S_FMT
HAL3 接口:实现 camera3_device_ops 中的 initialize()、configure_streams()、process_capture_request() 等函数。
camera3_device_ops
initialize()
configure_streams()
process_capture_request()
元数据处理:填充 camera_metadata_t,设置支持的分辨率、帧率、对焦模式等(通过 camera_metadata_add())。
camera_metadata_t
camera_metadata_add()
调试工具:使用 Camera2 API 测试应用(如 A Better Camera)验证预览、拍照功能。
Camera2 API
A Better Camera
日志分析:
内核日志:dmesg | grep -i "dsi\|touch\|camera"。
dmesg | grep -i "dsi\|touch\|camera"
Android 日志:logcat | grep -E "SurfaceFlinger\|InputReader\|Camera2"。
logcat | grep -E "SurfaceFlinger\|InputReader\|Camera2"
性能优化:
液晶屏:启用 DRM_PANEL_BRIDGE 减少帧缓冲拷贝。
DRM_PANEL_BRIDGE
摄像头:使用 DMA 缓冲区避免 CPU 拷贝(V4L2_MEMORY_DMABUF)。
DMA
CPU
V4L2_MEMORY_DMABUF
兼容性测试:
使用 CTS(Compatibility Test Suite)验证显示、输入、摄像头功能。
CTS
自动化测试工具:Monkey、UiAutomator 模拟用户操作。
Monkey
UiAutomator
Android 驱动开发,液晶屏适配,触摸屏驱动,摄像头 HAL,V4L2,DRM 框架