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 完全没有关系,只是"使用方法尽量做到兼容"。
由此带来三条直接后果:
- 不能用 Xilinx SDK / Vitis 开发 PS 裸机 ,必须用复旦微的 Procise 生成 BSP/FSBL ,再用 IAR 编译调试裸机程序。
- 网上搜到的 Zynq 裸机代码、寄存器地址不能直接照搬,要按复旦微 BSP 的 API 改写。
- 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 安装顺序
建议按下面顺序安装,避免后期返工:
- Vivado 2018.3(安装时勾选支持 Zynq-7000 器件)。
- Procise(从复旦微"下载站"下载最新稳定版,找销售 / FAE 申请下载站账号)。
- IAR Embedded Workbench for ARM 8.x。
- CP210x USB 串口驱动(位于 Procise 安装目录
...\Procise\driver\UART)。 - 在 Procise 中关联 IAR 路径(见 2.3)。
软件获取:所有正式安装包都在复旦微下载站。找对应销售经理或 FAE 申请账号和网址(同一单位一般共享一个账号)。
2.3 在 Procise 中关联 IAR
安装好 Procise 和 IAR 后,需要让 Procise 能找到并唤起 IAR:
- 打开 Procise,菜单选择 Tools → Integrated Tools Options。
- 在对应器件的输入框中,浏览并选择 IAR 的安装根目录:
- IAR 8.x 路径填入 FMQL(fmql10 / fmql20 / fmql45)对应的框;
- IAR 9.x 路径填入 9.x 对应的框。
- 确定后,可用 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 前后需要打两个补丁,否则(尤其在高低温下)可能出现功能异常。补丁是保证所有芯片一致性的关键:
- IP patch(IP 补丁):在 Vivado 工程上执行,替换部分 IP/时序库。补丁包和操作手册在下载站,全系列通用。
- 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 第一次上电检查清单
新手拿到板子,第一次上电前按此检查:
- 用 Mini USB 线连接扩展板"USB-UART(PS)"口和电脑(用于看串口)。
- (做 JTAG 实验时)用 J-Link 接到 PL-JTAG 或按实验要求连接;先不接也可,纯看启动信息不强制。
- 拨码开关:先设为 JTAG 启动模式(MIO5/4/3 = 000) ,MIO6 = 0,JTAG 设级联,Bank1 按需。
- 接通电源(扩展板供电)。
- 打开串口工具(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 一切交互的总开关。
📌 使用铁律
- 没有配置 bit,不能使能 User Level Shifter。
- 原因:PL 中有 4 根中断直通线(16~19 号中断)连到 CPU 的 FIQ/IRQ。没有 bit 时这 4 根线是不定态 。若此时使能 Level Shifter 又打开了 CPU 中断,而中断处理函数还没初始化好,CPU 会进入非预期中断导致程序跑飞。
- 正确顺序:先下载/配置 bit → 再使能 User Level Shifter → 再访问 PL 资源。
- 什么时候需要手动使能?
- 📌 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 重新使能的两个前提
- User Level Shifter 必须已经使能;
- 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 通路概念:
- MIO JTAG:通过 MIO 访问 PS DAP;
- EMIO JTAG:通过 EMIO 访问 PS DAP;
- 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
- 打开 Procise,点 New Project。
- 工程名(如
memtest_demo,首字母不要用数字),选择无中文、无空格的路径,Next。 - Device Family 选
FMQL,Device 选45,Next。 - 不添加已有文件,Next → Finish。
- 在 Design 选项卡点 Create Block Design ,取名
system,OK。 - 在 BD 空白处右键 Add IP ,双击选择 processing_system7(版本号可能显示为 processing_system7:1.0)。
5.2 配置 PS(最小可用配置)
双击加入的 processing_system7_0,打开配置界面:
- MIO Configuration :
- 勾选 UART 0(用 MIO 出调试串口,波特率默认 115200);
- 确认 Bank 电压设置(Bank1 / bank501 按板子,AG102 常用 1.8V)。
- DDR Configuration :
- 勾选 Enable DDR;
- DDR 型号选 MT41K256M16 RE-125(与核心板 MT41K256M16HA-125IT:E 对应)。
- (为界面简洁)可在 PS-PL Configuration 中关掉用不到的
M AXI GP0 interface、FCLK_CLK0、FCLK_RESET0_N(纯 PS 实验用不到)。 - 点 OK,Ctrl+S 保存 BD。
5.3 生成输出产物并导出硬件
- 在左侧 Hierarchy 中右键
system→ Generate Output Products,确认生成成功。 - 右键工程 / BD → Export Hardware(Export hardware) :
- 模板勾选 MemoryTest (同时可勾 FSBL,后面固化要用);
- 确定,Procise 会在工程目录的
SDK/...下生成对应 IAR 工程。
5.4 在 IAR 中编译
- 选择 Project → Launch IAR(或 Launch SDK),在弹窗点 OK / 选择默认,进入 IAR。
- 在 IAR 左侧工作区找到 MemoryTest 工程,右键 → Rebuild All。
- 编译成功后,确认产物后缀为
.out(如不确定:右键工程 → Options → Linker → Output,确认输出后缀是.out)。
📌 后缀铁律 :IAR 编译的裸机程序必须以 .out 结尾(不要改成 .elf)。后面 u-boot 用 gcc 编译则必须是 .elf。bootgen 靠后缀区分用哪套规则打包。
5.5 连接 J-Link,下载调试
- 用 J-Link 连接板子(级联实验接到 PL-JTAG 即可看到链路),板子上电。
- 拨码设为 JTAG 启动模式(MIO5/4/3=000)、MIO6=0、级联。
- 在 IAR 中点击工具栏绿色的 Download and Debug 按钮。
- 弹窗中选择内核 Cortex-A7,OK,进入调试界面。
- 点 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;
- FMQL45 的 DDR 从
- 也可在
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
- 新建 Vivado 工程(如
led_emio),路径无中文空格;器件筛选并选择xc7z045ffg900-2。 - 点左侧 Create Block Design ,取名
system,OK。 - 空白处右键 Add IP ,选择 ZYNQ7 Processing System。
第 2 步:配置 Zynq PS
双击 processing_system7_0 打开配置:
- MIO Configuration → I/O Peripherals → GPIO :勾选 EMIO GPIO ,宽度(Width)设为 4。
- 将 Bank 1 电压设为 LVCMOS 1.8V。
- 为界面简洁,取消勾选用不到的端口:
FCLK_RESET0_N、M AXI GP0 interface、FCLK_CLK0;- 本例不用 DDR,取消勾选 Enable DDR(也可保留使能)。
- OK。
第 3 步:引出 EMIO 引脚、生成 HDL Wrapper
- 点上方 Run Block Automation → OK,自动引出管脚(若 GPIO 未自动引出,在管脚处右键 Make External)。
- 选中引出的 GPIO 端口,在左侧改名为
led4。 - 左侧 Sources → Hierarchy ,右键
system.bd:- Generate Output Products;
- 再右键 Create HDL Wrapper。
- 打开生成的
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 导入
- Procise 新建空工程(如
led4),器件选 FMQL → 45。 - 菜单 PSOC → From Vivado。
- 添加两个文件:
- 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
- Block Design 文件 (
- OK 后,在模板选择窗口选择需要的模板(如 HelloWorld;可同时选 FSBL)。
- OK,Procise 自动启动 IAR。
第 7 步:在 IAR 写 EMIO 控制代码
打开 helloworld.c(或对应模板主文件),加入 EMIO 点灯 / 流水灯代码。
📌 代码关键结构(务必照此顺序):
- (可选,需要时)调用 PS 初始化;
- 先使能 User Level Shifter(这是访问 PL/EMIO 的前提);
- 再通过 EMIO GPIO 的 BSP API 操作 4 个引脚,实现点灯 / 流水。
具体 API 写法请直接参考官方配套 demo 工程(APPN101 配套
...基于AG102...zip中的 EMIO 例程)以及 Peripheral Test 中的 GPIO 例程 。复旦微 BSP 没有逐行 API 手册,Peripheral Test 就是最权威的 API 用法示范。
第 8 步:先下 bit,再调试 app
- Procise 菜单 Tools → Configure Device。
- 双击 Connect to board,连到板子(级联模式能看到 ARM + FPGA)。
- 右键 FPGA 器件(fm/fm7z045)→ Assign New Configuration File ,选择 Vivado 生成的
system_wrapper.bit。 - 右键 → Program,下载 bit,PL 部分就绪。
- 📌 关键 :在 Windows 任务管理器结束
procise_jtag.exe进程(否则 IAR/J-Link 识别不到 JTAG)。 - 回到 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
- 新建 Vivado 工程(如
axi_led),器件xc7z045ffg900-2;Create Block Design 取名system。 - Add IP → ZYNQ7 Processing System :
- Bank1 设为 LVCMOS 1.8V;
- 按需 Enable DDR(型号 MT41K256M16 RE-125)。
- 再 Add IP → AXI GPIO :
- 双击 AXI GPIO,勾选 All Outputs ,GPIO Width 设为 7(或按需,如 4)。
第 2 步:自动连接
- 点 Run Block Automation → OK(引出 Zynq 的外部管脚)。
- 点 Run Connection Automation → 全选(All Automation) → OK。
- Vivado 会自动加入 AXI Interconnect 和 Processor System Reset,并把 AXI GPIO 连到 PS 的 GP0 口、复位和时钟连好。
- 把 AXI GPIO 引出的端口改名为
led。 - 右键
system.bd→ Generate Output Products → Create HDL Wrapper。 - 确认
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 驱动再做少量适配。
- Vivado 中 File → Export → Export Hardware (勾选 Include bitstream)→ Launch SDK。
- 在 SDK 的
system.hdf中可看到axi_gpio_0的基地址 (地址由 BD 分配,例如常见0x4120_0000,以实际为准)。 - SDK 中 File → New → Application Project ,取名
led(BSP 名建议以_bsp结尾,Procise 只复制_bsp结尾的包),Finish。 - 之后可关闭 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 给出的典型改动):
-
需要的头文件:
xil_assert.h、xil_types.h、xparameters.h、xstatus.h;
源文件:xil_assert.c、以及gpio_v4_x驱动目录下的所有.c/.h。 -
在 IAR 中右键
pl/include→ Add Files 加入这些文件。 -
适配修改:
-
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))
-
-
也可以完全不参考 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 启动模式恢复)。
固化前确认:
- DDR 稳定:用第 5 章 MemoryTest 做全地址测试。
- QSPI Flash 能正常读写 :用 Peripheral Test 的 QSPI 例程(覆盖擦 / 写 / 读 / 校验)。
- QSPI 的 MIO 引脚与 Boot Mode 引脚复用,若失败先查上下拉电阻;
- 可用 SLCR 的 Boot Mode 寄存器(
0xE0026404)确认模式引脚实际状态。
- Flash 工作频率:QSPI 控制器配置时钟不能大于 Flash 支持时钟的 4 倍 。
- 例如 Flash 最高 33MHz,控制器可选 120MHz;
- 网络 / HDMI 教程中常用 100MHz(满足多数 QSPI Flash)。具体以 Flash 手册为准。
7.3 修改裸机工程,使其可被固化
在 AXI/EMIO 流水灯工程基础上修改:
- 使能 DDR (在 PS 配置中勾选,型号正确);
- 使能 DDR 后 FSBL 搬运 bit 走 DDR;不使能则走 OCM。
- 勾选 UART,用硬件串口打印(因为固化后没有 IAR Terminal I/O)。
- 勾选并正确配置 QSPI Flash。
- 重新 Generate Output、From Vivado 导入,导出 HelloWorld、FSBL、MemoryTest、PeripheralTest、FlashLoader 等模板。
修改 HelloWorld 工程:
bspconfig.h:定义PS_PREINITED为 1 (PS 已在 FSBL 中初始化,应用里不要重复初始化)。- 📌 FSBL 自己的
bspconfig.h不要改。
- 📌 FSBL 自己的
- 按需要处理
platform.c(参考 APPN101 对应截图的两处改动)。 - 串口打印改用
fmsh_print,不要用printf:printf只输出到 IAR Terminal I/O;fmsh_print通过 UART 输出(需使能 UART,且STDOOT_BASEADDRESS正确指向 UART 控制器基地址)。
- 📌 运行地址不能和 FSBL 冲突 :
- FSBL 默认在 AXI SRAM;
- HelloWorld 默认在 AHB SRAM,不冲突,无需改;
- 自己改 icf 时要确保应用不覆盖 FSBL。
- Rebuild All(改了 bspconfig.h 必须全量重编)。
- 单独编译 FSBL 工程 ,生成
FSBL.out。
7.4 打包 BOOT.BIN
Procise 菜单 PSOC → Create Boot Image:
- 选择
.bif和.bin的输出目录。 - 点 Add 按顺序添加分区(📌 顺序不能错 ):
- FSBL.out(Partition type = bootloader,Destination CPU = APU);
- bit 位流 (
system_wrapper.bit,用到 PL 时必须紧跟 FSBL 添加;纯 PS 可省); - 应用
HelloWorld.out(Partition type = datafile)。
- 需要完整性校验时,把对应分区的 Checksum 选
sha2(每个分区可独立选择)。- 没有 DDR 的系统,FSBL 暂不支持对 bit 做 SHA2 校验。
- 点 Create Image ,生成
BOOT.BIN。
7.5 烧写 Flash(Procise 方式)
- 📌 J-Link 插到 PL-JTAG ;拨码切到 JTAG 启动模式;板子上电。
- Procise 菜单 PSOC → Program Flash :
- 选择要烧的
BOOT.BIN; - Flash 偏移地址设
0x0; - Flash 类型选
qspi0_single; - FSBL 保持默认。
- 选择要烧的
- 点 Program ,等待烧写完成(烧写信息会记录到
history_log.txt)。
烧写小经验:独立模式烧写时一般不要勾硬件复位,成功率更高;务必接好 JTAG 复位脚,多一个恢复手段。
7.6 QSPI 启动验证
- 板子下电。
- 拨码切到 QSPI Flash 启动(MIO5/4/3 = 100),MIO6=0。
- 重新上电:FSBL 自动运行 → 配置 bit → 跳转应用。
- 串口(用
fmsh_print输出)能看到启动和应用打印,LED 同时运行。固化成功。
7.7 其它烧写方式:IAR Flash Loader
也可用第三方 IAR Flash Loader 烧写(详见 APPN101 附录 A.3):
- Procise Export Hardware 选 FlashLoader → Launch IAR。
- 进入 flashloader 子工程,右键 → Options:
- Linker → Input :选择生成的
BOOT.bin; - Debugger → Download :选择对应 board 文件(如
qspi0flash-fmql_64K.board); - I-jet → Interface :选择
cascade.ProbeConfig(用 I-jet 时;用 J-Link 时按实际仿真器配置)。
- Linker → Input :选择生成的
- 编译 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):
- Vivado 中打开 implemented design → Bitstream 设置 → Enable Bitstream Compression = TRUE,重新生成 bit;
- Create Boot Image 时选 Import from existing BIF ,沿用原
.bif;给 bit 和应用分区的 Checksum 选 sha2,重新生成 boot.bin; - 把同一个
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):
-
装好系统并确认能联网。
-
配置
/bin/sh指向 bash (Ubuntu 默认是 dash):bashsudo rm /bin/sh sudo ln -s /bin/bash /bin/sh ls -al /bin/sh -
安装依赖库(参考 APPN104,按需安装):
bashsudo 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 -
安装交叉工具链------复旦微 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
- Procise 新建工程,双击 processing_system7:
- 勾选 SD 0 (MIO40~45;CD 用 MIO47、WP 用 MIO48;高速卡 speed 设 fast);
- Bank1 设 LVCMOS 1.8V;
- 勾选 UART 0(MIO50~51,默认配置)。
- Generate Output Products。
- 菜单 PSOC → Repositories :确认只有一个仓库(多个仓库导出会报错)。
- Export Hardware:勾选 FSBL 和 DeviceTree 。
- DeviceTree 文件夹位于工程
SDK/system_platform/DeviceTree。
- DeviceTree 文件夹位于工程
- Launch IAR ,编译 FSBL 工程,确认
ps_init.c配置无误,生成FSBL.out。 - 把 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:
- 选输出目录;
- Add FSBL.out(bootloader,APU);
- Add u-boot.elf(datafile);
- Create Image 生成
BOOT.BIN。
8.4.5 SD 卡启动 u-boot
- SD 卡用 FAT32 格式化,拷入
BOOT.bin。 - 插卡,拨码:Bank1 设 1.8V、启动方式设 SD(MIO5/4 = 1/1)。
- 上电,串口看到 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 卡分区(两种方式)
-
方式一(图形,推荐新手) :
- 第一个分区:FAT32(放 BOOT.bin、image.ub),设为可引导;
- 第二个分区: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)绝不能选错,否则会损坏其他磁盘。
拷贝文件并启动
- 把
BOOT.bin和image.ub拷到 SD 卡 FAT32 分区(Windows 只能识别 FAT32)。 - 插卡、接 USB 串口、Bank1=1.8V、拨码 SD 启动、上电。
- u-boot 自动引导,随后看到 Linux 启动日志。
- 📌 登录用户名
root,无密码。
用 SD Ext 分区作为根文件系统(而非 ramdisk)
默认 image.ub 把 rootfs.cpio.gz 打包进去,启动后用 ramdisk。想用 SD 卡 Ext 分区做根文件系统:
-
编辑 SDK 根目录
env.sh,设IMAGE_TYPE="SD",重新./build.sh image(此时 image.ub 只打 dtb + zImage); -
把
rootfs.cpio.gz拷到 SD 的 Ext 分区并解压:bashsudo su gunzip rootfs.cpio.gz cpio -idmv < rootfs.cpio -
重新启动,挂载的根文件系统就是 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:Buildrootmake menuconfig→ Host utilities → 勾选host environment-setup,重新编译。
8.6.2 用 gdbserver 在线调试
-
Buildroot 中使能:Toolchain →
Build cross gdb for the host;Target packages → Debugging →gdbserver。 -
编译带调试信息程序:
arm-linux-gcc -g -o hello hello.c。 -
程序拷到目标板(tftp / U 盘 / scp 均可),目标板启动:
bashgdbserver :1234 ./hello -
主机端连接:
basharm-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):
- 工程中加入 CDC 文件(须在 Elaborate 之后;可 Rerun Elaborate)。
- 双击 CDC 配置:
- 设置 Trigger Width(触发信号总宽,最大 256);
- Match Type:Basic(=,<>)、带边沿(R/F/B/N)、Extended(比较运算)、Range(范围)等;
- Data Depth:触发后采样点数(抓 UART/I2C 等慢协议要设大些);
- 分配触发 / 数据信号和采样时钟(可用 FCLK_CLK0)。
- Tools → ChipXplorer Analyzer:init_chain → 给 FPGA 下载带调试核的 bit → 打开 Trigger Setup / Waveform,配置触发并观测。
9.3 DDR 常见问题排查(高频)
现象:DDR 初始化不过 / Memtest 出错。按顺序排查:
- 对比官方 demo 板原理图,检查实际焊接;
- 颗粒 0.75V 参考电压是否接对(控制器侧可不接,颗粒侧建议接);
- UG102 强调的两个 DDR 电阻差异 、CKE 上下拉电阻;
- 上电顺序、POR 复位释放是否正常;
- 📌 MIO6 是否被拉高 (PLL 被 bypass → DDR 无法倍频)。读 SLCR BootMode 寄存器
0xE0026404可查 MIO2~8 实际电平; - 仍不行可降频到 400MHz试;
- 确认考虑了 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 的三大条件:
- icf 里预留 MMU 表空间 :MMU 基地址必须 16KB 对齐(页表基地址寄存器低 14bit 是属性位);
- 在
ps_init/ DDR 初始化完成之后再使能 D-Cache(否则 CPU 随机预取到未初始化 DDR,可能概率性卡死总线); 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 内核启动死机排查基本思路
- 确认
BOOT.bin(FSBL+u-boot)本身能正常进 u-boot; - 检查设备树(内存大小、console、时钟)是否正确;
- 串口 console 是否与实际 UART 一致(必要时用 earlycon);
- 用 u-boot 查看 / 校验 dtb、内核镜像地址;
- 打开内核早期打印,定位最后一条日志。
第 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 电路设计建议(复旦微差异)
- 复旦微不支持 PS、PL 同时联调 ,建议引出两个 JTAG,且 PS-JTAG 建议用 EMIO 引出;
- JTAG 的 nRST 与系统复位 SRST_B 相连,提高烧写稳定性;
- JTAG 建议用 Buffer 芯片;
- JTAG 链路模式脚 MIO2 建议接成可调(0 = 级联,1 = 独立),便于切换调试;
- 级联模式不能调试 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 设计七条通用准则:
- L2 Cache 共享 :不要直接 invalidate all,用 range 操作;由主核先初始化 L2(受
USE_AMP控制),主核初始化完再唤醒从核; - DDR 隔离:每个核页表把其他核内存空间设为无效;
- GIC 共享:Distributor 由 4 核共享(处理竞争)、CPU interface 每核独有;主核先初始化 GIC 再唤醒从核;
- 共享资源加锁:spin lock 变量放在使能 L1/L2 cache 的内存;或用 SGI / Flag 同步;
- 外设是共享资源:可让一个核访问外设、通过共享内存传递,规避并发;
- 📌 User Level Shifter 必须保持使能,否则影响所有 PS↔PL 交互;
- 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
📌 两条官方反复强调的高效习惯:
- 先在两个 FAQ 文档里搜关键字 / 用书签,大部分外设问题已有专章;
- 裸驱 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)版本不同时,界面可能略有差异,请以所用版本及官方最新文档为准。
欢迎评审并提出修改意见,后续版本将据此完善(计划补充:更多外设实操、截图、各芯片差异对照、常见错误码表等)。