You are on page 1of 13

Charles Darwin University

HIT332: Embedded and Mobile Systems


Casuarina Campus
Practical No. 2: Introduction to embedded system development

This practical / tutorial is designed to familiarise you with the tools we will use throughout
this semester for embedded system development. These tools consist of a hardware
development board and a set of software tools for drawing schematics, writing code and
programming and debugging the target processor. By the end of this tutorial you should:

 understand the development hardware,


 be familiar with the microcontroller we will use and it's datasheet,
 be familiar with the available software tools,
 know how to create and edit a C source code file,
 understand how the AVR-GCC tools can be used to compile, link and generate a ‘hex’
file from this source code,
 understand how to program the ‘hex’ file into the microcontroller.

In all of these practical exercises, to minimise errors and maximise your success, make sure
you read the instructions carefully, enter commands and source code exactly as shown and
pay careful attention to wiring up your circuits. If you are unsure about anything, ask your
instructor for assistance.

Please make sure there are no spaces in file or directory names.

Before you begin


1. You should already have a copy of the CDU Embedded System Toolbox package
extracted in a convenient location.
2. For this practical you will also need a CDU Embedded Systems Board with USB cable.
In addition, you will need some jumper wires for making connections on the
development board. DO NOT connect the USB cable to the computer at this stage,
and not before reading the section about installing the driver.

Development board introduction


The development board we will use for these practical exercises is designed as a flexible
system for learning about embedded systems. The board itself is an example of an
embedded system. The development board has the following key parts:

 An ATmega1281 microcontroller ‘breakout’ card


 A USB-serial interface
 8 user controlled LEDs
 8 way DIP Switch
 Connectors for 5V power supply and ground return
 Connectors for the microcontroller input/output (I/O) ports
 An oscilloscope, waveform generator and digital logic analyser
 Two breadboards for connecting additional devices and circuits

Take a moment to identify and locate these parts on the development board. Make a sketch
of the board and label each of the key components.

The microcontroller
The microcontroller we will be using is an ATmega1281, manufactured by Atmel. It is an 8-
bit microcontroller with 128KB of flash memory (program storage space), 8KB of RAM (data
storage space) and 54 General purpose I/O pins. It is based around the Atmel AVR processor
core. In this application, the microcontroller operates with a supply voltage of 5V and is
clocked at 16MHz using an external crystal oscillator. The following diagram from the
datasheet (section 2) gives an overview of the internal structure of the microcontroller,
showing the AVR processor core and surrounding peripherals. By the end of the practical
exercises this semester you should have a good understanding of the processor and the
operation of many of its peripherals.
Take some time now to look through the datasheet for the ATmega1281 (you will find it in
the datasheets folder) and familiarise yourself with its contents and structure. You will see
that each chapter deals with a specific aspect of the processor core or one of the
peripherals. This datasheet will be your main reference when writing code and
understanding how to use the peripherals. While the complexity of the chip may seem
overwhelming, we will build up our knowledge slowly throughout these practical exercises
this semester.

The microcontroller has been assembled onto a ‘breakout’ daughter-card, with the required
supporting components installed on this board. These include power supply decoupling
capacitors, a reset circuit and a crystal oscillator. Each of the general purpose I/O pins is
connected to the main board through the connections at the top and bottom of the
daughter-card. This modular approach makes the system flexible; the microcontroller could
be upgraded in the future without needing to redesign the whole system.

The schematic for the ATmega1281 breakout module is shown below. It shows the
microcontroller IC and supporting components, the main parts being;

 power supply decoupling capacitors (C1-C5),


 the main crystal oscillator (Y2),
 a reset switch (SW1) and pull-up resistor(R4),
 power LED (LED2) and user controlled LED (LED1)

Note that some additional parts shown on the schematic are not always required and may
not actually be installed on the finished PCB.
Note how the main board has connectors for each of the 6 available ports on the
microcontroller, labelled PORT A – PORT F. Since this is an 8-bit microcontroller each port
has 8 I/O pins, numbered 0-7. For example, PORTA has 8 individual pins labelled PA0-PA7.
Section 2 in the datasheet (Overview) describes the various pins and ports on the
microcontroller. Make sure you understand how the pins on the microcontroller map to the
connectors on the main board. Refer to the schematics in the hardware folder if you are
unsure.

Connecting to the USB-serial port and installing the driver


Now that you are familiar with the development board it is time to connect it to the
computer and install the necessary driver. The development board communicates with the
host computer using a USB-Serial connection. This connection is used to communicate with
the on-board oscilloscope, a program running on the target microcontroller or to upload
programs into the microcontroller’s flash memory. This USB connection also provides power
to the development board.

1. BEFORE CONNECTING THE BOARD, make sure you have internet access on the
computer you are using (check that you can visit a website outside CDU). Windows
needs to access the windows update server to successfully install the driver. If your
computer cannot access the server, the driver install will fail.
2. Use a USB cable to connect the development board to an available USB port on the
computer.
3. Windows should detect the board and begin the process of searching windows
update for the driver and then installing the driver. You should see a pop-up as
shown below.

4. If you click the pop-up you can see more information about the installation process.
If everything was successful, after some time you should see the message “Ready to
use”.

5. Alternatively, if you do not click the pop-up you should see the following pop-up
when installation is successful.

6. You will see that the board is installed as a USB Serial Port device and assigned a
COM port number (your COM port may be different). Your development board is
now installed and ready to use.
Checking out the Hardware
Now that we have connected the board and installed the driver, power should be available
to the mainboard and the microcontroller breakout card (there should be 4 blue power LEDs
on). You can now check the operation of the 8 user LEDs and 8-way DIP switch. These are
the peripherals we will be using initially to understand digital input and output and the
basics of programming the ATmega1281.

1. Using a short jumper wire, connect one end of the wire to the “LEDs” connector
point labelled 0 and the other end to one of the points on the power connector
labelled 5V. You should find the LED lights up, powered by the 5V supply.
2. Check each of the LEDs operates correctly using this test.

You can also use the DIP switch to control the LEDs. Switching on the switch (sliding it up
towards the ON label) will connect 5V to the corresponding connector point.

3. Connect a wire from each of the terminals on the “Switches” connector to one of the
LEDs. Switching on the switches provides the 5V source to power the LED. You
should be able to check each of the switches function as intended, turning on the
corresponding LED it is connected to.

If the hardware is working as expected you can now move on to investigating the embedded
software development process.

A simple 'Hello World' example


In keeping with tradition in programming, we will begin with the embedded systems
equivalent of a “Hello World”, controlling an output on the microcontroller to show that
code is running. This confirms that the process of programming our microcontroller was
successful.

When developing code for an embedded system there are four main steps;

1. Write the program that tells the processor what to do


2. Compile it, that is, turn the program into machine code that the processor can
understand
3. Program the processor using a programmer, which will transfer the compiled
machine code to the device’s internal memory
4. Test, debug and repeat as required

Don’t worry if you don’t understand all these steps at this stage, for now we will just work
through them one-by-one to test all of the tools. You will have lots more practice
throughout the semester and hopefully gain a better understanding of each step as you
learn more about embedded systems.
Writing the source code
Keeping your source code organised is critical to the success of embedded system
development. During this semester you should organise the code for each of the practicals
into a corresponding folder in the ‘projects’ directory.

1. Using the main menu in the Launcher program, launch the editor. The
editor should open with a new empty file.
2. Save the new file in a directory called ‘practical2’ as ‘main.c’. To do
this, select File >> Save As… and then enter the file name. Make sure you also enter
the ‘.c’ extension. Once you have done this, notepad++ will know that the language
is C and the source code will be colour coded as shown.
3. Enter the following source code exactly as shown below into the ‘main.c’ file;

This is the only code we are required to write to make our processor do something useful (in
this case turn on a single output pin). Additional supporting and start-up code is
automatically ‘linked’ with our source code when we generate the machine code to
program into the processor memory. We will not worry about how this program works at
this stage; this will be explained in more detail in later practical exercises.

Once you have entered the source code make sure you save the file. You can now close the
editor if you wish.

Compiling and Linking


Now that we have written the program to tell the processor what we want it to do, the next
step is to compile the source into machine code that the processor can execute. We will be
using the AVR Libc library for developing our source code in the C language and the AVR-
GCC tools for compiling our source code. All these tools are command line programs and are
open-source and free to use.
AVR-Libc provides many of the same functions found in the regular Standard C Library you
will be familiar with, but also adds additional functions specific to the AVR core.

GCC stands for GNU Compiler Collection. GCC is highly flexible compiler system which can
be used for many different languages and platforms. We will be using a version of the GCC
compiler running on our host PC to ‘cross-compile’ our C code for the AVR core in our
processor. Additional tools are included to generate the final machine code output and load
the program into the processor memory.

Full documentation for all these tools is available in the AVR Libc reference manual:
https://www.microchip.com/webdoc/AVRLibcReferenceManual/

We will now use the build tools to compile our source code and program our processor,
interacting with the command line tools directly. While this is a little slow and cumbersome,
it will allow you to understand the individual steps in the process. Later, we will see a more
streamlined process for automating the ‘build’ process to enable faster development. If you
have never used the command line, don’t worry, the following steps will explain the process
and necessary commands step-by-step.

1. From the Launcher menu, click the button to launch a windows


command line.
 This command line has been pre-configured to enable access to
the included build tools (they are in the avr_tools directory)
 This is done by temporarily modifying the Windows system PATH variable.
This is required so that Windows knows where to find the various tools.
2. When you launch the command line you should see the following window. The
command line works much like the Windows explorer in that you are always in a
directory (as shown at the command line). You can type commands at the command
line and pressing enter will execute the command. You can then repeat the process
by typing further commands, pressing enter after each one.
3. Type the following at the command line and press enter

dir

4. This command lists the contents of the current directory. Note that you can see the
projects directory where our source code was saved.
5. Use the ‘cd’ command to change the current working directory of the command line
into the projects directory. At the command line, enter the following and press
enter:

cd projects

6. You should see that the current directory has changed, use the ‘dir’ command again
to check we have our practical2 directory here.

7. Using the ‘cd’ command again, change into the ‘practical2’ directory. Use dir again to
check we can see our ‘main.c’ file. Remember to press enter after entering each
command.
cd practical2
dir

8. Now that we are in the directory with our source file, we can run the compiler on
this file. Enter the following line at the command line exactly as written below, and
press enter:

avr-gcc -g -Os -mmcu=atmega1281 -c main.c

 The -g is used to embed debug info. The debug info may be useful and
doesn't end up in the .hex files, so it is generally a good idea to specify it.
 The -Os option will tell the compiler to optimize the code for efficient
memory space usage (at the possible expense of code execution speed).
 When compiling, the compiler needs to know the processor type so the -
mmcu option is specified.
 Finally, the –c option tells the compiler to compile and stop. This program is
small enough that we could compile and link in one step. However, real-
world projects will likely have several modules and we typically need to break
up the building of the project into several compiles of each source module,
followed by one final link step.
9. If everything worked correctly the command should execute
without giving any errors and you will have a new file ‘main.o’ in
the practical2 directory. Check to see that this file has been
generated. If you see any errors, make sure you entered the
source code exactly as shown and the compile command correctly.
10. Next we need to link the compiled source file into a binary file called ‘main.elf’. This
will link our compiled source code with other library and start-up code to generate
the complete machine code. To do this, enter the following at the command line
exactly as written below, remembering to press enter to execute the command:
avr-gcc -g -mmcu=atmega1281 -o main.elf main.o

 It is important to again specify the processor type when linking (again


with the –mmcu option). The compiler uses the -mmcu option to choose
the correct start-up files and run-time libraries that
get linked together with your compiled source
code.
11. If everything went well, you should now have a new file
‘main.elf’ in your project directory.

Creating a hex file and programming the processor


Now that we have our linked binary file, we need to turn it into a form that we can use to
load into our processor memory. To do this we need to generate a ‘hex’ file, the format
expected by our programmer.

1. To generate the ‘hex’ file, use the following command at the command line:

avr-objcopy -j .text -j .data -O ihex main.elf main.hex

 The -j option indicates that we want the information from the .text and
.data segments of our binary file extracted and converted into a hex file

2. This command should produce a new file, ‘main.hex’ in the


project directory. It is this file that we need to load into our
processor’s memory.
3. Open this file with the editor and you should see the raw
data that will be programmed into our processor. This
represents the compiled and linked source code we started with, in a form that can
be understood by the programmer. The programmer can write this to the processor
memory.
4. To load the hex file into our processor’s memory, we will use the following
command, which should be entered all on one line, before pressing enter. You need
to replace [port] with the serial port assigned to your board. You can find this by
looking at the bottom of the launcher window.

avrdude -c arduino -p atmega1281 -P [port] -b 57600 -U


flash:w:main.hex

In this example, the port assigned to the board is COM15. The command would
therefore be:

avrdude -c arduino -p atmega1281 -P COM15 -b 57600 -U


flash:w:main.hex

 Here we are using the avrdude program to upload our hex file, using the
serial connection, the –b option specifies the serial data rate (baud rate).
 The avrdude program communicates with a ‘bootloader’ program running
on the processor, using the ‘arduino’ programming protocol.

5. This command should result in lots of text being displayed on the command line.
Look through the output from the avrdude program. You should be able to identify
the process of connecting to the processor, erasing the memory, writing the hex file
to the flash memory and verifying the file was written correctly.
6. If the verification was successful, your program should now be running on the
processor. Connect a jumper wire from PORT D, pin 0 to one of the LEDs. If the
program is running, the LED should light up.

Further experimentation
Now you should understand the development board hardware and the process of creating a
source code file, building and finally loading the compiled code onto the processor. Now see
if you can change the embedded program to do something different.

1. Edit the source code file ‘main.c’ by replacing the line PORTD = 0x01; with the
following:

PORTD = 0xAA;

2. Remember to save the changes and then follow the same procedure to build and
load the program. Make sure there are no errors and that the verify step of the load
process completes successfully.
3. When you have achieved this, check the output state of the PORTD pins by
connecting all 8 LEDs to the PORT D connector. What does this new program do?
How does it relate to the value 0xAA which was assigned to the PORTD register?

Congratulations! You have completed Practical No. 2.

You might also like