1. 问题背景与现象描述
最近在使用Terasic DE25-Nano开发板进行FPGA开发时,遇到了一个Uboot阶段无法直接访问FPGA外设的问题。具体来说,当我尝试在Uboot命令行中使用内存写命令(mw)操作LED对应的寄存器时,系统提示"access not allowed"错误。
这个问题的出现场景是这样的:我使用的是友晶科技官方提供的de25_nano_revA_sdcard_console_v1.1.zip镜像,该镜像包含了完整的Uboot、Linux系统和FPGA硬件设计。我的目标是在操作系统启动前,通过Uboot直接控制FPGA端的LED,这样可以快速验证FPGA逻辑是否正确加载。
根据Agilex 5 HPS技术文档和DE25-Nano的硬件设计资料,我确认了以下几个关键信息:
- lwHPS-to-FPGA桥的基地址是0x2000000
- LED组件的偏移地址是0x00010080
- LED的控制逻辑是低电平点亮,高电平熄灭
基于这些信息,我尝试在Uboot命令行中执行以下命令:
bash复制mw.l 0x20010080 0x00
期望能够点亮所有LED,但实际却收到了访问权限错误。
2. 问题分析与定位
2.1 访问权限错误的可能原因
在嵌入式系统中,HPS(硬核处理器系统)访问FPGA外设需要通过特定的桥接器。根据Intel Agilex 5的架构设计,HPS与FPGA之间的通信需要通过以下几个桥接器之一:
- lwHPS-to-FPGA桥(轻量级)
- fpHPS-to-FPGA桥(全功能)
- HPS-to-FPGA桥(AXI主端口)
在我们的案例中,使用的是lwHPS-to-FPGA桥,基地址为0x2000000。当访问这个地址空间时出现权限错误,通常意味着:
- 桥接器未被使能
- FPGA配置未完成或配置失败
- 地址映射不正确
- 安全策略限制了访问
2.2 官方镜像的Uboot脚本分析
通过查看友晶科技提供的Uboot构建文档,我发现了以下关键脚本内容:
bash复制# Enable FPGA bridges
bridge enable
这段脚本的作用是在Uboot启动过程中使能HPS与FPGA之间的桥接器。然而,问题在于这个脚本是在Uboot的自动执行阶段运行的,而当我们手动中断Uboot启动过程进入命令行时,这个脚本尚未执行。
这就是为什么在Uboot命令行中直接尝试访问FPGA外设会失败的原因 - 桥接器尚未被使能。
3. 解决方案与验证
3.1 手动使能桥接器
既然问题出在桥接器未被使能,那么解决方案就是在尝试访问FPGA外设前,先手动执行桥接器使能命令:
bash复制bridge enable
执行这个命令后,再次尝试写入LED寄存器:
bash复制mw.l 0x20010080 0x00 # 点亮所有LED
mw.l 0x20010080 0xff # 熄灭所有LED
这次操作成功了,开发板上的LED能够按照预期点亮和熄灭。
3.2 原理深入解析
bridge enable命令实际上是在配置SoC内部的桥接器控制寄存器。对于Intel Agilex 5 SoC,这个操作主要完成以下工作:
- 解除HPS与FPGA之间的隔离
- 配置时钟和复位信号
- 建立地址映射关系
- 初始化数据传输通道
具体到寄存器级别,这个命令会设置以下关键寄存器位:
- FPGA接口控制寄存器(FPGAINTF)的ENABLE位
- 桥接器控制寄存器(BRIDGE)的各个使能位
- 安全策略寄存器(FPGA2SDRAM)的访问权限位
4. 完整操作流程与注意事项
4.1 完整操作步骤
为了帮助其他开发者完整复现这个过程,以下是详细的操作流程:
- 准备DE25-Nano开发板和SD卡
- 下载并烧写友晶官方镜像de25_nano_revA_sdcard_console_v1.1.zip
- 启动开发板,在Uboot启动过程中按任意键中断自动启动
- 在Uboot命令行中依次执行以下命令:
bash复制bridge enable mw.l 0x20010080 0x00 # 点亮LED mw.l 0x20010080 0xff # 熄灭LED
4.2 关键注意事项
在实际操作中,有几个关键点需要特别注意:
-
地址对齐:使用mw命令时,必须确保地址和值的大小匹配。对于32位访问,应使用
mw.l,地址也必须是4字节对齐的。 -
桥接器状态:每次重新进入Uboot命令行都需要重新执行
bridge enable,因为这个设置不会在重置后保持。 -
FPGA配置状态:确保FPGA已经成功配置。可以通过
fpga status命令检查FPGA的配置状态。 -
电压和时钟:如果操作不成功,检查开发板的供电是否稳定,时钟信号是否正常。
5. 扩展知识与高级应用
5.1 其他FPGA外设的访问
掌握了LED的控制方法后,我们可以类似地访问其他FPGA外设。关键在于:
- 确定外设在FPGA地址空间中的偏移地址
- 了解外设的寄存器映射和操作方式
- 计算正确的访问地址(基地址+偏移)
例如,如果要访问开发板上的开关和按键,需要先查阅GHRD工程中的地址分配。
5.2 自动化脚本编写
为了简化测试流程,可以将常用命令写入Uboot脚本。创建一个名为test_fpga.cmd的文件,内容如下:
bash复制bridge enable
mw.l 0x20010080 0x00
sleep 1000
mw.l 0x20010080 0xff
然后在Uboot中通过source命令执行这个脚本:
bash复制source test_fpga.cmd
5.3 性能与安全考量
在Uboot阶段直接操作FPGA外设虽然方便,但需要注意:
- 性能影响:频繁的寄存器访问可能会影响启动时间
- 安全性:确保不会意外修改关键配置寄存器
- 稳定性:某些操作可能需要等待FPGA侧的逻辑稳定
6. 常见问题排查指南
在实际开发中,可能会遇到各种问题。以下是常见问题及解决方法:
-
问题:执行
bridge enable后仍然无法访问FPGA
排查步骤:- 检查FPGA是否已配置(
fpga status) - 验证地址是否正确
- 检查硬件连接是否可靠
- 检查FPGA是否已配置(
-
问题:LED状态与预期相反
原因:- 可能误解了LED的极性(DE25-Nano是低电平点亮)
- FPGA逻辑可能实现了反向控制
-
问题:操作后系统不稳定
建议:- 检查是否意外修改了关键寄存器
- 尝试重新上电复位
-
问题:在某些开发板上操作无效
注意:- 不同版本的开发板可能有不同的地址映射
- 官方镜像可能针对特定硬件版本优化
7. 开发经验与技巧分享
经过多次实践,我总结出以下几点经验:
-
调试技巧:在Uboot中可以使用
md命令先读取寄存器值,确认访问是否正常,再尝试写入。 -
脚本优化:将常用的测试命令组合成脚本,可以大大提高调试效率。
-
版本管理:不同版本的官方镜像可能有细微差别,建议记录使用的具体版本号。
-
文档查阅:遇到问题时,优先查阅以下几个关键文档:
- Agilex 5 HPS技术手册
- DE25-Nano用户手册
- GHRD工程文档
-
安全操作:在实验阶段,建议先读取寄存器值,确认无误后再进行写操作,避免意外修改关键配置。
通过这个案例,我深刻理解了嵌入式系统中硬件与软件协同工作的重要性。在Uboot阶段访问FPGA外设虽然看似简单,但需要对系统架构有全面的了解,特别是桥接器的工作机制。这个经验对于后续开发其他FPGA-SoC应用也有很好的参考价值。
