日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當(dāng)前位置:首頁(yè) > > ZYNQ
		


1.簡(jiǎn)介

zynq系列開(kāi)發(fā)板有兩個(gè)板載Cortex-A9處理器,兩個(gè)ARM可以協(xié)同處理數(shù)據(jù)。

多核處理器硬件上的劃分

1.同構(gòu)多核:系統(tǒng)中的多個(gè)處理器在結(jié)構(gòu)上是相同的;

優(yōu)點(diǎn)是硬件和軟件設(shè)計(jì)上較為簡(jiǎn)單,通用性高。

2.異構(gòu)多核:系統(tǒng)中的處理器結(jié)構(gòu)上是不同的;

優(yōu)點(diǎn)是在某些特定場(chǎng)合,專用的硬件加速核可以提高性能。

ZYNQ中的兩個(gè)Cortex-A9處理器+可編程邏輯器件FPGA組成了異構(gòu)多核處理器。

多核處理器從軟件運(yùn)行方式上劃分

AMP(Asymmetric Muti-processing):非對(duì)稱多處理

多個(gè)內(nèi)核相對(duì)獨(dú)立的運(yùn)行不同的任務(wù),每個(gè)內(nèi)核相互隔離,可以運(yùn)行不同的操??作系統(tǒng)或者裸機(jī)程序。

SMP(Symmetric Muti-processing):

多個(gè)處理器運(yùn)行一個(gè)操作系統(tǒng),這個(gè)操作系統(tǒng)同等的管理多個(gè)內(nèi)核。

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

BMP與SMP類似,但是開(kāi)發(fā)者可以指定將某個(gè)任務(wù)僅在某個(gè)指定內(nèi)核上執(zhí)行。


AMP模式下要注意不要兩個(gè)CPU一起訪問(wèn)同一個(gè)地址或者共享外設(shè)。


2.CPU之間通訊原理

2.1 通訊步驟

1.系統(tǒng)初始化

2.啟動(dòng)CPU1

3.和CPU1進(jìn)行通訊

4.共享CPU外設(shè)


2.2 CPU資源

CPU資源分為私有資源和公共資源。私有資源是每個(gè)CPU都有的資源,只能被各自的CPU訪問(wèn),訪問(wèn)時(shí)無(wú)需注意沖突。公共資源為CPU之間共享的資源,訪問(wèn)時(shí)要注意訪問(wèn)沖突。

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

公共資源: L2Cache、DDR存儲(chǔ)器、OCM(on chip memory)、ICD(Interrupt control distributor)、全局時(shí)鐘和其他外等。


OCM用來(lái)和CPU之間的通訊的,與DDR相比,OCM具有更高的性能和更低的延遲。用于小數(shù)據(jù)量(256KB一下)用OCM更好。

避免同時(shí)訪問(wèn)的方法

DDR:CPU0只能訪問(wèn)0x00100000至0x001FFFFF,CPU1只能訪問(wèn)0x00200000到0x002FFFFF(可人為更改)

L2Cache:CPU0使用,CPU1不使用。

ICD:中斷來(lái)自PL,連接到CPU1。

Timer(定時(shí)器):只有CPU1使用。

OCM:OCM的某一地址進(jìn)行標(biāo)志。當(dāng)標(biāo)志為0時(shí)這個(gè)地址是某個(gè)CPU私有的;為1時(shí),這個(gè)地址是另一個(gè)CPU私有的?;蛘哕浖a(chǎn)生中斷的方式。


2.3 軟件設(shè)計(jì)

軟件設(shè)計(jì)分為三個(gè)階段

1.First stage boot loader(FSBL):第一啟動(dòng)階段

2.Bare-metal application for CPU0:裸機(jī)應(yīng)用程序

3.Bare-metal application for CPU1:裸機(jī)應(yīng)用程序

FSBL

一直運(yùn)行在CPU上面,是開(kāi)發(fā)板上電之后啟動(dòng)先啟動(dòng)Boot rom,后啟動(dòng)FSBL,負(fù)責(zé)配置PL然后拷貝兩個(gè)處理器的應(yīng)用程序(ELF)加載到DDR中,然后開(kāi)始運(yùn)行第一個(gè)應(yīng)用程序。

Bare-metal application Code

兩個(gè)CPU運(yùn)行各自的裸機(jī)的程序,CPU負(fù)責(zé)初始化共享外設(shè),并且負(fù)責(zé)啟動(dòng)CPU1.

CPU0 Application

內(nèi)存的起始地址為0x00100000。這個(gè)起始地址可以在鏈接腳本進(jìn)行修改的。

CPU0的配置步驟:

1.配置MMU來(lái)禁止cache緩存功能0xFFFF0000至0xFFFFFFFF來(lái)保證兩個(gè)CPU訪問(wèn)OCM的一致性。地址映射不可修改。

2.初始化ICD

3.啟動(dòng)CPU1

4.通過(guò)串口打印信息

5.設(shè)置OCM的地址作為信號(hào)量

6.等待地址里面的信號(hào)量被清除。

Boot rom代碼執(zhí)行后,CPU1也會(huì)在OCM的0xFFFFFF00地址上執(zhí)行一段代碼。功能是檢查地址0xFFFFFFF0的值是否為1來(lái)等待事件到來(lái)。

CPU0啟動(dòng)CPU1是通過(guò)向地址0x00200000寫(xiě)入地址0xFFFFFFF0然后CPU0運(yùn)行Set Event(SEV)命令啟動(dòng)CPU1。CPU1會(huì)讀取0xFFFFFFF0里面的值0x00200000。然后跳轉(zhuǎn)到該地址執(zhí)行程序。

CPU1的配置步驟


3 如何避免多個(gè)CPU同時(shí)訪問(wèn)OCM

CPU0向OCM寫(xiě)入一個(gè)數(shù)據(jù)之后,給CPU1產(chǎn)生軟件中斷。讓CPU1知道CPU0已經(jīng)不再操作該地址。此時(shí)CPU1讀取數(shù)據(jù),讀取完畢后產(chǎn)生一個(gè)中斷通知CPU0。

軟件中斷(SGIs):中斷來(lái)自CPU內(nèi)部,每個(gè)CPU可以中斷自己或者另外的CPU或者一起中斷,每個(gè)CPU有16個(gè)中斷號(hào),編號(hào)為0到15。向寄存器(ICDSGIR)寫(xiě)入中斷號(hào)并且指定CPU。目標(biāo)的CPU即可產(chǎn)生中斷。

OCM:PS的片上存儲(chǔ)器,包括256KB的RAM和128KB的ROM(BootROM)。地址范圍為0x00000000到0002FFFF的三個(gè)64KB加上0xFFFF_0000到0xFFFF_FFFF共256KB。


4 程序設(shè)計(jì)

4.1 程序任務(wù)

CPU0接收串口數(shù)據(jù)并寫(xiě)入OCM中,然后利用軟件中斷觸發(fā)CPU1;CPU1接收到中斷后,根據(jù)從OCM中讀出的數(shù)據(jù)控制呼吸燈的頻率,并在控制結(jié)束后觸發(fā)CPU0的中斷,實(shí)現(xiàn)雙核CPU通信的功能。


4.2 系統(tǒng)框圖


4.3 軟件操作


4.4 代碼

4.4.1 CPU0_UART

//****************************************Copyright (c)***********************************////原子哥在線教學(xué)平臺(tái):www.yuanzige.com//技術(shù)支持:www.openedv.com//淘寶店鋪:http://openedv.taobao.com//關(guān)注微信公眾平臺(tái)微信號(hào):"正點(diǎn)原子",免費(fèi)獲取ZYNQ & FPGA & STM32 & LINUX資料。//版權(quán)所有,盜版必究。//Copyright(C) 正點(diǎn)原子 2018-2028//All rights reserved//----------------------------------------------------------------------------------------// File name:           cpu0_uart// Last modified Date:  2019/6/8 17:25:36// Last Version:        V1.0// Descriptions:        CPU0應(yīng)用程序//----------------------------------------------------------------------------------------// Created by:          正點(diǎn)原子// Created date:        2019/6/8 17:25:36// 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應(yīng)用起始地址的地址#define CPU1_START_ADDR      0x10000000 //CPU1應(yīng)用起始地址  #define CPU1_ID              XSCUGIC_SPI_CPU1_MASK //CPU1 ID#define SOFT_INTR_ID_TO_CPU0 0 //軟件中斷號(hào) 0 ,范圍:0~15#define SOFT_INTR_ID_TO_CPU1 1 //軟件中斷號(hào) 1 ,范圍:0~15  //"SEV"指令喚醒CPU1并跳轉(zhuǎn)至相應(yīng)的程序#define sev()                __asm__("sev") //C語(yǔ)言內(nèi)嵌匯編寫(xiě)法 send event指令  //函數(shù)聲明void start_cpu1();void cpu0_intr_init(XScuGic *intc_ptr);void soft_intr_handler(void *CallbackRef);  //全局變量XScuGic Intc; //中斷控制器驅(qū)動(dòng)程序?qū)嵗?/span>int rec_freq_flag = 0; //接收到呼吸燈頻率設(shè)置的標(biāo)志int freq_gear; //頻率檔位  //CPU0 main函數(shù)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屬性   //啟動(dòng)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\r\n"); scanf("%d",&freq_gear); if(freq_gear >= 1 && freq_gear <=5){ xil_printf("You input number is %d\r\n",freq_gear); //向共享的地址中寫(xiě)入輸入的數(shù)據(jù) Xil_Out8(SHARE_BASE,freq_gear); //給CPU1觸發(fā)中斷 XScuGic_SoftwareIntr(&Intc,SOFT_INTR_ID_TO_CPU1,CPU1_ID); rec_freq_flag = 1; } else{ xil_printf("Error,The number range is 1~5\r\n"); xil_printf("\r\n"); } } } return 0 ;}  //啟動(dòng)CPU1,用于固化程序void start_cpu1(){ //向 CPU1_COPY_ADDR(0Xffffffff0)地址寫(xiě)入 CPU1 的訪問(wèn)內(nèi)存基地址 Xil_Out32(CPU1_COPY_ADDR, CPU1_START_ADDR); dmb(); //等待內(nèi)存寫(xiě)入完成(同步) sev(); //通過(guò)"SEV"指令喚醒CPU1并跳轉(zhuǎn)至相應(yīng)的程序}  //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); //設(shè)置并打開(kāi)中斷異常處理功能 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軟件中斷}  //軟件中斷函數(shù)void soft_intr_handler(void *CallbackRef){ xil_printf("This is CPU0,Soft Interrupt from CPU1\r\n"); xil_printf("\r\n"); rec_freq_flag = 0;}


4.4.2 CPU1_LED

//****************************************Copyright (c)***********************************////原子哥在線教學(xué)平臺(tái):www.yuanzige.com//技術(shù)支持:www.openedv.com//淘寶店鋪:http://openedv.taobao.com//關(guān)注微信公眾平臺(tái)微信號(hào):"正點(diǎn)原子",免費(fèi)獲取ZYNQ & FPGA & STM32 & LINUX資料。//版權(quán)所有,盜版必究。//Copyright(C) 正點(diǎn)原子 2018-2028//All rights reserved//----------------------------------------------------------------------------------------// File name:           cpu1_led// Last modified Date:  2019/6/8 17:25:36// Last Version:        V1.0// Descriptions:        CPU1應(yīng)用程序//----------------------------------------------------------------------------------------// Created by:          正點(diǎn)原子// Created date:        2019/6/8 17:25:36// 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 //軟件中斷號(hào) 0 ,范圍:0~15#define SOFT_INTR_ID_TO_CPU1 1 //軟件中斷號(hào) 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  //函數(shù)聲明void cpu1_intr_init(XScuGic *intc_ptr);void soft_intr_handler(void *CallbackRef);  //全局變量XScuGic Intc; //中斷控制器驅(qū)動(dòng)程序?qū)嵗?/span>int soft_intr_flag = 0; //軟件中斷的標(biāo)志int freq_gear; //頻率檔位  //CPU1 main函數(shù)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); //打開(kāi)呼吸燈 BREATH_LED_IP_mWriteReg(LED_IP_BASEADDR, LED_IP_REG0, 1); while(1){ if(soft_intr_flag){ freq_gear = Xil_In8(SHARE_BASE); //從共享OCM中讀出數(shù)據(jù) xil_printf("CUP1 Received data is %d\r\n",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; } //設(shè)置呼吸燈頻率,最高位為1,設(shè)置有效 BREATH_LED_IP_mWriteReg(LED_IP_BASEADDR,LED_IP_REG1,(0x80000000|freq_step)); //給給CPU0觸發(fā)中斷 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); //設(shè)置并打開(kāi)中斷異常處理功能 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軟件中斷}  //軟件中斷函數(shù)void soft_intr_handler(void *CallbackRef){ xil_printf("This is CUP1,Soft Interrupt from CPU0\r\n") ; soft_intr_flag = 1;}


本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
關(guān)閉