fpga 和arm 采用预留内存的方式,采用neon 协处理器只能做到 250M/S 的速度,预留内存采用mmap的方式,当读取内存页的时候采用缺页中断的方式,导致速度拖沓而且预留内存没有进行Linux系统的内存管理(在系统内 memcpy的速度 可以到 5G/S),自己写DMA驱动,虽然可以用Linux 本身的框架,但是结果不确定,
1.首先CPU 涉及Linux的调度损失,可能数据处理的实时性受到影响,即使用cpu的亲和性属性,但是结果还是存在风险
2.DMA 传递到 Linux管理的内存 类似内存拷贝,FPGA的乒乓结构+ DMA,在DDR 会存在叁份拷贝,况且3个通道,会导致内存的极大浪费
3.算法优化,Linux调用库函数,存在层层调用的问题,即使编译器极大优化,我认为跟与在裸机层面的优化 存在差距
现状:
1.实时处理在裸机上运行,算法C 实现,编译器开 -O2 优化,查看汇编代码,效率很高,经测试效果达到预期
2.3个通道分别用3个cpu 处理,读取,处理,结果输出,内存访问完全分开,互不影响
3.一个A53 跑Linux 系统,方便使用第三方库,和其他几个核的交互采用共享内存的方式
4.2个R5 核虽然是实时核,但是主频只有 500M ,且只是 32bit cpu ,经测试算法处理比较拉跨,只能做协议处理,屏幕驱动显示,同步相关的工作
裸机步骤:
1.分别开发裸机程序,并测试通过 (注意各个cpu内存的位置配置)按需求来且不需要太大
2.在裸机端先把除运行Linux系统的CPU的其他核都运行起来,测试是否正常,这可以参考官方AMP 手册,我是参考黑金Vitis 应用教程 双核AMP的使用,重点如下:
Note:前面我们已经建立了一个cpu0 的工程
3.如上建立3个A53 的工程,两个R5的工程,编译通过,且确认已经生成 elf 文件
4.板上验证
注意图中,Application下每个cpu 对应的 elf 是否存在,是否对应
正常情况下,我们配置的cpu 都会运行起来,可以用驱动led 或者串口打印的方式
注意:如果我们配置多个cpu ,且各个cpu的使用了同样的led 或者串口,也就是说一个硬件有多个驱动源,那么生效的是最后加载程序的那个cpu
Linux编译步骤:
1.打开虚拟机配置环境变量,确保可以编译 如:source /opt/pkg/petalinux/settings.sh 个人按自己的开发指导来
2.执行 petalinux-config
在 DTG Seting ---- > Kernel_Bootargs ----> 取消 generate boot args atuomatically
在底下配置填写如下:重点:maxcpus = 1 ,你需要几个核跑Linux就填写几个
console=ttyPS0,115200 maxcpus=1 clk_ignore_unused earlyprintk root=/dev/mmcblk1p2 rw rootwait
在 Subsystem AUTO Hardware Setting 下配置
1) System Processor ,指定运行Linux 系统的cpu 核心数
2)Memory Setting,配置ddr 参数 ,这里很关键,需要和 裸机那边的配置区别开,冲突了可能启动有问题,我配置到了低2G的空间,高2G 可能存在问题,还没试。下图是我自己的配置,裸机那边ddr 是从 0 地址开始的。
3.取消设备树里和目前地址冲突的预留内存配置
4.编译:执行
petalinux build
5.编译完成,查看生成文件,我一般查看文件生成 的时间确保系统更改导致新文件已生成
6.生成bootimag 把上图红框的文件拷贝出虚拟机,放到裸机程序的工程下,方便打包
注意 :
1.这里bootloader 要用虚拟机下编译出来的 zynqmp_fsbl.elf
最后点击 Create Image 生成 BOOT.bin 替换sd卡里的 BOOT.bin, image.ub 也要替换成虚拟机编译出来最新的
启动:设置板子 sd卡启动,打开调试串口 查看启动,启动过程中如果遇到错误,根据log 定位解决。
附加1:由于我的板子ps 端只有一个串口,裸机和 Linux是不能同时使用的,我是在裸机这里关闭了串口0,在Linux 设置里配置了串口0,linux 启动的log 才可以正常从串口 0 打印