BogoToBogo
  • Home
  • About
  • Big Data
  • Machine Learning
  • AngularJS
  • Python
  • C++
  • go
  • DevOps
  • Kubernetes
  • Algorithms
  • More...
    • Qt 5
    • Linux
    • FFmpeg
    • Matlab
    • Django 1.8
    • Ruby On Rails
    • HTML5 & CSS

Embedded Systems Programming Hello World for ARM - 2020

cplusplus_icon.png




Bookmark and Share





bogotobogo.com site search:




Toolchain
What is Toolchain?

A toolchain is a collection of programming tools.


It consists of a compiler, linker, assembler, and a debugger. The GNU toolchain is a programming tools produced by the GNU Project. The GNU toolchain plays a vital role in development of software for embedded systems. It can be ported to Microsoft Windows (via Cygwin and MinGW/MSYS).

Quite often, the toolchain used for embedded development is a cross toolchain (cross compiler). In other words, when the host and target architectures are different, the toolchain is called a cross compiler (e.g. if we develop a code on a Linux machine based on the x64 architecture, but we're compiling for an ARM target, then we need Linux-based ARM-targeting cross compiler). This is the typical way of building embedded software.

CompilerAssemblerToolchain_gcc.png

Picture source: Toolchains


Terminology for Cross Compilation Toolchain

Before we do any cross compilation, we need to clarify the terminology. (source: http://elinux.org/Toolchains - Toolchains)

When talking about toolchains, one must distinguish three different machines:

  1. the build machine, on which the toolchain is built
  2. the host machine, on which the toolchain is executed
  3. the target machine, for which the toolchain generates code

Host_Target.png

Picture source: Programming Embedded Systems, 2nd Edition With C and GNU Development Tools By Michael Barr, Anthony Massa


From these three different machines, we distinguish 3 different types of toolchain building processes:

  1. A native toolchain, as can be found in normal Linux distributions, has usually been compiled on x86, runs on x86 and generates code for x86.
  2. A cross-compilation toolchain, which is the most interesting toolchain type for embedded development, is typically compiled on x86, runs on x86 and generates code for the target architecture (ARM, MIPS, or PowerPC)
  3. A cross-native toolchain, is a toolchain that has been built on x86, but runs on your target architecture and generates code for your target architecture. It's typically needed when you want a native gcc on your target platform, without building it on your target platform.

Toolchain - Name convention

Toolchain has a name convention:

arch[-vendor][-os]-abi
  1. arch - architecture
    arm, mips, x86, i686, etc.
  2. vendor - tool chain supplier
  3. os - operating system
    linux, none (bare metal)
  4. abi - application binary interface
    eabi, gnueabi, gnueabihf

Samples:

  1. arm-none-eabi
    This toolchain targets the ARM architecture, has no vendor, does not target an operating system (i.e. targets a "bare metal" system), and complies with the ARM eabi.
    (Note) arm-elf and arm-none-eabi just use two versions of the ARM abi. The eabi toolchain uses a newer revision, but could also be called arm-elf-eabi, as it generates elf too. (http://stackoverflow.com/questions/5961701/arm-gcc-toolchain-as-arm-elf-or-arm-none-eabi-what-is-the-difference).
  2. 
  3. i686-apple-darwin10-gcc-4.2.1
    This toolchain targets the Intel i686 architecture, the vendor is Apple, and the target OS is Darwin version 10.
  4. 
  5. arm-none-linux-gnueabi
    The toolchain that can be installed in Debian-based systems using a package manager like apt (the package is called gcc-arm-linux-gnueabi). This toolchain targets the ARM architecture, has no vendor, creates binaries that run on the Linux operating system, and uses the GNU EABI. In other words, it is used to target ARM-based Linux systems.
  6. arm-linux-gcc
    This is actually binary for gcc which produces objects for ARM architecture to be run on Linux with default configuration (abi) provided by toolchain.
  7. i686-unknown-linux-gnu
    32-bit GNU/linux
  8. 
  9. arm-eabi
    Android ARM compiler

The following samples are not directly related to ARM, but could be helpful since MinGW/MSYS are widely used:

  1. x86_64-w64-mingw32
    x86_64 architecture means AMD64, w64 is actually mingw-w64 used as a "vendor" here, mingw32 is the same as win32 API for gcc's perspective.
  2. i686-pc-msys
    32-bit, "pc" is a generic name, msys binary


Hello World with ARM processor

This example is based on the code from Programming Embedded Systems, 2nd Edition With C and GNU Development Tools By Michael Barr, Anthony Massa.

This is an Embedded version of Hello World. However, since in the embedded world, the display for the string "Hello World" is not easily available, we will just replace the string output with the blinking LED.


main()
#include "led.h" 

int main(void) 
{ 
 /* Configure the green LED control pin. */ 
 ledInit( ); 
 while (1) 
 { 
 /* Change the state of the green LED. */ 
 ledToggle( ); 
 /* Pause for 500 milliseconds. */ 
 delay_ms(500); 
 } 
 return 0; 
} 

makefile - compile & link

Before anything else, let's see how it works. We'll make executable first. Then, we'll sit back and check the details later.

I used gcc toolchain on Ubuntu 13 and Fedora 18 targeting ARM processor.

Here is the makefile.

# Fedora 18
#XCC     = arm-linux-gnu-gcc 
#LD      = arm-linux-gnu-ld

# Ubuntu 13
XCC     = arm-linux-gnueabi-gcc
LD      = arm-linux-gnueabi-ld
CFLAGS  = -g -c -Wall -I./include
LDFLAGS = -Map blink.map -T viperlite.ld -N

all: blink.exe

led.o: led.c led.h
	$(XCC) $(CFLAGS) led.c

blink.o: blink.c led.h
	$(XCC) $(CFLAGS) blink.c

blink.exe: blink.o led.o viperlite.ld
	$(LD) $(LDFLAGS) -o $@ led.o blink.o

clean:
	-rm -f blink.exe *.o blink.map

The files used in this example: "Embed.tar.gz":
"makefile", "blink.c", "blink.map", "blink.hex", "led.c", "led.h", "viperlite.ld" and "include" where other .h files are located.

Here we used arm-linux-gnu-gcc on Fedora 18 and arm-linux-gnueabi-gcc on Ubuntu 13 instead of arm-elf-gcc. They seem to be the same according to my research. (see Toolchain - Name Convention).

This Blinking LED example consists of two source modules: "led.c" and "blink.c". After we made the two object files ("led.o" and "blink.o"), the GNU linker performs the linking and locating of the object files. For locating, there is a linker script file named "viperlite.ld" that we input to ld in order to establish the location of each section in the Arcom board's memory. The actual command for linking and locating is:

$ arm-linux-gnu-ld -Map blink.map -T viperlite.ld -N -o blink.exe led.o blink.o

If we break up the parts:

  1. -Map blink.map
    To generate a map file and use the given filename Programming Embedded Systems Second Edition
  2. -T viperlite.ld
    To read the linker script
  3. -N
    To set the text and data sections to be readable and writable
  4. -o blink.exe
    To set the output filename (if this option is not included, ld will use the default output file name a.out)

The two object files ("led.o" and (blink.o") are the last arguments on the command line for linking. The linker script file, "viperlite.ld", is also passed in for locating the data and code in the our target's (Arcom board's) memory. The result of this command is the creation of two files ("blink.map" and "blink.exe") in the working directory. The ".map" file gives a complete listing of all code and data addresses for the final software image.


Formatting the output file

In some cases, we might need to format the image from the build procedure for our specific target platform.

One tool included with the GNU toolset that can assist with formatting images is the strip utility, which is part of the binary utilities package called binutils. The strip utility can remove particular sections from an object file. The basic command structure for the strip utility is:

arm-elf-strip [options] input-file ... [-o output-file] 

The command used to strip symbol information is:

$ arm-elf-strip --remove-section=.comment blinkdbg.exe -o blink.exe

This removes the section named ".comment" from the image "blinkdbg.exe" and creates the new output file "blink.exe".

There might be another time when we need an image file that can be burned into ROM or flash. The GNU toolset has just what you need for this task. The utility objcopy is able to copy the contents of one object file into another object file. The basic structure for the objcopy utility is:

 
arm-elf-objcopy [options] input-file [output-file] 

Suppose we want to convert our program from ELF format into an Intel Hex Format file. The command line we use for this is:

$ arm-elf-objcopy -O ihex blink.exe blink.hex

This command uses the "-O" ihex option to generate an Intel Hex Format file. The input file is "blink.exe" (the objcopy utility determines the input file type). Finally, the output file is named "blink.hex".



Market Study - Microprocessor

MyCurrentProcessor.png

Picture source : My current embedded project's main processor - Embedded Market Study, 2013



Next32bit.png

Picture source : Which of the following 32-bit chip families would you consider for your next embedded project? - Embedded Market Study, 2013





Embedded Systems related pages
  1. Embedded Systems Programming I - Introduction
  2. Embedded Systems Programming II - gcc ARM Toolchain ans Simple Code on Ubuntu and Fedora
  3. Embedded Systems Programming III - Eclipse CDT Plugin for gcc ARM Toolchain
  4. Memory-mapped I/O vs Port-mapped I/O
  5. Interrupt & Interrupt Latency
  6. Little Endian/Big Endian & TCP Sockets
  7. Bit Manipulation
  8. Linux Processes and Signals
  9. Linux Drivers 1






Ph.D. / Golden Gate Ave, San Francisco / Seoul National Univ / Carnegie Mellon / UC Berkeley / DevOps / Deep Learning / Visualization

YouTubeMy YouTube channel

Sponsor Open Source development activities and free contents for everyone.

Thank you.

- K Hong






Sponsor Open Source development activities and free contents for everyone.

Thank you.

- K Hong






C++ Tutorials

C++ Home

Algorithms & Data Structures in C++ ...

Application (UI) - using Windows Forms (Visual Studio 2013/2012)

auto_ptr

Binary Tree Example Code

Blackjack with Qt

Boost - shared_ptr, weak_ptr, mpl, lambda, etc.

Boost.Asio (Socket Programming - Asynchronous TCP/IP)...

Classes and Structs

Constructor

C++11(C++0x): rvalue references, move constructor, and lambda, etc.

C++ API Testing

C++ Keywords - const, volatile, etc.

Debugging Crash & Memory Leak

Design Patterns in C++ ...

Dynamic Cast Operator

Eclipse CDT / JNI (Java Native Interface) / MinGW

Embedded Systems Programming I - Introduction

Embedded Systems Programming II - gcc ARM Toolchain and Simple Code on Ubuntu and Fedora

Embedded Systems Programming III - Eclipse CDT Plugin for gcc ARM Toolchain

Exceptions

Friend Functions and Friend Classes

fstream: input & output

Function Overloading

Functors (Function Objects) I - Introduction

Functors (Function Objects) II - Converting function to functor

Functors (Function Objects) - General



Git and GitHub Express...

GTest (Google Unit Test) with Visual Studio 2012

Inheritance & Virtual Inheritance (multiple inheritance)

Libraries - Static, Shared (Dynamic)

Linked List Basics

Linked List Examples

make & CMake

make (gnu)

Memory Allocation

Multi-Threaded Programming - Terminology - Semaphore, Mutex, Priority Inversion etc.

Multi-Threaded Programming II - Native Thread for Win32 (A)

Multi-Threaded Programming II - Native Thread for Win32 (B)

Multi-Threaded Programming II - Native Thread for Win32 (C)

Multi-Threaded Programming II - C++ Thread for Win32

Multi-Threaded Programming III - C/C++ Class Thread for Pthreads

MultiThreading/Parallel Programming - IPC

Multi-Threaded Programming with C++11 Part A (start, join(), detach(), and ownership)

Multi-Threaded Programming with C++11 Part B (Sharing Data - mutex, and race conditions, and deadlock)

Multithread Debugging

Object Returning

Object Slicing and Virtual Table

OpenCV with C++

Operator Overloading I

Operator Overloading II - self assignment

Pass by Value vs. Pass by Reference

Pointers

Pointers II - void pointers & arrays

Pointers III - pointer to function & multi-dimensional arrays

Preprocessor - Macro

Private Inheritance

Python & C++ with SIP

(Pseudo)-random numbers in C++

References for Built-in Types

Socket - Server & Client

Socket - Server & Client 2

Socket - Server & Client 3

Socket - Server & Client with Qt (Asynchronous / Multithreading / ThreadPool etc.)

Stack Unwinding

Standard Template Library (STL) I - Vector & List

Standard Template Library (STL) II - Maps

Standard Template Library (STL) II - unordered_map

Standard Template Library (STL) II - Sets

Standard Template Library (STL) III - Iterators

Standard Template Library (STL) IV - Algorithms

Standard Template Library (STL) V - Function Objects

Static Variables and Static Class Members

String

String II - sstream etc.

Taste of Assembly

Templates

Template Specialization

Template Specialization - Traits

Template Implementation & Compiler (.h or .cpp?)

The this Pointer

Type Cast Operators

Upcasting and Downcasting

Virtual Destructor & boost::shared_ptr

Virtual Functions



Programming Questions and Solutions ↓

Strings and Arrays

Linked List

Recursion

Bit Manipulation

Small Programs (string, memory functions etc.)

Math & Probability

Multithreading

140 Questions by Google



Qt 5 EXPRESS...

Win32 DLL ...

Articles On C++

What's new in C++11...

C++11 Threads EXPRESS...

Go Tutorial

OpenCV...








Contact

BogoToBogo
contactus@bogotobogo.com

Follow Bogotobogo

About Us

contactus@bogotobogo.com

YouTubeMy YouTube channel
Pacific Ave, San Francisco, CA 94115

Pacific Ave, San Francisco, CA 94115

Copyright © 2024, bogotobogo
Design: Web Master