0% found this document useful (0 votes)
14 views

Lab 1

This lab introduces students to the Linux toolchain used to program an ARM microcontroller. It covers assembling code using arm-none-eabi-as, loading and debugging code using openocd and arm-none-eabi-gdb, and programming the STM32F334 Nucleo-64 microcontroller board. Students will assemble a simple ARM assembly program that adds two numbers and get familiar with basic Linux commands.

Uploaded by

David
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
14 views

Lab 1

This lab introduces students to the Linux toolchain used to program an ARM microcontroller. It covers assembling code using arm-none-eabi-as, loading and debugging code using openocd and arm-none-eabi-gdb, and programming the STM32F334 Nucleo-64 microcontroller board. Students will assemble a simple ARM assembly program that adds two numbers and get familiar with basic Linux commands.

Uploaded by

David
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 13

1

COEN 311

Lab 1: Introduction to the software tool chain and


STM32F334 Nucleo-64 Microcontroller
2023

T. Obuchowicz
2

OBJECTIVES

• To learn the rudiments of Linux (create a directory, change into a directory, edit a text file with
the ‘nano’ text editor.

• To become acquainted with the ARM tool chain used in the COEN 311 labs for assembling, load-
ing an ARM assembly language program and single stepping through the execution of the machine
code on the STM32F334 Nucleo-64 microcontroller board

INTRODUCTION

This lab introduces the student to the Linux software tool chain used to assemble an ARM assem-
bly language program and to program the Nucleo-64 microcontroller and single step through its
execution. The tool chain consists of:

• arm-none-eabi-as: The GNU assembler (GNU Toolchain for the Arm Architecture)
• arm-none-eabi-ld: The GNU ld (loader) (GNU Toolchain for the Arm Architecture)
• arm-none-eabi-gdb: GNU gdb (GNU Toolchain for the Arm Architecture)
• openocd: The Open On-Chip Debugger, Licensed under GNU GPL v2

The assembler is used to assemble an program written in ARM assembly language into an object
file. The loader creates an executable program from the object file. The openocd program estab-
lishes the serial communication between the gdb debugger program running on the local host
Linux PC and the Nucleo-64 microcontroller board using a USB cable. Together, the openocd and
gdb software allow to program the microcontroller board with the machine code corresponding to
an executalbe program and to single-step through the execution of the program, one instruction at
a time viewing the register and/or memory contents.

0. PREPARING THE LINUX ENVIRONMENT

The following is to be performed from the Linux prompt, onceone has logged in to an AITS Linux
PC.

0. ted@deadflowers Code 4:28pm > module load COEN311

The ted@deadflowers Code 4:28pm > is an example of a Linux prompt. Your prompt
may appear different. Commands are entered after the prompt and are terminated by pressing the
Enter key.

The above command prepares one’s Linux environment to run the ‘openocd’ (open on-chip debug-
ger), the ‘arm-none-eabi-as’ ARM assembler, the ‘arm-none-eabi-ld’ loader, and the ‘arm-none-
eabi-gdb’ debugger.

After entering the above command, the Linux ‘which’ command may beused to verify that one’s
search path is set properly:
3

ted@deadflowers Code 4:28pm >which openocd


/encs/pkg/openocd-0.11.0/root/bin/openocd

ted@deadflowers Code 4:33pm >which arm-none-eabi-as


/encs/pkg/gcc-arm-11.2.2022.02/root/bin/arm-none-eabi-as

ted@deadflowers Code 4:34pm >which arm-none-eabi-ld


/encs/pkg/gcc-arm-11.2.2022.02/root/bin/arm-none-eabi-ld

ted@deadflowers Code 4:34pm >which arm-none-eabi-gdb


/encs/pkg/gcc-arm-11.2.2022.02/root/bin/arm-none-eabi-gdb

The which command shows the full path of built-in shell commands. The following is taken direct-
ly from the Linux man (manual) page entry:

ted@deadflowers 4:52pm >man which


WHICH(1) General Commands Manual
WHICH(1)

NAME
which - shows the full path of (shell) commands.

SYNOPSIS
which [options] [--] programname [...]

DESCRIPTION
Which takes one or more arguments. For each of its arguments
it prints to stdout the full path of the executables that would
have been executed when this argument had been entered at the shell
prompt. It does this by searching for an executable or script in
the directories listed in the environment variable PATH using the
same algorithm as bash(1).

If for some reason, the specified command is not found in your Linux search path, the which com-
mand indicates this by reporting “command not found”.

1. RUNNING THE ‘openocd’ MONITOR PROGRAM

1a. Plug in the STM Nucleo-64 board into the provided USB cable and plug in the other end of
the USB cable into the PC. Have your lab TA verify the connection is correct. To verify the USB
device has been recognized by the operatingsystem, issue the ‘lsusb’ command:

ted@deadflowers Code 4:37pm >lsusb


Bus 002 Device 004: ID 0483:374b STMicroelectronics ST-LINK/V2.1
4

Bus 002 Device 002: ID 8087:0020 Intel Corp. Integrated Rate Match-
ing Hub
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 004: ID 046d:c06a Logitech, Inc. USB Optical Mouse
Bus 001 Device 003: ID 03f0:0024 HP, Inc KU-0316 Keyboard
Bus 001 Device 002: ID 8087:0020 Intel Corp. Integrated Rate Match-
ing Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

The device of interest is the ‘STMicroelectronics ST-LINK/V2.1’ (Your listing may show other
devices)

1b. In a terminal window in which you have entered the ‘module load COEN311’, enter the fol-
lowing command:

ted@deadflowers Code 4:39pm > openocd -f board/st_nucleo_f3.cfg

The following will be displayed in the terminal window:

Open On-Chip Debugger 0.11.0


Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
Info : The selected transport took over low-level target control.
The results might differ compared to plain JTAG/SWD
srst_only separate srst_nogate srst_open_drain
connect_deassert_srst

Info : Listening on port 6666 for tcl connections


Info : Listening on port 4444 for telnet connections
Info : clock speed 1000 kHz
Info : STLINK V2J30M19 (API v2) VID:PID 0483:374B
Info : Target voltage: 3.267107
Info : stm32f3x.cpu: hardware has 6 breakpoints, 4 watchpoints
Info : starting gdb server for stm32f3x.cpu on 3333
Info : Listening on port 3333 for gdb connections

LED LD3 on the Nucleo-64 board will be illuminated in red, andLED LD1 will be alternating be-
tween green and red.

It is necessary for the ‘openocd’ monitor program to be running continuosly while one is using the
gdb debugger to single step through the machine code insructions. Leave ‘openocd’ running in the
terminal window and open a new terminal window. Once the single stepping with gdb is complet-
ed, the openocd monitor can be terminated with CTRL-C in its terminal window,or by simply clos-
ing its terminal window.
5

2. ASSEMBLING and LOADING an ARM ASSEMBLY LANGUAGE PROGRAM

These steps may be performed without the ‘openocd’ monitor running. They are best performed
in a new terminal window. The ‘openocd’ monitor program is only required when using the ‘gdb’
debugger program.

2a. Use a Linux text editor to edit an ASCII text file with the following contents:

.syntax unified
.cpu cortex-m4
.thumb

.word 0x20000400
.word 0x800000ed
.space 0xe4

start:
mov r0, #4
mov r1, #5
add r2, r1, r0

stop: b stop

It is strongly recommended that you create a directory called COEN311 to hold all your COEN
311 related files, and a directory called CODE within your COEN 311 directory
to hold all your assembly language programs. The followingLinux commands are used to do this:

mkdir COEN311
cd COEN311
mkdir CODE
cd CODE

Save the file with a name of your choice with a filename extension of .s . For example: add.s or
lab1.s .

The above assumed that the user is familiar with using a Linux text editor. For those unfamiliar
with Linux and the available text editors, here is a very short guide to using the ’nano’ Linux text
editor. Any Linux text command line text editor can be used such as ’vi’, ’emacs’, ’nano’, ’pico’.
This example gives the basics of using the ’nano’ text editor as it is easy anduser-friendly. To start
the ‘nano’ text editor, simply type the command ‘nano junk.txt’:

ted@willpower CODE 6:04pm > nano junk.txt

After you press Enter, you will see on your terminal:


6

GNU nano 2.3.1 File: junk.txt

Start to type your code here.


blah blah blah..
you can use the up, down, left, right
arrows to move around in the fkile and use
the Backspace and Delete keys.

[ New File ]
^G Get Help ^O WriteOut ^R Read File ^Y Prev Page ^K Cut Text ^C
Cur Pos
^X Exit ^J Justify ^W Where Is ^V Next Page ^U UnCut Text^T
To Spell

To save the file, press the Ctrl and O keys simultaneosly. The name of the file (junk.txt) will be the
default file name, you can specify another name if your wish and the contents of the file will be
saved a file residing in the directory from where you invoked the nano text editor from.
It is wise to save often, or else you may accidentally lose you typed in.

To exit from the text editor (after you have saved your file), press the Ctrl and X keys simulata-
neosly (this keystroke combination is shortened to ’Ctrl-X’ ).

You may use the nano text editor to create the assembly language program and save it with filena-
me of add.s or lab1.s .

2b. Assemble the source code using the assembler from the directory which contains your .s pro-
gram :

ted@deadflowers > arm-none-eabi-as -g add.s -o add.o -al=add.lst

Provided you have correctly typed in the code, there will be no errors/warnings listed and you will
be returned to the Linux prompt. Two files will be created:

-rw------- 1 ted ted 563 Oct 11 16:59 add.lst


-rw------- 1 ted ted 1644 Oct 11 16:59 add.o

Use the Linux ‘more’ command to view the contents of the add.lst file:

ted@deadflowers Code 4:24pm >more add.lst


ARM GAS add.s page 1

1 .syntax unified
2 .cpu cortex-m4
7

3 .thumb
4
5 0000 00040020 .word 0x20000400
6 0004 ED000080 .word 0x800000ed
7 0008 00000000 .space 0xe4
7 00000000
7 00000000
7 00000000
7 00000000
8
9 start:
10 00ec 4FF00400 mov r0, #4
11 00f0 4FF00501 mov r1, #5
12 00f4 01EB0002 add r2, r1, r0
13
14 00f8 FEE7 stop: b stop
15

The listing file gives the program line numbers in the left-most column, the addresses (actually off-
set values from some starting address) in the next column, and the machine code in the third col-
umn and the assembly language statements in the right-most columns. Addresses and machine
code are given in hexadecimal notation.

2c. Create an executable program (.elf) with the linker/loader (from the directory which contains
your .o file created with the assembler in step 2b):

ted@deadflowers > arm-none-eabi-ld add.o -o add.elf -Ttext=0x8000000


arm-none-eabi-ld: warning: cannot find entry symbol _start; defaulting
to 0000000008000000

This will create the file:

-rwx------ 1 ted ted 67188 Oct 11 17:00 add.elf

You can use the Linux ‘ls -al’ command to list the contents of a directory.

The add.elf file is a complete executable program, note that ‘x’ included in the file permissions -
‘x’ means the file has execute permissions. The input the the ‘ld’ command was the ‘add.o’ object
file created by the assembler. The -o option is used to specify the desired name of the output ex-
ecutable file. The -Ttext option is used to specify the starting address in the Nucleo-64 ARM
processor’s main memory.

The warning:

arm-none-eabi-ld: warning: cannot find entry symbol _start; de-


faulting to 0000000008000000
8

is of no concern and can be ignored as it is not relevant for running a program without an operating
system. [1]

3. SINGLE STEPPING THROUGH AN EXECUTABLE PROGRAM WITH ‘gdb’

3a. Ensure that you have the ‘openocd’ monitor program running in a Linux terminal window be-
fore you perform the following steps.

In a terminal window in which you have entered the ‘module load COEN311’ command, invoke
the debugger with your ‘add.elf’ file (the add.elf file should be located in thesame directory from
where you invoke the debugger):

ted@deadflowers > arm-none-eabi-gdb add.elf

You will see displayed in the terminal window:

GNU gdb (GNU Toolchain for the Arm Architecture 11.2-2022.02 (arm-
11.14)) 11.2.90.20220202-git
Copyright (C) 2022 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licens-
es/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type “show copying” and “show warranty” for details.
This GDB was configured as “--host=x86_64-pc-linux-gnu --tar-
get=arm-none-eabi”.
Type “show configuration” for configuration details.
For bug reporting instructions, please see:
<https://bugs.linaro.org/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.

For help, type “help”.


Type “apropos word” to search for commands related to “word”...
Reading symbols from add.elf...
(gdb)

3b. From the (gdb) prompt, issue the following:

(gdb) target extended-remote localhost:3333

The following will be listed:


9

Remote debugging using localhost:3333


0x00000000 in ?? ()
(gdb)

3c. From the gdb prompt:

(gdb) monitor reset halt

This command is used to stop the processor after a hard reset.You will see:

Unable to match requested speed 1000 kHz, using 950 kHz


Unable to match requested speed 1000 kHz, using 950 kHz
target halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x800000ec msp: 0x20000400

These are messages which can be safely ignored.

3d. Load the program machine code into the processor’s flash memory:

(gdb) load

You will see:

Loading section .text, size 0xfa lma 0x8000000


Start address 0x08000000, load size 250
Transfer rate: 718 bytes/sec, 250 bytes/write.

3e. Set a program breakpoint at some label defined in the source code. Our sample add.s pro-
gram contained the label ‘start’ at the first line of the code. In general, any line can have a
label and any label can be used to set a breakpoint. Since we want to stop executing at the first pro-
gram instruction, we set a breakpoint at label ‘start’:

(gdb) break start

Breakpoint 1 at 0x80000ec: file add.s, line 10.


Note: automatically using hardware breakpoints for read-only ad-
dresses.

3e. The program must first be run with the ‘continue’ command:

(gdb) continue
Continuing.

Breakpoint 1, start () at add.s:10


10 mov r0, #4
10

3f. Once the program has been run with a breakpoint set, we can single-step through the program
instruction-by-instruction and examine the contents of registers (using the info registers gdb com-
mand):

(gdb) info registers


r0 0x0 0
r1 0x0 0
r2 0x0 0
r3 0x0 0
r4 0x0 0
r5 0x0 0
r6 0x0 0
r7 0x0 0
r8 0x0 0
r9 0x0 0
r10 0x0 0
r11 0x0 0
r12 0x0 0
sp 0x20000400 0x20000400
lr 0xffffffff -1
pc 0x80000ec 0x80000ec <start>
xPSR 0x41000003 1090519043
fpscr 0x0 0
msp 0x20000400 0x20000400
psp 0x0 0x0
primask 0x0 0
basepri 0x0 0
faultmask 0x0 0
--Type <RET> for more, q to quit, c to continue without paging--
control 0x0 0
(gdb)

Note that the processor is waiting to execute the:

mov r0, #4

instruction , so the contents of register r0 is not yet equal to 4.

3g. Single step though the program with the ‘stepi’ command and examine the contents of the
various CPU registers as each instruction is executed:

(gdb) stepi
halted: PC: 0x080000f0
11 mov r1, #5

(gdb) info registers


11

r0 0x4 4
r1 0x0 0
r2 0x0 0
r3 0x0 0
r4 0x0 0
r5 0x0 0
r6 0x0 0
r7 0x0 0
r8 0x0 0
r9 0x0 0
r10 0x0 0
r11 0x0 0
r12 0x0 0
sp 0x20000400 0x20000400
lr 0xffffffff -1
pc 0x80000f0 0x80000f0 <start+4>
xPSR 0x41000003 1090519043
fpscr 0x0 0
msp 0x20000400 0x20000400
psp 0x0 0x0
primask 0x0 0
basepri 0x0 0
faultmask 0x0 0
--Type <RET> for more, q to quit, c to continue without paging--
control 0x0 0

Note that register r0 has been loaded with the immediate data 4. Continue single-stepping and ob-
serving register contents:

(gdb) stepi
halted: PC: 0x080000f4
12 add r2, r1, r0
(gdb) info registers
r0 0x4 4
r1 0x5 5
r2 0x0 0
r3 0x0 0
r4 0x0 0
r5 0x0 0
r6 0x0 0
r7 0x0 0

(Note all register contents shown here for reasons of brevity)


12

(gdb) stepi
halted: PC: 0x080000f8
stop () at add.s:14
14 stop: b stop
(gdb) info registers
r0 0x4 4
r1 0x5 5
r2 0x9 9
r3 0x0 0
r4 0x0 0
r5 0x0 0

The program is now executing an intentionally placed infinite loop:

stop: b stop

The b instruction is a branch statement which transfers control to the statement labelled stop.

3h. One can terminate the program using the “CTRL-C” sequence of characters entered from the
‘gdb’ terminal window. Enter the ‘quit’ command from the ‘gdb’ prompt to exit from ‘gdb’ and
return to the Linux prompt:

(gdb) quit

A debugging session is active.

Inferior 1 [Remote target] will be detached.

Quit anyway? (y or n)

Enter ‘y’ to quit:

Detaching from program: /nfs/home/t/ted/COEN311/ARM_LABS/Code/


Oct_4_Test/add.elf, Remote target
[Inferior 1 (Remote target) detached]

ted@deadflowers Oct_4_Test 5:31pm >

4. EXIT FROM THE ‘openocd’ MONITOR:

From the terminal window in which the ‘openocd’ command was run from,
press “CTRL-C” . You will be returned to the Linux prompt in thisterminal:

Info : halted: PC: 0x080000f8


Info : dropped ‘gdb’ connection
13

^Cshutdown command invoked

ted@deadflowers Code 5:32pm >

REFERENCES

1. ARM-ASM Tutorial, Niklas Gurtlet,


https://www.mikrocontroller.net/articles/ARM-ASM-Tutorial.

T. Obuchowicz
Dec. 6, 2022

You might also like