情回顾

(1)ZYNQ中PS端MIO操作
(2)ZYNQ中PS端MIO中断
(3)ZYNQ中PS端UART通信(4)ZYNQ中PS端XADC读取(5)Zynq中PL读写PS端DDR数据

(6)zynq中PS访问BRAM(一)

PS端程序设计流程为:

  • 输入起始地址和长度

  • PS通过BRAM控制器写入BRAM数据

  • 通知PL控制器读取BRAM数据

  • PL内部读完后向相同位置写入数据,初始数据由PS端确定: 

函数里先通过BRAM控制器写入数据,数据初值为TEST初值,之后配置PLRAM控制器参数,有长度,起始地址,初始数据,以及开始信号。 

  • 写完后使能write_end信号,触发GPIO中断

  • 中断读取BRAM数据,打印显示

主循环如下:

    while(1)

    {

        if (Gpio_flag)//如果完成,则进行下一次循环读写

        {

            Gpio_flag= 0 ;

            printf("Please provide start address\t\n") ;

            scanf("%d", &Start_Addr) ;

            printf("Start address is %d\t\n", Start_Addr) ;

            printf("Please provide length\t\n") ;

            scanf("%d", &Len) ;

            printf("Length is %d\t\n", Len) ;

            Status= bram_read_write() ;

            if (Status != XST_SUCCESS)

            {

               

                Gpio_flag = 1 ;

            }

        }

    }

控制BRAM读写如下:

int bram_read_write()

{

 

    u32 Write_Data = TEST_START_VAL ;//确定PL写的初值

    int i ;

//判断是否越界

    if ((Start_Addr + Len) > (BRAM_CTRL_HIGH -BRAM_CTRL_BASE + 1)/4)

    {

        xil_printf("******************************************\r\n");

        xil_printf("Error! Exceed BramControlAddress Range!\r\n");

        return XST_FAILURE ;

    }

    //BRAM中写数据

    for(i = BRAM_BYTENUM*Start_Addr ; i <BRAM_BYTENUM*(Start_Addr + Len) ; i += BRAM_BYTENUM)

    {

        XBram_WriteReg(XPAR_BRAM_0_BASEADDR, i ,Write_Data) ;

        Write_Data+= 1 ;

    }

    //设置BRAM的读长度和读地址

    PL_RAM_CTRL_mWriteReg(PL_RAM_BASE,PL_RAM_LEN , BRAM_BYTENUM*Len) ;

    PL_RAM_CTRL_mWriteReg(PL_RAM_BASE,PL_RAM_ST_ADDR , BRAM_BYTENUM*Start_Addr) ;

    //设置PL初始写数据地址

    PL_RAM_CTRL_mWriteReg(PL_RAM_BASE,PL_RAM_INIT_DATA , (Start_Addr+1)) ;

    //设置PLRAM开始

    PL_RAM_CTRL_mWriteReg(PL_RAM_BASE,PL_RAM_START , 1) ;

 

    return XST_SUCCESS ;

}


首先是PL控制器从BRAM读数据,之后是写数据,可以看到红色为PL读出的BRAM数据,正是CPU写入的数据,从12开始,共10个数据,PL写入的数据为黄色部分从1开始,共10个数据。

 

zynq中PS访问BRAM(二)_java

中断处理,打印出读RAM的数据

void GpioHandler(void *CallbackRef)

{

    XGpio *GpioInstancePtr = (XGpio *)CallbackRef ;

    int Read_Data ;

 

    int i ;

    printf("Enter interrupt\t\n");

    //clear interrupt status

    XGpio_InterruptClear(GpioInstancePtr,GPIO_INTR_MASK) ;

 

    for(i = BRAM_BYTENUM*Start_Addr ; i <BRAM_BYTENUM*(Start_Addr+ Len) ; i +=BRAM_BYTENUM)

    {

        Read_Data= XBram_ReadReg(XPAR_BRAM_0_BASEADDR , i) ;

        printf("Address is %d\t Read data is %d\t\n", i/BRAM_BYTENUM,Read_Data) ;

    }

    Gpio_flag= 1 ;

}

zynq中PS访问BRAM(二)_java_02