zedboard学习第一篇
1. 刚开始学习使用,不知道从哪里开始,手上的资料也很乱,至于这个板子需要学什么也不清楚。
2. 第一个工程就从helloworld开始吧,Zed板上的Zynq是一个PS(processing system, 双核A9 + 存储管理 + 外设)+ PL(programable Logic) 结构,如果不使用PL,zynq的开发和普通的ARM 芯片开发一样。不同的是PS单元是可配置,因而硬件信息是不固定的。这也是zynq灵活性的一个表现。 原来如此。
3. PlanAhead 14.1 + XPS 14.1 这两个软件没用过,只能按照前辈的经验了。
4. 配置硬件信息,启动PlanAhead(是个引脚配置工具吗?),这软件在哪里,听说新的vivado把所有的都集合都一起了。那就直接建立工程吧
5. 点击create block design,然后search这个IP,问题,PS系统是固化的ARM cortex a9双核,应该直接就有的,为啥还要IP核去使用?
6. 点击run block automation,会生成FIXED_IO(什么用途?),DDR接口,并且创建外部接口。
7. 配置zynq,双击zynq的图标,进入zynq的配置界面。点击Presets->zedboard,选择vivado里面已经有的配置。
8. 用同样的方法,我们增加外设,在Diagram右击,选择Add IP,在搜索页,输入gpio找到AXI GPIO IP,点击enter确认添加,重复上述步骤,输入axi bram添加AXI BRAM Controller;输入block加入Block Memory Generator。
9. 双击Block Memory Generator进入Re--customize IP界面,在Basic页,将Mode设置为BRAM Controller,Memory Type设置为True Dual Port RAM。其中AXI BRAM Controller为Block Memory Generator提供AXI内存映射接口。通过点击连接点并拖动连线将Block Memory Generator与AXI BRAM Controller连接起来。
10. Block Designer Assistance可以帮助我们将AXI GPIO和AXI BRAM Controller连接到Zynq-7000 PS。点击Run Connection Automation然后选择/axi_gpio_1/s_axi将GPIO IP和BRAM Controller连接到Zynq PS上,再次选择Run Connection Automation,连接/axi_gpio_1/gpio,然后会弹出一个对话框,选择板子接口为leds_8bits。这一步可是配置IP核,创建一些必要的文件约束(XDC),再次再次选择Run Connection Automation,选择剩下的/axi_bram_ctrl_1/S_AXI选项,这样就完成了Zynq7 PS与AXI BRAM Controller的连接。布局完成的连线如下所示:
11.打开Address Editor标签页,这里是我们所使用的IP的内存映射,在这里有两个IP:GPIO和BRAM Controller,一般来说Vivado会自动分配这些内存映射,我们也可以修改它,这里把AXI BRAM Controller改成32K。
12. 保存配置(CTRL+S);
在工具栏那里,通过Validate Design按钮运行DRC(Design-Rules-Check)
13. 在Sources窗口,右击顶层子系统设计选择Generate Output Products,这会生成用于结构图IP核的源文件和相关的约束文件。
14.还是在顶层子系统设计选择Create HDL Wrapper创建一个顶层HDL文件
15.在Flow Navigator中,点击Generate Bitstream完成设计并生成比特流(这一步时间会很长)
16. 将硬件信息导入SDK,File->export->export hardware,launch SDK
17. 打开SDK之后可以看到,分配好的地址map文件,可以看到工程浏览器Project Explorer中已经有一个硬件平台hw_platform_0,里面有一系列配置和初始化文件。
18. 新建一个工程,file->new->application project,输入工程的名字,然后选择Hello World工程,这个工程是viivado自带的,可以直接使用
19.此时会产生两个文件夹,helloworld_test_Design和helloworld_test_bsp。新建源文件main.c,输入代码
1 #include<stdio.h> 2 #include"platform.h" 3 void printf(char *str); 4 int main() 5 { 6 init_platform(); 7 printf("hello world\n\r"); 8 return 0; 9 }
20. 确保给ZedBoard上电,将启动模式设置为Jtag启动,将mini USB下载线接上,并将mini USB to Uart接上。其中vivado大约会用到1.4G的内存,所以电脑有点卡。
21. 将.bit文件下载到开发板上,Xilinx Tools->Program FPGA将比特流写入FPGA中,右键工程helloworld_test,run as->run configuration,打开下载配置界面。双击Xilinx C/C++ ELF,建立新的下载配置。默认即可。
22.可以看到串口有输出,串口设置波特率115200。
23. 分析,大致理解为,FPGA配置成一个串口,作为一个ARM内核的外设,通过AXI总线连接的,有时间需要研究下AXI总线。
24. 下面去分析串口是怎么配置的。main->init_platform()->init_uart()
1 void init_uart() 2 { 3 #ifdef STDOUT_IS_16550 4 XUartNs550_SetBaud(STDOUT_BASEADDR, XPAR_XUARTNS550_CLOCK_HZ, UART_BAUD); 5 XUartNs550_SetLineControlReg(STDOUT_BASEADDR, XUN_LCR_8_DATA_BITS); 6 #endif 7 #ifdef STDOUT_IS_PS7_UART 8 /* Bootrom/BSP configures PS7 UART to 115200 bps */ 9 #endif 10 }
25. 应该使用的是STDOUT_IS_PS7_UART这个宏定义,然后下面说是BSP配置PS7作为115200的串口,那么说的这个BSP板级支持包就是之前的helloworld_test_bsp这个工程了。去看一看里面有什么
26. 找到一个串口发送函数
1 unsigned int XUartPs_Send(XUartPs *InstancePtr, u8 *BufferPtr, 2 unsigned int NumBytes) 3 { 4 unsigned int BytesSent; 5 6 /* 7 * Asserts validate the input arguments 8 */ 9 Xil_AssertNonvoid(InstancePtr != NULL); 10 Xil_AssertNonvoid(BufferPtr != NULL); 11 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); 12 13 /* 14 * Disable the UART transmit interrupts to allow this call to stop a 15 * previous operation that may be interrupt driven. 16 */ 17 XUartPs_WriteReg(InstancePtr->Config.BaseAddress, XUARTPS_IDR_OFFSET, 18 (XUARTPS_IXR_TXEMPTY | XUARTPS_IXR_TXFULL)); 19 20 /* 21 * Setup the buffer parameters 22 */ 23 InstancePtr->SendBuffer.RequestedBytes = NumBytes; 24 InstancePtr->SendBuffer.RemainingBytes = NumBytes; 25 InstancePtr->SendBuffer.NextBytePtr = BufferPtr; 26 27 /* 28 * Transmit interrupts will be enabled in XUartPs_SendBuffer(), after 29 * filling the TX FIFO. 30 */ 31 BytesSent = XUartPs_SendBuffer(InstancePtr); 32 33 return BytesSent; 34 }
27. done