学习内容
开发环境
vivado 18.3&SDK,PYNQ-Z2开发板。
双核通信
多核处理器从结构上划分:
同构多核: 同构多核处理器是指系统中的处理器在结构上是相同的,在软硬件设计上较为简单,通用性高。
异构多核: 异构多核处理器是指系统中的处理器在结构上不同的,在特定场合中可以进行加速,提高性能。
Xilinx 的 ZYNQ SOC 融合了这两种架构, ZYNQ SOC 芯片包含两个独立的 Cortex-A9 处理器,这两个处理器核在结构上是相同的,同时又包括了可编程的逻辑单元( PL),使得 ZYNQ 整体系统成为了一个异构多核系统,同时具有较高的通用性和性能。
多核处理器软件运行方式
多核处理器的运行模式有 AMP(非对称多处理)、 SMP(对称多处理)和 BMP(受约束多处理)三种运行模式。
AMP(非对称多处理): 多个内核相对独立的运行不同的任务,每个内核相互隔离,可以运行不同的操作系统。
SMP(对称多处理): 多个处理器运行一个操作系统,这个操作系统管理多个内核。
BMP(受约束多处理): BMP运行和SMP运行模式类似,开发者可以指定将某个任务仅在某个指定内核上执行。
下图为SMP和AMP的示意图:
在这个设计中,当VIO产生一个脉冲时,自定义核心将一个中断转发给PS Core1_nlRQ引脚。核心还连接到PS主通用端口(M AXI_GP0),通过一个允许CPU0和CPU1访问核心内的控制寄存器的AXI互连。在中断服务程序期间,CPU1访问控制寄存器以清除中断请求(IRQ)。CPU0可以选择使用控制寄存器来创建一个指向CPU1的中断。Core1_nlRQ引脚直接连接到CPU1 PPI块,因此不需要修改共享ICD的配置。还包括一个ChipScope分析仪axis监视器核心,允许用户测量正在服务的IRQ的延迟。
参考设计软件设计
该软件可以分为三个部分:
- 第一阶段引导加载程序(FSBL)
- 用于CPU0的裸机应用程序
- 用于CPU1的裸机应用程序
参考设计让CPU0和CPU1运行它们自己的裸机应用程序代码。CPU0负责初始化共享资源并且启动CPU1。CPU0的应用程序位于从地址0x00100000开始的内存中。链接器脚本用于设置起始地址。
CPU0的设计步骤:
- 配置MMU对0xFFFF0000 ~ oxfffffe地址范围内的OCM访问关闭缓存功能。OCM的地址映射是不变的,所以OCM存在于地址0x00000000到0x0002FFFF和地址0xFFFF0000到0XFFFFFFFF。示例设计只使用了高64kb的OCM,因此在地址0xFFFFo000到oxfffffe上禁用缓存。
- 初始化ICD;
- CPU1开始启动;
- 打印到UART;
- 在OCM中设置一个用作信 量标志的内存位置;
- 等待OCM中用作信 量标志的内存位置被清除。
CPUO应用程序无限期地重复步骤3到步骤6。
PS启动后,内部 boot ROM完成执行,CPU1被重定向到0xFFFFFE00的OCM中的一小段代码。这段代码是一个连续循环,它等待一个事件,检查地址位置0xFFFFFFF0的非零值,然后继续循环。如果0xFFFFFFF0包含一个非零值,CPU1将跳转到获取的地址。
CPU0通过将Ox00200000的值写入地址0xFFFFFFF0,然后运行Set Event (SEV)命令来启动CPU1(两者都运行裸机程序)。SEV唤醒CPU1,从地址0xFFFFFFF0读取值0x00200000,然后跳转到地址0x00200000。FSBL负责将CPU1 ELF放置在0x00200000。
CPU1应用程序位于从地址Ox00200000开始的内存中。链接器脚本用于设置起始地址。
CPU1应用程序执行以下操作:
- 配置MMU对地址范围为0xFFFF0000 –0XFFFFFFFF的OCM访问关闭缓存功能。OCM的地址映射是不变的,因此OCM存在于地址0x00000000到0x0002FEEF和地址0xFFEF0000到xFFFFFFFE。这个应用程序笔记只使用了OCM的高64kb,所以缓存在地址0xFFFF0000到0XFFFFFFFF上被禁用。
- 初始化PPl中断控制器和中断子系统。
- 等待OCM中用于设置信 量标志的内存位置。
- 打印到UART。打印的字符串的选择取决于中断服务例程是否增加了一个全局变量。如果全局变量irq_count不为零,CPU1将该值设置为零
- 清除OCM中用作信 量标志的内存位置。
CPU1应用程序无限期地重复步骤3到步骤5。
一些细节
启动CPU1
CPU 0负责在CPU 1上启动代码执行。BootROM将CPU 1设置为Wait for Event模式。什么都没有启用,只有少数通用寄存器被修改,以将其置于等待WFE指令的状态。
CPU0在CPU1上启动应用程序需要少量的协议。CPU 1收到系统事件后,立即读取地址0xFFFFFFF0的内容并跳转到该地址。如果SEV在更新目的地址位置(0xFFEEFFE0)之前发出,CPU1继续处于WFE状态,因为0xFFFFFFF0将WFE指令的地址作为安全 。如果编写0xFFFFFFF0地址的软件无效或指向未初始化的内存,则结果是不可预测的。
CPU 1上的初始跳转只支持Arm-32 ISA代码。在跳转的目的地不支持Thumb和Thumb-ll代码。这意味着目的地址必须是32位对齐的,并且必须是有效的Arm-32指令。如果不满足这些条件,结果是不可预测的。
CPU0在CPU1上启动应用的步骤如下:
- 将cpu1的应用程序地址写入0xFFFFFFF0。
- 执行SEV指令,唤醒CPU1并跳转到应用程序。
地址范围0xFFFFEE00到0xFFFFFFF0是保留的,在第1阶段或以上的应用程序完全可用之前不能使用。在第二个CPU成功启动之前对这些区域的任何访问都会导致不可预测的结果。
软件中断
前面提到两个处理器都使用 OCM 来相互通信。 而OCM属于两个CPU共用的资源,如果同时调用会出现问题,所以为了防止共享资源出现问题,可以进行使用中断的办法进行控制。也即让CPU0在完成对OCM的相关操作并完成释放OCM后,产生软件中断,CPU1接收到软件中断即可知道CPU0完成对OCM的操作,即可进行CPU1的对OCM的相关操作。
每个CPU都有一组私有外设中断(PPls),它们使用存储的reqisters进行私有访问。PPls包括全局定时器、私有看门狗定时器、私有定时器和来自PL的FIQ/IRQ。软件生成的中断(SGIs)被路由到一个或两个cpu。SGIs是通过写入通用中断控制器(GIC)中的寄存器而生成的。共享外围中断(SPls)是由PS和PL中的各种I/O和内存控制器产生的。它们被路由到其中一个或两个cpu。来自PS外围设备的SPI中断也被路由到PL。
通过一个SGI (software generated interrupt,软件生成中断),每个CPU可以中断自己,也可以中断另一个CPU,也可以中断两个CPU。软件生成中断共有16个,如表所示。
程序设计
见下篇 ZYNQ-双核AMP通信(二)。
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!