Lab4 Modificado
Lab4 Modificado
Lab4 Modificado
Objectives
After completing this lab, you will be able to:
Procedure
This lab is separated into steps that consist of general overview statements that provide information on
the detailed instructions that follow. Follow these detailed instructions to progress through the lab.
This lab comprises 4 primary steps: You will open the Vivado project, export to and invoke SDK, create a
software project, analyze assembled object files and verify the design in hardware.
Design Description
The design was extended at the end of the previous lab to include a memory controller (see Figure 1),
and the bitstream should now be available. A basic software application will be developed to access the
LEDs on the Zybo board.
1-1-1. Start the Vivado if necessary and open either the lab3 project (lab3.xpr) you created in the
previous lab or the lab3 project in the {labsolutions} directory using the Open Project link in the
Getting Started page.
1-1-2. Select File > Save Project As … to open the Save Project As dialog box. Enter lab4 as the
project name. Make sure that the Create Project Subdirectory option is checked, the project
directory path is {labs} and click OK.
This will create the lab4 directory and save the project and associated directory with lab4 name.
2-1-2. Click on the checkbox of Include the bitstream and then click Yes to overwrite.
2-2. Close previously created projects. Create an empty project called lab4.
Import lab4.c file from the {sources} directory
2-2-1. To tidy up the workspace and save unnecessary building of a project that is not being used, right
click on the TestApp, standalone_bsp_0, and the system_wrapper_hw_platform_1 projects
from the previous lab, and click Close Project, as these projects will not be used in this lab. They
can be reopened later if needed.
2-2-3. Enter lab4 as the Project Name, and for Board Support Package, choose Create New lab4_bsp
(should be the only option).
2-2-4. Click Next, and select Empty Application and click Finish.
2-2-5. Expand lab4 in the project view and right-click in the src folder and select Import.
2-2-8. Select lab4.c and click Finish to add the file to the project. (Ignore any errors for now).
2-2-10. Click on Documentation link corresponding to buttons peripheral under the Peripheral Drivers
section to open the documentation in a default browser window. As our led_ip is very similar to
GPIO, we look at the mentioned documentation.
2-2-11. View the various C and Header files associated with the GPIO by clicking Files at the top of the
page.
2-2-12. Double-click on lab4.c in the Project Explorer view to open the file. This will populate the Outline
tab.
2-2-13. Double click on xgpio.h in the Outline view and review the contents of the file to see the available
function calls for the GPIO.
The following steps must be performed in your software application to enable reading from the
GPIO: 1) Initialize the GPIO, 2) Set data direction, and 3) Read the data
InstancePtr is a pointer to an XGpio instance. The memory the pointer references must be pre-
allocated by the caller. Further calls to manipulate the component through the XGpio API must
be made with this pointer.
DeviceId is the unique id of the device controlled by this XGpio component. Passing in a device
id associates the generic XGpio instance to a specific device, as chosen by the caller or
application developer.
DirectionMask is a bitmask specifying which bits are inputs and which are outputs. Bits set to 0
are output and bits set to 1 are input.
2-2-14. Open the header file xparameters.h by double-clicking on xparameters.h in the Outline tab
The xparameters.h file contains the address map for peripherals in the system. This file is
generated from the hardware platform description from Vivado. Find the following #define used to
identify the switches peripheral:
2-2-15. Modify line 14 of lab4.c to use this macro (#define) in the XGpio_Initialize function.
Figure 4. Imported source, highlighting the code to initialize the switches as input, and
read from it
2-2-16. Do the same for the BUTTONS; find the macro (#define) for the BUTTONS peripheral in
xparameters.h, and modify line 17 in lab4.c, and save the file.
The project will be rebuilt. If there are any errors, check and fix your code. Your C code will
eventually read the value of the switches and output it to the led_ip.
2-3. Assign the led_ip driver from the driver directory to the led_ip instance.
2-3-1. Select lab4_bsp in the project view, right-click, and select Board Support Package Settings.
2-3-3. If the led_ip driver has not already been selected, select Generic under the Driver column for
led_ip to access the dropdown menu. From the dropdown menu, select led_ip, and click OK.
Notice the files in this directory and open led_ip.c. This file only includes the header file for the IP.
2-4-2. Close led_ip.c and open the header file led_ip.h and notice the macros:
LED_IP_mWriteReg( … )
LED_IP_mReadReg( … )
/**
*
* Write a value to a LED_IP register. A 32 bit write is performed.
* If the component is implemented in a smaller width, only the least
* significant data is written.
*
* @param BaseAddress is the base address of the LED_IP device.
* @param RegOffset is the register offset from the base to write to.
* @param Data is the data written to the register.
*
* @return None.
*
* @note
* C-style signature:
* void LED_IP_mWriteReg(Xuint32 BaseAddress, unsigned RegOffset,
Xuint32 Data)
*
*/
#define LED_IP_mWriteReg(BaseAddress, RegOffset, Data) \
Xil_Out32((BaseAddress) + (RegOffset), (Xuint32)(Data))
For this driver, you can see the macros are aliases to the lower level functions Xil_Out32( ) and
Xil_Out32( ). The macros in this file make up the higher level API of the led_ip driver. If you are
writing your own driver for your own IP, you will need to use low level functions like these to read
and write from your IP as required. The low level hardware access functions are wrapped in your
driver making it easier to use your IP in an Application project.
2-4-3. Modify your C code (see figure below, or you can find modified code in lab4_sol.c from the
{sources} folder) to echo the dip switch settings on the LEDs by using the led_ip driver API
macros, and save the application.
#include "led_ip.h"
2-4-5. Include the function to write to the IP (insert before the for loop):
LED_IP_mWriteReg(XPAR_LED_IP_S_AXI_BASEADDR, 0, dip_check);
Remember that the hardware address for a peripheral (e.g. the macro
XAR_LED_IP_S_AXI_BASEADDR in the line above) can be found in xparameters.h
2-4-6. Save the file and the program will be compiled again.
3-1-1. Make sure that micro-USB cable(s) is(are) connected between the board and the PC. Turn ON
the power.
3-1-2. Select the tab. If it is not visible then select Window > Show view > Terminal.
3-1-3. Click on and if required, select appropriate COM port (depends on your computer), and
configure it with the parameters as shown. (These settings may have been saved from previous
lab).
3-2. Program the FPGA by selecting Xilinx Tools > Program FPGA and
assigning system_wrapper.bit file. Run the TestApp application and verify
the functionality.
3-2-3. Select lab4 in Project Explorer, right-click and select Run As > Launch on Hardware (GDB) to
download the application, execute ps7_init, and execute lab4.elf
Flip the DIP switches and verify that the LEDs light according to the switch settings. Verify that
you see the results of the DIP switch and Push button settings in SDK Terminal.
Figure 8. DIP switch and Push button settings displayed in SDK terminal
Note: Setting the DIP switches and push buttons will change the results displayed.
3-3. Change the linker script to target Code sections to the BRAM controller
and objdump lab4.elf and look at the sections it has created.
Note that all four major sections, code, data, stack and heap are to be assigned to BRAM
controller.
3-3-2. In the Basic Tab change the Code and Data sections to ps7_ddr_0, leaving the Heap and Stack
in section to axi_bram_ctrl_0_Mem0 memory and click Generate, and click Yes to overwrite.
3-4. Execute the lab4.elf application and observe the application working even
when various sections are in different memory.
3-4-1. Select lab4 in Project Explorer, right-click and select Run As > Launch on Hardware (GDB) to
download the application, execute ps7_init, and execute lab4.elf
Click Yes if prompted to stop the execution and run the new application.
Observe the SDK Terminal window as the program executes. Play with dip switches and observe
the LEDs. Notice that the system is relatively slow in displaying the message in the Terminal tab
and to change in the switches as the stack and heap are from a non-cached BRAM memory.
3-4-2. When finished, click on the Terminate button in the Console tab.
Conclusion
Use SDK to define, develop, and integrate the software components of the embedded system. You can
define a device driver interface for each of the peripherals and the processor. SDK imports an hdf file,
creates a corresponding MSS file and lets you update the settings so you can develop the software side
of the processor system. You can then develop and compile peripheral-specific functional software and
generate the executable file from the compiled object code and libraries. If needed, you can also use a
linker script to target various segments in various memories. When the application is too big to fit in the
internal BRAM, you can download the application in external memory and then execute the program.