ZYNQ配置AMP模式(linux+裸机)

使用的是正点原子zynq开发板

Zynq配置AMP模式(cpu0跑linuxc+cpu1跑裸机)

在 AMP 运行环境下,必须要小心以防止两个 CPU 争夺这些共享资源,在 SoC 硬件系统当中,有一些
资源是每个 CPU 私有的,而有一些资源则是公用的;

CPU 私有资源如下所示:
1)L1 cache(一级缓存);
2)CPU 私有外设中断(PPI);
3)内存管理单元(MMU);
4)CPU 私有定时器。
CPU 共享资源如下所示:
1)中断控制分配器(ICD);
2)DDR 内存;
3)片内存储器(OCM);
4)全局定时器(Global Timer);
5)SUC 和 L2 cache(二级缓存)。
6)片上外设,例如 GPIO、SD、QSPI、UART、I2C、SPI(共享外设中断)、USB、CAN、SPI 等等。
私有资源可以不用管,但是对于双核公共资源来说,必须要小心处理,避免两个 CPU 同时使用这些资源的情况下导致混乱、数据错误,例如同时控制某一个 GPIO、同时使用串口等。
对于 ZYNQ 来说,当硬件上电启动之后,BootROM 是第一个运行的代码(BootROM 代码被固化在ZYNQ SoC 片内 RoM 存储器中),并且运行于 CPU0 上;BootROM 代码会从启动介质中读取 BotROM 头信息,BootROM 头信息就存储在 BOOT.BIN 文件中,BootROM 头信息记录了 bitstream、用户代码等数据存放在 BOOT.BIN 文件中的位置偏移量以及对应在内存中加载地址,根据这些信息来加载 PL 端 bitstream流文件以及在 PS 端启动用户代码。
BootROM 启动之后会使 CPU1 进入等待事件模式(WFE),没有对其启用任何功能,也就是说此时CPU1 处于一个等待指令的状态;而这个指令由 CPU0 给它,说白了就是必须由 CPU0 来启动 CPU1,解除它的等待指令状态,使其运行我们的用户代码。CPU0 在 CPU1 上启动应用程序需要少量协议,当 CPU1 接收到 CPU0 给到的 SEV 指令后,它会被唤醒,然后立即读取 0xFFFFFFF0 这个内存地址中存放的数据,并把这个读取到的数据作为应用程序的入口地址,接着跳转到该地址启动应用程序。所以由此可知,如果在执行 SEV 指令的时候,地址 0xFFFFFFF0 中存放的是一个无效的应用程序入口地址,则结果是不可预测的。

创建CPU1工程

点击 File–>New–>Application Project 新建应用工程。
在这里插入图片描述

注意在 Processor 栏选择“ps7_cortexa9_1”,点击 Next 按钮进入工程模板选择界面,同样这里我们也是创建一个空工程,首先双击 CPU1 工程的链接脚本文件 lscript.ld 打开它,修改 CPU1 应用程序内存空间的基地址和大小,这里笔者将基地址设置为 0x21000000。大小设置为 0x200000;
在这里插入图片描述
此外我们还需要对 CPU1 工程的板级支持包做额外的设置
在这里插入图片描述

在配置界面当中,选择 drivers–>ps7_cortexa9_1,在 extra_compiler_flags 栏添加“-DUSE_AMP=1”; 该页面用于配置工程的交叉编译工具,例如compiler指定了编译工程源码时所使用的交叉编译工具arm none-eabi-gcc,而 compiler_flags 和 extra_compiler_flags 则是执行 arm-none-eabi-gcc 命令时所携带的选项,“-D”选项的作用则是定义一个宏,所以我们这里添加“-DUSE_AMP=1”其实就类似于定义了一个宏“#defineUSE_AMP 1”,这里定义的宏与普通.c、.h 文件中定义宏有所不同,这个宏在整个工程源码中都是有效的,你不需要包含任何的头文件都能使用它。
那问题来了?我们为什么需要定义这个宏,主要是跟 L2 Cache 有关系,因为 L2 Cache 属于 CPU0 和CPU1 的共享资源,都可以使用,这对于 AMP 运行模式来说是一个麻烦,所以这里直接让 CPU1 禁止使用L2 Cache,避免出现问题。当定义了这个宏之后,CPU1 就不可以使用 L2 Cache 了。
在这里插入图片描述

将共享内存地址设置为 0x25000000,同样这个地址既不在 CPU0 Linux 系统内存空间中、
也不在 CPU1 裸机应用程序内存空间中。

#define SHARE_MEM_ADDR 0x25000000U // 共享内存地址
  /*
   * 禁止共享内存 Cache,保持数据的一致性
   * S=b1 TEX=b100 AP=b11, Domain=b1111, C=b0, B=b0
   */
Xil_SetTlbAttributes(SHARE_MEM_ADDR, 0x14de2);
创建FSBL工程

菜单栏中选择“File->New->Application Project”
在这里插入图片描述

接下来点击 Next,并在示例工程中选择“Zynq FSBL”,最后点击“Finish”,如下图所示
在这里插入图片描述

FSBL 工程创建完成之后,SDK 软件会自动执行编译过程,生成 FSBL.elf 文件。 双击打开 fsbl 工程中的 main.c 源文件,在 main 函数前添加如下代码

#define sev() __asm__ ("sev") // C 语言内嵌汇编写法
#define CPU1_RUN_ADDR 0x21000000U
#define CPU1_COPY_ADDR 0xFFFFFFF0U
static void StartCpu1(void)
{
 Xil_Out32(CPU1_COPY_ADDR, CPU1_RUN_ADDR); // 将 0x10000000 拷贝到 0xFFFFFFF0 地址处
 dmb(); // 等待内存写入完成(同步)
 sev(); // 执行 sev 指令唤醒 CPU1
}

添加完成之后,然后在“HandoffAddress = LoadBootImage()”代码后面调用上面定义的函数 StartCpu1();
选中FSBL后点击工具栏Xilinx->Create boot image
在这里插入图片描述

u-boot在编译之前打开设备树文件,arch/arm/dts/atk-zynq-7020.dts找到 memory 节点reg 属性描述了 u-boot 和 Linux 系统所能使用的内存空间,起始地址为 0x0,大小为 0x40000000,也就是 1GB;这里我们将 0x40000000 修改为 0x20000000,也就是该为 512MB,修改完成之后保存退出;修改u-boot环境变量bootargs设置成只有一个cpu核,在u-boot源码board/xilinx/zynq/board.c

bootargs=console=ttyPS0,115200 maxcpus=1 earlyprintk root=/dev/mmcblk0p2 rw rootwait

目的是为了让 Linux 系统只能使用一个 CPU,也就是 CPU0,不要使用 CPU1,把 CPU1
独立出来运行一个裸机程序;

  • 18
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
文档共60页。主要向初学者提供了Zynq开发的技术方向,针对不同应用给出了基本的参考文档;同时对Zynq双核AMP加载方式做了详细描述,对Zynq的fsbl启动流程做了简单介绍。章节如下: Zynq User Guide 1 介绍 4 2 快速上手指南 4 3 多核开发教程 4 3.1 AMP开发说明 6 3.1.1 快速生成amp工程 6 3.1.2 Generating Boot File 8 3.1.3 烧写程序 9 3.1.4 启动 10 3.1.5 调试 10 3.1.6 总结 11 3.2 SMP开发说明 11 4 ZC706启动代码分析 11 4.1 启动代码 12 4.2 FSBL流程(FOR AMP) 13 4.3 CPU0启动CPU1流程 14 5 程序在线烧写方案及流程 14 5.1 程序烧写需求 14 5.2 提出该需求的原因 14 5.3 程序烧写方案 14 5.3.1 BOOT.BIN组成 14 5.3.2 BOOT.BIN生成方法 15 5.4 FSBL.BIN和APP.BIN等的生成 15 5.5 制作*BIN及烧写的具体步骤 15 5.5.1 制作*bin流程 15 5.5.2 BOOT.bin制作过程 15 5.5.3 FSBL.bin和APP.bin等的生成过程 22 5.6 烧写BOOT.BIN步骤 26 5.6.1 通过SDK工具烧写步骤 26 5.6.2 通过上位机烧写软件的烧写步骤 29 5.6.3 通过串口调试助手烧写步骤 29 6 Zynq Qspi控制器 30 6.1 基本特性 30 6.2 I/O接口 31 6.3 QSPI控制器模式 33 6.3.1 I/O模式 33 6.3.2 线性地址(linear address)模式 33 6.3.3 传统(legacy)SPI模式 34 6.4 QSPI 例程 34 6.5 QSPI控制器支持访问32MB方法 35 6.5.1 Bank地址寄存器(Bank address register) 35 6.5.2 扩展地址模式(Extended address mode) 35 6.5.3 使用新写命令(New commands) 35 6.6 QSPI FLASH选择 35 6.7 作为BOOT器件考虑 35 7 µC/OS系统启动指南 36 7.1 INTRODUCTION 36 7.1.1 Software Requirements 36 7.1.2 Hardware Requirements 36 7.2 HARDWARE DESIGN 37 7.2.1 Step 1. Invoke the Vivado IDE and Create a project 37 7.2.2 Step 2. Create an IP Integrator Design 39 7.2.3 Step 3. Add and setup the Zynq processor system IP block 39 7.2.4 Step 4. Customize the Zynq block for our design 41 7.2.5 Step 5. Add the soft peripherals 45 7.2.6 Step 6. Generate HDL Design Files 47 7.2.7 Step 7. Synthesis, Implement and Generate Bitstream 48 7.3 SOFTWARE DESIGN 49 7.3.1 Step 1. Installation of the µC/OS Repository 49 7.3.2 Step 2. Generate the µC/OS BSP 50 7.3.3 Step 3. Build and Debug the Demonstration Project 54 7.3.4 Step 4. Program the AXI Timer 0 with the ucos_axitimer Driver 55 7.3.5 Step 5. Program the AXI Timer 1 with the Xilinx tmrctr Driver 58 7.4 CONCLUSION 59 8 Linux系统启动指南 59
Zynq SoC处理器上可以同时运行Linux裸机系统。 1. Linux系统:Zynq SoC支持在ARM Cortex-A9处理器上运行Linux操作系统。通过在处理器上加载Linux内核,可以实现强大的操作系统功能,例如多任务处理、文件系统支持、网络连接、驱动程序管理等。Linux具有强大的应用开发生态系统,可以使用各种工具和语言进行开发,如C、C++、Python等。此外,通过使用Linux,可以方便地访问各种软件库和框架,为应用程序的开发提供更加便捷和高效的环境。 2. 裸机系统:裸机系统是在裸机环境中直接编写的嵌入式系统。在Zynq SoC处理器上,可以使用ARM Cortex-A9芯片上的处理器核心或FPGA逻辑开发裸机系统。在裸机系统中,没有操作系统提供高级功能的抽象层,所有的硬件访问和功能实现都需要自己编写。裸机系统可以实现高度定制化的功能,能够更好地控制硬件资源和系统性能,适用于对实时性要求较高的应用场景。裸机系统开发需要熟悉底层硬件架构和编程语言,如汇编语言和C语言。 在Zynq SoC处理器上同时运行Linux裸机系统可以实现系统的功能分层。可以将高级功能和应用程序运行在Linux操作系统中,通过操作系统提供的API进行开发。而底层的硬件控制和实时任务可以运行在裸机系统中,通过对处理器和FPGA逻辑的直接访问实现更高效的功能实现。 综上所述,在Zynq SoC处理器上运行Linux裸机系统能够充分发挥处理器和FPGA的优势,拓展系统的功能和性能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值