0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

ZYNQ多核处理器硬件上的划分

lhl545545 来源:ZYNQ 作者:ZYNQ 2022-09-19 09:06 次阅读

1.简介

zynq系列开发板有两个板载Cortex-A9处理器,两个ARM可以协同处理数据。

多核处理器硬件上的划分

  1.同构多核:系统中的多个处理器在结构上是相同的;

        优点是硬件和软件设计上较为简单,通用性高。

  2.异构多核:系统中的处理器结构上是不同的;

        优点是在某些特定场合,专用的硬件加速核可以提高性能。

ZYNQ中的两个Cortex-A9处理器+可编程逻辑器件FPGA组成了异构多核处理器。

多核处理器从软件运行方式上划分

  AMP(Asymmetric Muti-processing):非对称多处理

    多个内核相对独立的运行不同的任务,每个内核相互隔离,可以运行不同的操  作系统或者裸机程序。

  SMP(Symmetric Muti-processing):

    多个处理器运行一个操作系统,这个操作系统同等的管理多个内核。

  BMP(Bound Muti-processing):混合多模式

    BMP与SMP类似,但是开发者可以指定将某个任务仅在某个指定内核上执行。

AMP模式下要注意不要两个CPU一起访问同一个地址或者共享外设。

2.CPU之间通讯原理

2.1 通讯步骤

1.系统初始化

2.启动CPU1

3.和CPU1进行通讯

4.共享CPU外设

2.2 CPU资源

  CPU资源分为私有资源和公共资源。私有资源是每个CPU都有的资源,只能被各自的CPU访问,访问时无需注意冲突。公共资源为CPU之间共享的资源,访问时要注意访问冲突。

  私有资源: L1Cache、PPI(Private peripheral interrupts)、MMU(Memory management unit)。

  公共资源: L2Cache、DDR存储器、OCM(on chip memory)、ICD(Interrupt control distributor)、全局时钟和其他外等。

  OCM用来和CPU之间的通讯的,与DDR相比,OCM具有更高的性能和更低的延迟。用于小数据量(256KB一下)用OCM更好。

  避免同时访问的方法

  DDR:CPU0只能访问0x00100000至0x001FFFFF,CPU1只能访问0x00200000到0x002FFFFF(可人为更改)

  L2Cache:CPU0使用,CPU1不使用。

  ICD:中断来自PL,连接到CPU1。

  Timer(定时器):只有CPU1使用。

  OCM:OCM的某一地址进行标志。当标志为0时这个地址是某个CPU私有的;为1时,这个地址是另一个CPU私有的。或者软件产生中断的方式。

2.3 软件设计

软件设计分为三个阶段

1.First stage boot loader(FSBL):第一启动阶段

2.Bare-metal application for CPU0:裸机应用程序

3.Bare-metal application for CPU1:裸机应用程序

FSBL

  一直运行在CPU上面,是开发板上电之后启动先启动Boot rom,后启动FSBL,负责配置PL然后拷贝两个处理器的应用程序(ELF)加载到DDR中,然后开始运行第一个应用程序。

Bare-metal application Code

  两个CPU运行各自的裸机的程序,CPU负责初始化共享外设,并且负责启动CPU1.

CPU0 Application

  内存的起始地址为0x00100000。这个起始地址可以在链接脚本进行修改的。

  CPU0的配置步骤:

  1.配置MMU来禁止cache缓存功能0xFFFF0000至0xFFFFFFFF来保证两个CPU访问OCM的一致性。地址映射不可修改。

  2.初始化ICD

  3.启动CPU1

  4.通过串口打印信息

  5.设置OCM的地址作为信号

  6.等待地址里面的信号量被清除。

  Boot rom代码执行后,CPU1也会在OCM的0xFFFFFF00地址上执行一段代码。功能是检查地址0xFFFFFFF0的值是否为1来等待事件到来。

  CPU0启动CPU1是通过向地址0x00200000写入地址0xFFFFFFF0然后CPU0运行Set Event(SEV)命令启动CPU1。CPU1会读取0xFFFFFFF0里面的值0x00200000。然后跳转到该地址执行程序。

  CPU1的配置步骤

3 如何避免多个CPU同时访问OCM

  CPU0向OCM写入一个数据之后,给CPU1产生软件中断。让CPU1知道CPU0已经不再操作该地址。此时CPU1读取数据,读取完毕后产生一个中断通知CPU0。

  软件中断(SGIs):中断来自CPU内部,每个CPU可以中断自己或者另外的CPU或者一起中断,每个CPU有16个中断号,编号为0到15。向寄存器(ICDSGIR)写入中断号并且指定CPU。目标的CPU即可产生中断。

  OCM:PS的片上存储器,包括256KB的RAM和128KB的ROM(BootROM)。地址范围为0x00000000到0002FFFF的三个64KB加上0xFFFF_0000到0xFFFF_FFFF共256KB。

4 程序设计

4.1 程序任务

  CPU0接收串口数据并写入OCM中,然后利用软件中断触发CPU1;CPU1接收到中断后,根据从OCM中读出的数据控制呼吸灯的频率,并在控制结束后触发CPU0的中断,实现双核CPU通信的功能。

4.2 系统框图

beff3422-37b0-11ed-ba43-dac502259ad0.png

4.3 软件操作

bf37dcdc-37b0-11ed-ba43-dac502259ad0.png

4.4 代码

4.4.1 CPU0_UART

//****************************************Copyright (c)***********************************////原子哥在线教学平台:www.yuanzige.com//技术支持:www.openedv.com//淘宝店铺:http://openedv.taobao.com//关注微信公众平台微信号:"正点原子",免费获取ZYNQ & FPGA & STM32 & LINUX资料。//版权所有,盗版必究。//Copyright(C) 正点原子 2018-2028//All rights reserved//----------------------------------------------------------------------------------------// File name:           cpu0_uart// Last modified Date:  2019/6/8 1736// Last Version:        V1.0// Descriptions:        CPU0应用程序//----------------------------------------------------------------------------------------// Created by:          正点原子// Created date:        2019/6/8 1736// Version:             V1.0// Descriptions:        The original version////----------------------------------------------------------------------------------------//****************************************************************************************//

#include "xparameters.h"#include "xscugic.h"#include "xil_printf.h"#include "xil_exception.h"#include "xil_mmu.h"#include "stdio.h"

//宏定义#define INTC_DEVICE_ID       XPAR_SCUGIC_SINGLE_DEVICE_ID //中断ID#define SHARE_BASE           0xffff0000                   //共享OCM首地址#define CPU1_COPY_ADDR       0xfffffff0                   //存放CPU1应用起始地址的地址#define CPU1_START_ADDR      0x10000000                   //CPU1应用起始地址

#define CPU1_ID              XSCUGIC_SPI_CPU1_MASK        //CPU1 ID#define SOFT_INTR_ID_TO_CPU0 0                            //软件中断号 0 ,范围:0~15#define SOFT_INTR_ID_TO_CPU1 1                            //软件中断号 1 ,范围:0~15

//"SEV"指令唤醒CPU1并跳转至相应的程序#define sev()                __asm__("sev")               //C语言内嵌汇编写法 send event指令

//函数声明void start_cpu1();void cpu0_intr_init(XScuGic *intc_ptr);void soft_intr_handler(void *CallbackRef);

//全局变量XScuGic Intc;                    //中断控制器驱动程序实例int rec_freq_flag = 0;           //接收到呼吸灯频率设置的标志int freq_gear;                   //频率档位

//CPU0 main函数int main(){  //S=b1 TEX=b100 AP=b11, Domain=b1111, C=b0, B=b0  Xil_SetTlbAttributes(SHARE_BASE,0x14de2);    //禁用OCM的Cache属性

  //S=b1 TEX=b100 AP=b11, Domain=b1111, C=b0, B=b0  Xil_SetTlbAttributes(CPU1_COPY_ADDR,0x14de2);//禁用0xfffffff0的Cache属性

  //启动CPU1  start_cpu1();  //CPU0中断初始化  cpu0_intr_init(&Intc);  while(1){    if(rec_freq_flag == 0){      xil_printf("This is CPU0,Please input the numbers 1~5 to change "          "breath led frequency
");      scanf("%d",&freq_gear);      if(freq_gear >= 1 && freq_gear <=5){        xil_printf("You input number is %d
",freq_gear);        //向共享的地址中写入输入的数据        Xil_Out8(SHARE_BASE,freq_gear);        //给CPU1触发中断        XScuGic_SoftwareIntr(&Intc,SOFT_INTR_ID_TO_CPU1,CPU1_ID);        rec_freq_flag = 1;      }      else{        xil_printf("Error,The number range is 1~5
");        xil_printf("
");      }    }  }  return 0 ;}

//启动CPU1,用于固化程序void start_cpu1(){  //向 CPU1_COPY_ADDR(0Xffffffff0)地址写入 CPU1 的访问内存基地址  Xil_Out32(CPU1_COPY_ADDR, CPU1_START_ADDR);  dmb();  //等待内存写入完成(同步)  sev();  //通过"SEV"指令唤醒CPU1并跳转至相应的程序}

//CPU0中断初始化void cpu0_intr_init(XScuGic *intc_ptr){  //初始化中断控制器  XScuGic_Config *intc_cfg_ptr;  intc_cfg_ptr = XScuGic_LookupConfig(INTC_DEVICE_ID);    XScuGic_CfgInitialize(intc_ptr, intc_cfg_ptr,        intc_cfg_ptr->CpuBaseAddress);    //设置并打开中断异常处理功能    Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,        (Xil_ExceptionHandler)XScuGic_InterruptHandler, intc_ptr);    Xil_ExceptionEnable();

    XScuGic_Connect(intc_ptr, SOFT_INTR_ID_TO_CPU0,          (Xil_ExceptionHandler)soft_intr_handler, (void *)intc_ptr);

    XScuGic_Enable(intc_ptr, SOFT_INTR_ID_TO_CPU0); //CPU0软件中断}

//软件中断函数void soft_intr_handler(void *CallbackRef){  xil_printf("This is CPU0,Soft Interrupt from CPU1
");  xil_printf("
");  rec_freq_flag = 0;}

4.4.2 CPU1_LED

//****************************************Copyright (c)***********************************////原子哥在线教学平台:www.yuanzige.com//技术支持:www.openedv.com//淘宝店铺:http://openedv.taobao.com//关注微信公众平台微信号:"正点原子",免费获取ZYNQ & FPGA & STM32 & LINUX资料。//版权所有,盗版必究。//Copyright(C) 正点原子 2018-2028//All rights reserved//----------------------------------------------------------------------------------------// File name:           cpu1_led// Last modified Date:  2019/6/8 1736// Last Version:        V1.0// Descriptions:        CPU1应用程序//----------------------------------------------------------------------------------------// Created by:          正点原子// Created date:        2019/6/8 1736// Version:             V1.0// Descriptions:        The original version////----------------------------------------------------------------------------------------//****************************************************************************************//

#include "xparameters.h"#include "xscugic.h"#include "xil_printf.h"#include "xil_exception.h"#include "xil_mmu.h"#include "stdio.h"#include "breath_led_ip.h"

//宏定义#define INTC_DEVICE_ID       XPAR_SCUGIC_SINGLE_DEVICE_ID //中断ID#define SHARE_BASE         0xffff0000                   //共享OCM首地址

#define CPU0_ID              XSCUGIC_SPI_CPU0_MASK        //CPU0 ID#define SOFT_INTR_ID_TO_CPU0 0                            //软件中断号 0 ,范围:0~15#define SOFT_INTR_ID_TO_CPU1 1                            //软件中断号 1 ,范围:0~15

#define  LED_IP_BASEADDR     XPAR_BREATH_LED_IP_0_S0_AXI_BASEADDR //LED IP基地址#define  LED_IP_REG0         BREATH_LED_IP_S0_AXI_SLV_REG0_OFFSET //LED IP寄存器地址0#define  LED_IP_REG1         BREATH_LED_IP_S0_AXI_SLV_REG1_OFFSET //LED IP寄存器地址1

//函数声明void cpu1_intr_init(XScuGic *intc_ptr);void soft_intr_handler(void *CallbackRef);

//全局变量XScuGic Intc;               //中断控制器驱动程序实例int soft_intr_flag = 0;     //软件中断的标志int freq_gear;              //频率档位

//CPU1 main函数int main(){  int freq_step = 0;  //S=b1 TEX=b100 AP=b11, Domain=b1111, C=b0, B=b0  Xil_SetTlbAttributes(SHARE_BASE,0x14de2);    //禁用OCM的Cache属性

  //CPU1中断初始化  cpu1_intr_init(&Intc);  //打开呼吸灯  BREATH_LED_IP_mWriteReg(LED_IP_BASEADDR, LED_IP_REG0, 1);  while(1){    if(soft_intr_flag){      freq_gear = Xil_In8(SHARE_BASE);     //从共享OCM中读出数据      xil_printf("CUP1 Received data is %d
",freq_gear) ;      switch(freq_gear){        case 1 : freq_step = 20;break;        case 2 : freq_step = 50;break;        case 3 : freq_step = 100;break;        case 4 : freq_step = 200;break;        case 5 : freq_step = 500;break;        default : freq_step = 50;break;      }      //设置呼吸灯频率,最高位为1,设置有效      BREATH_LED_IP_mWriteReg(LED_IP_BASEADDR,LED_IP_REG1,(0x80000000|freq_step));      //给给CPU0触发中断      XScuGic_SoftwareIntr(&Intc,SOFT_INTR_ID_TO_CPU0,CPU0_ID);      soft_intr_flag = 0;    }  }  return 0 ;}

//CPU1中断初始化void cpu1_intr_init(XScuGic *intc_ptr){  //初始化中断控制器  XScuGic_Config *intc_cfg_ptr;  intc_cfg_ptr = XScuGic_LookupConfig(INTC_DEVICE_ID);    XScuGic_CfgInitialize(intc_ptr, intc_cfg_ptr,        intc_cfg_ptr->CpuBaseAddress);    //设置并打开中断异常处理功能    Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,        (Xil_ExceptionHandler)XScuGic_InterruptHandler, intc_ptr);    Xil_ExceptionEnable();

    XScuGic_Connect(intc_ptr, SOFT_INTR_ID_TO_CPU1,          (Xil_ExceptionHandler)soft_intr_handler, (void *)intc_ptr);

    XScuGic_Enable(intc_ptr, SOFT_INTR_ID_TO_CPU1); //CPU1软件中断}

//软件中断函数void soft_intr_handler(void *CallbackRef){  xil_printf("This is CUP1,Soft Interrupt from CPU0
") ;  soft_intr_flag = 1;}
审核编辑:彭静
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 处理器
    +关注

    关注

    68

    文章

    19259

    浏览量

    229649
  • 硬件
    +关注

    关注

    11

    文章

    3312

    浏览量

    66200
  • Zynq
    +关注

    关注

    10

    文章

    609

    浏览量

    47174

原文标题:ZYNQ之双核通讯原理以及程序设计

文章出处:【微信号:ZYNQ,微信公众号:ZYNQ】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    嵌入式多核处理器硬件结构分析与对排序算法进行并行化优化

    常常在嵌入式领域使用,常见的是通用嵌入式处理器+DSP核。本文探究的嵌入式多核处理器采用同构结构,实现同一段代码在不同处理器的并行执行。
    的头像 发表于 10-17 07:55 3998次阅读

    调节多核处理器硬件适应软件设计方法

    调节多核处理器硬件适应软件设计方法 典型的嵌入式系统设计人员在硬件平台上进行编程,他们最关注的一点就是硬件平台的稳定性。如果
    发表于 09-25 17:17

    数字信号处理器重新采纳多核架构

    中的多核处理器设计。这些处理器的目标应用可以被很好地划分为适合DSP的信号处理任务和适合RISC CPU的控制任务,从而使得
    发表于 04-09 23:14

    多核处理器设计九大要素

    商用CPU的“未来”高性能处理器结构。  虽然多核能利用集成度提高带来的诸多好处,让芯片的性能成倍地增加,但很明显的是原来系统级的一些问题便引入到了处理器内部。  1 核结构研究: 同构还是异构
    发表于 04-13 09:48

    多核处理器的优点

    处理器。通过在两个执行内核之间划分任务,多核处理器可在特定的时钟周期内执行更多任务。 多核技术能够使服务
    发表于 06-20 06:47

    典型的支持多核处理器的RTOS功能解析

    1、基于同步原语扩展的实时操作系统 在多核处理器的每一个处理器都运行一个完全相同的RTOS,然后提供扩展的组件库,这种组件库提供相应的同步原语以支持
    发表于 06-29 08:30

    集成电路多核处理器虚拟化技术

    多核处理器以其高性能、低功耗、设计周期短等诸多优势成为未来高性能处理器的发展趋势。由于应用对计算能力的需求是无限的,随着芯片晶体管数目的进一步增多,
    发表于 05-30 10:06 52次下载
    集成电路<b class='flag-5'>多核</b><b class='flag-5'>处理器</b>虚拟化技术

    多核处理器存储系统研究

    针对 多核处理器 计算能力和访存速度间差异不断增大对多核系统性能提升的制约问题,分析几款典型多核处理器存储系统的设计特点,探讨
    发表于 07-27 15:49 29次下载
    <b class='flag-5'>多核</b><b class='flag-5'>处理器</b>片<b class='flag-5'>上</b>存储系统研究

    多核处理器会取代FPGA吗?

    有人认为诸如图形处理器(GPU)和Tilera处理器多核处理器在某些应用中正逐步替代现场可编程门陈列(FPGA)。理由是这些多核
    发表于 02-11 11:15 1036次阅读
    <b class='flag-5'>多核</b><b class='flag-5'>处理器</b>会取代FPGA吗?

    第1章 多核处理器基础

    多核处理器基础,介绍了嵌入式的多核的信息
    发表于 04-11 14:17 2次下载

    基于FPGA的NoC多核处理器的设计

    NoC多核处理器的规模以及对FPGA硬件资源的需求,在此基础给出了集成4片FPGA的开发板详细设计方案,并对各主要模块如互联架构、电源、板级时钟分布、接口技术、存储资源等关键设计要点
    发表于 11-22 09:15 4700次阅读

    处理器关于多核概念与区别 多核处理器工作原理及优缺点

    摘要:目前关于处理器的单核、双核和多核已经得到了普遍的运用,今天我们主要说说关于多核处理器的一些相关概念,它的工作与那里以及优缺点而展开的分析。
    发表于 12-08 13:31 3.1w次阅读

    如何在Zynq处理器lwIP实现网络功能

    了解如何在Zynq处理器使用轻量级IP堆栈(lwIP)来实现网络功能。 本次会议既包括独立用例,也包括与流行的轻量级FreeRTOS操作系统的集成。
    的头像 发表于 11-27 06:17 5425次阅读

    浅议多核处理器技术

    多核处理器以其高性能、低功耗优势正逐步取代传统的单处理器成为市场的主流。随着应用需求的扩大和技术的不断进步,多核必将展示出其强大的性能优势。但目前
    发表于 03-29 10:47 8次下载

    Zynq的非对称多核处理器

    Zynq SoC 还拥有大量共享资源,常见示例包括 I/O 外设、片存储、中断控制分配器、L2 高速缓存和位于 DDR 存储内的系统
    的头像 发表于 06-16 10:18 1559次阅读