zynq中PS访问BRAM(二)
- 2019 年 11 月 5 日
- 笔记
前情回顾
(1)ZYNQ中PS端MIO操作 (2)ZYNQ中PS端MIO中断 (3)ZYNQ中PS端UART通信
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 addresstn") ;
scanf("%d", &Start_Addr) ;
printf("Start address is %dtn", Start_Addr) ;
printf("Please provide lengthtn") ;
scanf("%d", &Len) ;
printf("Length is %dtn", 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("******************************************rn");
xil_printf("Error! Exceed Bram ControlAddress Range!rn");
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)) ;
//设置PL读RAM开始
PL_RAM_CTRL_mWriteReg(PL_RAM_BASE,PL_RAM_START , 1) ;
return XST_SUCCESS ;
}
首先是PL控制器从BRAM读数据,之后是写数据,可以看到红色为PL读出的BRAM数据,正是CPU写入的数据,从12开始,共10个数据,PL写入的数据为黄色部分从1开始,共10个数据。

中断处理,打印出读RAM的数据
void GpioHandler(void *CallbackRef)
{
XGpio *GpioInstancePtr = (XGpio *)CallbackRef ;
int Read_Data ;
int i ;
printf("Enter interrupttn");
//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 %dt Read data is %dtn", i/BRAM_BYTENUM,Read_Data) ;
}
Gpio_flag= 1 ;
}
