Lab 4- Writing Basic Software Applications
PowerPC Processor
Writing Basic Software Applications Lab:
PowerPC Processor
Introduction
This lab guides you through the process of writing a basic software application. The software
will write to the my_leds peripheral. You will modify the linker script to place the instructions (.text section) in the plb_bram_if_cntlr_2_bram memory. Finally, you will verify that the design still operates as expected in on the XUP Virtex-II Pro board.
Objectives
After completing this lab, you will be able to:
• Write a basic application to access an IP peripheral
• Utilize XPS to generate an MSS file
• Generate a bit file
• Download the bit file and verify on the XUP Virtex-II Pro Board
• Develop a simple linker script
Procedure
The first three labs defined the hardware for the processor system. This lab comprises several steps, including the writing of a basic software application to access one of the peripherals created in Lab3. Below each general instruction for a given procedure, you will find accompanying step-by-step directions and illustrated figures providing more detail for performing the general instruction. If you feel confident about a specific instruction, feel free to skip the step-by-step directions and move on to the next general instruction in the procedure.
Open the Project Step 1

![]()
Create a lab4 folder and copy the contents of the lab3 folder into the lab4 folder if you wish to continue with the design you created in the previous lab. Launch Xilinx Platform Studio (XPS) and open the project file located in the C:\xup\embedded\labs\lab4 (if you want to continue with your created design)
If you wish to continue using the design that you created in Lab 3, create a lab4 folder in the C:\xup\embedded\ppc\labs directory and copy the contents from lab3 to lab4
Open XPS by selecting Start Programs Xilinx Platform Studio 8.2i Xilinx Platform Studio
Select Open Recent Project, Click OK and browse to C:xup\embedded\ppc\labs\lab4
Select system.xmp to open the project
Create a BSP Step 2

![]()
Specify the PPC405 core clock frequency and driver interface level.
The BSP is created based on the peripherals included in the design
Selecting Software Software Platform Settings

Figure 4-1. Software Platform Settings Dialog Box for the PPC405_0 Instance
Note: You can select the driver for each of the peripherals in the system. You can also select the kernel and operating systems for each of the processor instances. In addition, you can select supporting libraries, if they will be used.
Select the Processor, Driver Parameters and Interrupt Handlers tab and verify the following parameters:
Processor Parameters: Instance
• core_clock_freq_hz: 300000000
•compiler: powerpc-eabi-gcc
•archiver: powerpc-eabi-ar
•EXTRA_COMPILER_FLAGS: -g

Figure 4-2. Software Platform Parameters for the PPC405_0 Instance
Select the Library/OS Parameters tab and verify that RS232_Uart_1 is selected for stdin and stdout. Leave the Current Value for need_xil_malloc as false because your application does not use any malloc function call. Verify that the rest of the selections according to the figure below.

Figure 4-3. OS Configuration Parameters
In the Drivers section, select my_led as the driver for the my_led peripheral. Make sure that the settings match those shown in the figure below

Figure 4-4. Driver Configuration
Click OK to accept the settings
Generate the BSP.
Double-click the system.mss file under the System tab in XPS to open the MSS file for this project

Figure 4-5. System Tab
XPS has written the parameters that are specified in the Peripheral Options to the system.mss file
1. List the assigned driver for each of the following peripheral instances. (Note that you can obtain this same information from the Software Platform tab of the Software Platform Settings dialog box.)
plb:
opb:
plb2opb:
my_led:
dip1:
push1:
RS232_Uart_1:
plb_bram_if_cntlr_1:
plb_bram_if_cntlr_2:
Why do some of the above mentioned devices not have a specific driver (i.e., the driver is specified as “generic”)?
________________________________________________________
________________________________________________________
________________________________________________________
Close the system.mss fileGenerate the BSP by selecting Software
Generate Libraries and BSPs or clicking the
button
This runs LibGen on the system.mss file to generate the BSP library files.
2. List the created subfolders, their contents, and their possible purposes under the ppc405_0 folder in the lab4 folder.
_____________________________________________________
_____________________________________________________
_____________________________________________________
Update Basic C File Step 3

![]()
Update the C code written in Lab 3 to display the DIP switch settings on the my_led peripheral.
Open TestApp_Memory.c
The first step is adding the header files for the required functions. All of the header files related to this project were placed in the ppc405_0/include and /drivers directories.
Add the following to the C file:
#include “my_led.h
Add a function writes the value of the DIP switch settings to the my_led peripheral.
Open the header file my_led.h located in the following directory:
C:xup\embedded\ppc\labs\lab4\drivers\my_led_v1_00_a\src
Find the description for the MY_LED_mWriteReg function. This header file contains a detailed description of the MY_LED_mWriteReg function
The header file outlines three parameters that MY_LED_mWriteReg requires:
• BaseAddress is the base address of the MY_LED device.
• RegOffset is the register offset from the base to write to.
• Data is the data written to the register.
The first parameter is the BASE ADDRESS for the device that you want to write to. This information can be found in the xparameters.h file.
Under the ppc405_0 instance for the TestApp_Memory project in the Applications tab, double-click the Generated Header: ppc405_0/include/xparameters.h entry

Figure 4-8. Double-Click the Generated Header File
• LibGen writes the xparameters.h file, which provides critical information for driver function calls.
• In the xparameters.h file, find the following #define used to identify the MY_LED_0 peripheral:
#define XPAR_MY_LED_0_BASEADDR ![]()
Note: The MY_LED_0 matches the instance name assigned in the MHS file for this peripheral.
This #define can be used as the BASEADDR in the function call.
Add the following function so that the dip_switch settings are written to the LEDs:
MY_LED_mWriteReg(XPAR_MY_LED_0_BASEADDR, 0 ,dip_check);
The c code should now look like the following:

Figure 4-9. Partially Completed C File
Save the file
![]()
Compile the source code.
Select the Applications tab to view the current project’s compiler options and sources
Double-click Compiler Options under Project: TestApp_Memory in the Applications tab
Select the Environment tab and change the Stack Size and Heap Size entries to 0x100.

Figure 4-10. Specifying the Stack and Heap Size
Linker Script Step 4

Analyze the assembled object files and how using the objdump utility links them. Start the Cygwin shell, execute the powerpc-eabi-objdump –h executable.elf command and analyze the output.
Go to Project Launch EDK shell to start the Cygwin shell
Change the directory to C:/xup/embedded/ppc/labs/lab4/TestApp_Memory by using the cd command.
You can determine your directory path by using the pwd command.

Figure 4-11. EDK Shell
Type powerpc-eabi-objdump –h executable.elf at the prompt in the Xygwin shell window to list various sections of the program, along with the starting address and size of each section
You should see results similar to that below

Figure 4-12. Object Dump Results
Note: The LMA and VMA may differ, for example, in a ROM based system. A particular case may involve loading a data section into ROM and then copying it into RAM. In this case, the LMA would be associated with the ROM and the VMA associated with the RAM.
![]()
Change the location of the text section so that it resides in the plb_bram_if_cntlr_bram2 memory. Recompile the code, re-execute the objdump command, and analyze the output.
Double-click Compiler Options under Project: TestApp_Memory in the Applications tab and delete the values in the stack and heap fields
Right-click on Project:TestApp_Memory in the Applications tab and select Generate Linker Script.
/'
Select plb_bram_if_cntlr_2 as the memory space for the instructions (.text section)

Make sure that the Output Linker Script path is set to the TestApp_Memory/src directory and click generate
Recompile the program and execute the powerpc-eabi-objdump command in the Xygwin shell

Generate and download bitstream to verify the functionality. Flip the DIP switches and verify that the LEDs will light according to the switch settings.
Close the project
Conclusion
Use Xilinx Platform Studio 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. XPS creates an MSS file that represents 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 codes and libraries. If needed, you can also use a linker script to target various segments in various memories. You can edit the linker script to control placement of various code segments into target memory.
1. List the assigned driver for each of the following peripheral instances. (Note that you can obtain this same information from the Software Platform tab of the Software Platform Settings dialog box.)
plb: plbarb
opb: opbarb
plb2opb: plb2opb
my_led: my_led
dip1: gpio
push1: gpio
RS232_Uart_1: uartlite
plb_bram_if_cntlr_1: bram
plb_bram_if_cntlr_2: bram
Why do some of the above mentioned devices not have a specific driver (i.e., the driver is specified as “generic”)?
Devices such as system_dcm do not have programmability features. Therefore, no specific device drivers are assigned
2. List the created subfolders, their contents, and their possible purposes under the ppc405_0 folder in the lab4 folder.
• code – empty folder – this is where the executable file will be placed
• include – several header files – for included peripherals and functions
• lib – library files – lbc, libm, libxil
• libsrc – source for all the libraries
Completed MHS File
# ##############################################################################
# Created by Base System Builder Wizard for Xilinx EDK 8.2 Build EDK_Im.14
# Tue Aug 29 14:15:28 2006
# Target Board: Xilinx XUP Virtex-II Pro Development System Rev C
# Family: virtex2p
# Device: xc2vp30
# Package: ff896
# Speed Grade: -7
# Processor: PPC 405
# Processor clock frequency: 300.000000 MHz
# Bus clock frequency: 100.000000 MHz
# Debug interface: FPGA JTAG
# On Chip Memory : 64 KB
# ##############################################################################
PARAMETER VERSION = 2.1.0
PORT fpga_0_RS232_Uart_1_RX_pin = fpga_0_RS232_Uart_1_RX, DIR = I
PORT fpga_0_RS232_Uart_1_TX_pin = fpga_0_RS232_Uart_1_TX, DIR = O
PORT sys_clk_pin = dcm_clk_s, DIR = I, SIGIS = CLK, CLK_FREQ = 100000000
PORT sys_rst_pin = sys_rst_s, DIR = I, RST_POLARITY = 0, SIGIS = RST
PORT dip = DIP, DIR = I, VEC = [0:3]
PORT push = PUSH, DIR = I, VEC = [0:4]
PORT led = fpga_0_LEDs_4Bit_GPIO_d_out, DIR = O, VEC = [0:3]
BEGIN ppc405
PARAMETER INSTANCE = ppc405_0
PARAMETER HW_VER = 2.00.c
BUS_INTERFACE JTAGPPC = jtagppc_0_0
BUS_INTERFACE IPLB = plb
BUS_INTERFACE DPLB = plb
PORT PLBCLK = sys_clk_s
PORT C405RSTCHIPRESETREQ = C405RSTCHIPRESETREQ
PORT C405RSTCORERESETREQ = C405RSTCORERESETREQ
PORT C405RSTSYSRESETREQ = C405RSTSYSRESETREQ
PORT RSTC405RESETCHIP = RSTC405RESETCHIP
PORT RSTC405RESETCORE = RSTC405RESETCORE
PORT RSTC405RESETSYS = RSTC405RESETSYS
PORT CPMC405CLOCK = proc_clk_s
END
BEGIN ppc405
PARAMETER INSTANCE = ppc405_1
PARAMETER HW_VER = 2.00.c
BUS_INTERFACE JTAGPPC = jtagppc_0_1
END
BEGIN jtagppc_cntlr
PARAMETER INSTANCE = jtagppc_0
PARAMETER HW_VER = 2.00.a
BUS_INTERFACE JTAGPPC0 = jtagppc_0_0
BUS_INTERFACE JTAGPPC1 = jtagppc_0_1
END
BEGIN proc_sys_reset
PARAMETER INSTANCE = reset_block
PARAMETER HW_VER = 1.00.a
PARAMETER C_EXT_RESET_HIGH = 0
PORT Ext_Reset_In = sys_rst_s
PORT Slowest_sync_clk = sys_clk_s
PORT Chip_Reset_Req = C405RSTCHIPRESETREQ
PORT Core_Reset_Req = C405RSTCORERESETREQ
PORT System_Reset_Req = C405RSTSYSRESETREQ
PORT Rstc405resetchip = RSTC405RESETCHIP
PORT Rstc405resetcore = RSTC405RESETCORE
PORT Rstc405resetsys = RSTC405RESETSYS
PORT Bus_Struct_Reset = sys_bus_reset
PORT Dcm_locked = dcm_0_lock
END
BEGIN plb_v34
PARAMETER INSTANCE = plb
PARAMETER HW_VER = 1.02.a
PARAMETER C_DCR_INTFCE = 0
PARAMETER C_EXT_RESET_HIGH = 1
PORT SYS_Rst = sys_bus_reset
PORT PLB_Clk = sys_clk_s
END
BEGIN opb_v20
PARAMETER INSTANCE = opb
PARAMETER HW_VER = 1.10.c
PARAMETER C_EXT_RESET_HIGH = 1
PORT SYS_Rst = sys_bus_reset
PORT OPB_Clk = sys_clk_s
END
BEGIN plb2opb_bridge
PARAMETER INSTANCE = plb2opb
PARAMETER HW_VER = 1.01.a
PARAMETER C_DCR_INTFCE = 0
PARAMETER C_RNG0_BASEADDR = 0x40000000
PARAMETER C_RNG0_HIGHADDR = 0x7fffffff
PARAMETER C_NUM_ADDR_RNG = 1
BUS_INTERFACE SPLB = plb
BUS_INTERFACE MOPB = opb
END
BEGIN opb_uartlite
PARAMETER INSTANCE = RS232_Uart_1
PARAMETER HW_VER = 1.00.b
PARAMETER C_BAUDRATE = 115200
PARAMETER C_DATA_BITS = 8
PARAMETER C_ODD_PARITY = 0
PARAMETER C_USE_PARITY = 0
PARAMETER C_CLK_FREQ = 100000000
PARAMETER C_BASEADDR = 0x40600000
PARAMETER C_HIGHADDR = 0x4060ffff
BUS_INTERFACE SOPB = opb
PORT RX = fpga_0_RS232_Uart_1_RX
PORT TX = fpga_0_RS232_Uart_1_TX
END
BEGIN plb_bram_if_cntlr
PARAMETER INSTANCE = plb_bram_if_cntlr_1
PARAMETER HW_VER = 1.00.b
PARAMETER c_plb_clk_period_ps = 10000
PARAMETER c_baseaddr = 0xffff0000
PARAMETER c_highaddr = 0xffffffff
BUS_INTERFACE SPLB = plb
BUS_INTERFACE PORTA = plb_bram_if_cntlr_1_PORTA
END
BEGIN bram_block
PARAMETER INSTANCE = plb_bram_if_cntlr_1_bram
PARAMETER HW_VER = 1.00.a
BUS_INTERFACE PORTA = plb_bram_if_cntlr_1_PORTA
END
BEGIN dcm_module
PARAMETER INSTANCE = dcm_0
PARAMETER HW_VER = 1.00.a
PARAMETER C_CLK0_BUF = TRUE
PARAMETER C_CLKFX_BUF = TRUE
PARAMETER C_CLKFX_DIVIDE = 1
PARAMETER C_CLKFX_MULTIPLY = 3
PARAMETER C_CLKIN_PERIOD = 10.000000
PARAMETER C_CLK_FEEDBACK = 1X
PARAMETER C_DFS_FREQUENCY_MODE = HIGH
PARAMETER C_DLL_FREQUENCY_MODE = LOW
PARAMETER C_EXT_RESET_HIGH = 1
PORT CLKIN = dcm_clk_s
PORT CLK0 = sys_clk_s
PORT CLKFX = proc_clk_s
PORT CLKFB = sys_clk_s
PORT RST = net_gnd
PORT LOCKED = dcm_0_lock
END
BEGIN plb_bram_if_cntlr
PARAMETER INSTANCE = plb_bram_if_cntlr_2
PARAMETER HW_VER = 1.00.b
PARAMETER c_baseaddr = 0x00000000
PARAMETER c_highaddr = 0x00003fff
BUS_INTERFACE SPLB = plb
BUS_INTERFACE PORTA = plb_bram_if_cntlr_2_PORTA
END
BEGIN bram_block
PARAMETER INSTANCE = plb_bram_if_cntlr_2_bram
PARAMETER HW_VER = 1.00.a
BUS_INTERFACE PORTA = plb_bram_if_cntlr_2_PORTA
END
BEGIN opb_gpio
PARAMETER INSTANCE = dip1
PARAMETER HW_VER = 3.01.b
PARAMETER C_GPIO_WIDTH = 4
PARAMETER C_IS_BIDIR = 0
PARAMETER C_ALL_INPUTS = 1
PARAMETER C_BASEADDR = 0x40020000
PARAMETER C_HIGHADDR = 0x400201ff
BUS_INTERFACE SOPB = opb
PORT GPIO_in = DIP
END
BEGIN opb_gpio
PARAMETER INSTANCE = push1
PARAMETER HW_VER = 3.01.b
PARAMETER C_GPIO_WIDTH = 5
PARAMETER C_IS_BIDIR = 0
PARAMETER C_ALL_INPUTS = 1
PARAMETER C_BASEADDR = 0x40000000
PARAMETER C_HIGHADDR = 0x400001ff
BUS_INTERFACE SOPB = opb
PORT GPIO_in = PUSH
END
BEGIN my_led
PARAMETER INSTANCE = my_led_0
PARAMETER HW_VER = 1.00.a
PARAMETER C_BASEADDR = 0x7D800000
PARAMETER C_HIGHADDR = 0x7D8001FF
BUS_INTERFACE SOPB = opb
PORT LED = fpga_0_LEDs_4Bit_GPIO_d_out
END


