3. EyeQ软件开发工具链与环境搭建

EyeQ 平台上的软件开发与通用 Linux 或桌面视觉开发有本质区别:EyeQ 是一颗以视觉加速器为核心的 SoC,程序最终运行在资源受限、异构多核的嵌入式环境中,因此工具链被拆分为“主机侧”和“目标侧”两部分。主机侧负责编写、编译、仿真与打包,目标侧负责在真实 EyeQ 芯片或评估板上加载运行。理解这条工具链的边界,是写出第一个 Hello World 视觉程序的前提。

工具链的组成与职责划分

Mobileye 为 EyeQ 提供的开发套件通常包含以下核心组件:

  • Mobileye SDK:提供 EyeQ 专用 API 头文件、静态/动态库、板级支持包(BSP)以及示例工程。SDK 中的视觉原语(如金字塔、光流、角点检测)以库函数形式暴露,开发者无需直接操作加速器寄存器。
  • 交叉编译器:EyeQ 的 CPU 核(如 MIPS 或 ARM 变体,视具体 EyeQ 代次而定)与主机 x86 架构不同,必须使用 SDK 附带的交叉工具链(如 mips-mobileye-linux-gcc 或 aarch64-mobileye-linux-gcc)生成目标可执行文件。
  • 调试工具:包括 GDB 交叉调试器、串口终端(UART)以及 EyeQ 专用的 trace/log 工具。调试通常通过 JTAG 或以太网连接目标板,配合 gdbserver 进行远程断点调试。
  • 仿真环境:Mobileye 提供 EyeQ 仿真器(Emulator/Simulator),允许在主机上运行部分 EyeQ 指令与视觉加速器行为,用于早期算法验证,但仿真结果不能完全替代真实硬件时序。
  • 目标板部署工具:包括镜像烧录工具、文件传输(scp/tftp)以及启动脚本管理。

这些组件的关系可以用下面的信号与数据流图表示:主机侧完成源码到可执行文件的转换,目标侧完成加载与运行,调试通道贯穿两者。

主机侧(Host / x86) 源码编辑 hello_vision.c + SDK 头文件 交叉编译 mips-mobileye-linux-gcc 链接 SDK 库 -lmobileye_vision -lmobileye_os 仿真验证(可选) EyeQ Simulator 功能级验证 生成 hello_vision 可执行文件 目标侧(EyeQ 评估板) 文件传输 scp / tftp 上传可执行文件 加载运行 ./hello_vision 视觉加速器调用 SDK 库 → EyeQ 硬件加速器 输出与日志 UART 串口 / 网络回传 观察 Hello Vision 输出结果 部署传输 GDB 远程调试 主机侧负责构建与仿真,目标侧负责运行与观测,调试通道贯穿两侧

环境搭建的关键步骤

搭建 EyeQ 开发环境的第一步是安装 SDK。以 Linux 主机为例,通常将 SDK 解压到 /opt/mobileye/eyeQ_sdk,然后执行 source setup_env.sh 将交叉编译器路径、库路径和头文件路径写入当前 shell 环境。验证安装是否成功,可以运行 mips-mobileye-linux-gcc --version,若正确输出编译器版本信息,说明工具链已就绪。

第二步是配置目标板连接。EyeQ 评估板一般通过串口提供控制台,通过以太网提供文件传输和调试通道。串口参数常见为 115200-8-N-1,使用 minicom 或 screen /dev/ttyUSB0 115200 即可进入板端 shell。网络方面,需要确保主机与目标板处于同一网段,例如主机 192.168.1.100,目标板 192.168.1.200,然后通过 ping 确认连通性。

第三步是准备一个最小工程目录。建议结构如下:

hello_vision/
├── src/
│   └── hello_vision.c
├── Makefile
└── build/

Makefile 中需要显式指定交叉编译器和 SDK 库路径,例如:

CC = mips-mobileye-linux-gcc
CFLAGS = -I$(EYEQ_SDK)/include -O2 -Wall
LDFLAGS = -L$(EYEQ_SDK)/lib -lmobileye_vision -lmobileye_os
TARGET = hello_vision

all: $(TARGET)

$(TARGET): src/hello_vision.c
	$(CC) $(CFLAGS) -o build/$(TARGET) $< $(LDFLAGS)

clean:
	rm -f build/$(TARGET)

第一个 Hello World 视觉程序

“Hello World 视觉程序”的目标不是打印一行文字,而是完成一次最小可验证的视觉处理链路:从内存中构造一幅测试图像,调用 SDK 的视觉原语做一次简单处理(例如灰度化或高斯模糊),然后输出处理结果的统计信息。这样既能验证工具链、库链接和板端运行是否正常,又能建立对 EyeQ 视觉 API 调用方式的直观认识。

下面是一个合理的示例代码框架(参数为教学示例,非实测结果):

#include <stdio.h>
#include <string.h>
#include "mobileye_vision.h"

#define WIDTH  640
#define HEIGHT 480

int main(void) {
    unsigned char src[WIDTH * HEIGHT];
    unsigned char dst[WIDTH * HEIGHT];

    /* 构造渐变测试图:从左到右亮度递增 */
    for (int y = 0; y < HEIGHT; y++) {
        for (int x = 0; x < WIDTH; x++) {
            src[y * WIDTH + x] = (unsigned char)(x * 255 / WIDTH);
        }
    }

    /* 调用 SDK 高斯模糊,核大小 5x5 */
    mb_vision_blur_gray(src, dst, WIDTH, HEIGHT, 5);

    /* 统计输出:均值与首行首像素 */
    unsigned long sum = 0;
    for (int i = 0; i < WIDTH * HEIGHT; i++) {
        sum += dst[i];
    }
    printf("Hello Vision from EyeQ!\n");
    printf("image: %dx%d, mean=%lu, first_pixel=%u\n",
           WIDTH, HEIGHT, sum / (WIDTH * HEIGHT), dst[0]);
    return 0;
}

编译命令为 make,成功后会在 build/ 下生成 hello_vision。接着用 scp build/hello_vision root@192.168.1.200:/tmp/ 上传到目标板,在板端执行 chmod +x /tmp/hello_vision && /tmp/hello_vision。若串口输出类似 Hello Vision from EyeQ! 以及一行图像统计信息,说明整条链路已经打通。

如果运行时报 error while loading shared libraries: libmobileye_vision.so,说明目标板上缺少 SDK 动态库。可将 SDK 中对应的 .so 文件一并上传到 /usr/lib,或改用静态链接方式编译。

仿真环境与真机验证的差异

EyeQ 仿真器可以在主机上模拟视觉加速器的功能行为,适合在硬件到位前验证算法逻辑。但仿真器通常不模拟真实的内存带宽、DMA 延迟和多核调度,因此仿真通过不代表真机性能达标。合理的做法是:先在仿真环境中确认功能正确,再在评估板上观察实际耗时和资源占用。SDK 一般提供 mb_vision_get_time() 之类的计时接口,可在板端测量单帧处理时间,作为后续优化的基线。

交叉编译时务必确认头文件与目标板上的库版本一致。若主机 SDK 版本高于板端 BSP 版本,可能出现符号未定义或结构体布局不匹配的问题,表现为运行时段错误或输出异常。建议在工程中固定 SDK 版本,并记录到版本说明中。

常见问题与排查思路

现象 可能原因 排查方法
编译报找不到 mobileye_vision.h SDK 头文件路径未加入 CFLAGS 检查 EYEQ_SDK 环境变量与 -I 参数
链接报未定义符号 库顺序或库名错误 确认 -lmobileye_vision 在源文件之后
板端运行提示权限不足 可执行文件无执行权限 执行 chmod +x
输出为空或乱码 串口波特率不匹配 确认 115200-8-N-1 设置

完成第一个 Hello World 视觉程序后,开发者已经具备了三项基础能力:使用交叉工具链构建 EyeQ 可执行文件、通过串口和网络与目标板交互、调用 SDK 视觉原语并观察输出。后续更复杂的视觉流水线,都是在这个最小闭环上逐步叠加模块与优化手段。