– Lab1 – Getting Started 1 Introduction The goal of this assignment is that you should become familiar with the Arcom board and the cross compiler tools. This course uses special hardware and software that is only available in U2-114 and U2-1241 . The lab instructions are tested in Linux, but it should be possible to use Windows/Cygwin in the first two labs (the final two labs requires Linux). If you need help during the lab-session you should write your name on the whiteboard (first to write should write on top of the board) so that the lab assistant can help you in first-come-firstserved order. 1.1 Preparation Be sure to be well prepared before the lab-session starts and use the scheduled time to ask questions and to demonstrate your solutions. Read through the lab instructions and chapter 2–5 in the textbook. You should also skim through the “quick start manual” available in the Viper-lite development kit. Deliverables for all assignments When demonstrating your solutions to the lab assistant, both students (in a lab group) must be prepared to answer any questions. Also, both students should submit the written answers and program source code by attaching them to an e-mail to the lab assistent with cc to the course leader. Please write your name(s) and e-mail address(es) in all documents/program sources that you submit. Write your name and personal number in the e-mail. The program sources must be well documented and you should include a description of the major software components and how they interact. 2 Getting Started – Blinking LED Program Download lab1.tar.gz from the course homepage and extract it with the following command: $ tar xvzf lab1.tar.gz This will create a directory called lab1 that contains the files needed for the first lab. The most important files will be presented in section 2.2. 2.1 Setup Your Account You need modify your search path for commands and manual pages to access the cross compilation tools. Add the following lines to your .bashrc in your top-level home directory (e.g. /home/abc01234/.bashrc). Use an editor of your choice, e.g. kwrite, gedit, nano, or kate. Listing 1: .bashrc snippet export PATH=$PATH: / opt /arm−e l f −t o o l s / b in export MANPATH=$MANPATH: / opt /arm−e l f −t o o l s /man Hint: Use the ls -a command to see the “hidden files” in a directory. 1 You can install the required software on your own computer (see appendix A for more information). Programming Embedded Systems, Spring 2009 – Lab1 – Page 1 of 11 NB: You might need to create the .bashrc file if it does not exist. Also, if you do not have a .bash_profile file you need to create it with the following contents: Listing 2: .bash profile i f [ −f $HOME/ . b a s h r c ] ; then source $HOME/ . b a s h r c fi Start a new command shell and verify the new settings by writing $ echo $PATH /usr/bin:...:/opt/arm-elf-tools/bin $ echo $MANPATH /usr/local/man:...:/opt/arm-elf-tools/man $ arm-elf-gcc -v Reading specs from ... 2.2 Code Walkthrough This section highlights important sections of the example files. 2.2.1 blink.c This file contains the main program loop. It includes required header files, initializes the hardware, and call functions to blink the green LED once per second. Listing 3: Includes #include ” s t d i n t . h ” #include ”pxa255 . h ” #include ” l e d . h ” #include ” d e l a y . h ” #include ” v i p e r l i t e . h ” /* Declares integer types (e.g. int8_t) */ /* Addresses to registers and cach e i n i t i a l i z a t i o n macros ∗/ /* Declares function prototypes for l e d I n i t and l e d T o g g l e ∗/ /* Declares function prototypes for d elay m s ∗/ /* Defines for the ViperLite board */ Listing 4: Hardware initialization and main loop DCACHE ENABLE ( ) ; ICACHE ENABLE ( ) ; ledInit (); /* Macro to enable data cache */ /* Macro to enable instruction cache */ /* Configure LED hardware ( see below) */ while (TRUE) { ledToggle ( ) ; d elay m s ( 5 0 0 ) ; } /* Loop forever */ /* Toggle LED state (see below) */ /* Delay execution 500 ms ( see below) */ 2.2.2 led.c This file contain functions to initialize I/O hardware and to change state (on/off) of the green LED. The green LED is connected to pin 22 (corresponds to address mask 0x00400000). See PXA255 Developers Manual section 4.1 for more information. Programming Embedded Systems, Spring 2009 – Lab1 – Page 2 of 11 Listing 5: ledInit #define PIN22 FUNC GENERAL #define LED GREEN (0xFFFFCFFF) (0 x00400000 ) /* Turn off voltage on bit 22 ( will turn the green LED on) */ /* This should be done before the pins are configured . */ GPIO 0 CLEAR REG = LED GREEN; /* Clear bit 12 and 13 in GAFR0_U. This makes sure that GPIO pin 22 is used as general purpose I/O */ GPIO 0 FUNC HI REG &= PIN22 FUNC GENERAL; /* Set pin 22 in GPDR0 ( green LED) to operate as output */ GPIO 0 DIRECTION REG |= LED GREEN; Listing 6: ledToggle /* Check the current state of the green LED in the GPIO */ /* Pin - Level Register 0 ( GPLR0). */ i f (GPIO 0 LEVEL REG & LED GREEN) { /* Turn off voltage on bit 22 ( will turn the green LED on) */ GPIO 0 CLEAR REG = LED GREEN; } else { /* Turn on voltage on bit 22 (will turn the green LED off) */ GPIO 0 SET REG = LED GREEN; } 2.2.3 delay.c This file contains the delay_ms function that delays execution for specified number of milliseconds. Listing 7: delay ms #define CYCLES PER MS (9000) long v o l a t i l e c y c l e s = ( m i l l i s e c o n d s ∗ CYCLES PER MS) ; /* Busy wait calculated number of clock cycles */ while ( c y c l e s != 0) { c y c l e s −−; } 2.2.4 viperlite.ld This file is used by the linker to decide the memory location for program code and data. The first section (MEMORY) defines the base address and size for the memories available on the Arcom board. The second section (SECTIONS) is used to control where program code and data are stored (in this case on the on-board ram). NB: You should not modify this file. Programming Embedded Systems, Spring 2009 – Lab1 – Page 3 of 11 2.3 Cross Compile The next step is to compile your program. You must use the arm-elf cross compiler to generate code for the Arcom board. Use the following commands to compile the source files into object files: $ arm-elf-gcc -Wall -g -c -I../include -o blink.o blink.c $ arm-elf-gcc -Wall -g -c -I../include -o delay.o delay.c $ arm-elf-gcc -Wall -g -c -I../include -o led.o led.c -Wall -g -c -I -o Print warnings for program codes that are considered questionable Include debugging information Compile, but do not link, that is generate an object file Path to include files that does not reside in the current directory Name of output file You can write arm-elf-gcc --help, man arm-elf-gcc, or info arm-elf-gcc to get more information about the compiler. 2.4 Linking The next step is to link the object files together with the following command: $ arm-elf-ld -Map blink.map -T viperlite.ld -N blink.o delay.o led.o -o blink -Map -T -N -o Print a map file with information about how objects are mapped into memory Use the viperlite.ld linker script Set text and data sections to be readable and writable Name of output file (you can use blink.exe if you like) You can write arm-elf-ld --help, man arm-elf-ld, or info arm-elf-ld to get more information about the linker. Take a look at the generated blink.map file. In this file you will find the memory configuration (specified by the viperlite.ld linker script) and a memory map that describes the addresses for our program. 2.5 Connect Hardware The next step is to connect the hardware as shown in figure 1 (we will not use the network cable in this lab). Attach the serial cable to your host computer, but do not attach the power cord to the power outlet yet. 2.6 Download Start “cutecom” (or the HyperTerminal in Windows) and configure the serial port as follows (see figure 2). • Device: /dev/ttyS0 (Serial port #0) • Baudrate: 115200 • Databits: 8 • Stop bits: 1 • Parity: none • Handshake: none (neither hardware nor software) • Open for: reading and writing Programming Embedded Systems, Spring 2009 – Lab1 – Page 4 of 11 Figure 1: ARCOM development board Attach the power cord to the power outlet, and you should see the Arcom boot message in your terminal within a few seconds. If nothing happens, check your cables again and ask the lab assistant for help if necessary. The Arcom board starts Linux by default, but since we want to use it as a stand-alone system we will have to abort the boot process before Linux starts. Press the reset button (attached to the power cable) and press Ctrl+c in your terminal within one second after you pressed the reset button2 You will now end-up in the RedBoot environment as shown in figure 3. NB: You should be very careful when writing commands in the RedBoot environment. You are only allowed to use the help, load, and go commands3 . The next step is to download our example program to the board as shown in figure 4. 1. Write load -m xmodem in the terminal window 2. Make sure that protocol in the selection list next to the send button is set to xmodem 3. Press the “send file” button and select the binary file produced by the cross compiler 2 You can press the Reset button at any time to restart the board (you do not have to wait for Linux to finish the startup process). 3 Improper use of commands in the RedBoot environment might cause the board to become unusable! Programming Embedded Systems, Spring 2009 – Lab1 – Page 5 of 11 Figure 2: Cutecom settings 2.7 Program Execution The only thing that remains is to start your program by writing go in the terminal window. If everything works as expected you should see the green LED blinking on the Arcom board. The board is now executing our program and the only way to download a new program is to press the reset button and start all over again. 2.8 Debugging A debugger can be used to see what is going on “inside” the program running on the target platform. It is possible to look at variable contents, set breakpoints, single-step instructions, etc. Note that the source files must be compiled with the “-g” flag in order to work in the debugger. It is somewhat tricky to use the debugger when we only have one serial cable connected to the board. To use the debugger we must first enter the RedBoot environment using cutecom as described earlier (press reset button followed by Ctrl+c in cutecom). Next, close cutecom and start the insight debugger4 by: $ arm-elf-insight Open the binary file (blink) in the debugger via File->Open. The next step is to connect to the target board. Select File->Target Settings and specify the following connection details (see figure 6) 4 You can use arm-elf-gdb or ddd --debugger arm-elf-gdb as a replacement for the insight debugger Programming Embedded Systems, Spring 2009 – Lab1 – Page 6 of 11 Figure 3: Boot • Target: Remote/Serial • Baud rate: 115200 • Port: /dev/ttyS0 Next press the “Run” button, and you are ready to go. Play around and learn how to use the debugger – you will need it in later labs. It is especially useful to learn how to use breakpoints, step through the program code, display the contents of variables, and display the memory contents at a given address. 3 Assignment 1 Use the example program to answer the following questions: 1. Use the generated map file (blink.map) to determine the physical starting address of the main and ledToggle functions. 2. Use the debugger to set a breakpoint in the main and ledToggle functions. Execute the Programming Embedded Systems, Spring 2009 – Lab1 – Page 7 of 11 Figure 4: Downloading and executing a program 3. 4. 5. 6. 7. 8. program to the breakpoints and determine the address of the functions by looking at the pc register. Are they the same as the addresses in the map file? Write arm-elf-objdump --disassemble-all blink in a terminal to display the generated assembly code. Write down the first instruction of the main function. Optional: What is the purpose of this instruction? (Most functions start with this instruction) Write arm-elf-size blink to determine the size of the program. This command list both the total size and the section sizes. Write down the total size. Optional: Briefly describe which type of instructions and data that goes into text, data, and bss sections. Recompile all program source files with the -O2 flag and link the object files into an executable. Now look at the starting addresses of the main and ledToggle functions. Are they still the same? Use arm-elf-size to determine the total size of the new executable. Is it smaller or larger compared to the original one? Optional: Briefly describe what the -O2 flag does. Write arm-elf-strip --strip-all blink -o blink_strip in a terminal. Determine the size of the program and write down the total size. Is it smaller or larger compared to the original program? What is the purpose of the arm-elf-strip program? Use arm-elf-objdump --disassemble-all on the blink and blink_strip executables. What is the difference between the generated outputs? Programming Embedded Systems, Spring 2009 – Lab1 – Page 8 of 11 Figure 5: The Insight debugger Figure 6: Target settings 3.1 Deliverables Write the answers to the questions above in a text document and show them to the lab assistant. You should be able to show how to use the tools (e.g. the debugger) and explain how you obtained the answers. 4 Assignment 2 Modify the example program to make it work as a light switch. Use a button on the Viper I/O board to turn on/off the green LED. That is, the first time you press the button the LED should light up, and the second time it should be turned off, etc. Use the buttonDebounce() function (in file button.c) to read the state of button 0. 4.1 Deliverables You do not need to show this assignment to the lab assistant (it is a part of assignment 3). 5 Assignment 3 Extend assignment 2 so that you can use the buttons on the Viper I/O board as follows: • Button 0 (SW0) – turn on/off LED0 • Button 1 (SW1) – turn on/off LED1 • Button 2 (SW2) – turn on/off LED2 • Button 3 (SW3) – switch state of all LEDs Programming Embedded Systems, Spring 2009 – Lab1 – Page 9 of 11 It should be possible to press the buttons in arbitrary order. For example, assuming that all LEDs are off when we press “SW1” followed by “SW3” then LED1 will be off and LED0 and LED2 will be on. 5.1 Deliverables Demonstrate your working program to the lab assistant and explain how your program works. Programming Embedded Systems, Spring 2009 – Lab1 – Page 10 of 11 A Software Installation Notes This appendix shows how to install the ARM cross compiler on your own computer (the software is already installed in the lab rooms). You can find more information in the Programming Embedded Systems book, appendix B and C. A.1 Cross Compiler Toolchain You can download a pre-compiled toolchains arm-elf-tools-*.tar.bz2 from the course webpage. Use the following commands to install a toolchain: $ su (or sudo sh) to start a root shell (not required for cygwin) # cd /opt # tar xvjf arm-elf-tools-linux.tar.bz2 NB: There are some pre-compiled software available on the book webpage at http://examples.oreilly.com/embsys2/, but unfortunately it does not include the insight debugger used in the labs. Note: It is possible to build your own toolchain from scratch. Have a look at the build_es_crosscompiler.sh script available on the course web-page if you are interested. A.2 Serial Port You must have a serial communication program installed. The labs assumes that you use cutecom, but it should be possible to use other programs such as minicom, or Hyper-terminal (Windows). Also, you must have a program to handle the x-modem protocol. In Linux this is handled by the rx program available in the lrzsz package. Furthermore, all users must be members of the dialout group (or whatever group that has write permission to /dev/ttyS0). Programming Embedded Systems, Spring 2009 – Lab1 – Page 11 of 11