1. 背景
在 xilinx mpsoc 平台上进行 Linux 软件开发,不可避免的会涉及到 PS 与 PL 之间的数据交互。这个系列介绍一种基于 DDR 的信息交互方式。
这篇文章首先介绍下如何从系统中“偷”内存。
2. 交互框图
交互流程:
- PS 写入数据到 DDR 中,使用中断通知 PL,PL 从协商好的 DDR 中读取数据;
- PL 写入数据到 DDR 中,使用中断通知 PS,PS 从协商好的 DDR 中读取数据;
3. reserved memory
如果 PS 与 PL 要基于 DDR 进行交互,那么,在 PS 端必须将内存空间从系统中“拿”出来,让系统无法知晓或无法使用这个空间。然后,应用程序要想办法操作 DDR 的物理地址进行数据读写。 如何做呢?需要借助预留内存。实现预留内存的简单方法是在设备树中增加 reserved-memory 设备节点,在该节点中定义预留内存的起始地址及大小。
3.1 reserve 1
比如,我要使用一块内存空间作为 PS 与 PL 信息交互的空间,该空间以 0x30000000 为起始地址,大小为 256MB。那么可以在设备树中定义如下节点信息。
project-spec/meta-user/recipes-bsp/device-tree/files/system-user.dtsi:
/include/ "system-conf.dtsi"
/ {
reserved-memory {
#address-cells = <2>;
#size-cells = <2>;
ranges;
buffer@0x30000000 {
no-map;
reg = <0 0x30000000 0 0x10000000>;
};
};
}
按照上述方式修改设备树并编译内核,系统启动后通过命令 cat /proc/iomem
即可查看系统的内存分配:
cat /proc/iomem
从下图中可以看到系统使用的内存空间被分为了两部分,0~0x2fffffff 和 0x40000000~0x7fefffff。中间丢失的部分 0x30000000~0x3fffffff 即为我们的预留内存。
3.2 reserve more
如果需要预留多块内存,可以添加多个节点。比如预留两块 256MB 的空间,起始地址分别是 0x30000000 和 0x50000000,如下:
/include/ "system-conf.dtsi"
/ {
reserved-memory {
#address-cells = <2>;
#size-cells = <2>;
ranges;
res1:buffer@0x30000000 {
no-map;
reg = <0 0x30000000 0 0x10000000>;
};
res2:buffer@0x50000000 {
no-map;
reg = <0 0x50000000 0 0x10000000>;
};
};
};
从下图中可以看到,0x30000000~0x3fffffff 和 0x50000000~0x5fffffff 这两个地址空间系统无法使用。
4. 总结
基于 DDR 的 PS 与 PL 交互,PS 需要操作 DDR 的物理地址。此时就需要通过预留内存的手段让 Linux 无法使用进行交互的空间。那么,如何在用户空间中使用这块内存呢?答案是借助 UIO。
文章来源:https://www.toymoban.com/news/detail-427276.html
文章来源地址https://www.toymoban.com/news/detail-427276.html
到了这里,关于zynq pl访问ps ddr的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!