Petalinux环境下BRAM通讯指南
前言
- 本文目标:依托之前搭建的Zynq-7000-完整硬件平台构建与验证权威指南硬件平台文件,开发对应的Petalinux下BRAM通信回环实验,并通过该实验了解Petalinux下UIO,中断,内存映射相关概念
创建Petalinux项目
第一步:创建PetaLinux项目
1 | # 创建基于Zynq模板的项目 |
说明: 选择zynq模板为Zynq 7000系列芯片提供基础配置框架。
第二步:导入硬件配置
1 | # 创建硬件文件目录 |
重要事项:
- 使用相对路径导入,确保路径正确性
- 如果弹出配置菜单,通常可以直接保存退出
- 导入后会在
project-spec/hw-description/
生成硬件信息
第三步:系统配置
1 | petalinux-config |
关键配置项:
缓存配置
参考PetaLinux-2023-2-离线缓存与加速编译配置
启动配置为SD卡
- 路径:
Subsystem AUTO Hardware Settings
->SD/SDIO Settings
- 设置: 确认
Primary SD/SDIO (ps7_sd_0)
已选择 Image Packaging Configuration -> Root filesystem type
,从INITRD
改为EXT4 (SD/eMMC/SATA/USB)
串口配置
- 路径:
Subsystem AUTO Hardware Settings
->Serial Settings
- 配置(此处是因为开发板的底板串口为串口1,此处配置要看开发板):
FSBL Serial stdin/stdout (ps7_uart_1)
DTG Serial stdin/stdout (ps7_uart_1)
System stdin/stdout baudrate for ps7_uart_1 (115200)
以太网配置
- 路径:
Subsystem AUTO Hardware Settings
->Ethernet Settings
- 配置:
Primary Ethernet (ps7_ethernet_0)
- 确认已选择[*] Obtain IP address automatically
- 启用DHCP- MAC地址保持默认即可
启动参数配置
路径:
DTG Settings -> Kernel Bootargs
设置为手动设置参数,设置如下1
console=ttyPS0,115200 earlycon root=/dev/mmcblk0p2 ro rootwait uio_pdrv_genirq.of_id=generic-uio
第四步:内核配置
1 | petalinux-config -c kernel |
必需启用的驱动模块:
DMA引擎支持
- 路径:
Device Drivers
->DMA Engine support
- 启用:
<*> Xilinx AXI DMAS Engine
- 状态: 通常默认已启用
GPIO支持
- 路径:
Device Drivers
->GPIO Support
->Memory mapped GPIO drivers
- 启用:
<*> Xilinx Zynq GPIO support
- 状态: 通常默认已启用
UIO支持(用户空间IO访问)
路径:
Device Drivers
->Userspace I/O drivers
必须启用:
<M> Userspace I/O platform driver with generic IRQ handling
,该项无法修改为*
<*> Userspace platform driver with generic irq and dynamic memory
重要性: 用于用户空间访问BRAM控制器等自定义IP
UIO驱动的作用
Userspace I/O (UIO) 的优势:
允许用户空间程序直接访问硬件寄存器
避免编写复杂的内核驱动
适用于自定义IP核的快速原型开发
支持中断处理和内存映射
适用场景:
- BRAM控制器的用户空间访问
- 自定义AXI IP核的控制
- 硬件加速器的用户空间接口
以太网驱动
- 路径:
Device Drivers
->Network device support
->Ethernet driver support
- 启用:
<*> Xilinx 10/100/1000 AXI Ethernet support
PHY驱动(关键!)
- 路径:
Device Drivers
->Network device support
->PHY Device support and infrastructure
- 必须启用:
[*] Micrel Phys
- 重要性: 没有正确的PHY驱动,网卡无法工作
第五步:根文件系统配置
1 | petalinux-config -c rootfs |
推荐配置:
基础系统
- 路径:
Filesystem Packages -> base -> busybox
[*] busybox
- 基础系统工具集[*] busybox-udhcpc
- DHCP客户端(用于自动获取IP)
网络支持
- SSH服务默认已配置,无需额外设置
GPIO库支持
- 路径:
Filesystem Packages
->libs
->libgpiod
- 启用:
[*] libgpiod
自动登录配置(重要!)
- 路径:
Image Features
- 必须启用,在该开发板上使用UART1登录时root密码登录会出现一直失败的情况,可能是BUG:
-*- empty-root-password
- 设置root用户空密码[*] serial-autologin-root
- 串口自动以root身份登录
第六步:设备树文件配置
编辑
project-spec/meta-user/recipes-bsp/device-tree/files/system-user.dtsi
添加如下内容
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17/include/ "system-conf.dtsi"
/ {
};
// BRAM控制器配置为UIO模式
&axi_bram_ctrl_0 {
compatible = "generic-uio";
};
&axi_bram_ctrl_1 {
compatible = "generic-uio";
};
// CDMA配置为UIO模式
&axi_cdma_0 {
compatible = "generic-uio";
};设备树配置原理
compatible = "generic-uio"
: 告诉Linux使用UIO框架- UIO框架自动创建
/dev/uioX
设备文件 - 支持用户空间直接访问硬件寄存器和中断
第七步:系统构建
1 | # 完整构建(首次构建20-60分钟) |
构建说明:
- 首次构建会下载并编译大量软件包
- 构建过程包括:内核编译、根文件系统生成、设备树编译等
- 如果出现网络下载错误,根据URL下载并补充在downloads目录下,详情参考PetaLinux-2023-2-离线缓存与加速编译配置
第八步:生成启动镜像
1 | 打包启动镜像 |
- 生成的关键文件:
BOOT.BIN
(~5MB) - 包含FSBL、FPGA比特流、U-Boot、设备树image.ub
(~76MB) - FIT格式,包含Linux内核和根文件系统boot.scr
(~3.5KB) - U-Boot启动脚本
- 注意,2023.2版本似乎不会在后续编译的时候生成boot.scr,因此该文件时间在后续构建是旧的
第九步:SD卡制作
先查看自己的sd卡名称,我的设备是sdb1
1
sudo fdisk -l
挂载SD卡分区(需要提前分区:FAT32启动分区 + EXT4根文件系统分区)
1
2sudo mount /dev/sdb1 /mnt/boot
sudo mount /dev/sdb2 /mnt/rootfs复制启动文件到boot分区,解压根文件系统到rootfs分区
1
2
3
4sudo cp images/linux/BOOT.BIN /mnt/boot/
sudo cp images/linux/image.ub /mnt/boot/
sudo cp images/linux/boot.scr /mnt/boot/
sudo tar -xzf images/linux/rootfs.tar.gz -C /mnt/rootfs/同步并卸载
1
2sync
sudo umount /mnt/boot /mnt/rootfs
Linux下硬件正确性检查
登录Linux
通过串口连接,启动开发板后可以进入串口的控制台页面,添加用户,配置网卡
1 | mv /etc/network/interfaces /etc/network/interfaces.bak |
添加如下内容
1 | /etc/network/interfaces -- configuration file for ifup(8), ifdown(8) |
添加用户
1 | adduser kuang |
这样就可以ssh登录linux了
硬件设计
1 | 硬件架构: |
系统硬件检查命令
1 | # 检查UIO设备 |
输出结果
1 | zynq_linux_project:~$ ls -la /dev/uio* |
输出分析
- 设备文件路径:
/dev/uio0
,/dev/uio1
,/dev/uio2
- 硬件地址映射:
- BRAM A: 0x40000000
- BRAM B: 0x40001000
- CDMA: 0x7e200000
- 设备类型确认:两个BRAM控制器 + 一个DMA控制器
查看中断信息
1 | root@zynq_linux_project:/home/kuang# cat /proc/device-tree/amba_pl/dma@*/interrupts | hexdump -C |
- 解析:在第一个命令中,除了每行首位的行号,剩下的一共36个字节,每十二个字节为一组,每组的前四个字节是只能高端类型,中间四个是中断号,后四个是触发方式
00 00 00 00
: 中断类型 = 0 (SPI中断)00 00 00 1d
: 中断号 = 0x1d = 2900 00 00 04
: 触发方式 = 4 (高电平触发)
- 中断号计算
- 硬件中断号 = 29
- Linux中断号 = 29 + 32 = 61
- SPI中断: Linux中断号 = 设备树中断号 + 32
代码实现回环功能
代码编译参考配置-Windows-CLion-为-PetaLinux-虚拟机进行远程交叉编译
1 | /* |
核心概念深度解析
文件描述符机制
1 | int fd = open("/dev/uio2", O_RDWR); |
- fd是进程级索引:每个进程独立的文件表索引
- 内核文件对象:fd指向内核中的file结构体
- 资源隔离:不同进程的相同fd值可能指向不同文件
内存映射原理
1 | volatile uint32_t *regs = (volatile uint32_t*)mmap(...); |
- 虚拟地址映射:硬件物理地址 ↔ 用户空间虚拟地址
- 零拷贝访问:直接操作硬件,无系统调用开销
- volatile关键字:防止编译器缓存优化,确保每次访问都是真实硬件操作
UIO中断处理机制
1 | // 使能中断等待 |
内核内部流程:
- 硬件产生中断 → 内核中断处理函数
- 增加中断计数器 → 唤醒等待的用户进程
- 用户进程继续执行 → 检查硬件状态寄存器
CDMA寄存器控制详解
关键寄存器映射:
1 | 物理地址 虚拟地址 功能 |
控制流程解析:
1 | // 1. 复位CDMA(清除所有内部状态) |
测试结果
1 | === BRAM中断DMA传输流程 === |
构建优化
1 | 硬件配置变更后的最小重构 |