FMQL15/20/45 (复旦微青龙系列 PSOC)新手使用说明

FMQL15/20/45 新手使用说明(复旦微青龙系列 PSOC)

适用读者:第一次接触复旦微电子(FMSH)青龙系列 PSOC 的软件 / 硬件 / FPGA 工程师。

目标:从零开始,照着本手册一步一步做,最终能够独立完成 FMQL45(以及同系列 FMQL10/15/20)的裸机开发、固件固化和 Linux 开发。

版本:v0.1(初稿,待评审修改)

配套硬件:FMQL45 DEMO 核心板 + DEMO 扩展板(AG102,子母板)


阅读约定

  • PS:Processing System,处理器系统(ARM 侧)。
  • PL:Programmable Logic,可编程逻辑(FPGA 侧)。
  • OCM:On-Chip Memory,片内存储器。
  • MIO / EMIO:PS 的多功能引脚 / 扩展到 PL 中的多功能引脚。
  • 文中带 📌 的内容是新手最容易踩坑、务必记住的要点。
  • 文中操作均以 Windows + Vivado 2018.3 + Procise + IAR 为准;Linux 编译在 Ubuntu 虚拟机中进行。

第 1 章 认识青龙系列 PSOC

1.1 这是一颗什么样的芯片

青龙系列是复旦微推出的"全可编程片上系统(PSOC)",把**多核 ARM 处理器(PS)**和 FPGA 可编程逻辑(PL)集成在同一颗芯片内。它的定位对标 Xilinx Zynq-7000 系列,但内部是复旦微全新设计,二者只是"用法尽量兼容",硬件本身并不相同。

常用型号:

型号 PS(全系列相同) PL 规模(约对标) 封装
FMQL10 / JFMQL10 4× Cortex-A7 Artix-7 级(较小) S400
FMQL15 / JFMQL15 4× Cortex-A7 介于 10 与 20 之间 T485
FMQL20 / JFMQL20 4× Cortex-A7 Kintex-7 级 S400 / S484
FMQL45 4× Cortex-A7 Kintex-7 级(较大,约对标 7045) T900 / T676

另有 JFMSP15/20/45 等型号,主要是 PSOC 的衍生版本,本手册暂不展开。

1.2 📌 最重要的一条认知:PS 与对标芯片完全不一样

请务必从一开始就建立这个概念:

青龙系列 PS 侧是 4 个 Cortex-A7(对标 Xilinx Zynq 是 2 个 Cortex-A9),属于全新设计。寄存器地址、外设 IP、BSP 与 Xilinx 完全没有关系,只是"使用方法尽量做到兼容"。

由此带来三条直接后果:

  1. 不能用 Xilinx SDK / Vitis 开发 PS 裸机 ,必须用复旦微的 Procise 生成 BSP/FSBL ,再用 IAR 编译调试裸机程序。
  2. 网上搜到的 Zynq 裸机代码、寄存器地址不能直接照搬,要按复旦微 BSP 的 API 改写。
  3. PL 侧与 Zynq-7000 引脚兼容,可用标准 Vivado 开发,但必须打复旦微的两个补丁(IP patch + bit patch)。

1.3 PS 与 PL 的关系(PSOC 的核心思想)

复制代码
                 ┌──────────────────────── FMQL45 ────────────────────────┐
                 │                                                          │
   DDR3(PS) ◄──── │  ┌────────────┐   AXI GP / HP / ACP / 中断 / FCLK         │
   1GB,32bit      │  │     PS     │◄──────────────────────────────┐          │
                 │  │ 4×Cortex-A7│                               │          │
                 │  │  +外设     │   EMIO / MIO                  ▼          │
                 │  └────────────┘                          ┌────────┐      │
                 │      MIO ──► UART/SD/USB/网口(直接出脚)   │   PL   │      │
                 │                                         │ (FPGA) │      │
                 │                                         └────────┘      │
                 └──────────────────────────────────────────────────────────┘
  • PS 像一颗独立的高性能 ARM SoC:4 核 A7,自带 UART、SD、USB、千兆网口、QSPI 控制器、DDR 控制器等。
  • PL 是一片 FPGA,可放自定义逻辑、各种 AXI 外设。
  • 二者通过 AXI 总线接口、中断、时钟(FCLK)、EMIO 紧密相连。这正是 PSOC 相对"ARM + 外挂 FPGA"方案的最大优势。

开发遵循"先硬件、后软件,从简单到复杂":先在 Procise/Vivado 里把 PS 配置和 PL 位流做好 → 导出到 IAR 写裸机程序 → 打包固化 → (需要时)再上 Linux。


第 2 章 开发环境搭建

2.1 工具链总览

工具 作用 推荐版本 备注
Vivado 开发 PL(FPGA),生成 bit 位流 2018.3 不支持更高版本;需打补丁
Procise 复旦微自研:配置 PS、生成 FSBL / 裸机 BSP / 设备树、关联 PL 工程、打包/烧写 下载站最新稳定版 新版免 License
IAR Embedded Workbench for ARM 编译、调试 PS 裸机程序 8.x(FMQL 系列) IAR 9.x 也可,但以 8.x 教程为主
CP210x 驱动 USB 转串口 随 Procise 自带 必装,否则看不到串口
Ubuntu 虚拟机(仅 Linux 开发需要) 编译 u-boot / kernel / rootfs Ubuntu 16.04 / 18.04 + VMware 见第 8 章

📌 版本对应关系 :FMQL10/15/20/45 裸机均用 IAR 8.x(IAR 9.x 主要面向更新的 100TAI 系列,但也能编译 FMQL)。新手直接装 IAR 8.x + Vivado 2018.3 最省心。

2.2 安装顺序

建议按下面顺序安装,避免后期返工:

  1. Vivado 2018.3(安装时勾选支持 Zynq-7000 器件)。
  2. Procise(从复旦微"下载站"下载最新稳定版,找销售 / FAE 申请下载站账号)。
  3. IAR Embedded Workbench for ARM 8.x。
  4. CP210x USB 串口驱动(位于 Procise 安装目录 ...\Procise\driver\UART)。
  5. 在 Procise 中关联 IAR 路径(见 2.3)。

软件获取:所有正式安装包都在复旦微下载站。找对应销售经理或 FAE 申请账号和网址(同一单位一般共享一个账号)。

2.3 在 Procise 中关联 IAR

安装好 Procise 和 IAR 后,需要让 Procise 能找到并唤起 IAR:

  1. 打开 Procise,菜单选择 Tools → Integrated Tools Options。
  2. 在对应器件的输入框中,浏览并选择 IAR 的安装根目录:
    • IAR 8.x 路径填入 FMQL(fmql10 / fmql20 / fmql45)对应的框;
    • IAR 9.x 路径填入 9.x 对应的框。
  3. 确定后,可用 Project → Launch IAR(或 Launch SDK)验证是否能正常唤起 IAR。

2.4 安装 USB 串口驱动

开发板用 CP2102(CP210x)做 USB 转串口。安装好驱动后,用 USB 线连接板子,在 Windows 设备管理器中应能看到一个 COM 口(如 Silicon Labs CP210x USB to UART Bridge (COMx))。

  • 看不到 COM 口:换 USB 线 / 重装驱动;
  • 端口号可在设备管理器中查看;
  • 串口参数:115200 / 8 / N / 1(FSBL 默认波特率 115200)。

推荐串口工具:MobaXterm、Tera Term、SecureCRT、串口调试助手等,能记录日志、支持中文显示即可。

2.5 工程路径的硬性要求

📌 所有工程路径(Vivado / Procise / IAR)都不能含中文字符、空格,路径不宜过长。

  • 正确示例:E:\work\fmql45\led_demo
  • 错误示例:E:\我的工程\LED 测试

Procise 工程名称首字母不能是数字 (如应取名 led_demo,不能叫 1led)。

2.6 Vivado PL 补丁(重要)

用 Vivado 开发 FMQL 的 PL,工程在生成 bit 前后需要打两个补丁,否则(尤其在高低温下)可能出现功能异常。补丁是保证所有芯片一致性的关键:

  1. IP patch(IP 补丁):在 Vivado 工程上执行,替换部分 IP/时序库。补丁包和操作手册在下载站,全系列通用。
  2. bit patch(位流补丁) :已集成在 Procise 的 Tools 菜单 中,对 Vivado 生成的未压缩 bit 进行处理。

新手第一遍做纯 PS 实验时可暂不涉及补丁;一旦要正式开发 PL,务必按下载站补丁手册操作,或联系 FAE 协助。


第 3 章 硬件准备:认识 AG102 开发板

本手册以 **FMQL45 DEMO 核心板 + DEMO 扩展板(AG102 子母板)**为例。核心板 + 扩展板的设计方便二次开发。

3.1 核心板组成

FMQL45 DEMO 核心板是一个最小系统:

  • FMQL45T900 主芯片;
  • PS 端 DDR3:2 片,共 1GB,32bit 数据位宽,最高数据速率 1066Mbps(时钟 533MHz,常温可更高,三温推荐 533MHz);
  • PL 端 DDR3:4 片,共 2GB,64bit 位宽;
  • 两个晶振:
    • 33.3333MHz ------ 给 PS 系统(PS_CLK);
    • 50MHz ------ 给 PL 逻辑;
  • 高速板间连接器,用于和扩展板相连。

核心板 6 片 DDR3 均为 Micron MT41K256M16HA-125IT:E ,每片 512MB。PS 侧在 Procise/Vivado 中可选用 MT41K256M16 RE-125(与 HA 版仅封装不同,宽度/深度/速度一致)。

3.2 扩展板接口

DEMO 扩展板引出了丰富的外设,便于学习和验证:

接口 说明
QSPI Flash 板载(启动 / 固化用),注意核对实际容量
千兆以太网(×1) Marvell 88E1116,接 PS 端,RJ45
USB 2.0(×1) USB3320(ULPI),Micro USB,支持 Host/Device/OTG
HDMI 输出(×1) SIL9134 编码芯片,最高 1080P@60Hz
USB 转 UART(×2) CP2102,一路接 PS MIO,一路接 EMIO,Mini USB
SD 卡座(×1) 放启动镜像 / Linux 系统
JTAG 接口(×3) PS-JTAG(14pin J15)、PL-JTAG(20pin J16)、USB-JTAG
用户 LED(×8) D9~D16,接 PL Bank11
用户按键(×5) KEY1~KEY5
拨码开关 SW3 / SW4 配启动模式;SW2 用户测试
40pin 扩展口 可接双目摄像头等

3.3 8 个用户 LED 的引脚(实验会反复用到)

8 个用户 LED 接在 PL Bank11,高电平熄灭、低电平点亮:

LED 引脚号 LED 引脚号
LED1 AJ24 LED5 AD23
LED2 AK18 LED6 AF24
LED3 AB29 LED7 AE23
LED4 AC27 LED8 AG25

按键引脚(按下为低):KEY1 = AK25、KEY2 = AH23、KEY3 = AB30、KEY4 = AC29、KEY5 = AH24。

3.4 📌 启动模式拨码开关(Boot Mode)

芯片上电时会采样 MIO3 / MIO4 / MIO5 的电平来决定启动方式;MIO2 决定 JTAG 级联 / 独立;MIO6 决定 PLL 是否使能;MIO7 选择 Bank500(MIO Bank0)电压,MIO8 选择 Bank501(MIO Bank1)电压。

启动方式(MIO5 / MIO4 / MIO3):

启动方式 MIO5 MIO4 MIO3
JTAG(最常用,级联) 0 0 0
NOR 0 0 1
NAND 0 1 0
QSPI Flash 1 0 0
SD Card 1 1 0

其它关键引脚:

引脚 取值与含义
MIO2(JTAG 链路) 0 = 级联(Cascade,常用);1 = 独立(Independent)
MIO6(PLL) 📌 必须接 0:3 个 PLL 正常使能;接 1 则 PLL 被 bypass,会导致串口乱码、DDR 初始化失败等典型问题
MIO7(Bank500 电压) 选择 Bank500(MIO Bank0,MIO0~15)的 IO 电压:1.8V 或 2.5V/3.3V
MIO8(Bank501 电压) 选择 Bank501(MIO Bank1,MIO16~53)的 IO 电压:1.8V 或 2.5V/3.3V

⚠️ 上面各 MIO 引脚在拨码开关上的"拨到 ON/OFF(0/1)↔ 电平 "对应关系,务必以扩展板 SW3/SW4 旁边的丝印表格(表 3-10-1)实物为准 (不同批次拨码的有效电平方向可能不同)。做 SD 启动、HDMI、网络时,Bank501 一般需要设为 1.8V。

3.5 第一次上电检查清单

新手拿到板子,第一次上电前按此检查:

  1. 用 Mini USB 线连接扩展板"USB-UART(PS)"口和电脑(用于看串口)。
  2. (做 JTAG 实验时)用 J-Link 接到 PL-JTAG 或按实验要求连接;先不接也可,纯看启动信息不强制。
  3. 拨码开关:先设为 JTAG 启动模式(MIO5/4/3 = 000) ,MIO6 = 0,JTAG 设级联,Bank1 按需。
  4. 接通电源(扩展板供电)。
  5. 打开串口工具(115200/8/N/1)。
    • JTAG 模式下芯片不主动运行程序,可能没有打印,这是正常的;
    • 若板载了出厂固件(QSPI/SD 启动),则能看到启动日志。

强烈建议:自己设计板子时一定要预留调试串口(哪怕只留两个测试焊盘)。串口是嵌入式调试的"眼睛",FSBL / u-boot / Linux 的所有信息都靠它输出。


第 4 章 PS-PL 交互的三大核心机制(务必理解)

这是复旦微 PSOC 区别于"理想 Zynq 体验"、新手最容易卡住的地方。先理解,后面所有实验都会用到。

4.1 机制一:User Level Shifter(电平转换总开关)

它是什么

User Level Shifter 是 PS 与 PL 之间的电平隔离 / 安全开关 ,作用是保证 PS 与 PL 之间的电压隔离与安全。上电后默认是关闭的,需要在"配置好 PL 位流(bit)之后"手动使能。

以下所有操作,都必须在使能 User Level Shifter 之后才能进行:

  • PS 使用 PL 的 FCLK 时钟;
  • PS 通过 AXI GP 访问 PL;
  • PS 访问 PL 的 EMIO 引脚;
  • PL 通过 HP 访问 PS 的 DDR。

它是 PS↔PL 一切交互的总开关。

📌 使用铁律

  1. 没有配置 bit,不能使能 User Level Shifter。
    • 原因:PL 中有 4 根中断直通线(16~19 号中断)连到 CPU 的 FIQ/IRQ。没有 bit 时这 4 根线是不定态 。若此时使能 Level Shifter 又打开了 CPU 中断,而中断处理函数还没初始化好,CPU 会进入非预期中断导致程序跑飞。
  2. 正确顺序:先下载/配置 bit → 再使能 User Level Shifter → 再访问 PL 资源。
  3. 什么时候需要手动使能?
    • 📌 JTAG 启动 + IAR 在线调试时 :因为 bit 是通过 JTAG 从外部"注入"的,PS 根本没运行,无法感知 bit 是否已加载,所以必须在应用程序里手动写使能 Level Shifter 的代码(APPN101 的 EMIO / AXI demo 里都有这段代码)。
    • QSPI / SD / NAND 自主启动时 :FSBL(以及 u-boot、Linux)会自动判断 bit 是否配置好,并在配置完 bit 后自动使能 Level Shifter,无需用户处理。

一句话记住:只要用 IAR 在线 JTAG 调试 PL,就在 app 里、配完 bit 之后手动使能 Level Shifter;固化自主启动则不用管。

4.2 机制二:HP 接口的"重新使能(HP Re-enable)"

为什么需要重新使能

  • HP(S_AXI_HP)是 PL 主动高带宽访问 PS DDR 的接口,共 4 路,只支持 64bit、只能访问 DDR(不能访问 OCM)。
  • FSBL 的 ps_init 会根据 Block Design 中是否勾选 HP 去使能它("第 1 次使能")。但此时 bit 还没加载、Level Shifter 也没使能 ,所以这次使能是无效功。
  • 因此在 FSBL 配置完 bit 之后,需要再使能一次 HP ------这就是"HP Re-enable(重新使能)"。

HP 重新使能的两个前提

  1. User Level Shifter 必须已经使能;
  2. HP 使用的时钟必须已稳定 :
    • 若 HP 用 PS 的 FCLK,FSBL 在重使能前默认延时约 5ms,足够时钟稳定;
    • 若 PL 用外部晶振 / 时钟芯片(尤其还要软件配置的时钟芯片),要按实际情况加大延时,确保时钟稳定后再重使能。

现象与处理

  • HP 没有 re-enable 成功的典型现象:HP 口完全没有任何动作(可用 ILA 抓信号确认)。
  • 📌 JTAG 在线调试时 :和 Level Shifter 一样,必须在 app 里手动增加 HP re-enable 代码(先使能 Level Shifter → 延时 ≥5ms → 重新使能 HP)。
  • 自主启动(QSPI/SD)时:新版 FSBL / u-boot / Linux 已自动处理(u-boot、Linux 驱动中已含 re-enable + 延时),无需用户干预。
  • 务必保持 FSBL 与 Block Design 的 HP 配置一致:逻辑工程师在 BD 里新增了 HP 口,软件就要重新生成 / 更新 FSBL,否则重使能会失败。

HP 大数据量要加 FIFO

复旦微 PSOC 的 DDR 控制器没有 Xilinx 那样的硬件 FIFO 。当 HP 访问 DDR 数据量很大、或同时使能多路 HP 时,可能出现 ready 信号拉不高(DDR 控制器响应不过来)。

  • 解决:在 HP 连接的 AXI SmartConnect / Interconnect 上加 FIFO(推荐 SmartConnect 加 FIFO;有用户反映 AXI Interconnect 加 FIFO 会影响带宽)。一般打开靠近 PS 一侧的 FIFO 即可,深度自定义。
  • 可用 ILA 抓 ready,并读 DDR 控制器状态寄存器(0xE00293FC)辅助判断:正常时该端口状态会动态变化;若一直非零表示某次 AXI 传输未结束。

HP 其它必记约束

  • 📌 HP 不支持 burst 跨 4KB 边界(不符合 AMBA 规范,Xilinx 同样建议不要跨)。自己写 RTL 直接驱动 HP 时尤其注意,否则可能表现为"明明维护了 cache,数据还是不对"。
  • GP / HP 接口设计最大频率 100MHz (接口频率),需要更高频率必须打最新的 IP patch;PL 内部模块工作频率可以更高。GP 访问 DDR 效率相对较低。

4.3 机制三:JTAG 级联模式 vs 独立模式

PSOC 有三条 JTAG 通路概念:

  1. MIO JTAG:通过 MIO 访问 PS DAP;
  2. EMIO JTAG:通过 EMIO 访问 PS DAP;
  3. PL JTAG:标准通路,可单独访问 PL,也可把 PS 和 PL 串成一条链(级联)访问。

级联模式(Cascade,新手默认)

  • JTAG 链路模式脚 MIO2 = 0。
  • PS 与 PL 在同一条 JTAG 链上:通过 PL-JTAG 可同时看到 / 访问 PS 和 PL。
  • 📌 APPN101 所有入门实验都用级联模式,把 J-Link 接到 PL-JTAG 即可完成全部实验(实验里不需要用 ILA 抓 PL)。
  • 用 J-Link 调试 PS 时:不要打开 Procise 的 Configure Device 并占用链路;若打开过要关闭,并在任务管理器结束 procise_jtag.exe 进程,否则 IAR/J-Link 识别不到 JTAG。

独立模式(Independent)

  • JTAG 链路模式脚 MIO2 = 1,PS 与 PL 之间的链被断开:通过 PL-JTAG 只能单独访问 PL。
  • 独立模式存在的主要意义:用 ILA 抓 PL 内部信号(PL 必须用 Xilinx/PL 下载线调试;PS 用 J-Link,两者无法用同一个仿真器)。
  • 通过 PL-JTAG 下载一个"打通 EMIO JTAG"的特殊 bit 后,才能经 EMIO JTAG 访问 PS(EMIO PJTAG 信号同样受 User Level Shifter 控制)。
  • 老版本芯片:独立模式用法见 APPN101 附录;新版本(u01/u02)有差异,下面 4.4 说明。

📌 调试器分工(复旦微与 Xilinx 的重要差异):

  • PL 用 PL JTAG 下载线(Xilinx 兼容 cable)
  • PS 用 J-Link(通用 ARM 仿真器)
  • 复旦微不支持 PL、PS 用同一个仿真器同时联调 。需要 PS/PL 同时调试时,建议把 EMIO JTAG 引出。

4.4 新版本 PSOC 的注意事项(u01 / u02)

青龙系列芯片在迭代中存在"老版本 / 新版本(u01、u02)"的区别,主要影响独立 JTAG 模式的用法:

  • u01 新版本 :要求出厂默认硬件级联(MIO2 = 0) ,由 FSBL 在运行时切换到独立模式;一旦有问题还可回退到级联。
  • u02 新版本:JTAG 用法优化得和"老版本"一致。
  • 所有 FMQL20 都是 u01 版本;FMQL15 为新版本;FMQL45 新老版本共存;FMQL10 只有老版本。

📌 如何区分手里芯片是哪个版本? 参考资料中的《青龙系列 PSOC 各个芯片版本如何区分》表格,或直接咨询 FAE。设计独立模式相关硬件前务必先确认版本。


第 5 章 裸跑快速上手:第一个 PS 程序

新手的第一个目标:不碰 PL,先让 PS 跑起来,看到串口输出,建立信心,并熟悉 Procise → IAR → J-Link 的完整链路。

我们用 Procise 导出一个 MemoryTest(内存测试) 模板(也可以用 HelloWorld)。它不需要 bit,纯 PS,能验证 J-Link、串口、DDR 是否正常。

5.1 在 Procise 中新建工程、添加 PS

  1. 打开 Procise,点 New Project。
  2. 工程名(如 memtest_demo,首字母不要用数字),选择无中文、无空格的路径,Next。
  3. Device Family 选 FMQL,Device 选 45,Next。
  4. 不添加已有文件,Next → Finish。
  5. 在 Design 选项卡点 Create Block Design ,取名 system,OK。
  6. 在 BD 空白处右键 Add IP ,双击选择 processing_system7(版本号可能显示为 processing_system7:1.0)。

5.2 配置 PS(最小可用配置)

双击加入的 processing_system7_0,打开配置界面:

  1. MIO Configuration :
    • 勾选 UART 0(用 MIO 出调试串口,波特率默认 115200);
    • 确认 Bank 电压设置(Bank1 / bank501 按板子,AG102 常用 1.8V)。
  2. DDR Configuration :
    • 勾选 Enable DDR;
    • DDR 型号选 MT41K256M16 RE-125(与核心板 MT41K256M16HA-125IT:E 对应)。
  3. (为界面简洁)可在 PS-PL Configuration 中关掉用不到的 M AXI GP0 interface、FCLK_CLK0、FCLK_RESET0_N(纯 PS 实验用不到)。
  4. 点 OK,Ctrl+S 保存 BD。

5.3 生成输出产物并导出硬件

  1. 在左侧 Hierarchy 中右键 system → Generate Output Products,确认生成成功。
  2. 右键工程 / BD → Export Hardware(Export hardware) :
    • 模板勾选 MemoryTest (同时可勾 FSBL,后面固化要用);
    • 确定,Procise 会在工程目录的 SDK/... 下生成对应 IAR 工程。

5.4 在 IAR 中编译

  1. 选择 Project → Launch IAR(或 Launch SDK),在弹窗点 OK / 选择默认,进入 IAR。
  2. 在 IAR 左侧工作区找到 MemoryTest 工程,右键 → Rebuild All。
  3. 编译成功后,确认产物后缀为 .out (如不确定:右键工程 → Options → Linker → Output,确认输出后缀是 .out)。

📌 后缀铁律 :IAR 编译的裸机程序必须以 .out 结尾(不要改成 .elf)。后面 u-boot 用 gcc 编译则必须是 .elf。bootgen 靠后缀区分用哪套规则打包。

5.5 连接 J-Link,下载调试

  1. 用 J-Link 连接板子(级联实验接到 PL-JTAG 即可看到链路),板子上电。
  2. 拨码设为 JTAG 启动模式(MIO5/4/3=000)、MIO6=0、级联。
  3. 在 IAR 中点击工具栏绿色的 Download and Debug 按钮。
  4. 弹窗中选择内核 Cortex-A7,OK,进入调试界面。
  5. 点 Go(运行) :
    • 打开 View → Terminal I/O 可看到 IAR 的终端输出;
    • MemoryTest 会进行内存读写测试。

第一次进入调试若连接失败,检查:J-Link 驱动是否正常、是否被 Procise 的 Configure Device / procise_jtag.exe 占用了链路、拨码是否为 JTAG 模式。

5.6(可选)改成全地址 DDR 压力测试

MemoryTest 默认测试范围较小。想做全面压力测试:

  • 在源码中修改测试起始地址与范围:
    • FMQL45 的 DDR 从 0x0010_0000 开始,最大到 0x3FFF_FFFF(低 1MB 是空洞,不可访问);
    • 例如把范围设为 0x3FF0_0000,即可遍历 0x10_0000 ~ 0x3FFF_FFFF;
  • 也可在 memory_ranges[] 数组中自定义测试区间;
  • 📌 不能超过实际 DDR 颗粒支持的范围。1GB 系统可跑满,小容量 DDR 要相应缩小。

结论意义:Memtest 能过 ≠ DDR 一定没问题,但跑不过 = DDR 一定有问题。新板卡建议把双 cache 使能后做全地址测试,更贴近真实使用场景。


第 6 章 PS + PL 经典实验

裸跑链路打通后,进入 PSOC 的精髓------PS 与 PL 协同。我们做两个递进实验:

  • 实验 6.A:PS 通过 EMIO 控制 PL 的 LED(最简单的 PS→PL);
  • 实验 6.B:PS 通过 AXI 总线(AXI GPIO)控制 PL 的 LED(最常用的工程模式)。

两个实验的硬件流程一致:Vivado 建 BD(含 Zynq PS)→ 生成 bit → 用 Procise 的 From Vivado 导入 → IAR 写程序 → 先下 bit、再调试 app。

6.A PS 通过 EMIO 控制 LED

第 1 步:Vivado 建工程、建 Block Design

  1. 新建 Vivado 工程(如 led_emio),路径无中文空格;器件筛选并选择 xc7z045ffg900-2。
  2. 点左侧 Create Block Design ,取名 system,OK。
  3. 空白处右键 Add IP ,选择 ZYNQ7 Processing System。

第 2 步:配置 Zynq PS

双击 processing_system7_0 打开配置:

  1. MIO Configuration → I/O Peripherals → GPIO :勾选 EMIO GPIO ,宽度(Width)设为 4。
  2. 将 Bank 1 电压设为 LVCMOS 1.8V。
  3. 为界面简洁,取消勾选用不到的端口:
    • FCLK_RESET0_N、M AXI GP0 interface、FCLK_CLK0;
    • 本例不用 DDR,取消勾选 Enable DDR(也可保留使能)。
  4. OK。

第 3 步:引出 EMIO 引脚、生成 HDL Wrapper

  1. 点上方 Run Block Automation → OK,自动引出管脚(若 GPIO 未自动引出,在管脚处右键 Make External)。
  2. 选中引出的 GPIO 端口,在左侧改名为 led4。
  3. 左侧 Sources → Hierarchy ,右键 system.bd:
    • Generate Output Products;
    • 再右键 Create HDL Wrapper。
  4. 打开生成的 system_wrapper.v,确认顶层已有 led4_tri_io 端口。

第 4 步:添加引脚约束

新建约束文件 system.xdc,把 4 个 EMIO 引脚绑到 4 个用户 LED(LVCMOS33):

xdc 复制代码
set_property PACKAGE_PIN AJ24 [get_ports {led4_tri_io[0]}]
set_property PACKAGE_PIN AK18 [get_ports {led4_tri_io[1]}]
set_property PACKAGE_PIN AB29 [get_ports {led4_tri_io[2]}]
set_property PACKAGE_PIN AC27 [get_ports {led4_tri_io[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led4_tri_io[*]}]

第 5 步:生成 bit

点 Generate Bitstream (Vivado 会自动综合、实现、生成 bit)。完成后记住 bit 路径:

...\led_emio.runs\impl_1\system_wrapper.bit。

正式工程请记得按补丁手册打 IP / bit 补丁;学习阶段可先跑通流程。

第 6 步:用 Procise 的 From Vivado 导入

  1. Procise 新建空工程(如 led4),器件选 FMQL → 45。
  2. 菜单 PSOC → From Vivado。
  3. 添加两个文件:
    • Block Design 文件 (.bd):
      {工程名}.srcs\sources_1\bd\system\system.bd
    • PS 配置文件 (.xci):
      {工程名}.srcs\sources_1\bd\system\ip\system_processing_system7_0_0\system_processing_system7_0_0.xci
  4. OK 后,在模板选择窗口选择需要的模板(如 HelloWorld;可同时选 FSBL)。
  5. OK,Procise 自动启动 IAR。

第 7 步:在 IAR 写 EMIO 控制代码

打开 helloworld.c(或对应模板主文件),加入 EMIO 点灯 / 流水灯代码。

📌 代码关键结构(务必照此顺序):

  1. (可选,需要时)调用 PS 初始化;
  2. 先使能 User Level Shifter(这是访问 PL/EMIO 的前提);
  3. 再通过 EMIO GPIO 的 BSP API 操作 4 个引脚,实现点灯 / 流水。

具体 API 写法请直接参考官方配套 demo 工程(APPN101 配套 ...基于AG102...zip 中的 EMIO 例程)以及 Peripheral Test 中的 GPIO 例程 。复旦微 BSP 没有逐行 API 手册,Peripheral Test 就是最权威的 API 用法示范。

第 8 步:先下 bit,再调试 app

  1. Procise 菜单 Tools → Configure Device。
  2. 双击 Connect to board,连到板子(级联模式能看到 ARM + FPGA)。
  3. 右键 FPGA 器件(fm/fm7z045)→ Assign New Configuration File ,选择 Vivado 生成的 system_wrapper.bit。
  4. 右键 → Program,下载 bit,PL 部分就绪。
  5. 📌 关键 :在 Windows 任务管理器结束 procise_jtag.exe 进程(否则 IAR/J-Link 识别不到 JTAG)。
  6. 回到 IAR,点 Download and Debug → 选 Cortex-A7 → OK → Go。

预期:4 个 LED(或 LED1~LED4)按程序点亮 / 流水。EMIO 实验完成。


6.B PS 通过 AXI GPIO 控制 LED(最常用模式)

与 EMIO 实验的区别:这次 PS 通过 AXI GP 总线 去访问挂在 PL 上的 AXI GPIO IP。这是实际项目中最常见的"PS 挂自定义 AXI 外设"模式,务必掌握。

第 1 步:Vivado 建 BD,加 Zynq PS + AXI GPIO

  1. 新建 Vivado 工程(如 axi_led),器件 xc7z045ffg900-2;Create Block Design 取名 system。
  2. Add IP → ZYNQ7 Processing System :
    • Bank1 设为 LVCMOS 1.8V;
    • 按需 Enable DDR(型号 MT41K256M16 RE-125)。
  3. 再 Add IP → AXI GPIO :
    • 双击 AXI GPIO,勾选 All Outputs ,GPIO Width 设为 7(或按需,如 4)。

第 2 步:自动连接

  1. 点 Run Block Automation → OK(引出 Zynq 的外部管脚)。
  2. 点 Run Connection Automation → 全选(All Automation) → OK。
    • Vivado 会自动加入 AXI Interconnect 和 Processor System Reset,并把 AXI GPIO 连到 PS 的 GP0 口、复位和时钟连好。
  3. 把 AXI GPIO 引出的端口改名为 led。
  4. 右键 system.bd → Generate Output Products → Create HDL Wrapper。
  5. 确认 system_wrapper.v 顶层有 led_tri_o。

第 3 步:约束 + 生成 bit

新建 system.xdc,把 AXI GPIO 输出绑到 LED:

xdc 复制代码
set_property PACKAGE_PIN AJ24 [get_ports {led_tri_o[0]}]
set_property PACKAGE_PIN AK18 [get_ports {led_tri_o[1]}]
set_property PACKAGE_PIN AB29 [get_ports {led_tri_o[2]}]
set_property PACKAGE_PIN AC27 [get_ports {led_tri_o[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led_tri_o[*]}]

点 Generate Bitstream。

第 4 步:(参考)在 Xilinx SDK 中看地址、准备 PL 驱动

复旦微 PS 的 BSP 与 Xilinx 无关,但 PL 侧 AXI IP(如 AXI GPIO)的驱动可以参考 Xilinx SDK 生成的 PL 驱动再做少量适配。

  1. Vivado 中 File → Export → Export Hardware (勾选 Include bitstream)→ Launch SDK。
  2. 在 SDK 的 system.hdf 中可看到 axi_gpio_0 的基地址 (地址由 BD 分配,例如常见 0x4120_0000,以实际为准)。
  3. SDK 中 File → New → Application Project ,取名 led(BSP 名建议以 _bsp 结尾,Procise 只复制 _bsp 结尾的包),Finish。
  4. 之后可关闭 Vivado/SDK。

第 5 步:Procise From Vivado 导入

同实验 6.A 第 6 步:新建 Procise 空工程(FMQL45)→ PSOC → From Vivado → 添加 system.bd + system_processing_system7_0_0.xci → 选择模板(HelloWorld / Empty + FSBL)→ 启动 IAR。

Procise 会在 IAR 工程的 FM_QL_bsp 下建立 ps_a7(PS 驱动)和 pl(PL 驱动路径索引)。

第 6 步:把 Xilinx 的 PL 驱动加进来并适配(如使用)

若复用 Xilinx AXI GPIO 驱动,把 SDK 生成的相关文件加入 IAR 的 pl 路径,并做最小改动以兼容复旦微平台(APPN101 给出的典型改动):

  1. 需要的头文件:xil_assert.h、xil_types.h、xparameters.h、xstatus.h;
    源文件:xil_assert.c、以及 gpio_v4_x 驱动目录下的所有 .c/.h。

  2. 在 IAR 中右键 pl/include → Add Files 加入这些文件。

  3. 适配修改:

    • xparameters.h:注释掉 #include "xparameters_ps.h";

    • xgpio_l.h:注释 #include "xil_io.h",改为 #include "fmsh_common_io.h";

    • 把寄存器读写宏替换为复旦微接口:

      c 复制代码
      #define XGpio_In32(addr)        FMSH_ReadReg((addr), 0x0)
      #define XGpio_Out32(addr, data) FMSH_WriteReg((addr), 0x0, (data))
  4. 也可以完全不参考 Xilinx,直接用复旦微 BSP 的寄存器读写 API 自己写 AXI GPIO 驱动(更简单,推荐新手在理解后采用)。

第 7 步:写应用代码

打开 helloworld.c(或主文件),清空模板内容,加入控制 AXI GPIO 的代码:

📌 顺序:先使能 User Level Shifter → (用 AXI GPIO 基地址)初始化 GPIO 为输出 → 循环写数据实现流水。

第 8 步:下 bit + 调试

步骤与实验 6.A 第 8 步完全相同 :Configure Device → 给 FPGA Assign bit → Program → 结束 procise_jtag.exe → IAR Download and Debug → 选 Cortex-A7 → Go。

预期:AXI GPIO 驱动的 LED 流水。到此你已掌握 PSOC 最核心的开发模式。

6.C 使用到 PL2PS 中断时的必记要点

如果自定义 PL IP 要通过中断通知 PS(PL2PS / F2P):

  • 📌 中断脉冲宽度至少 3 个 PS AXI 时钟周期(上升沿 / 高电平有效),否则可能采不到。PS AXI 时钟频率按 DS101 时钟章节计算。
  • PL2PS 共 16 个中断号:
    • 低 8 个 :复旦微与 Xilinx 中断号不同,裸跑自己移植驱动时要手动改中断号;
    • 高 8 个:与 Xilinx 一致。
    • Linux 下编译脚本会自动处理 PL 设备树的中断差异。
  • GIC 的初始化与用法,参考 Peripheral Test 的 TTC 例程(最经典的 GIC 用法示范)。

第 7 章 固件固化:从 QSPI Flash 自主启动

在线 JTAG 调试完成后,要让板子上电自启动 ,需要把 FSBL + bit + 应用 打包成 BOOT.BIN,烧到 QSPI Flash,并把拨码切到 QSPI 启动。

7.1 启动流程回顾

复制代码
上电 → BootROM(片内):判断启动方式,加载 FSBL 到 OCM
     → FSBL:初始化 PS(MIO/PLL/CLK/DDR)、配置 PL bit、加载并跳转应用(或 u-boot)
     → 应用 / u-boot(→ Linux)
  • FSBL(First Stage Bootloader):由 BootROM 加载到 OCM 运行,负责初始化 PS、下载 PL bit、加载并启动第二阶段程序或裸机应用。
  • 📌 FSBL 必须运行在 AXI SRAM(OCM)中。

7.2 固化前的准备:务必先测 DDR 和 QSPI

📌 不要在新板子上还没验证硬件就急着固化。 否则可能跑不起来、甚至一上电就跑飞导致 J-Link 连不上(那种情况需要切回 JTAG 启动模式恢复)。

固化前确认:

  1. DDR 稳定:用第 5 章 MemoryTest 做全地址测试。
  2. QSPI Flash 能正常读写 :用 Peripheral Test 的 QSPI 例程(覆盖擦 / 写 / 读 / 校验)。
    • QSPI 的 MIO 引脚与 Boot Mode 引脚复用,若失败先查上下拉电阻;
    • 可用 SLCR 的 Boot Mode 寄存器(0xE0026404)确认模式引脚实际状态。
  3. Flash 工作频率:QSPI 控制器配置时钟不能大于 Flash 支持时钟的 4 倍 。
    • 例如 Flash 最高 33MHz,控制器可选 120MHz;
    • 网络 / HDMI 教程中常用 100MHz(满足多数 QSPI Flash)。具体以 Flash 手册为准。

7.3 修改裸机工程,使其可被固化

在 AXI/EMIO 流水灯工程基础上修改:

  1. 使能 DDR (在 PS 配置中勾选,型号正确);
    • 使能 DDR 后 FSBL 搬运 bit 走 DDR;不使能则走 OCM。
  2. 勾选 UART,用硬件串口打印(因为固化后没有 IAR Terminal I/O)。
  3. 勾选并正确配置 QSPI Flash。
  4. 重新 Generate Output、From Vivado 导入,导出 HelloWorld、FSBL、MemoryTest、PeripheralTest、FlashLoader 等模板。

修改 HelloWorld 工程:

  1. bspconfig.h:定义 PS_PREINITED 为 1 (PS 已在 FSBL 中初始化,应用里不要重复初始化)。
    • 📌 FSBL 自己的 bspconfig.h 不要改。
  2. 按需要处理 platform.c(参考 APPN101 对应截图的两处改动)。
  3. 串口打印改用 fmsh_print ,不要用 printf:
    • printf 只输出到 IAR Terminal I/O;
    • fmsh_print 通过 UART 输出(需使能 UART,且 STDOOT_BASEADDRESS 正确指向 UART 控制器基地址)。
  4. 📌 运行地址不能和 FSBL 冲突 :
    • FSBL 默认在 AXI SRAM;
    • HelloWorld 默认在 AHB SRAM,不冲突,无需改;
    • 自己改 icf 时要确保应用不覆盖 FSBL。
  5. Rebuild All(改了 bspconfig.h 必须全量重编)。
  6. 单独编译 FSBL 工程 ,生成 FSBL.out。

7.4 打包 BOOT.BIN

Procise 菜单 PSOC → Create Boot Image:

  1. 选择 .bif 和 .bin 的输出目录。
  2. 点 Add 按顺序添加分区(📌 顺序不能错 ):
    1. FSBL.out(Partition type = bootloader,Destination CPU = APU);
    2. bit 位流 (system_wrapper.bit,用到 PL 时必须紧跟 FSBL 添加;纯 PS 可省);
    3. 应用 HelloWorld.out(Partition type = datafile)。
  3. 需要完整性校验时,把对应分区的 Checksum 选 sha2 (每个分区可独立选择)。
    • 没有 DDR 的系统,FSBL 暂不支持对 bit 做 SHA2 校验。
  4. 点 Create Image ,生成 BOOT.BIN。

7.5 烧写 Flash(Procise 方式)

  1. 📌 J-Link 插到 PL-JTAG ;拨码切到 JTAG 启动模式;板子上电。
  2. Procise 菜单 PSOC → Program Flash :
    • 选择要烧的 BOOT.BIN;
    • Flash 偏移地址设 0x0;
    • Flash 类型选 qspi0_single;
    • FSBL 保持默认。
  3. 点 Program ,等待烧写完成(烧写信息会记录到 history_log.txt)。

烧写小经验:独立模式烧写时一般不要勾硬件复位,成功率更高;务必接好 JTAG 复位脚,多一个恢复手段。

7.6 QSPI 启动验证

  1. 板子下电。
  2. 拨码切到 QSPI Flash 启动(MIO5/4/3 = 100),MIO6=0。
  3. 重新上电:FSBL 自动运行 → 配置 bit → 跳转应用。
  4. 串口(用 fmsh_print 输出)能看到启动和应用打印,LED 同时运行。固化成功。

7.7 其它烧写方式:IAR Flash Loader

也可用第三方 IAR Flash Loader 烧写(详见 APPN101 附录 A.3):

  1. Procise Export Hardware 选 FlashLoader → Launch IAR。
  2. 进入 flashloader 子工程,右键 → Options:
    • Linker → Input :选择生成的 BOOT.bin;
    • Debugger → Download :选择对应 board 文件(如 qspi0flash-fmql_64K.board);
    • I-jet → Interface :选择 cascade.ProbeConfig(用 I-jet 时;用 J-Link 时按实际仿真器配置)。
  3. 编译 flashloader,板子设 JTAG 模式上电,Download and Debug 运行即烧写。

📌 FlashLoader 的 mac 脚本(...\config\resources\qspiflash_fmql.mac)若带硬件复位可能导致 EMIO JTAG 断链;新版 Procise 已去掉该复位。升级 Procise 后建议删除 flashloader 目录重新生成。

7.8 Multiboot:多镜像冗余启动

Multiboot 可在一定程度上保障启动可靠性:在 Flash 中放多个镜像,当前镜像的某些区域数据出错时,自动跳转到下一个镜像继续启动。

  • 可跳转的出错区域:boot header、PL bit、usercode、u-boot 区域;
    • 📌 FSBL 区域数据错误无法跳转。
  • 因为 SHA 运算运行在 DDR,要 Multiboot 跳转必须使能 DDR。
  • 实验要点(AG102 板载 16MB QSPI,放两个未压缩镜像不够,需先压缩 bit):
    1. Vivado 中打开 implemented design → Bitstream 设置 → Enable Bitstream Compression = TRUE,重新生成 bit;
    2. Create Boot Image 时选 Import from existing BIF ,沿用原 .bif;给 bit 和应用分区的 Checksum 选 sha2,重新生成 boot.bin;
    3. 把同一个 BOOT.BIN 烧到 Flash 两个地址(如偏移 0x0 和 0x800000)。
  • 使能多镜像:在 fmsm_ps_parameters.h 中打开 FSBL_MULTI_BOOT_ENABLE 。启动失败时 FSBL 更新 multi_boot_reg 并软件复位重跑 BootROM,引导 Golden Image。

各启动方式 Boot Header 搜索范围:NOR 0~32MB、NAND 0~128MB、QSPI 0~16MB;SD 卡 multi_boot_reg=0 搜 BOOT.bin,非 0 搜 BOOT0000.bin。

7.9 Split 镜像:bit 与应用分离加载

当镜像较大时,FSBL 支持把 bit 和应用分置在不同地址 / 分区,按计算好的偏移分别存放与加载(split 镜像)。制作步骤见 APPN101 第 2.10 节(计算各部分地址偏移 → 制作 split 镜像 → 烧写 → 启动)。该功能也为"分离加载 bit 和 app、运行时固件升级"提供基础,参考汇总工程中的固件升级 demo。

7.10 eMMC 扩展:QSPI 引导 + eMMC 存大镜像

QSPI 容量有限时,可让 FSBL 从 QSPI 引导,其余镜像(bit / u-boot)从 eMMC 加载 :在 fmsm_ps_parameters.h 使能 MMC_SUPPORT,把只含 FSBL 的镜像烧到 QSPI,拨码 QSPI 启动,FSBL 运行后直接从 eMMC 加载其余内容。


第 8 章 Linux 开发入门

前提:已熟练掌握第 5~7 章的裸机开发。复旦微建议先裸跑、再上 Linux。

8.1 Linux 启动三阶段

复制代码
① BootROM:判断启动方式,加载 FSBL
② FSBL → 加载 u-boot;u-boot 负责引导 Linux
③ Linux 内核启动 → 挂载根文件系统(rootfs)

Linux 下 SD 卡启动需要两个文件:BOOT.bin (FSBL + u-boot,无 bit 或带 bit)和 image.ub(内核 + 设备树 + 可选 rootfs,FIT 格式)。

8.2 搭建 Linux 编译环境(Ubuntu 虚拟机)

需要一台 x86 Linux(推荐 VMware + Ubuntu 16.04 / 18.04):

  1. 装好系统并确认能联网。

  2. 配置 /bin/sh 指向 bash (Ubuntu 默认是 dash):

    bash 复制代码
    sudo rm /bin/sh
    sudo ln -s /bin/bash /bin/sh
    ls -al /bin/sh
  3. 安装依赖库(参考 APPN104,按需安装):

    bash 复制代码
    sudo apt update
    sudo apt install build-essential vim tofrodos iproute2 gawk gcc git make
    sudo apt install net-tools zlib1g-dev libssl-dev flex bison libselinux1
    sudo apt install libncurses5-dev device-tree-compiler u-boot-tools
  4. 安装交叉工具链------复旦微 Linux SDK 已自带交叉编译器,无需额外 Petalinux(Petalinux 仅在需要其工具时安装)。

📌 文件传输要点:

  • 用 VMware 共享目录(/mnt/hgfs)把 BSP 包拷进 Ubuntu 本地目录后再编译;
  • 不要直接在共享目录里编译(Windows 不支持软链接);
  • 不要用"复制粘贴大文件"的方式导入 BSP,可能导致编译出错。

8.3 Linux SDK 目录结构

向销售 / FAE 申请 FMQL-Linux-SDK(BSP 包),主要内容:

目录 / 文件 作用
u-boot-2018.07-fmsh u-boot 源码
linux-4.14.55-fmsh Linux 内核源码(生成 zImage)
buildroot-2018.02.3 生成根文件系统、(可重建)交叉编译器
device-tree 设备树源文件(dts/dtsi)
gcc-linaro-7.3.1-... SDK 自带交叉编译器
conf image.ub 配置
images 编译产物输出目录
build.sh / env.sh 一键编译脚本 / 环境变量脚本

build.sh 常用用法:./build.sh [选项] [目标]

  • 目标:dtb(设备树)、u-boot、kernel(内核)、rootfs、image(打包 image.ub)、all(全部)。
  • 常用选项:
    • --hw <设备树目录>:指定 Procise 导出的 PS 设备树文件夹;
    • --hdf <hdf文件>:指定 Vivado 导出的 PL 硬件描述;
    • --nofpga:没有 PL 时必加(默认按有 PL 处理);
    • --force:编译 u-boot/kernel 前先 distclean,切换芯片型号时使用。

8.4 第一步:制作 u-boot(只用 PS 的 SD + UART)

8.4.1 Procise 配 PS、导出 FSBL + DeviceTree

  1. Procise 新建工程,双击 processing_system7:
    • 勾选 SD 0 (MIO40~45;CD 用 MIO47、WP 用 MIO48;高速卡 speed 设 fast);
    • Bank1 设 LVCMOS 1.8V;
    • 勾选 UART 0(MIO50~51,默认配置)。
  2. Generate Output Products。
  3. 菜单 PSOC → Repositories :确认只有一个仓库(多个仓库导出会报错)。
  4. Export Hardware:勾选 FSBL 和 DeviceTree 。
    • DeviceTree 文件夹位于工程 SDK/system_platform/DeviceTree。
  5. Launch IAR ,编译 FSBL 工程,确认 ps_init.c 配置无误,生成 FSBL.out。
  6. 把 DeviceTree 文件夹 拷到 Ubuntu 本地(如 ~/Downloads/)。

8.4.2 编译设备树

在 Ubuntu 的 FMQL-Linux-SDK 根目录:

bash 复制代码
source env.sh        # 每个终端只需执行一次
./build.sh --hw ~/Downloads/DeviceTree/ --nofpga dtb
  • 📌 没配 PL 必须加 --nofpga。
  • 产物:images/system-top.dtb。

8.4.3 编译 u-boot

bash 复制代码
cd u-boot-2018.07-fmsh
make fmql_common_defconfig
make EXT_DTB=../images/system-top.dtb -j4
  • 成功后生成 u-boot(elf)、u-boot.bin、u-boot.srec。
  • 修改配置可用 make menuconfig(退出前 Save),make savedefconfig 可保存为 defconfig。
  • 把 u-boot 重命名为 u-boot.elf,拷出备用。

📌 u-boot 是 gcc 编译的,必须以 .elf 结尾 (不能改成 .out)。

8.4.4 打包 BOOT.bin(FSBL + u-boot,无 bit)

Procise PSOC → Create Boot Image:

  1. 选输出目录;
  2. Add FSBL.out(bootloader,APU);
  3. Add u-boot.elf(datafile);
  4. Create Image 生成 BOOT.BIN。

8.4.5 SD 卡启动 u-boot

  1. SD 卡用 FAT32 格式化,拷入 BOOT.bin。
  2. 插卡,拨码:Bank1 设 1.8V、启动方式设 SD(MIO5/4 = 1/1)。
  3. 上电,串口看到 u-boot 启动信息;进入命令行可输入 help 查看命令。

8.5 第二步:编译内核 + 根文件系统,启动完整 Linux

bash 复制代码
# 在 FMQL-Linux-SDK 根目录(已 source env.sh)
./build.sh kernel     # 编译内核,产物 linux-.../arch/arm/boot/zImage
./build.sh rootfs     # Buildroot 生成根文件系统 rootfs.cpio.gz
./build.sh image      # 把 dtb+zImage(+rootfs) 打包成 images/image.ub
  • 内核配置:cd linux-4.14.55-fmsh && make fmsh_fmql_defconfig,之后 make menuconfig 可改配置。
  • image.ub 是 FIT(Flattened Image Tree)格式 ,用 dts 语法的 .its 描述,把设备树、zImage、(可选)ramdisk 打成一个镜像。

SD 卡分区(两种方式)

  • 方式一(图形,推荐新手) :

    1. 第一个分区:FAT32(放 BOOT.bin、image.ub),设为可引导;
    2. 第二个分区:Ext4(用 SD 卡真实 rootfs 时使用;用 ramdisk 可不建)。
  • 方式二(脚本) :SDK 自带 tools/install_to_sd.sh,会格式化 SD 并把 rootfs 解压到 Ext 分区:

    bash 复制代码
    ./tools/install_to_sd.sh /dev/sdb images/rootfs.tar.bz2

    📌 设备名(/dev/sdb)绝不能选错,否则会损坏其他磁盘。

拷贝文件并启动

  1. 把 BOOT.bin 和 image.ub 拷到 SD 卡 FAT32 分区(Windows 只能识别 FAT32)。
  2. 插卡、接 USB 串口、Bank1=1.8V、拨码 SD 启动、上电。
  3. u-boot 自动引导,随后看到 Linux 启动日志。
  4. 📌 登录用户名 root,无密码。

用 SD Ext 分区作为根文件系统(而非 ramdisk)

默认 image.ub 把 rootfs.cpio.gz 打包进去,启动后用 ramdisk。想用 SD 卡 Ext 分区做根文件系统:

  1. 编辑 SDK 根目录 env.sh,设 IMAGE_TYPE="SD" ,重新 ./build.sh image(此时 image.ub 只打 dtb + zImage);

  2. 把 rootfs.cpio.gz 拷到 SD 的 Ext 分区并解压:

    bash 复制代码
    sudo su
    gunzip rootfs.cpio.gz
    cpio -idmv < rootfs.cpio
  3. 重新启动,挂载的根文件系统就是 Ext 分区内容。

8.6 Linux 用户程序:交叉编译与调试

8.6.1 用哪个编译器

SDK 里有两个交叉编译器:SDK 预装的、以及 Buildroot 构建的。因为根文件系统和库是 Buildroot 编译器编出来的,用户程序推荐用 Buildroot 编译器以获得最佳兼容性。

bash 复制代码
cd buildroot-2018.02.3/output/host
source environment-setup     # 导入后 CC 等变量已配置(如 arm-buildroot-linux-gnueabihf-gcc)
arm-linux-gcc hello.c -o hello
  • 若没有 environment-setup:Buildroot make menuconfig → Host utilities → 勾选 host environment-setup,重新编译。

8.6.2 用 gdbserver 在线调试

  1. Buildroot 中使能:Toolchain → Build cross gdb for the host;Target packages → Debugging → gdbserver。

  2. 编译带调试信息程序:arm-linux-gcc -g -o hello hello.c。

  3. 程序拷到目标板(tftp / U 盘 / scp 均可),目标板启动:

    bash 复制代码
    gdbserver :1234 ./hello
  4. 主机端连接:

    bash 复制代码
    arm-linux-gdb -tui ./hello
    (gdb) target remote <目标板IP>:1234

8.6.3 编译器迁移 / 备份

在 Buildroot 目录 make sdk,生成可重定位工具链;备份 output/host,拷到新位置后执行其中的 relocate-sdk.sh 即可(只修正绝对路径)。

8.7 常见 Linux 定制(设备树 + Buildroot)

需求 做法
改硬件配置 编辑设备树 system-user.dtsi(用户自定义,优先级高于板级 dtsi);./build.sh dtb
删除某节点 / 属性 用 /delete-node/、/delete-property/
静态 / 自动 IP 在自定义启动脚本里配置网络(参考 buildroot 文档);出厂测试镜像常用 192.168.1.10
开机自启脚本 Buildroot 加自定义 init 脚本(含 start/stop/restart),或用 user_custom.sh
FTP / SFTP / SSH 新版 BSP 在 Buildroot menuconfig 直接使能 vsftpd / openssh 等
看门狗 / DHCP Buildroot menuconfig 使能,重新 make
Qt / OpenCV Buildroot 集成对应 package(Qt 可离线放源码;OpenCV 用下载站 cortex-A7 库)
驱动模块(.ko) 内核 menuconfig 选 =m,make modules_install 安装到 overlay,modprobe 加载
根文件系统追加文件 放入 Buildroot 的 fmsh(overlay)目录;或用 post-build 脚本

📌 FTP/SSH 时间报错 :板子无 RTC 电池、时间过旧会导致登录报错,在启动脚本里 date -s "YYYY-MM-DD HH:MM" 设置一个不太旧的日期即可。

设备树文件层级(理解覆盖关系)

  • fmsh-psoc.dtsi:SDK 板级硬件,外设默认关闭;
  • pl.dtsi:Vivado 导出的 PL 配置;
  • system-user.dtsi:用户自定义;
  • system-top.dts:顶层(Procise 导出)。
  • 覆盖规则:dts 覆盖 dtsi;后引用的覆盖先引用的。

切换 UART1 控制台 / earlycon

  • 从 bsp-20220223 起,用内核启动参数 earlycon 切换串口控制台。
  • u-boot / Linux 切到 UART1:修改对应设备树(stdout 路径)并启用 earlycon。
  • PS UART 作普通通信口时,各种波特率以实际测试为准(详见 linux-faq 第 9 节)。

第 9 章 调试方法与常见问题排查

9.1 IAR 常用调试手段

手段 操作 用途
查看寄存器 / 内存 / 变量 View → Memory / Locals / Registers Locals 某些变量提示 unavailable:把优化等级改 None
函数调用栈 View → Call Stack 定位跑飞位置
单步 / 断点 工具栏按钮 普通断点、数据断点、条件断点(View → Breakpoints)
终端输出 View → Terminal I/O 调试 printf(固化后用 fmsh_print 走 UART)
反汇编 View → Disassembly / 工具输出 对照汇编与源码,排查 bin 异常
复位方式 Options → Debugger 调试 DDR 应用选 Software 复位(只复位 CPU PC,不复位 DDR 控制器)

📌 栈 / 堆太小导致莫名异常 :检查 CSTACK、中断栈大小。跑在 DDR 时建议直接把栈改到 1MB 以上(ttc 中断打印常因中断栈过小异常)。

9.2 PL 在线调试:ChipXplorer(类比 ILA)

Procise 自带 ChipXplorer 在线抓 PL 内部信号(对应 Xilinx ILA):

  1. 工程中加入 CDC 文件(须在 Elaborate 之后;可 Rerun Elaborate)。
  2. 双击 CDC 配置:
    • 设置 Trigger Width(触发信号总宽,最大 256);
    • Match Type:Basic(=,<>)、带边沿(R/F/B/N)、Extended(比较运算)、Range(范围)等;
    • Data Depth:触发后采样点数(抓 UART/I2C 等慢协议要设大些);
    • 分配触发 / 数据信号和采样时钟(可用 FCLK_CLK0)。
  3. Tools → ChipXplorer Analyzer:init_chain → 给 FPGA 下载带调试核的 bit → 打开 Trigger Setup / Waveform,配置触发并观测。

9.3 DDR 常见问题排查(高频)

现象:DDR 初始化不过 / Memtest 出错。按顺序排查:

  1. 对比官方 demo 板原理图,检查实际焊接;
  2. 颗粒 0.75V 参考电压是否接对(控制器侧可不接,颗粒侧建议接);
  3. UG102 强调的两个 DDR 电阻差异 、CKE 上下拉电阻;
  4. 上电顺序、POR 复位释放是否正常;
  5. 📌 MIO6 是否被拉高 (PLL 被 bypass → DDR 无法倍频)。读 SLCR BootMode 寄存器 0xE0026404 可查 MIO2~8 实际电平;
  6. 仍不行可降频到 400MHz试;
  7. 确认考虑了 PCB 的 Pin delay。

其它 DDR 要点:

  • 📌 DDR 从 0x10_0000 开始,低 1MB 是空洞,最大 1GB;
  • DDR3 Pin swap:Byte 内可调换;Byte 间可调换但 DQS 要跟着换;地址线不能 swap;
  • 16bit 系统:ECC 不要使能(PSOC DDR ECC 不可用,某些 Procise 版本会自动使能);不支持单颗 1GB(行地址最大 15bit)。

9.4 Cache 使能要点(与 Xilinx 不同)

📌 Xilinx 在 BSP 汇编里就开了 cache;复旦微需要在 main 入口主动调用 icache_enable / dcache_enable(dcache 使能会设置 SMP bit;新版 FSBL 汇编已开 SMP)。

使能 D-Cache 的三大条件:

  1. icf 里预留 MMU 表空间 :MMU 基地址必须 16KB 对齐(页表基地址寄存器低 14bit 是属性位);
  2. 在 ps_init / DDR 初始化完成之后再使能 D-Cache(否则 CPU 随机预取到未初始化 DDR,可能概率性卡死总线);
  3. mmu_table.s 各区域属性正确 :仅调 dcache_enable() 不够,要靠页表控制每个区域(如 GMAC DMA 描述符需放 uncacheable 区,且 cache line 对齐)。

📌 DDR-Less + 使能 cache :必须把 mmu_table.s 中 DDR 空间页表项改为无效,防止使能 cache 后随机预取访问空洞导致卡死。

9.5 QSPI / Flash 常见问题

  • 固化失败:先确认 MIO 上下拉、Flash 频率(控制器时钟 ≤ Flash×4)、MIO 改成 fast(千兆场景);
  • 不支持 Parallel 4bit(stack 双 Flash)模式启动;
  • 老版本 BootROM 仅支持 3 字节寻址;新版本已修复;
  • XIP(在 Flash 上直接运行):代码量大时性能差,只能当单片机用;XIP 下 Flash 频率不能太高;
  • 烧写断链:检查 FlashLoader 的 mac 复位、EMIO/MIO JTAG 是否被复位。

9.6 网络(lwip / GMAC)常见问题

  • PHY:用 GPIO 复位 PHY、PHY 不能用 3.3V 电平、正确设置 TX/RX delay;
  • MIO 出 RGMII 跑千兆:MAC 的 MIO 设 fast;
  • 完全不通:先用 Peripheral Test 的 GMAC PHY 回环验证硬件;
  • lwip 版本:性能优化版从 Procise 20210527 起;GMAC DMA 描述符放 uncacheable 区;
  • 调试:定义 LWIP_DEBUG=1 或改 lwipopts.h;
  • Linux 双网口冗余:用 bond;双 GMAC 可共享 MDIO。

9.7 内核启动死机排查基本思路

  1. 确认 BOOT.bin(FSBL+u-boot)本身能正常进 u-boot;
  2. 检查设备树(内存大小、console、时钟)是否正确;
  3. 串口 console 是否与实际 UART 一致(必要时用 earlycon);
  4. 用 u-boot 查看 / 校验 dtb、内核镜像地址;
  5. 打开内核早期打印,定位最后一条日志。

第 10 章 自研硬件设计要点(硬件工程师)

如果要基于 FMQL45 设计自己的板子,重点参考《原理图功能点 CheckList》和《PCB 设计手册》。以下为关键摘要。

10.1 电源

电源 标称电压 说明
VCCPINT 1.0V PS 内核
VCCPAUX 1.8V PS 辅助
VCCPLL 1.8V PS PLL
VCCO_DDR 1.2~1.5V 📌 即使不用 DDR 也必须供电
VCCO_MIO0 1.8~3.3V MIO 0~15
VCCO_MIO1 1.8~3.3V MIO 16~53
VCCINT 1.0V PL 内核
VCCAUX 1.8V PL 辅助
VCCO_# 1.2/1.5/1.8/2.5/3.3V 各 PL Bank 独立可配

📌 PS 推荐上电顺序 :VCCPINT → VCCPAUX 和 VCCPLL → PS VCCO。上电时 IO 为三态;PS_POR_B 在 VCCPINT/VCCPAUX/VCCO_MIO0 达到最低工作电压前保持低。

10.2 时钟与复位

  • PS 时钟:AG102 用 33.3333MHz 晶振;PL 用 50MHz。
  • 复位:
    • PS_POR_B :电源域 VCCO_MIO0;上电复位,会重新采样 Boot Mode;
    • PS_SRST_B :电源域 VCCO_MIO1;系统复位,不重新采样 Boot Mode;
    • 📌 PS 复位不会清除 PL 逻辑(Xilinx 会清);看门狗复位效果等同系统复位。
  • 外部 MCU 复位 PSOC:建议接 POR(POR 会清 multiboot 寄存器;系统复位不会,可能导致一直 multiboot 失败)。硬件无法改时可关闭 FSBL 的 multiboot。

10.3 Bank0 配置引脚

信号 推荐接法
CFGBVS 建议接成可选;📌 任何 VCCO0 电压下都用 100Ω 上拉到 VCCO0,保证 JTAG 稳定
PUDC_B 通过 ≤1KΩ 电阻下拉到地(配置时使能内部上拉)
VREFP(XADC) 不用 XADC 时接 0.1µF 到地;外部参考时接 1.25V;📌 VCCADC 必须供电
JTAG TCK/TMS/TDI/TDO 各 4.7K 上拉;nRST 接系统复位
  • 多芯片 JTAG 级联:用菊花链,在 TCK/TMS 拓扑中加驱动芯片;做好 TCK/TMS 信号完整性。

10.4 JTAG 电路设计建议(复旦微差异)

  1. 复旦微不支持 PS、PL 同时联调 ,建议引出两个 JTAG,且 PS-JTAG 建议用 EMIO 引出;
  2. JTAG 的 nRST 与系统复位 SRST_B 相连,提高烧写稳定性;
  3. JTAG 建议用 Buffer 芯片;
  4. JTAG 链路模式脚 MIO2 建议接成可调(0 = 级联,1 = 独立),便于切换调试;
  5. 级联模式不能调试 PL,调试 PL 必须切独立模式(MIO2 = 1)。

10.5 外设设计差异(与 Xilinx)

  • SD 启动 :📌 只能用 SDIO0(MIO40~45) 。
    • 注意:早期差异文档要求 MIO46 接卡检测 / 接地 ;较新 CheckList(新版本芯片)说明 MIO46 无需接卡检测、兼容原厂 。请以手里芯片版本和最新 CheckList 为准,新板建议 MIO 模式脚接成可调。
  • USB :早期差异文档称仅支持 USB1.0 / 低 + 全速、不支持高速(480M),且三个状态标识不支持 EMIO;较新 CheckList 列出 USB2.0 含高速、ULPI。📌 此差异同样源于芯片版本,设计前以芯片版本 + 最新手册 / FAE 确认为准。
  • SMC :写使能 WEn 在 MIO2(Xilinx 在 MIO8)。
  • XADC :复旦微仅支持 8 路辅助模拟通道 ,硬件通道与 DRP 读取通道不是一一对应:
    • 硬件引脚用通道:0,1,2,3,8,9,10,11;
    • DRP 读取通道:0,1,10,11,8,2,3,4;
    • XADC IP 须勾选:0,1,2,3,4,8,9,10,11。

10.6 PCB 设计

  • 必须使用按器件型号提供的 Pin delay 文件;
  • DDR 严格做信号完整性(阻抗、等长、端接);
  • JTAG 布线参考《JTAG 级联 PCB 布线推荐》;
  • 注意器件上下电时序(参见《PSOC 器件上下电设计指导》及《下电时序不满足导致 QSPI Flash 被误写的机理说明》)。
  • Flash 选型:参考《Flash 支持列表(高可靠)》,速率以 Flash 手册为准。

第 11 章 进阶方向:FreeRTOS、AMP

11.1 FreeRTOS

Procise 可像生成 HelloWorld 一样直接导出 FreeRTOS 模板(含 BSP)。常用组合:

  • FreeRTOS + LwIP :参考汇总工程 汇总工程-freertos相关/freertos_lwip,配套《FreeRTOS 上移植 LwIP》文档;
  • FreeRTOS 工程常改到 DDR 运行(任务 / 栈需要更大空间),注意 icf 与 FSBL 不冲突;
  • 在线调试与固化方法见《FreeRTOS 在线调试和固化》文档。

11.2 AMP(非对称多处理)

AMP 指在 4 个 A7 核上分别跑不同系统 / 任务(如核0 跑 Linux,其余核跑裸机 / FreeRTOS)。复旦微提供大量配套 demo(linux + baremetal、Linux + FreeRTOS、四核裸跑等,见汇总工程 AMP 目录)。

📌 AMP 设计七条通用准则:

  1. L2 Cache 共享 :不要直接 invalidate all,用 range 操作;由主核先初始化 L2(受 USE_AMP 控制),主核初始化完再唤醒从核;
  2. DDR 隔离:每个核页表把其他核内存空间设为无效;
  3. GIC 共享:Distributor 由 4 核共享(处理竞争)、CPU interface 每核独有;主核先初始化 GIC 再唤醒从核;
  4. 共享资源加锁:spin lock 变量放在使能 L1/L2 cache 的内存;或用 SGI / Flag 同步;
  5. 外设是共享资源:可让一个核访问外设、通过共享内存传递,规避并发;
  6. 📌 User Level Shifter 必须保持使能,否则影响所有 PS↔PL 交互;
  7. SLCR 在 AMP 时保持 unlock:避免一核加锁后另一核操作失败。

新手做 AMP:直接从官方 AMP demo(含 mmu_table 关键区域保护)开始改,先跑双核 hello/IPI,再逐步替换业务逻辑。

11.3 其它可探索方向

  • PL 部分重配置(PR)、XVC 调试;
  • MicroBlaze 在 PL 中协同;
  • Ubuntu 18.04 文件系统(资料包提供 ql10~ql45 rootfs);
  • PS 性能基准(Dhrystone / Whetstone / Linpack / NEON / HPL / SPECint)。

第 12 章 资料索引与学习路径

12.1 推荐学习路径

复制代码
第1步:读《QL10~QL45 PSOC 入门资料详细说明》+ 本手册第1~4章,建立认知
第2步:做 APPN101(从 2.3 节 PS+PL 实验开始,纯PS/PL流程也过一遍)
        ├─ 配 Procise + Vivado + IAR 环境
        ├─ EMIO / AXI GPIO 点灯
        ├─ MemoryTest 测 DDR
        └─ Flash 固化、Multiboot
第3步:查《裸跑-faq 汇总》+ Peripheral Test,学习各外设 BSP API
第4步:需要 Linux:做 APPN104,用 build.sh 编译 u-boot/kernel/rootfs
第5步:查《linux-faq 汇总》,进阶 FreeRTOS / AMP / PR / Qt / OpenCV

📌 两条官方反复强调的高效习惯:

  1. 先在两个 FAQ 文档里搜关键字 / 用书签,大部分外设问题已有专章;
  2. 裸驱 API 看 Peripheral Test 例程------BSP 没有详细 API 手册,例程就是最好的文档。

12.2 核心文档清单

文档 用途
《QL10~QL45 PSOC 入门资料详细说明》 资料导航总纲(先读)
APPN101 开发平台基础教程 裸机入门主教程(配 demo 工程)
APPN102 Procise 使用教程 Procise 全流程
APPN103 Procise from Vivado Vivado 导入、不兼容项、DDR 映射
APPN104 Linux 应用教程 Linux BSP / build.sh 全流程
《FMQL 系列开发差异说明》 与 Xilinx 总体差异
《裸跑-faq 汇总》 裸机排故 + 配套 demo(主文档)
《linux-faq 汇总》 Linux 排故(主文档)
《原理图功能点 CheckList》 自研硬件必看
《PSOC 器件上下电设计指导》 电源 / 时序
《JTAG 级联 PCB 布线推荐》 JTAG 硬件设计
《FlashLoader Buglist & 错误排查手册》 烧录问题
AG102 开发板用户手册 板子接口 / 拨码 / 原理图
《青龙系列 PSOC 芯片版本如何区分》 u01/u02/老版本判别

DS101(产品手册,对标 ug585)、DS102(寄存器列表)、UG102/103/104(差异手册)、UG201(PCB 手册)等需向销售 / FAE 单独申请。

12.3 关键地址速查

项目 地址 / 值
DDR 起始 / 最大 0x0010_0000 ~ 0x3FFF_FFFF(低 1MB 空洞)
AXI SRAM(FSBL 运行处) 0x0002_0000 ~ 0x0005_FFFF(256KB)
AHB SRAM(裸机 app 默认) 0xE1FE_0000 ~ 0xE1FF_FFFF(128KB)
SLCR BootMode 寄存器 0xE0026404(查 MIO2~8 状态)
DDR 控制器 HP 状态寄存器 0xE00293FC
串口参数 115200 / 8 / N / 1

12.4 技术支持

  • 软件安装包、补丁、BSP:复旦微下载站(找销售 / FAE 申请账号);
  • 遇到怀疑 BSP bug 的情况:📌 原则上不要直接改 BSP ,先与技术支持确认;确需临时修改请备份原始 .c,或把函数拷到自己应用里改,避免改乱后难以维护升级。

附:版本说明

本手册为 v0.1 初稿 ,基于 FMQL45 / AG102 资料整理,覆盖青龙系列共性(PS 侧全系列相同)。

因原始资料中部分操作步骤以软件截图呈现,本手册已将其转写为文字 + 菜单路径;实际软件(Procise / Vivado / IAR)版本不同时,界面可能略有差异,请以所用版本及官方最新文档为准。

欢迎评审并提出修改意见,后续版本将据此完善(计划补充:更多外设实操、截图、各芯片差异对照、常见错误码表等)。

相关推荐
漫漫长远2 小时前
低功耗UPF介绍(一)
笔记·嵌入式硬件·学习·fpga开发
自小吃多14 小时前
【Verilog/FPGA】存储器(数组)
嵌入式硬件·fpga开发
szxinmai主板定制专家14 小时前
RK3588+FPGA异构架构|高速数据采集+边缘AI落地应用全解析
人工智能·嵌入式硬件·fpga开发·架构·zynq
明德扬19 小时前
FPGA MIPI 多路视频聚合方案
fpga开发·mipi视频拼接·mipi多路拼接·mipi协议·mipi视频拼接方案·fpga mipi方案·mipi csi
XMAIPC_Robot19 小时前
为什么大型储能需要边缘 AI 协调控制器?RK3588+FPGA 高速采集方案
人工智能·嵌入式硬件·fpga开发·arm+fpga·rk3588+fpga·协调控制器
szxinmai主板定制专家19 小时前
RK3576+CODESYS+RK182X+FPGA异构架构:半导体精密设备一体化控制器方案
人工智能·fpga开发·架构·rk3576+codesys
szxinmai主板定制专家20 小时前
半导体设备控制器:RK3576+CODESYS+RK182X异构架构,实现晶圆视觉检测与运动联动闭环
人工智能·fpga开发·架构·视觉检测·边缘计算·codesys·rk3576
szxinmai主板定制专家21 小时前
FPGA高速IO+RK182X AI算力|RK3576+CODESYS工业自动化运动控制平台设计
运维·人工智能·嵌入式硬件·fpga开发·自动化·zynq
FPGA小徐21 小时前
原理图分析:Type-C 转串口(CH340C)最小系统板 CSDN 博客
fpga开发