2、开发环境搭建:SDK包结构解析、交叉编译工具链配置、ADB与串口调试环境搭建

好,咱们正式开始动手了。这一章我带你搭开发环境。说实话,很多新手拿到MTK8676的SDK,第一反应就是懵——文件夹一堆,不知道从哪下手。我当年第一次接触MTK平台时也差不多,对着目录树发呆了半小时。

别急,咱们一步步来。环境搭好了,后面所有实验才能跑起来。这就像盖房子打地基,马虎不得。

2.1 SDK包结构解析

先看看MTK8676的SDK长什么样。你解压之后,会看到一个类似这样的目录结构:

mtk8676_sdk/
├── bootloader/          # 启动引导代码
├── kernel/              # Linux内核源码
├── vendor/              # 供应商相关代码
├── hardware/            # 硬件抽象层
├── packages/            # 应用包
├── out/                 # 编译输出目录
├── build/               # 编译脚本
├── prebuilts/           # 预编译工具链
├── device/              # 设备配置
├── external/            # 第三方库
└── Makefile             # 顶层Makefile

嗯,这里要注意。MTK的SDK和AOSP(Android Open Source Project)结构很像,但多了不少MTK自家的东西。我个人习惯先看device/目录,因为这里面定义了板级配置。

核心目录说明:

  • bootloader/:负责硬件初始化,引导内核启动。我曾在项目中遇到过bootloader里CAN控制器初始化时序不对,导致内核起来后CAN模块死活不工作。排查了两天才找到问题。
  • kernel/:Linux内核,包含CAN驱动(SocketCAN)、SPI、I2C等总线驱动。
  • vendor/mediatek/:MTK的私有实现,CAN协议栈的移植主要在这里改。
  • hardware/:硬件抽象层,CAN HAL接口定义在这里。
  • out/:编译产物,生成的镜像、ko模块都在这里。

你想想看,整个SDK大概有几十个G。但咱们做CAN总线移植,真正要关心的其实就几个目录。别被吓到。

2.2 交叉编译工具链配置

交叉编译,说白了就是在PC上编译出能在ARM芯片上跑的程序。MTK8676用的是ARM Cortex-A系列内核,所以工具链得选对。

MTK SDK里自带了预编译好的工具链,在prebuilts/gcc/linux-x86/aarch64/目录下。但我建议你手动配一下环境变量,这样更可控。

2.2.1 设置环境变量

打开终端,执行:

export PATH=$PATH:~/mtk8676_sdk/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin
export CROSS_COMPILE=aarch64-linux-android-
export ARCH=arm64

为什么要设CROSS_COMPILE?因为Makefile里编译内核和驱动时,会调用$(CROSS_COMPILE)gcc。你不设这个变量,它就会用PC本地的gcc,编译出来的东西在ARM上跑不了。

小技巧:我个人习惯把这几个export写到~/.bashrc里,这样每次打开终端就不用重新设了。但如果你同时做多个平台的项目,建议用source脚本的方式,避免冲突。

2.2.2 验证工具链

配好了,验证一下:

aarch64-linux-android-gcc --version

如果看到版本信息,说明工具链能用。我曾经遇到一个坑——下载的SDK里工具链权限不对,执行时提示"Permission denied"。当时我还以为是环境变量没配好,折腾了半天才发现是文件没加执行权限。嗯,chmod +x一下就好了。

2.2.3 编译第一个测试程序

写一个简单的CAN测试程序,验证工具链是否正常工作:

// can_test.c
#include <stdio.h>
#include <linux/can.h>
#include <linux/can/raw.h>

int main() {
    printf("CAN Socket Test on MTK8676\n");
    printf("CAN_MAX_DLEN: %d\n", CAN_MAX_DLEN);
    return 0;
}

编译命令:

aarch64-linux-android-gcc -o can_test can_test.c
file can_test

看到输出是"ELF 64-bit LSB executable, ARM aarch64",就说明编译成功了。

2.3 ADB调试环境搭建

ADB(Android Debug Bridge)是咱们和车机通信的主要手段。MTK8676跑的是Android系统,所以ADB是标配。

2.3.1 安装ADB

PC端安装ADB很简单:

sudo apt-get install adb

或者从SDK的prebuilts/misc/目录下拿MTK定制的ADB版本。我建议用SDK自带的,因为MTK有时会加一些私有协议。

2.3.2 连接车机

用USB线连接开发板和PC。执行:

adb devices

如果看到设备号,说明连接成功。如果显示"unauthorized",检查一下开发板上的USB调试授权。

注意:有些车机的USB口是OTG模式,需要先切换到Host模式才能连ADB。我在某款车型上就遇到过这个问题——插上USB没反应,后来发现是硬件上有个GPIO要拉高才能切到Host模式。嗯,这种问题硬件工程师最清楚,多和他们沟通。

2.3.3 常用ADB命令

做CAN开发时,我常用的ADB命令:

命令 用途
adb shell 进入车机终端
adb push 把PC文件传到车机
adb pull 从车机拉文件到PC
adb logcat 查看系统日志
adb reboot 重启车机

你想想看,调试CAN协议栈时,最常用的就是adb logcatadb shell。一个看日志,一个敲命令。

2.4 串口调试环境搭建

ADB虽然方便,但有个致命问题——如果内核还没起来,或者USB驱动没加载,ADB就用不了。这时候串口就是救命稻草。

MTK8676通常有2-3个UART口。其中一个用作调试串口(一般是UART0),波特率通常是115200或921600。

2.4.1 硬件连接

你需要一个USB转串口工具(比如FT232、CP2102)。连接方式:

  • 开发板的TX接USB转串口的RX
  • 开发板的RX接USB转串口的TX
  • GND接GND

注意,MTK8676的UART电平是1.8V还是3.3V?这个得看硬件原理图。我曾经因为电平不匹配,烧坏过一个串口芯片。嗯,从那以后我每次都会先确认电平。

2.4.2 软件配置

PC端用minicom或screen:

sudo apt-get install minicom
minicom -D /dev/ttyUSB0 -b 115200

或者用screen:

sudo screen /dev/ttyUSB0 115200

我个人更喜欢screen,因为它可以滚动查看历史输出。退出时按Ctrl+A然后按K

2.4.3 验证串口

连接好后,给开发板上电。如果看到类似下面的输出,说明串口通了:

U-Boot 2020.01 (Jan 10 2024 - 15:30:00 +0800)
CPU: MT8676
DRAM:  4 GiB
MMC:   mmc@11230000: 0
...

如果没输出,检查一下:

  • TX/RX有没有接反?
  • 波特率对不对?
  • 串口工具有没有权限?sudo chmod 666 /dev/ttyUSB0

经验之谈:串口调试时,我习惯同时开两个终端——一个用ADB看Android日志,一个用串口看内核日志。这样能同时看到应用层和内核层的输出,定位问题快很多。

2.5 环境验证:跑一个CAN测试

环境都搭好了,咱们验证一下。通过ADB或串口进入车机终端,执行:

# 加载CAN驱动
insmod /vendor/lib/modules/can.ko
insmod /vendor/lib/modules/can_raw.ko

# 查看CAN设备
ip link show

# 配置CAN接口
ip link set can0 type can bitrate 500000
ip link set can0 up

# 发送测试数据
cansend can0 123#DEADBEEF

如果看到"send: Success",说明CAN驱动和工具链都正常工作。如果报错,别慌——大概率是驱动没加载对,或者设备树里CAN节点没配好。这些咱们后面章节会详细讲。

好,环境搭建就到这里。下一章咱们开始真正动刀——移植CAN协议栈。到时候你会看到,今天搭的环境有多重要。