SDK快速开发指南¶
本文基于COMAKE PI D3开发板,主要介绍D3开发板接口和描述SDK的基本使用方法,旨在帮助您快速上手D3开发板和熟悉SGS SDK开发包。
1. 系统介绍¶
- 主芯片SCM8003G采用六核ARM Cortex-A55,主频最高1.8GHz;
- VDD_CPU电压:默认1.0V,软件设定可以随频率调压;
- VDD_IPU电压:默认1.0V,软件设定可以随频率调压;
- VDD_Core电压:默认1.0V,软件设定可以随频率调压;
- DVDD_DDR电压:默认1.0V,不可调;
- DRAM电压:LPDDR4X-1.8V、1.1V、0.6V;
- IO电压:1.8V/3.3V;
- 核心板板载外置32bit 32Gbit LPDDR4X-3200Mbps;
- 核心板板载1.8V_EMMC容量:64GB;
- 支持5英寸MIPI Panel(接口最大Max 2560*1600@60fps);
- 具备3个USB2.0,1个USB3.0(USB2.0_P0和P1只支持Host mode);
- 具备2个RGMII接口,核心板和底板各搭载1个GPHY,支持1000M/100M/10M自适应;
- 具备2个SATA接口,支持1.5/3/6Gbps,1个SATA连接器,1个mSATA连接器;
- 具备2个PCIe gen2*2接口,1个PCIe-64p连接器,1个M.2 B-key连接器;
- 具备HDMI-TX接口,支持v1.4b,最大3840*2160@30fps;
- 支持2路AMIC差分输入;
- 支持4x2DMIC输入;
- 支持Lineout单端双声道输出;
- 电源输入:12V 3A;
- 核心板正常工作温度范围:-20℃~+70℃;
1.1 开发板信息¶
底板正反面:
主板正反面:
| 组件编号 | 组件 | 描述 |
|---|---|---|
| J1 | RTC PWR | RTC电池插针 |
| J2 | SODIMM CON | SODIMM连接器 |
| J4 | mSTATA | mSATA接口,支持mSATA硬盘 |
| J7 | SATA PWR | SATA硬盘电源接口 |
| J13 | FAN CON | 风扇接口,可用PWM控制风扇,默认5V,可选12V |
| JP1 | 40P Expansion Header | 40pin插针 |
| JP2 | 30P Expansion Header | 30pin插针 |
| JPF6 | USB BOOT | 进入USB boot启动方式的插针,插入跳帽后,改为USB启动 |
| JPF8 | USB3.0 PWR | CONU8中USB3.0 VBUS供电插针,配置为HOST给Device供电时,需插跳帽 |
| JPF9 | USB2.0 PWR | CONU8中USB2.0 VBUS供电插针,配置为HOST给Device供电时,需插跳帽 |
| JPO1 | DBG | Debug串口,默认波特率为1500000,烧录UBoot后,波特率为115200。 也能切换到I2C mode,使用Sgs ISP Tool升级uboot,读取寄存器信息 |
| JZ2 | DMIC | 4ch DMIC接口,最多支持8颗DMIC |
| JW1 | IPEX | Wifi天线的IPEX座子 |
| SDC2 | TF Socket | TF卡座 |
| CN1 | M.2 B-KEY 2230 | M.2 B-Key座子,包含PCIe2.0*2支持Nvme SSD 2230硬盘和一对USB2.0支持4G模块EM05-CN |
| CN4 | NANO-SIM CON | SIM卡座子,配合M.2的4G模块使用 |
| UW2 | USB-Wifi | 预留USB Wifi模组,接SSW105AT,USB P0默认做Type-A |
| CON4 | SPK_L | 左声道喇叭接口,预留AEC电路拉回MIC0,用作硬件AEC |
| CON8 | MIPI Panel | MIPI-TX接口,用于接MIPI屏,MIPI屏为FPC上接,注意不要接反 |
| CON9 | TP CON | 触摸接口,默认为左侧线序,默认带的为异面FPC排线。 靠近屏幕侧为FPC下接,靠近主板侧为FPC上接,注意不要接反 |
| CON10 | SPK_R | 右声道喇叭接口,预留AEC电路拉回MIC1,用作硬件AEC |
| CON11 | USB2.0*2 | 双层USB2.0接口,分别为USB P0/P1,只能做Host,上层为P0,下层为P1 |
| CON23 | MIC0 | 默认接麦克风,接Line In需要修改板子上分压电阻 |
| CON24 | MIC1 | 默认接麦克风,接Line In需要修改板子上分压电阻 |
| CONP2 | PCIE CON | PCIe连接器,规格为gen2*2 |
| CONS4 | SATA | SATA接口,支持SATA gen3 |
| CONG1 | RJ45 GE0 | 千兆网口座子,内置网络变压器 |
| CONG2 | RJ45 GE1 | 千兆网口座子,内置网络变压器 |
| CONH1 | HDMI | HDMI-TX接口 |
| CONU8 | USB2.0+USB3.0 | 双层USB3.0+USB2.0接口,上层为USB2.0,下层为USB3.0 |
| CONV1 | DC 12V | DC 12电源输入接口 |
1.2 串口¶
电源:DC 12V;调试串口:TTL电平,比特率115200
连接方式:
将Sgs Debug Tool小板Type-A USB口连接至Windows,另一端连接至D3 Debug UART口,连接方式如图1-1所示。
图1-1 D3板Uart Debug连接图示
2. 环境搭建¶
2.1. 开发环境概述¶
开发环境通常包括 Linux服务器、Windows工作台 和 D3开发板,三者处于同一个网络中,如图 2-1 所示。
开发环境说明:
- 目标板 上的Bootloader(IPL+U-Boot)启动后,目标板中的操作信息通过串口输出到宿主机上显示
- 在 宿主机 上的控制台中输入命令,可以控制目标机
- 在 Linux服务器 上建立交叉编译环境,用于程序开发
- Windows工作台 通过串口与Comake PI D3板连接,用于程序开发和调试
图 2-1 嵌入式开发环境图示
表 2-1 开发环境软件描述
| 操作平台 | 操作系统 | 软件描述 |
|---|---|---|
| Windows工作台 | Windows XP/7/10 | putty(或Xshell/SecureCRT等)、tftp服务器(tftpd32)、SGS ISP工具(Flash_Tool_xxx.exe) |
| Linux服务器 | Ubuntu或CentOS(建议Ubuntu 24.04) | NFS、telnetd、samba、vim、ARM交叉编译环境等 |
| Comake PI D3开发板 | SGS Linux | Linux内核基于6.1.111版本移植,根文件系统基于busybox 1.33.0版本制作 |
2.2. 服务器环境搭建¶
2.2.1. 服务器硬件要求¶
推荐使用64位Linux服务器,具体配置如下:
- CPU:Intel(R) Xeon(R) CPU E5-2450 0 @ 2.10GHz 或更优
- 内存:>= 16GB
- 硬盘:>= 600GB
- 网络:千兆以太网
- 操作系统:Ubuntu 22.04 64bit
或使用相同配置的虚拟机。
已验证的系统:
| 服务器发行版本 | Docker 版本 | 镜像加载 | 编译 |
|---|---|---|---|
| Ubuntu 24.04 | 20.10.21 | pass | pass |
2.2.2. 软件包安装¶
Docker 环境准备
Step 1:安装依赖软件包
执行以下命令安装 qemu-user-static、binfmt-support、docker.io,以提供跨架构运行能力和容器运行环境:
sudo apt-get update && sudo apt-get install -y qemu-user-static binfmt-support docker.io
Step 2:验证 aarch64 跨架构支持
安装完成后,执行以下命令验证 aarch64 跨架构支持是否已启用:
update-binfmts --display | grep "aarch64"
预期输出:
qemu-aarch64 (enabled):
interpreter = /usr/libexec/qemu-binfmt/aarch64-binfmt-P
若未启用,执行:
sudo update-binfmts --enable
Step 3:配置 Docker 用户权限(root用户可跳过)
将当前用户加入 docker 用户组,避免每次执行 docker 命令都需要 sudo:
sudo usermod -aG docker $USER
注意:执行上述命令后,需重新登录或执行
newgrp docker使配置生效。
软件包下载
Step 1:获取 Git 下载凭证
在 Comake 社区注册账号后,访问 Comake 用户中心,记录以下信息以便进行 Git 认证:
-
邮箱:注册 Comake 账号时用到的邮箱

-
Token:在 “HTTP 凭据” 界面点击 “获取下载凭证” 按钮生成

Step 2:配置 Git 环境
-
将 Git 下载凭证写入本地
.netrc文件(让 Git 自动使用凭据进行认证,无需每次手动输入用户名和密码):echo "machine git.sigmastar.com.cn login <邮箱> password <Token>" >> ~/.netrc chmod 600 ~/.netrc -
安装
repo多仓库管理工具(下载脚本会通过它拉取 SDK 源码):sudo wget https://mirrors.tuna.tsinghua.edu.cn/git/git-repo -O /usr/bin/repo sudo chmod a+x /usr/bin/repo
Step 3:下载脚本和软件包
-
下载脚本:
git clone https://git.sigmastar.com.cn:9090/sigmastar/download_scripts.git其中
D3_linux_setup.sh为 linux 软件包一键下载脚本,docker_versions.yaml为相关版本信息。 -
进入 download_scripts 目录,执行脚本,一键下载全部资源(包含 Docker 镜像、SDK 源码、SDK 工具集、算法模型等):
bash D3_linux_setup.sh allD3_linux_setup.sh使用说明:命令 说明 bash D3_linux_setup.sh all一键下载最新版本全部资源 bash D3_linux_setup.sh all <version>一键下载指定版本全部资源 bash D3_linux_setup.sh docker下载最新版本 Docker 镜像 bash D3_linux_setup.sh docker <version>下载指定版本 Docker 镜像 bash D3_linux_setup.sh sdk_toolchains下载交叉编译工具链 bash D3_linux_setup.sh sdk下载最新版本 SDK 源码 bash D3_linux_setup.sh sdk <version>下载指定版本 SDK 源码 bash D3_linux_setup.sh image下载最新版本 烧录固件 bash D3_linux_setup.sh image <version>下载指定版本 烧录固件 bash D3_linux_setup.sh tools下载全部工具 bash D3_linux_setup.sh tools <tool_name>下载单个工具 bash D3_linux_setup.sh model_zoo下载最新版本算法模型库 bash D3_linux_setup.sh model_zoo <version>下载指定版本算法模型库 bash D3_linux_setup.sh docs下载最新版本文档 bash D3_linux_setup.sh docs <version>下载指定版本文档 bash D3_linux_setup.sh hw_ref_design下载硬件参考设计资料 bash D3_linux_setup.sh list_version查看可用版本号 bash D3_linux_setup.sh list_tools查看可用工具列表 bash D3_linux_setup.sh build_image编译最新版本系统镜像 bash D3_linux_setup.sh build_image <version>编译指定版本系统镜像
2.2.3. 系统配置¶
1. 设置默认shell为bash
编译脚本默认使用bash,要求系统的默认shell为bash:
2. 设置默认awk实现
编译脚本默认使用awk/gawk:
# 确认awk版本
awk --version
# 安装gawk(如需要)
sudo apt-get install gawk
# 配置默认awk为gawk
sudo update-alternatives --config awk
# 选择 gawk
3. 编译说明/SDK使用指南¶
3.1. SDK介绍¶
3.1.1. SDK整体架构¶
SGS SDK架构从上到下分为应用层,软件库层,驱动层以及硬件层。
- 应用层:即用户开发的Linux 应用程序,运行在Linux用户态;
- MI 用户接口层:MI SDK在用户态的接口,应用程序通过该层访问到MI Driver,从而操作硬件;
- 驱动层:MI 驱动的具体实现;
- 硬件层:Sgs平台的硬件。
设计特点:
- MI 用户接口以lib库形式提供;
- SDK功能代码在驱动层实现,提高执行效率,以ko(内核模块)形式提供;
- 用户层APP直接调用MI接口即可使用对应功能。
图 3-1 SDK软件架构
3.1.2. SDK目录结构¶
SDK目录结构
| 目录 | 说明 |
|---|---|
| boot | U-Boot 引导加载程序。基于 U-Boot 定制的二级引导加载器,负责硬件初始化、内核加载及启动镜像签名/烧录。 |
| kernel | Linux 内核。适配 SGS SoC 的 Linux 内核源码,包含厂商专用驱动,客户可在其中定制内核配置和设备树。 |
| sdk | 核心媒体/平台 SDK。包含所有媒体处理模块(视频编解码、ISP、显示、音频 等)的内核驱动、用户态库、HAL 实现及示例/演示应用。是客户集成应用和定制媒体管线的主要工作目录。 |
| project | 编译环境与工程入口。整个 SDK 的编译环境目录,包含顶层 Makefile、板级配置(board/)、镜像打包脚本(image/)、内核/SDK 编译集成(kbuild/)、发布输出(release/)及各类主机端工具(tools/)。客户通过该目录下的 Makefile 和 defconfig 完成整个工程的配置与编译。 |
| optee | OP-TEE 安全执行环境。包含可信 OS(optee_os)、客户端库(optee_client)、示例可信应用(optee_examples)及测试套件(optee_test),用于 DRM、安全存储、密码学等安全场景。 |
3.1.3. SDK Tools工具集¶
SDK提供了丰富的开发工具,位于 SDK/Tools/ 目录下,这些工具可以帮助开发者提高开发效率。
| 工具 | 简介 |
|---|---|
| BWLATool | 带宽延迟分析工具,实时监测 DDR 带宽并配置各 IP 的 QoS 参数,支持多 IP 数据对比 |
| CalibrationTool | DDR 内存校准工具,用于校准 DRAM 时序参数并生成优化后的 MIU 初始化脚本 |
| FlashTool | 串口烧录工具,通过 UART 将固件写入板载 Flash 存储 |
| GenScalerTbl | SCL 滤波器系数生成工具,用于生成自定义图像缩放插值系数表,优化缩放画质 |
| IQTool | 图片质量调试工具,用于 ISP 图像质量的调校和验证 |
| MakeBin | 母片制作工具,支持 SPINAND/SPINOR/eMMC 三种存储介质的量产母片制作 |
| PQTool | 画质调试工具,在线调节 Gamma、CSC、锐度、色彩等显示参数,实时预览画面效果 |
| sgs_comake_tools | 环境搭建工具,用于构建根文件系统和镜像 |
| SystemTool | 系统调试工具,支持在线读写寄存器、批量脚本读写、寄存器比对及 OTP 烧录 |
| Tftpd | TFTP服务器工具,用于网络烧录 |
| ToolChain | 交叉编译工具链,用于在 PC 端为 ARM 等目标架构编译嵌入式程序 |
| UartBurnTool | UART 固件升级工具,空片(无固件)状态下将升级镜像通过串口写入板载 Flash 存储 |
| USBFactoryTool | USB 固件升级工具,将打包好的 USB 升级镜像通过 USB 写入板载 Flash 存储,支持产线自动升级 |
| UsbDevelopTool | USB 固件升级工具,将 USB 升级固件通过 USB 写入板载 Flash 存储,支持整包升级与单分区升级 |
3.1.4. 主要功能模块¶
| 模块 | 全称 | 功能描述 |
|---|---|---|
| SYS | System | MI系统初始化、内存管理、数据流管理 |
| SCL | Scaler | 缩放/裁剪/格式转换等功能 |
| VDISP | Virtual Display | 软件拼图 |
| VENC | Video Encoder | H264/H265/MotionJpeg编码 |
| AI | Audio Input | 音频采集 |
| AO | Audio Output | 音频输出 |
| DISP | Display | 视频处理及显示 |
| FB | Frame Buffer | 基于Linux Framebuff实现的图形层设备驱动 |
| GFX | Graphic Engine | 在硬件上提供快速的图形绘制功能 |
| RGN | Region | 区域管理模块 |
| HDMI | High Definition Multimedia Interface | 高清多媒体接口 |
| IVE | Intelligent Video Engine | 智能识别算法基本算子 |
| IPU | Intelligent Process Unit | AI模型推演加速 |
| IPU_CASCADE | IPU Cascade | 面向多 IPU 并行级联推演大模型的接口,用于在本地/远端 IPU 板卡上协同加速 LLM 等离线级联模型推理 |
| JPD | Jpeg Decoder | JPEG解码模块 |
| VDF | Video Detect Function | 视频侦测 |
| VDEC | Video Decoder | 视频解码 |
| CIPHER | Cipher | 数据加解密:AES/RSA/SHA算法 |
3.2 编译SDK¶
如果只需要用默认的参数做编译,可以用以下命令直接编译生成sdk image。(这条命令默认会启动进入docker容器)
bash D3_linux_setup.sh build_image
如果需要修改编译配置再做编译,可以参考以下章节的说明。
3.2.1 进入docker容器¶
SDK 编译在交叉编译 Docker 容器中进行。在 download_scripts 目录下启动并进入容器:
docker run --privileged --rm -w /home/sgs -it -v $(pwd):/home/sgs docker.sigmastar.com.cn/sigmastar/sgs_debian_rootfs:<version> /bin/bash
<version>为 Docker 镜像版本号,请查阅docker_versions.yaml,例如 2.0.0
进入容器后,可以配置交叉工具链。
3.2.2. 交叉编译工具链下载以及安装¶
确定工具链
根据确认并配置defconfig中确定的defconfig确认需要配置的交叉工具链:
主工具链
| defconfig Toolchain Version字段 | 工具链 | CROSS_COMPILE |
|---|---|---|
| glibc-12.4.0 |
获取工具链
交叉⼯具链可以从SDK发布包根⽬录下Tools/ToolChain/获取。
安装
主工具链:
64位工具链:aarch64-unknown-linux-gcc-12.4.0-glibc-2.37-gnu.tar.xz
# Step 1: 创建工具目录
sudo mkdir -p /tools/toolchain
# Step 2: 解压安装
sudo tar -xJvf ./aarch64-unknown-linux-gcc-12.4.0-glibc-2.37-gnu.tar.xz -C /tools/toolchain
# Step 3: 配置环境变量
export PATH=${PATH}:/tools/toolchain/aarch64-unknown-linux-gcc-12.4.0-glibc-2.37-gnu/bin
export CROSS_COMPILE=aarch64-unknown-linux-gnu-12.4.0-
export ARCH=arm64
建议将环境变量添加到
~/.bashrc或/etc/profile以永久生效。
3.2.3. 确认并配置defconfig¶
根据不同的应用场景选择不同defconfig。
以下是SDK默认支持的defconfig
| 序号 | defconfig | 硬件说明 |
|---|---|---|
| 1 | linux-comake_mhera.emmc.glibc-12.4.0-arm64-ext4.d3.4096.fccsp16_lpddr4x_defconfig | 用于Comake PI D3板,搭载4096MB LPDDR4X,芯片丝印SCM8003G,存储是emmc |
| 2 | linux-comake_mhera.emmc.glibc-12.4.0-arm64-ext4.d3.2048.fccsp16_lpddr4x_defconfig | 用于Comake PI D3板,搭载2048MB LPDDR4X,芯片丝印SCM8003G,存储是emmc |
defconfig说明
SDK的image defconfig位于project/configs/verify/defconfigs/目录下,以linux-comake_mhera.emmc.glibc-12.4.0-arm64-ext4.d3.4096.fccsp16_lpddr4x_defconfig为例:

| defconfig字段 | 说明 |
|---|---|
| OS(操作系统) | Linux |
| community(社区) | comake |
| platform(平台) | mHera |
| boot medium(启动介质) | emmc |
| toolchain(工具链) | glibc-12.4.0 |
| rootfs type(根文件系统类型) | ext4fs |
| DDR size(DDR 大小) | |
| package(芯片封装类型) | fccsp16 |
defconfig配置项说明
SDK的配置在project/configs/verify/defconfigs目录下,defconfig文件是SDK编译的重要文件。
project/configs/current.configs会记录最新配置项说明。
3.2.4. 整体编译¶
cd project
# 根据硬件配置选择对应的defconfig
make <defconfig名称> # 示例:make linux-comake_mhera.emmc.glibc-12.4.0-arm64-ext4.d3.4096.fccsp16_lpddr4x_defconfig
make clean; make image -j16
编译完成后,可从 project/image/output/images/ 目录获取烧录所需的所有镜像文件。
3.2.5. 编译kernel¶
进入kernel单独编译
cd kernel
make <kerenl_config> # 如果已经在project下make image不需要此操作。示例:make mhera_comake_d3_linux_emmc_defconfig
make -j16
生成文件的存放目录:kernel/arch/arm64/boot/uImage.xz
3.2.6. 编译U‑Boot¶
cd boot
make <xxx_config> # 如果已经在project下make image不需要此操作。示例:make mhera_comake_d3_emmc_arm64_defconfig
make -j16
生成文件的存放目录:boot/u-boot.xz.img.bin(emmc 方案;spinand 方案为 boot/u-boot_spinand.xz.img.bin)
3.2.7. 编译模块ko¶
SDK与Kernel不可避免的会有一些耦合,导致客户自行配置和裁剪Kernel时,需要依赖SGS重新release SDK ko。
为此实现SDK与Kernel解耦,将SDK部分需要依赖kernel源码的source code,开源到sdk/linux目录,客户在自行配置和裁剪Kernel时,可以自行重新编译SDK ko。
修改kernel后,重新编译ko方式(注意先配置工具链环境变量):
完整编译:
工具链配置可参考2.2.2 交叉编译工具链下载以及安装
快速编译:
# 1. 配置必要路径
export PROJ_DIR=/home/xxx/project
export KDIR=/home/xxx/kernel
# 2. 编译 & 打包
cd sdk/linux
make clean ; make all -j32
make install -j32
cd ../../project
make image-fast -j16
编译单个mi_xxx.ko(以mi_ai.ko为例):
忽略某些模块:
3.2.8. 编译app¶
生成文件的存放目录:sdk/verify/sample_code/out/
3.3. 烧写镜像¶
3.3.1. USB Factory Tool烧写¶
SGS提供USB_Factory_Tool来支持usb upgrade image,具体参考 USB升级:USB工厂工具升级
3.3.2. 使用TFTP网络烧写¶
PC端设置:
- 运行tftp工具,指向
project/image/output/images/目录(或单独拷贝到其他目录) -
选择正确的网卡
-
连接板子的网口到PC端(与PC同一网段),连接Debug串口工具到PC端,并检查连接的正确性
板子端操作:
- 先按住电脑键盘的enter键,然后板子上电,板子进入bootloader command line
-
设置网络参数(首次烧录或IP变更时需要):
setenv ipaddr 10.31.0.10; //设置板端ip,要求能跟PC端ping通 setenv serverip 10.31.0.29; //设置PC端的ip setenv -f ethact sgs_gmac0; //设置使用gmac,本平台使用的是gmac setenv -f ethaddr 00:70:20:00:00:01; //设定mac地址 setenv -f netmask 255.255.252.0; //设置掩码 setenv -f gatewayip 10.34.19.254; //设置网关 saveenv; -
执行自动网络烧录:
estar
注意
- 为保证烧录顺利,请使用静态IP,并确保PC和开发板在同一网段
- 可以使用独立网卡使PC端直连开发板,固定该网卡的内网IP地址
3.3.3. 使用ISP Tool空片升级进入U‑Boot¶
请确认 ISP Tool 版本。ISP Tool会在首次版本发布的时候一起打包在tool目录下。
注意:在项目开发的过程或者不同的项目上,分区很可能会不同。实际使用的分区请参考编译镜像中的
images/partition_layout.txt。
NAND Emmc烧录步骤:
点击Connect连接板子,多次上下电重试连接
Warning
如果emmc一直报‘Connect Fail’,请尝试更新Flash Tool到最新版本再试试! emmc 默认启用AB partition,如果开机14次都无法顺利进kernel,将会直接在ipl halt,并且重新使用isptool烧录后仍然卡在此处:
此为env未erase干净导致,一般重新烧录emmc boot.bin,请严格遵循以下步骤:
step1. 因为emmc有三个物理分区可作为boot分区使用,烧录前请点击erase all,并且size调整为400KB:
step2. 再选择需要烧录的分区,并且依次按connect-→start programe即可:
3.3.4. 其他升级方式¶
SD卡升级:U盘&SD卡升级
UART升级:UART升级
3.4. 母片工具介绍¶
母片工具用于制作NAND/NOR/EMMC的母片。
使用方法参考:SDK工具集
4. 软件架构介绍¶
SGS随SDK release有多种sample code提供参考,位于sdk/verify/sample_code/demo下,sample code的详细说明请参考对应demo下的readme_zh.md。
第一个应用程序
| 应用程序 | 使用链接 |
|---|---|
| 深度学习 | DLA_demo |
| 图形处理 | GFX_demo |
| 大模型 | LLM_and_VLM_demo |
| NVR | NVR_demo |
5. 软件开发指南¶
5.1. 编译相关问题¶
5.1.1. 编译时提示找不到交叉编译工具链?¶
# 解决方法:确认工具链路径配置
export PATH=${PATH}:/tools/toolchain/aarch64-unknown-linux-gcc-12.4.0-glibc-2.37-gnu/bin
export CROSS_COMPILE=aarch64-unknown-linux-gnu-12.4.0-
export ARCH=arm64
# 验证工具链
aarch64-unknown-linux-gnu-12.4.0-gcc --version
5.1.2. make image执行失败或镜像不完整?¶
5.2. 烧录相关问题¶
5.2.1. ISP Tool无法连接开发板?¶
- 检查串口连接:确认USB转串口驱动已安装
- 检查波特率设置:115200
5.2.2. TFTP烧录时传输失败?¶
# 检查网络连通性
ping 10.31.0.29 # PC端IP
# 确保使用静态IP,同一网段
setenv -f ipaddr 10.31.0.10
setenv -f serverip 10.31.0.29
saveenv
# 重新执行烧录
estar
5.2.3. 烧录后系统无法启动?¶
- 检查Flash类型选择是否正确
- 验证分区表配置:
cat images/partition_layout.txt - 查看串口启动日志,确认bootloader加载是否正常
- 尝试重新烧录完整的固件包
5.3. 系统相关问题¶
5.3.1. 如何使用coredump调试应用崩溃?¶
-
gdb位置
SDK中有提供已编译完成的gdb,位置
project/release/common_prebuilt/glibc/12.4.0/arm64/debug/gdb -
板端设置coredump⽂件⼤⼩
ulimit -c unlimited -
查看codedump文件中堆栈信息
gdb ./your_app /path/to/core
5.3.2. 如何跟踪MI模块数据流?¶
-
参考文档Sgs NVR 应用开发指南,在平台执行demo,保持运行状态。
-
查看VDEC/DISP节点信息,其中会有与前级的绑定关系 cat /proc/mi_modules/mi_vdec/mi_vdec0
cat /proc/mi_modules/mi_disp/mi_disp0
-
查看节点信息完毕退出demo。
5.3.3. 如何启用内核调试日志?¶
# 方法1: U‑Boot环境bootargs变量中修改:
loglevel=7
# 方法2: 运行时修改
echo 7 > /proc/sys/kernel/printk
# 查看dmesg
dmesg | grep -i "your_keyword"
5.3.4. 性能不达标怎么办?¶
-
帧率不足
检查模块CLK配置是否满足帧率需求
-
带宽不够
检查stream pipe IP之间的绑定方式是否符合预期
-
CPU loading过高
使用perf抓火焰图查看具体的模块,如果是APP占用过高请检查对应的实现,如果是SGS的模块过高请联系FAE
5.3.5. 如何添加第三方库到SDK编译?¶
参考以下步骤:
-
检查配置
在
{SourceCode}/project/configs/current.configs中检查配置:CONFIG_MI_SDK_SUPPORT = y # 一般默认为启动如果不存在,则全编译时,选择defconfig有误
-
将库源码放在合适目录
mkdir -p {SourceCode}/sdk/verify/sample_code/3rdparty/mylib # 创建目录 cp -r your_lib {SourceCode}/sdk/verify/sample_code/3rdparty/mylib/ # 存放需要添加的源码(.c与.h文件) -
创建Makefile编译规则
touch {SourceCode}/sdk/verify/sample_code/3rdparty/mylib/lib.mk
# 如果源码(.c与.h文件)单个存放于mylib目录下,如下 # mylib/ # | # |——xxx.c # |——xxx.h # |——xxx.c # |——xxx.h # |....... 则lib.mk文件可以为空 # 如果有子目录和额外头文件,如下 # mylib/ # ├── include/ ← 头文件放在这个子目录 # │ └── xxx.h # ├── src/ ← 源码放在这个子目录 # │ └── xxx.c # |—— lib.mk # |—— xxx.c # |—— xxx.h # |...... 则lib.mk需要添加相关.h和.c文件的搜索路径 INC += $(MODULE_PATH)/include SUBDIRS += $(MODULE_PATH)/src -
在 APP 的 dep.mk 中声明依赖
找到你要用这个库的 APP 目录,比如
{SourceCode}/sdk/verify/sample_code/demo/my_demo/,编辑它的 dep.mk:DEP += 3rdparty/mylib # 如果没有 dep.mk,需要创建一个注意: 如果没有此步骤(需要使用),则编译后不会有生成结果
-
重新编译整个SDK
# 切换到{SourceCode}/project下 cd project make image -j16 # 编译编译后会生成如下结果:
{SourceCode}/sdk/verify/sample_code/out/arm/libs/glibc/12.4.0/static存在libmylib.a{SourceCode}/sdk/verify/sample_code/out/arm/libs/glibc/12.4.0/dynamic存在libmylib.so
5.3.6. 如何在SDK中增加新的应用程序?¶
5.3.6.1. 步骤1:创建DEMO目录¶
在 demo/ 目录下创建新的 demo 目录。推荐使用小写字母和下划线,例如 my_demo。
5.3.6.2. 步骤 2:创建配置文件¶
1. 创建 my_demo.mk 文件
每个 demo 必须有一个与目录名同名的 .mk 文件。文件名必须与目录名一致。
命名规则:
- 文件名:
[目录名].mk - 例如:
my_demo.mk
必须定义的变量:
# 启用 clang-format 代码格式检查
CLANG_FORMAT_ENABLE := yes
# 启用 clang-tidy 静态分析
CLANG_TIDY_ENABLE := yes
# 定义生成的可执行文件名
# 命名格式: sgs_demo_[路径中的下划线分隔]
EXEFILE := sgs_demo_my_demo
可选的变量:
# 外部库链接类型(可选)
LINK_TYPE := static # 静态链接(默认)
# 或
LINK_TYPE := dynamic # 动态链接
# 内部库链接类型(可选)
INTER_LINK_TYPE := static # 静态链接(默认)
# 或
INTER_LINK_TYPE := dynamic # 动态链接
# 添加外部库依赖(可选)
LIBS += -lmi_sys
LIBS += -lmi_common
2. 创建 dep.mk 文件
此文件用于声明内部库依赖。
没有依赖的情况:
有依赖的情况:
# 添加内部库依赖
DEP += 3rdparty/sgs_rtsp
DEP += libraries/some_lib
# 添加头文件搜索路径
INC += $(BUILD_TOP)/../../../kernel/drivers/sgs_common/include/
5.3.6.3. 步骤 3:创建源代码文件¶
源文件必须命名为 sgs_demo.c
基本程序结构:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char** argv)
{
if (argc < 1) {
return -1;
}
printf("Program: %s\n", argv[0]);
printf("Hello from my_demo!\n");
// 你的代码可以添加在这里
// 如需命令行参数解析,可使用 getopt() 等
return 0;
}
注意:示例中
argc和argv的使用是必需的,以符合 SDK 的 clang-tidy 代码检查规则(misc-unused-parameters,且编译时-warnings-as-errors)。若你的应用不需要命令行参数,至少保留类似printf("%s", argv[0])这样的基础使用,否则编译会失败。更复杂的参数解析可参考demo/scl/sgs_demo.c或demo/venc/venc_demo/sgs_demo.c的实现。
5.3.6.4. 步骤 4:创建文档文件¶
自行选择在my_demo目录下是否创建 readme_zh.md
5.3.6.5. 步骤 5:编译和测试¶
编译 demo
查看编译产物
编译成功后,可执行文件位于:
运行测试
将demo copy到板端,在板端运行
5.3.7. 如何优化启动速度?¶
5.3.7.1. flash¶
使用支持DTR(Double Transfer Rate)的nand flash。参考:flash文档。
5.3.7.2. IPL优化¶
-
跳过U-Boot
CONFIG_FAT_BOOT=y # U‑Boot CONFIG_BOOT_KEYBOARD=y # 上电前按enter进入U‑Boot -
调整log level
CONFIG_LOGGING_LEVEL=1
5.3.7.3. kernel优化¶
- 将built-in驱动修改为外部模块,内核启动后手动按需加载
- disable非必要的built-in驱动
5.3.8. 如何优化系统内存占用?¶
Kernel 配置项裁剪
| 配置项 | 推荐状态 | 预计节省 | 影响 |
|---|---|---|---|
CONFIG_KALLSYMS |
N | 300-500KB | 移除符号表,无法通过地址反查函数名 |
CONFIG_PRINTK |
N | 300-700KB | 移除 printk,关闭内核日志输出 |
CONFIG_BUG |
N | 10-30KB | 移除 BUG() 宏 |
CONFIG_ELF_CORE |
N | 50-100KB | 移除 coredump 支持 |
CONFIG_FUTEX |
N | 10-20KB | 移除 futex |
CONFIG_SIGNALFD |
N | 5-10KB | 移除 signalfd |
CONFIG_TIMERFD |
N | 5-10KB | 移除 timerfd |
CONFIG_EVENTFD |
N | 5-10KB | 移除 eventfd |
裁剪方式:
cd kernel
make menuconfig
# 或者直接编辑defconfig,比如编辑:
# kernel/arch/arm64/configs/mhera_comake_d3_linux_emmc_defconfig(spinand 方案:mhera_ssm004a_s02a_spinand_defconfig)
注意:关闭
CONFIG_PRINTK后串口将没有内核日志,调试期建议保留,量产再关闭。
5.3.9. 如何修改内存分布?¶
5.3.9.1. 内存布局组成¶
mhera 系统的 DRAM 同时承载几类用途:
| 区域 | 用途 | 控制方式 |
|---|---|---|
uImage(Linux) |
Linux 内核镜像加载区 | uImage header 中的 load address |
IPL_CUST.rom / .ram / .dram_shmem / .dram_heap |
IPL 客制段(启动早期 RAM 初始化、共享区、堆) | IPL defconfig(CONFIG_IPL_CUST_*、CONFIG_SHMEM_DRAM_*、CONFIG_HEAP_DRAM_*) |
u-boot.img.bin |
U-Boot 自身 | CONFIG_SYS_TEXT_BASE(U-Boot defconfig) |
u-bl31.bin |
ARM TF-A BL31(secure monitor) | 由原厂提供,不可修改,只需保证不与之重叠即可 |
| LX_MEM | Linux 运行期可用内存 | bootargs LX_MEM=<base>,<size> |
| MMA Heap | MI Pipeline use | CONFIG_MMA_MEM_SIZE / bootargs mma_heap=...,sz=... |
| CMA | Linux 内核连续内存池 | CONFIG_CMA_MEM_SIZE / bootargs cma=2M |
| FB | bootlogo / framebuffer | CONFIG_FB_MEM_SIZE / bootargs mma_heap=mma_heap_fb,... |
关于 TF-A:BL31 的加载地址(u-bl31.bin 当前为 0x27F00000)由原厂提供,使用方不可修改,只需保证其他镜像不与之重叠即可。
关于 rootfs:本 defconfig(emmc D3 4g)rootfs 为 ext4,位于 emmc 分区,不使用 ramdisk。bootargs 中 rootfs 相关项实测为:
(对照)spinand 方案的 rootfs 来自 spinand 上的 squashfs(通过 ubi block 挂载),bootargs 中 rootfs 相关项实测为:
关于 CMA:CMA 是 Linux 内核的“连续内存分配器”,专门给“需要大块物理连续内存、又走标准 DMA API”的设备驱动用,例如:
- 视频/图形子系统:V4L2 video buffer、DRM/KMS framebuffer;
- 早期没有 IOMMU 的 DMA 设备:USB host、SDHC、外设 DMA;
-
dma_alloc_coherent()在分配较大 buffer 时的 fallback。这是“通用 Linux DMA 池”,与 MI Pipeline 用的 MMA 是两套独立机制。本配置只给了 CMA 2 MB,是因为业务大块内存全部走 MMA,CMA 一般只提供给通用驱动;如果接入了大量走标准 V4L2/DRM 路径的外设,可适当上调
CONFIG_CMA_MEM_SIZE。
5.3.9.2. 实际加载地址¶
以下是 make image 后的真实加载地址(来自 project/image/output/images/load_addr.txt):
uImage 0x20200000 - 0x21079200
IPL_CUST.rom 0x22400000 - 0x22408910
IPL_CUST.ram 0x22420000 - 0x22431010
IPL_CUST.dram_shmem 0x22440000 - 0x23D00000 (≈ 24 MB)
IPL_CUST.dram_heap 0x23D00000 - 0x23DF0000
u-boot.img.bin 0x23E00000 - 0x23EF5BB0 (≈ 1 MB)
u-bl31.bin 0x27F00000 - 0x27F08100 (TF-A,由原厂提供,不可修改)
DRAM 物理基址 0x20000000,CONFIG_DRAM_SIZE=0x100000000(4 GB),所以所有加载地址必须落在 [0x20000000, 0x120000000) 内。
布局示意如下(左:加载阶段;右:Linux 运行期):
(对照)spinand 2g 方案布局:
5.3.9.3. 内存布局调整方法¶
| 想改的地址 | 改哪里 |
|---|---|
| uImage 加载地址 | 重新打包 uImage 时的 mkimage -a/-e 参数 |
| IPL_CUST 各段 | IPL defconfig:CONFIG_IPL_CUST_ROM_BASE/LIMIT、CONFIG_IPL_CUST_RAM_BASE、CONFIG_SHMEM_DRAM_BASE/LIMIT、CONFIG_HEAP_DRAM_BASE/LIMIT |
| U-Boot 加载地址 | boot/configs/mhera_comake_d3_emmc_arm64_defconfig 的 CONFIG_SYS_TEXT_BASE(spinand 方案为 ..._spinand_arm64_defconfig) |
| BL31(u-bl31.bin) | 不可改(由原厂提供,只需保证不与之重叠即可) |
LX_MEM 大小 |
本 defconfig 的 CONFIG_LX_MEM_SIZE(自动写到 bootargs) |
| MMA Heap 大小 | 本 defconfig 的 CONFIG_MMA_MEM_SIZE(自动写到 bootargs mma_heap=...,sz=...) |
| CMA 大小 | 本 defconfig 的 CONFIG_CMA_MEM_SIZE(自动写到 bootargs cma=...) |
| FB 大小 | 本 defconfig 的 CONFIG_FB_MEM_SIZE |
调整完成后:
make image 会自动调用:
project/scripts/parser_loadaddr.py—— 解析各镜像头,得到加载区间project/scripts/loadaddr_layout_graph.py—— 输出load_addr.svgproject/scripts/check_loadaddr.py—— 检查重叠 / 越界
输出位于 project/image/output/images/:
load_addr.txt:地址清单-
load_addr.svg:可视化地址区域load_addr.svg 由
loadaddr_layout_graph.py生成。USED 区为镜像实际占用,灰色 UNUSED 为空洞。把 SVG 用浏览器打开后,鼠标悬停可以看到每段的精确大小(十进制 / 十六进制 / 人类可读)。load_addr.txt 是对应 SVG 的源数据。
5.3.9.3.1. load_addr.svg 图示¶
load_addr.svg 显示(emmc D3 4g):
(对照)spinand 2g 方案的 load_addr.svg:
5.3.9.4. 布局调整原则¶
调整内存布局时需遵守以下原则:
- 所有地址必须落在
[0x20000000, 0x20000000 + CONFIG_DRAM_SIZE)内(本例为[0x20000000, 0x120000000))。 - 加载阶段任意两个 USED 区间不得重叠(
check_loadaddr.py会拦下)。 - IPL_CUST 各段、U-Boot、uImage 都要避开 BL31 占用的
0x27F00000附近。 - MMA、FB 等保留内存从 LX_MEM 内部划出,总和不得超过 LX_MEM,且各区互不重叠。
5.3.9.5. 调试方法¶
调整后开机异常时:
- 看
project/image/output/images/load_addr.txt与load_addr.svg,确认没有重叠 / 越界。 -
看串口日志,按阶段定位:
- IPL 之前挂 → IPL_CUST 段地址有问题;
- 进了 U-Boot 但起 Linux 失败 → uImage 加载地址 或 LX_MEM 范围;
- Linux 起来但 rootfs 挂载失败 → emmc 方案检查 ext4 分区表;spinand 方案检查
mtdparts/ ubi 分区配置; - Linux 起来但 MMA 初始化失败 → bootargs 的
mma_heap与CONFIG_MMA_MEM_SIZE是否一致。
-
Linux 起来后查实际占用:
bash cat /proc/meminfo cat /proc/mi_modules/mi_sys/mi_sys0 cat /proc/mi_modules/mi_sys_mma/mma_heap_name0
5.3.10. 如何调整分区?¶
系统分区管理是嵌入式开发中的重要环节。mHera平台支持灵活的分区配置,可以根据实际需求调整分区大小、增加或删除分区。
5.3.10.1. 存储介质以及文件系统类型介绍¶
| 存储介质 | 支持的可读写文件系统格式 | 支持的只读文件系统格式 |
|---|---|---|
| spi nand | ubifs、lfs、fwfs | squashfs |
| eMMC | ext4 | squashfs |
5.3.10.2. 分区表说明¶
| 分区 | 说明 |
|---|---|
| BOOT | 启动镜像分区(IPL/IPL_CUST/U‑Boot/TEE) |
| BOOT_BAK | BOOT的备份分区 |
| ENV | 环境变量分区 |
| ENV1 | ENV备份分区 |
| KERNEL | Linux内核镜像分区 |
| KERNEL_BACKUP | KERNEL备份分区 |
| rootfs | 根文件系统分区 |
| MISC | 配置文件分区(屏参等) |
| ubia | 包括miservice和customer两个分区,miservice是SDK服务分区(ko、so、IQ文件等),customer是客户自定义分区 |
5.3.10.3. 分区配置文件¶
分区配置脚本位于:
通过defconfig中的IMAGE_CONFIG变量可以找到当前使用的分区配置文件。
5.3.10.4. 修改分区大小¶
1. 找到对应的分区配置变量
每个分区由一组变量定义,例如customer分区:
# customer
customer$(RESOURCE) = $(OUTPUTDIR)/customer
customer$(FSTYPE) = ubifs
customer$(IMAGE) = customer.ubifs
customer$(UBIVOLID) = 1
ifneq ($(DEBUG), )
customer$(PATSIZE) = 0x4500000
else
customer$(PATSIZE) = 0x5000000
endif
customer$(MOUNTTG) = /customer
customer$(MOUNTPT) = ubi0:customer
customer$(UBIPART) = ubia
customer$(OTABLK) = /dev/ubi0_1
2. 修改分区大小
修改xxx$(PATSIZE)变量即可调整分区大小:
3. 验证分区大小
修改后编译,在project/image/output/images/partition_layout.txt中查看分区size是否有溢出。
5.3.10.5. 增加自定义分区¶
步骤1:定义新分区变量
# 新增myapp分区,大小为3MB。如果超了size,需要在其他分区减去超出的size。
# myapp
myapp$(RESOURCE) = $(OUTPUTDIR)/myapp
myapp$(FSTYPE) = ubifs
myapp$(IMAGE) = myapp.ubifs
myapp$(PATSIZE) = 0x300000
myapp$(UBIVOLID) = 2
myapp$(MOUNTTG) = /myapp
myapp$(MOUNTPT) = ubi0:myapp
myapp$(UBIPART) = ubia
myapp$(OTABLK) = /dev/ubi0_2
步骤2:添加到编译列表
步骤3:添加文件拷贝逻辑
在Makefile中添加往$(OUTPUT)/myapp拷贝文件的逻辑。
5.3.10.6. 删除分区¶
按照增加分区的操作反向执行:
- 从
IMAGE_LIST和USR_MOUNT_BLOCKS中移除分区名 - 删除分区的变量定义
- 删除Makefile中添加的往
$(OUTPUT)/myapp拷贝文件的逻辑。
5.3.10.7. 进阶参考¶
mHera还支持备份分区和AB分区,请参考:
- 详细分区配置文档:系统分区
5.3.11. 如何进入U-Boot终端¶
如果已经烧录了kernel需要上电之前按住enter键,开机后会进入U‑Boot终端。
如果没有烧录kernel上电会自动进入U‑Boot终端,日志打印如下:
SP16 NTC16G LPDDR4X 3200
miu pll: 466MHz
MRR read zero
ddr train finish
SHMEM@relocate 0xa0016100->0x22440000
HEAP@re-init 0x23d00000~0x23df0000
*** Warning - readenv() failed, using default environment
RECORD@moving tc from 0xa0015ae8 to 0x20002000 count:1
IMG_READ@devs:0x2 img:TF_A bak:0 ofs:0x0 sz:0x580 dst:0x23d00000
IMG_READ@devs:0x2 img:TF_A bak:0 ofs:0x0 sz:0x8140 dst:0x27efffc0
IMG_VERIFY@TF_A
IMG_DECOMP@0 from 0x27f00000 to 0x27f00000
IMG_READ@devs:0x2 img:IPL_CUST bak:0 ofs:0x0 sz:0x580 dst:0x23d00580
IMG_READ@devs:0x2 img:IPL_CUST bak:0 ofs:0x0 sz:0x8fc0 dst:0x22400000
IMG_VERIFY@IPL_CUST
IMG_DECOMP@0 from 0x22400000 to 0x22400000
Flashing D-Cache and Disabling MMU
OS_JUMP@method:2(0x27f00000)
NOTICE: Mhera bl31_setup
NOTICE: BL31: v2.5(release):v2.5-114-gc3988ee
NOTICE: BL31: Built : 12:31:23, Mar 12 2026
IPL_CUST 3f84974
D-0
SHMEM@at 0x22440000~0x23d00000
HEAP@init 0x23d00000~0x23df0000
IMG_READ@devs:0x2 img:UBOOT bak:0 ofs:0x0 sz:0x580 dst:0x23d00000
IMG_READ@devs:0x2 img:UBOOT bak:0 ofs:0x0 sz:0x5253c dst:0x22545140
IMG_VERIFY@UBOOT
IMG_DECOMP@2 from 0x22545180 to 0x23e00000
Flashing D-Cache and Disabling MMU
OS_JUMP@method:2(0x23e00000)
U-Boot 2021.10 (Apr 24 2026 - 11:19:06 +0800)
SoC: Sgs mhera
Model: MHERA
Version: M###g1aca0d3
DRAM: 510 MiB
[Padmux]reset PAD16(reg 0x153400:5c; mask0x1) t0 MIPITX_OUT_MODE_1 (org: MIPITX_OUT_MODE_2)
[Padmux]reset PAD17(reg 0x153400:5c; mask0x100) t0 MIPITX_OUT_MODE_1 (org: MIPITX_OUT_MODE_2)
[Padmux]reset PAD18(reg 0x153400:5c; mask0x2) t0 MIPITX_OUT_MODE_1 (org: MIPITX_OUT_MODE_2)
[Padmux]reset PAD19(reg 0x153400:5c; mask0x200) t0 MIPITX_OUT_MODE_1 (org: MIPITX_OUT_MODE_2)
[Padmux]reset PAD20(reg 0x153400:5c; mask0x4) t0 MIPITX_OUT_MODE_1 (org: MIPITX_OUT_MODE_2)
[Padmux]reset PAD21(reg 0x153400:5c; mask0x400) t0 MIPITX_OUT_MODE_1 (org: MIPITX_OUT_MODE_2)
[Padmux]reset PAD22(reg 0x153400:5c; mask0x8) t0 MIPITX_OUT_MODE_1 (org: MIPITX_OUT_MODE_2)
[Padmux]reset PAD23(reg 0x153400:5c; mask0x800) t0 MIPITX_OUT_MODE_1 (org: MIPITX_OUT_MODE_2)
WDT: Not found!
NAND: SPI 54M
[SPINAND] RFC use command 0x6b
[SPINAND] dummy clock 0x8
[SPINAND] Program with command 0x32
[SPINAND] Random with command 0x34
[FLASH] BDMA mode.
[FLASH] spinand init done!
spi clk already initialized
[FLASH] dev_id = 0xee
[FLASH] mfr_id = 0xc8, dev_id= 0x91 id_len = 0x2
128 MiB
MMC: Fail to get pad(0x2000f) ip(0x0_8) form padmux !
MSC: 1, MSC: 0
Loading Environment from NAND...
ENV: offset = 0x500000 size = 0x40000
ENV1: offset = 0x540000 size = 0x40000
*** Warning - bad CRC, using default environment
In: serial
Out: serial
Err: serial
Net: eth0: gmac0
5.4. BSP相关问题¶
5.4.1. 如何修改GPIO配置?¶
GPIO(General Purpose Input Output)通用输入/输出引脚是嵌入式系统中重要的外设接口。
5.4.1.1. GPIO基础知识¶
GPIO Index与PAD对应关系
原理图上的GPIO Pad Name需要转换为GPIO Index才能在软件中使用。例如:PAD_SPI_DO对应的GPIO Index为39。
部分常用PAD与GPIO Index对应表(完整对应表请查阅kernel/drivers/sgs_common/gpio/hal/mhera/pub/gpio.h):
| Pad Name | GPIO Index | Pad Name | GPIO Index |
|---|---|---|---|
| PAD_SD0_D0 | 65 | PAD_SD0_D1 | 64 |
| PAD_SPI_DO | 39 | PAD_PWM0 | 72 |
| PAD_GPIO17 | 5 | PAD_GPIO18 | 6 |
| PAD_I2C1_SCL | 11 | PAD_I2C1_SDA | 12 |
5.4.1.2. U-Boot阶段配置¶
1. U-Boot menuconfig配置
配置选项:
CONFIG_SGS_GPIO=y
CONFIG_SGS_PADMUX=y
CONFIG_SGS_PAD_INIT=n # 引脚初始状态设置
2. DTS配置
在U-Boot dts文件中配置GPIO节点,dts位置{SourceCode}/boot/arch/arm/dts/mhera.dtsi:
3. U-Boot命令行操作
在U-Boot命令行可以直接操作GPIO:
| 命令 | 说明 | 示例 |
|---|---|---|
gpio input <gpio#> |
设置GPIO为输入模式 | gpio input 69 |
gpio set <gpio#> |
设置GPIO为输出高电平 | gpio set 10 |
gpio clear <gpio#> |
设置GPIO为输出低电平 | gpio clear 49 |
gpio toggle <gpio#> |
翻转GPIO电平 | gpio toggle 49 |
gpio status <gpio#> |
查看GPIO状态 | gpio status 20 |
5.4.1.3. Kernel阶段配置¶
1. Kernel menuconfig配置
配置选项:
CONFIG_GPIO_SYSFS=y
CONFIG_MSYS_GPIO=n
CONFIG_SGS_GPIO=y
CONFIG_SGS_PADMUX=y
CONFIG_SGS_PAD_INIT=n # 引脚初始状态设置
2. DTS配置
在Kernel dts文件中配置GPIO节点,dts位置{SourceCode}/kernel/arch/arm/boot/dts/mhera.dtsi:
5.4.1.4. 引脚复用功能配置(Padmux)¶
当需要使用GPIO的复用功能(如I2C、SPI、PWM等)时,需要在{SourceCode}/kernel/arch/arm/boot/dts/xxx-padmux.dtsi文件中进行配置。
配置格式:
配置示例(I2C0):
<PAD_HDMITX_SCL PINMUX_FOR_I2C0_MODE_1 PINMUX_FOR_I2C0_MODE_1>,
<PAD_HDMITX_SDA PINMUX_FOR_I2C0_MODE_1 MDRV_PUSE_I2C0_SDA>,
配置示例(GPIO模式):
配置注意事项:
- 一个Pad只能配置一种Mode,不能同时配置多个Mode
- 一个MDRV_PUSE_XXX只能对应一组Pad配置,不能重复使用
- 配置的Pad和Mode必须匹配(查阅
drivers/sgs/include/mhera/padmux.h) - 不允许在驱动中直接进行复用操作,统一在padmux.dtsi中配置
5.4.1.5. 引脚初始状态设置¶
在xxx-padmux.dtsi中配置引脚的初始状态,包括输入/输出方向、电平状态、内部上拉状态、驱动能力等级。
配置格式:
/*
* Format:
* <Pad_Index Direction Level_State Pull_State Driving_Level>
*/
<PAD_GPIO0 GPIO_DIR_OUT GPIO_LEVEL_HIGH PAD_PULL_UP PAD_DRV_1>,
<PAD_I2C0_SDA GPIO_DIR_IN GPIO_LEVEL_NA PAD_PULL_DEFAULT PAD_DRV_DEFAULT>,
参数说明:
| 参数 | 可选值 | 说明 |
|---|---|---|
| Direction | GPIO_DIR_IN、GPIO_DIR_OUT、GPIO_DIR_NA | 输入/输出/不设置 |
| Level_State | GPIO_LEVEL_HIGH、GPIO_LEVEL_LOW、GPIO_LEVEL_NA | 高电平/低电平/不设置 |
| Pull_State | PAD_PULL_UP、PAD_PULL_DOWN、PAD_HIZ、PAD_PULL_DEFAULT | 上拉/下拉/悬空/默认 |
| Driving_Level | PAD_DRV_0~PAD_DRV_8、PAD_DRV_DEFAULT | 驱动能力等级0~8 |
5.4.1.6. 用户空间操作GPIO¶
通过sysfs接口在用户空间操作GPIO:
1. 导出GPIO引脚
2. 设置方向
# 设置为输出
echo out > /sys/class/gpio/gpio12/direction
# 设置为输入
echo in > /sys/class/gpio/gpio12/direction
3. 读写电平
# 读取电平
cat /sys/class/gpio/gpio12/value
# 设置高电平
echo 1 > /sys/class/gpio/gpio12/value
# 设置低电平
echo 0 > /sys/class/gpio/gpio12/value
4. 配置上下拉
# 设置上拉(需先设置为输入)
echo 12 up > /sys/class/sgs/msys/gpio_pull
# 设置下拉
echo 12 down > /sys/class/sgs/msys/gpio_pull
5. 配置驱动能力
5.4.1.7. 调试方法¶
1. 使用U-Boot命令快速验证
在U-Boot阶段使用gpio命令验证引脚功能:
2. 使用sysfs接口验证
在Linux运行时使用sysfs验证:
# 导出并测试
echo 61 > /sys/class/gpio/export
echo out > /sys/class/gpio/gpio61/direction
echo 1 > /sys/class/gpio/gpio61/value
cat /sys/class/gpio/gpio61/value
3. 检查Padmux配置冲突
使用iocheck工具(make kernel之后在kernel/drivers/sgs_common/gpio/ut/io_check下会生成prog_io_check工具,可以将工具copy到板子的customer下)检查padmux配置是否正确:
# 假设prog_io_check工具在customer路径下
cd /customer
# 查询某GPIO的当前复用情况
prog_io_check -i 61
# 设置为指定mode
prog_io_check -i 61 -m mode_index -s
# 校验padmux mode冲突情况
prog_io_check -v
4. 常见问题排查
| 问题 | 排查方法 |
|---|---|
| GPIO无法拉高拉低 | 使用万用表直接测量引脚电压,检查硬件连接 |
| Padmux异常 | 使用iocheck工具检查padmux配置,检查是否有冲突 |
| 上下拉不生效 | 确保GPIO已设置为输入模式,输出模式下上下拉无法测量 |
5.4.1.8. 驱动开发API参考¶
在驱动代码中可以使用以下API操作GPIO:
#include <drv_gpio.h>
// 申请和释放GPIO
gpio_request(gpio_index, "test");
gpio_free(gpio_index);
// 设置方向
gpio_direction_input(gpio_index);
gpio_direction_output(gpio_index, value);
// 读写电平
value = gpio_get_value(gpio_index);
gpio_set_value(gpio_index, 1);
// 设置上下拉
drv_gpio_pull_up(gpio_index);
drv_gpio_pull_down(gpio_index);
drv_gpio_pull_off(gpio_index);
// 设置驱动能力
drv_gpio_drv_set(gpio_index, level);
5.4.1.9. 参考资料¶
详细的GPIO使用说明请参考:GPIO使用参考
如果想要了解GPIO寄存器配置以及驱动能力,请查看硬件提供的HW Checklist表格。
5.4.2. SD卡插入后检测不到设备?¶
1.U‑Boot
U‑Boot查看SD卡内容命令
如果报错检查U‑Boot config是否有打开SDMMC driver,defconfig中CONFIG_UBOOT_CONFIG配置项为对应U‑Boot config
CONFIG_CMD_SGS_MMC=y
CONFIG_CMD_SGS_MMC_FDISK=y
2.kernel
kernel config打开SDMMC driver,defconfig中CONFIG_KERNEL_CONFIG配置项为对应KERNEL config
CONFIG_SGS_SDMMC=m
5.4.3. 如何调整USB驱动能力?¶
参考:USB使用参考
5.4.4. 如何使用rndis功能?¶
RNDIS(Remote Network Driver Interface Specification)是微软基于USB定义的网络协议,可用于通过USB线实现开发板与PC之间的网络通信。
注意:使用RNDIS会导致USB WIFI不能使用!
5.4.4.1. Kernel配置¶
1. 配置USB宏支持RNDIS
在 kernel menuconfig 中启用以下配置:
CONFIG_USB_DWC3_GADGET=y
CONFIG_USB_GADGET=m
CONFIG_USB_CONFIGFS=m
CONFIG_USB_CONFIGFS_RNDIS=y
CONFIG_USB_CONFIGFS_MASS_STORAGE=y
CONFIG_USB_ETH=m
CONFIG_USB_MASS_STORAGE=m
CONFIG_USB_MASS_STORAGE=m
# CONFIG_TYPEC is not set
2.修改dts设置usb为peripheral
以arm 32bit为例。
diff --git a/arch/arm/boot/dts/mhera.dtsi b/arch/arm/boot/dts/mhera.dtsi
index 8458b82..340b6cd 100644
--- a/arch/arm/boot/dts/mhera.dtsi
+++ b/arch/arm/boot/dts/mhera.dtsi
@@ -2069,7 +2069,7 @@
status = "okay";
dwc3_p3: dwc3 {
- dr_mode = "host"; /* host or peripheral */
+ dr_mode = "peripheral"; /* host or peripheral */
compatible = "snps,dwc3";
reg = <0x0 0x1f348000 0x1400>;
maximum-speed = "super-speed";
3.添加KO到kernel_mod_list
按照顺序添加以下ko到{SourceCode}/project/kbuild/customize/{kernel_version}/{chip}/{product}/kernel_mod_list
usb-common.ko
usbcore.ko
sgs_usb3_phy.ko
udc-core.ko
dwc3.ko
sgs_dwc3_of_simple.ko
libcomposite.ko
u_ether.ko
usb_f_ecm.ko
usb_f_ecm_subset.ko
usb_f_rndis.ko
g_ether.ko
4. 编译并烧录固件
编译完成后会生成包含RNDIS支持的固件镜像,烧录到开发板。
5.4.4.2. 确认KO模块¶
系统启动后,确认以下RNDIS相关驱动模块已加载:
应看到类似以下输出:
usb_f_rndis 24576 2 g_ether
usb_f_ecm_subset 16384 0
usb_f_ecm 16384 1
u_ether 24576 4 g_ether,usb_f_rndis,usb_f_ecm_subset,usb_f_ecm
usbhid 24576 0
usb_storage 53248 0
udc_msb250x 32768 0
libcomposite 53248 4 g_ether,usb_f_rndis,usb_f_ecm_subset,usb_f_ecm
udc_core 32768 6 usb_f_rndis,usb_f_ecm,u_ether,udc_msb250x,libcomposite,dwc3
sgs_usb3_phy 49152 3
sgs_usb2_phy 32768 2
usbcore 204800 5 usbhid,usb_storage,xhci_plat_hcd,xhci_hcd,ehci_hcd
usb_common 20480 10 udc_msb250x,libcomposite,xhci_plat_hcd,xhci_hcd,sgs_dwc3_of_simple,dwc3,udc_core,sgs_usb3_phy,sgs_usb2_phy,usbcore
5.4.4.3. 板端验证方法¶
1. 确认USB网卡存在
应能看到 usb0 网卡。
2. 启动USB网卡
3. 配置IP地址
注意:只有执行
ifconfig usb0 up后,PC端才能识别到RNDIS网络设备。
5.4.4.4. PC端配置IP地址¶
在PC的网络设备中找到以太网设备(USB Ethernet/RNDIS Gadget),设置与板端同一网段的IP地址,比如192.168.1.100。
5.4.5. 如何使用NFS文件系统?¶
- 默认NFS配置已打开
-
PC端打开NFS应用
待挂载的文件需要everyone可读可写的权限
-
单板端NFS挂载命令
# Get the IP address 192.168.1.123 of the PC mount -t nfs -o nolock 192.168.1.123:/share /mnt
5.4.6. 如何修改串口波特率?¶
默认串口波特率为115200
-
U‑Boot
调整
boot/include/configs/{chip}.h中的CONFIG_BAUDRATE为指定波特率 -
kernel
调整bootargs中的波特率,文件位置在:
kernel/arch/arm/boot/dts/xxx.dts
5.5. Model Zoo¶
Model Zoo 为 IPU 模型示例与转换脚本集合,面向运行在 IPU 上的 AI 模型部署与应用开发,用于帮助开发者快速上手 IPU、快速跑通模型推理流程。
详情请查阅: https://git.sigmastar.com.cn:9090/sigmastar/sgs_model_zoo
5.6. 如何更换flash?¶
5.7. 如何使用安全启动?¶
Security Boot(安全启动)是系统上电后 首个执行的安全验证流程,核心目标是确保设备从硬件启动到操作系统加载的全链路中,所有执行代码(固件、引导程序、内核等)的 完整性、真实性和合法性,防止恶意代码(如病毒、篡改固件)注入或替换,从启动源头阻断安全威胁,保护设备的运行安全。
安全启动代码路径:{SourceCode}/project/image/security_boot_tools
安全启动文档路径:Security Boot使用参考和Security Boot手动签章使用参考
使用Security Boot的核心工作有两步:人为将镜像文件进行签章(或加密+签章),以及将签章(或加密+签章)使用到的对应key烧录在芯片OTP中。
以RSA2048和AES128为例:
5.7.1. 生成Key¶
5.7.1.1. 制作RSA Key¶
RSA主要用于固件签名,防止恶意篡改固件。使用RSA2048算法,需要生成RSA private.pem和public.pem。
通过以下命令生成的E key值默认为0x10001,security boot flow不支持自定义E key值。
RSA2048 :
-
生成 RSA2048 私钥
openssl genrsa -out private.pem 2048 -
生成 RSA2048 公钥
openssl rsa -in private.pem -out public.pem -outform PEM -pubout
5.7.1.2. 制作AES Key¶
AES用于加密固件。这边通过xxd tool来生成AES key binary file,制作方式适用于OTP里的8把 aes-128 key或者4把aes-256 key。可根据需求,多个Image使用同一把aes Key或者多个Image使用不同的aes Key。
AES-128 Key
5.7.2. 烧录OTP栏位¶
烧录OTP栏位的方法是使用SGS U‑Boot optpctrl Command,U‑Boot需要打开CONFIG_ARM_SMCCC,否则otpctrl命令无法进行读写操作。先编译一包普通不加签和加密的image烧录到SOC。
进入U‑Boot使用U‑Boot Command otpctrl 烧录 OTP_SECURITY_BOOT、 RSA KEY的LOCK和BLOCK、OTP_ROM_SELECT_AES_KEY等。
注意
- OTP只能烧写一次,一旦烧写则无法清除和重烧。为了防止误操作导致系统无法启动甚至IC作废,一般建议先使用Debug模式调试PASS以后,再进行正式OTP流程。
- Debug模式与正式模式的区别:
- 硬件:Debug模式不烧录OTP_SECURITY_BOOT栏位,正式模式需要烧录OTP_SECURITY_BOOT栏位。
- 软件:Debug模式下,Security_boot_tools会将IPL header里的AUTH栏位置1,rom code加载IPL、IPL加载IPL_CUST/TF-A/OPTEE、IPL_CUST加载LINUX会根据AUTH标记决定走验签启动流程。正式模式下,rom code加载IPL、IPL加载IPL_CUST/TF-A/OPTEE、IPL_CUST加载LINUX会根据OTP是否烧录 OTP_SECURITY_BOOT 标记决定走验签启动流程。
各参数含义详见Security Boot使用参考
根据公版的RSA2048和AES128,Debug模式为例:
####### RSA N-Key ########
otpctrl -w 0x0 0x0 0x083692f7;otpctrl -w 0x0 0x4 0x767a3811;otpctrl -w 0x0 0x8 0xee760a12;otpctrl -w 0x0 0xc 0x36981e3f;otpctrl -w 0x0 0x10 0x567d7c80;otpctrl -w 0x0 0x14 0x5386d79a;otpctrl -w 0x0 0x18 0xb30c364c;otpctrl -w 0x0 0x1c 0x0509b6ec;otpctrl -w 0x0 0x20 0x2d5b7fba;otpctrl -w 0x0 0x24 0x603faaa9;otpctrl -w 0x0 0x28 0xf6001bff;otpctrl -w 0x0 0x2c 0x65f24742;otpctrl -w 0x0 0x30 0xea1eb046;otpctrl -w 0x0 0x34 0x8279db13;otpctrl -w 0x0 0x38 0xfcda08f2;otpctrl -w 0x0 0x3c 0x7945946b;
otpctrl -w 0x0 0x40 0x5ab90d76;otpctrl -w 0x0 0x44 0xa62381c8;otpctrl -w 0x0 0x48 0xcfe07b8d;otpctrl -w 0x0 0x4c 0xd060c666;otpctrl -w 0x0 0x50 0x8934ad74;otpctrl -w 0x0 0x54 0x6e7b524b;otpctrl -w 0x0 0x58 0xd158d907;otpctrl -w 0x0 0x5c 0x4fbe917b;otpctrl -w 0x0 0x60 0x234cd758;otpctrl -w 0x0 0x64 0x6cc50b4f;otpctrl -w 0x0 0x68 0xd2a4c9ae;otpctrl -w 0x0 0x6c 0x92c7ef0c;otpctrl -w 0x0 0x70 0x839adec4;otpctrl -w 0x0 0x74 0x0cdd9bba;otpctrl -w 0x0 0x78 0xb2525bc1;otpctrl -w 0x0 0x7c 0x59b47c13;
otpctrl -w 0x0 0x80 0x438a1be1;otpctrl -w 0x0 0x84 0xd2e85ab1;otpctrl -w 0x0 0x88 0xc4c83dce;otpctrl -w 0x0 0x8c 0x606841ea;otpctrl -w 0x0 0x90 0x71dc495e;otpctrl -w 0x0 0x94 0xb0f26ac1;otpctrl -w 0x0 0x98 0xf8beac9b;otpctrl -w 0x0 0x9c 0x353c787f;otpctrl -w 0x0 0xa0 0xea55a5cf;otpctrl -w 0x0 0xa4 0xf7f8e4cd;otpctrl -w 0x0 0xa8 0x87f3fb58;otpctrl -w 0x0 0xac 0x6f3032b0;otpctrl -w 0x0 0xb0 0x7dba24a5;otpctrl -w 0x0 0xb4 0x7866ae54;otpctrl -w 0x0 0xb8 0xbdb3e5dd;otpctrl -w 0x0 0xbc 0x40c58158;
otpctrl -w 0x0 0xc0 0x7c3eadcc;otpctrl -w 0x0 0xc4 0xd93922e9;otpctrl -w 0x0 0xc8 0xc3cdaa7b;otpctrl -w 0x0 0xcc 0xfadfcd0d;otpctrl -w 0x0 0xd0 0xbb82dac5;otpctrl -w 0x0 0xd4 0x83d259a8;otpctrl -w 0x0 0xd8 0x99025f3c;otpctrl -w 0x0 0xdc 0x2de1b36a;otpctrl -w 0x0 0xe0 0xfe7c22c8;otpctrl -w 0x0 0xe4 0x15bb8c06;otpctrl -w 0x0 0xe8 0x4b975ff2;otpctrl -w 0x0 0xec 0xa91031eb;otpctrl -w 0x0 0xf0 0x8bfadaf0;otpctrl -w 0x0 0xf4 0x355b52e4;otpctrl -w 0x0 0xf8 0xfc4ac084;otpctrl -w 0x0 0xfc 0xcc317580;
####### RSA E-Key ########
otpctrl -w 0x1 0x0 0x00010001
# AES128_key1
otpctrl -w 0x5 0x0 0x03020100;otpctrl -w 0x5 0x4 0x07060504;otpctrl -w 0x5 0x8 0x0B0A0908;otpctrl -w 0x5 0xC 0x0F0E0D0C;
用otpctrl -r 0x5读到如下数据表示写AES key成功写入
[OTP ATF-32] operation = R, cmd = 5, off = 0, data = 0
Results:
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
5.7.3. OTP设置用aesKey128_1加密¶
otpctrl -w 0x24 0x0 0xFF000000
用otpctrl -r 0x24读到如下数据表示成功写入
[OTP ATF-32] operation = R, cmd = 24, off = 0, data = 0
Results:
0x00, 0x00, 0x00, 0xff,
5.7.4. 拷贝key到指定路径¶
-
拷贝RAS key
将上述生成的n对RSA key,替换project/image/security_boot_tools/下的rsa2048对应目录下需要用到的key binary文件。
-
拷贝AES key
将上述生成的aesKey_128.bin,替换成project/image/security_boot_tools/下的aesKey目录下对应的aesKey128_1.bin文件。
5.7.5. 配置文件sign_image.config¶
OTP烧录后接下来制作加签+加密的image,在已生成普通没有加签+加密的image的环境下,进入project/image/security_boot_tools/下,修改sign_image.config文件。
sw_debug=1 #置为1表示即使OTP没有烧录 OTP_SECURITY_BOOT 栏位,系统启动过程也会走security boot验签和解密流程。
ipl_aeskeynum=1 #IPL将使用security_boot_tools/aeskey/aesKey128_1.bin作为aes-key进行加密。
ipl_aeskeylen=128 #aeskey目录下有8把aes128和4把aes256,aeskeylen的值为128 或者256。和ipl_aeskeynum搭配使用。
5.7.6. 生成security image¶
sign_image.config修改完成后编译加密+加签的image,在project/image/security_boot_tools/下执行:
生成的image在:security_boot_tools/image_secure
生成USB升级的固件:
生成的固件在:security_boot_tools/image_secure/SgsUsbImage_xxx.bin
5.7.7. 检查系统打印¶
检查系统打印确认ROM->IPL->IPL_CUST->U-Boot已进行到SecurityBoot的flow。
ROM->IPL确认是否走SecurityBoot的方式
ROM验签IPL成功不会有任何log,但验签失败则会打印AUTH ERR(波特率可能需要调为115200,否则乱码)。
IPL->IPL_CUST->U-Boot确认是否走SecurityBoot的方式
查看log即可,一般带有Authenticate image关键字,若开启解密流程则还会有AES ECB关键字。
举例如下:
U-Boot -> kernel确认是否走SecurityBoot的方式
查看bootcmd中是否存在sigauth字段
5.7.8. 如何对自家制作的系统镜像进行手动签章¶
前面的操作都需要依赖提前编译好的SDK image包,如果是自家制作的系统镜像,请参考Security Boot手动签章使用参考
5.7.9 Thermal控制¶
主要温度点
| 温度点 | 阈值 | 说明 |
|---|---|---|
| 降频温度 | 115°C | 超过时自动降频 |
| 宕机温度 | 125°C | 超过时紧急关机 |
查看降频温度阈值:
查看宕机温度阈值:
设置温度点
设置降频温度阈值(如85000):
设置宕机温度阈值(如105000):
开启 1.7GHz 或 1.8GHz 后,CPU 要求的结温更低,不能超过95度(需更好的散热措施),且使用寿命会明显减少。
下一步:深入了解"开发"文档