Getting Started With SAM3N Microcontrollers
Getting Started With SAM3N Microcontrollers
1. Introduction
This application note is intended as an aid in familiarizing the user with the Atmel AT91SAM
ARM® Cortex® M3-based SAM3N series of microcontrollers. It describes in detail a
simple project that uses several important features present on the SAM3N MCU, ARM-based
including how to set up the microcontroller prior to executing the application, as well
as adding functionality. After examination of this application note, the reader should
Flash MCU
be able to successfully start a new project from scratch.
This application note also explains how to setup and use a GNU ARM toolchain in
order to compile and run a software project.
Application
Note that the getting started example has been ported and is included in IAR® Embed- Note
ded Workbench for ARM (EWARM) and Keil ® MDK-ARM development kit. When
using these tools, the reader should disregard Section 4. “Building the Project”.
To use this document efficiently, the reader should be experienced in using the ARM
core. For more information about the ARM core architecture, please refer to the rele-
vant documents available from http://www.arm.com.
2. Requirements
The software provided with this application note requires several components:
• The SAM3N-EK Evaluation Kit
• A computer running Microsoft® Windows® 2000/XP
• An ARM cross-compiler toolchain supporting ARM Cortex-M3 (such as
CodeSourcery-2010-q1)
• SAM-BA® V2.10 or later
11097A–ATARM–07-Jan-11
3. Getting Started with a Software Example
This section describes how to program a basic application to become familiar with SAM3N
microcontrollers. It is divided into two main sections:
• the specification of the example (what it does, what peripherals are used)
• details of the programming aspect
3.1 Specification
3.1.1 Features
The demonstration program causes two LEDs on the board blink at a fixed rate. This rate is gen-
erated by using a timer for the first LED and a Wait function based on a 1 ms tick generated by
using the System Timer (SysTick). The blinking can be stopped using two buttons (one for each
LED).
While this software may look simple, it uses several peripherals which make up the basis of an
operating system. As such, it provides a good starting point for someone wanting to become
familiar with the AT91SAM family of microcontrollers.
3.1.2 Peripherals
In order to perform the operations introduced above, the software example uses the following
set of peripherals:
• Parallel Input/Output (PIO) controller
• Timer Counter (TC)
• Universal Asynchronous Receiver Transmitter (UART)
• Cortex M-3 System Timer (SysTick)
• Nested Vectored Interrupt Controller (NVIC)
LEDs and buttons on the board are connected to standard input/output pins of the chip and man-
aged by a PIO controller. In addition, it is possible to have the controller generate an interrupt
when the status of one of its pins changes, and buttons are configured accordingly.
The TC and SysTick are used to generate two time bases, in order to obtain the LED blinking
rates. Both are used in interrupt mode.
• The TC triggers an interrupt at a fixed rate, each instance toggling the LED state (on/off).
• The SysTick triggers an interrupt every millisecond, incrementing a variable by one tick. The
Wait function monitors this variable to provide a precise delay for toggling the second LED
state.
Using the NVIC is required to manage interrupts. It allows the configuration of a separate inter-
rupt handler for each source. Two different functions are used to handle PIO and SysTick
interrupts.
Finally, an additional peripheral, the UART, is used to output debug traces on a serial line. Hav-
ing the firmware send debug traces at key points of the code can greatly help the debugging
process.
2 Application Note
11097A–ATARM–07-Jan-11
Application Note
3.1.3.1 Memories
The SAM3N4C located on the SAM3N-EK evaluation board features one internal 24-Kbyte
SRAM memory and a 256-Kbyte Flash Memory block. The Getting Started example software
can be compiled and loaded on the internal Flash and the internal SRAM.
3.1.3.2 Buttons
The SAM3N4 Evaluation Kit features two push buttons, connected to pins PA15 and PA16.
When pressed, they force a logical low level on the corresponding PIO line.
The Getting Started example uses both buttons by means of the internal hardware debouncing
circuitry embedded in the SAM3N. Refer to Section 3.2.8.6 “Configuring Input Debouncing” for
more details.
3.1.3.3 LEDs
There are three general-purpose LEDs (blue, green and amber) on the SAM3N-EK, as well as a
software-controllable red power LED. They are wired to pins PA23, PB14, PA25 and PA0,
respectively. Setting a logical low level on these PIO lines turns the corresponding LED on.
The example application uses the two general-purpose LEDs (PA23 and PB14).
3.1.3.4 UART
On the SAM3N-EK, the UART uses pins PA9 and PA10 for the URXD and UTXD signals,
respectively.
3.2 Implementation
As stated previously, the example defined above requires the use of several peripherals. It must
also provide the necessary code for starting up the microcontroller. Both aspects are described
in detail in this section, with commented source code when appropriate.
3.2.1 C-Startup
Most of the code of an embedded application is written in C. This makes the program easier to
understand, more portable and modular. The C-startup code must:
• Provide vector table
• Initialize critical peripherals
• Initialize stacks
• Initialize memory segments
• Locate Vector Table Offset
These steps are described in the following paragraphs.
3
11097A–ATARM–07-Jan-11
Table 3-1. Exception numbers
Exception number Exception
1 Reset
2 RESERVED
3 HardFault
4 MemManage
5 BusFault
6 UsageFault
7-10 RESERVED
11 SVCall
12 Debug Monitor
13 RESERVED
14 PendSV
15 SysTick
16 External Interrupt (0)
... ...
16 + N External Interrupt (N)
The vector table’s current location can be determined or relocated in the CODE or SRAM parti-
tions of the memory map using the Vector Table Offset Register (VTOR), details of the register
can be found in the “Cortex-M3 TechnicalReference Manual”.
In the example, a full vector table looks like this:
extern uint32_t _estack;
void ResetException( void ) ;
__attribute__((section(".vectors")))
IntFunc exception_table[] = {
NMI_Handler,
HardFault_Handler,
MemManage_Handler,
4 Application Note
11097A–ATARM–07-Jan-11
Application Note
BusFault_Handler,
UsageFault_Handler,
0, 0, 0, 0, /* Reserved */
SVC_Handler,
DebugMon_Handler,
0, /* Reserved */
PendSV_Handler,
SysTick_Handler,
/* Configurable interrupts */
SUPC_IrqHandler, /* 0 Supply Controller */
RSTC_IrqHandler, /* 1 Reset Controller */
RTC_IrqHandler, /* 2 Real Time Clock */
RTT_IrqHandler, /* 3 Real Time Timer */
WDT_IrqHandler, /* 4 Watchdog Timer */
PMC_IrqHandler, /* 5 PMC */
EEFC_IrqHandler, /* 6 EEFC */
IrqHandlerNotUsed, /* 7 Reserved */
UART0_IrqHandler, /* 8 UART0 */
UART1_IrqHandler, /* 9 UART1 */
IrqHandlerNotUsed, /* 10 Reserved */
PIOA_IrqHandler, /* 11 Parallel IO Controller A */
PIOB_IrqHandler, /* 12 Parallel IO Controller B */
PIOC_IrqHandler, /* 13 Parallel IO Controller C */
USART0_IrqHandler, /* 14 USART 0 */
USART1_IrqHandler, /* 15 USART 1 */
IrqHandlerNotUsed, /* 16 Reserved */
IrqHandlerNotUsed, /* 17 Reserved */
IrqHandlerNotUsed, /* 18 Reserved */
TWI0_IrqHandler, /* 19 TWI 0 */
TWI1_IrqHandler, /* 20 TWI 1 */
SPI_IrqHandler, /* 21 SPI */
IrqHandlerNotUsed, /* 22 Reserved */
TC0_IrqHandler, /* 23 Timer Counter 0 */
TC1_IrqHandler, /* 24 Timer Counter 1 */
TC2_IrqHandler, /* 25 Timer Counter 2 */
TC3_IrqHandler, /* 26 Timer Counter 3 */
TC4_IrqHandler, /* 27 Timer Counter 4 */
TC5_IrqHandler, /* 28 Timer Counter 5 */
ADC_IrqHandler, /* 29 ADC controller */
DAC_IrqHandler, /* 30 DAC controller */
PWM_IrqHandler /* 31 PWM */
};
5
11097A–ATARM–07-Jan-11
3.2.1.2 Vectors: Reset Exception
The reset exception handler runs after the core reads the start SP, SP_main from vector table
offset 0, and the start PC from vector table offset. A normal reset exception handler follows the
steps in Table 3-3.
6 Application Note
11097A–ATARM–07-Jan-11
Application Note
while(1);
}
Since the SysTick exception is used in the example, the user can re-implement the SysTick
exception handler in the example as follows:
/**
* Handler for Sytem Tick interrupt. Increments the timestamp counter.
*/
void SysTick_Handler(void)
{
timestamp++;
}
In this way, when a SysTick exception occurs, a variable “timestamp” will be increased instead
of executing an infinite loop.
7
11097A–ATARM–07-Jan-11
RSTC->RSTC_MR |= RSTC_MR_URSTEN;
8 Application Note
11097A–ATARM–07-Jan-11
Application Note
DIV = 1
MUL = ( 8 – 1 ) = 7
12
f Output = ------ × 8 = 96MHz
1
Like the main oscillator, a PLL startup time must also be provided. Again, it can be calculated by
looking at the electrical characteristics given in the “SAM3N Series Datasheet”. After
CKGR_PLLR is modified with the PLL configuration values, the software must wait for the PLL
to be locked. This is done by monitoring the Status Register of the PMC:
#define BOARD_PLLR (CKGR_PLLR_STUCKTO1 \
| CKGR_PLLR_MUL(0x7) \
| CKGR_PLLR_PLLCOUNT(0x1) \
| CKGR_PLLR_DIV(0x1))
PMC->CKGR_PLLR = BOARD_PLLR;
timeout = 0;
while (!(PMC->PMC_SR & PMC_SR_LOCK) && (timeout++ < CLOCK_TIMEOUT));
Finally, the prescale value of the main clock must be set, and the PLL output selected. Note that
the prescale value must be set first, to avoid having the chip run at a frequency higher than the
9
11097A–ATARM–07-Jan-11
maximum operating frequency defined in the SAM3N AC characteristics. As such, this step is
done using two register writes, with two loops to wait for the main clock to be ready.
PMC->PMC_MCKR = BOARD_MCKR ;
for ( timeout = 0; !(PMC->PMC_SR & PMC_SR_MCKRDY) && (timeout++ <
CLOCK_TIMEOUT) ; );
At this point, the chip is configured to run on the main clock at 48 MHz (96 MHz/2) with the PLL
at 96 MHz.
10 Application Note
11097A–ATARM–07-Jan-11
Application Note
pSrc = &_etext ;
pDest = &_srelocate ;
if ( pSrc != pDest )
{
for ( ; pDest < &_erelocate ; )
{
*pDest++ = *pSrc++ ;
}
}
In addition, it is both safer and more useful for debug purposes to initialize the BSS segment by
filling it with zeroes. Theoretically, this operation is unneeded, however, it can have several ben-
efits. For example, it makes it easier when debugging to see which memory regions have been
modified. This can be a valuable tool for spotting stack overflow and similar problems.
Initialization of the BSS looks like:
for ( pDest = &_szero ; pDest < &_ezero ; )
{
*pDest++ = 0;
}
11
11097A–ATARM–07-Jan-11
3.2.2 Debug Message Implementation
The UART peripheral is used to print debug messages. Refer to Section 3.2.9 “Using the UART”
for detailed UART operations.
3.2.4.1 Initialization
Most peripherals are initialized by performing four actions
• Enabling the peripheral clock in the PMC
• Enabling the control of the peripheral on PIO pins
• Configuring the interrupt source of the peripheral in the NVIC
• Enabling the interrupt source at the peripheral level
Most peripherals are not clocked by default. This makes it possible to reduce the power con-
sumption of the system at startup. However, it requires that the programmer explicitly enable the
peripheral clock. This is done in the Power Management Controller (PMC). Exception is made
for the System Controller (which comprises several different controllers), as it is continuously
clocked.
For peripherals which need to use one or more pins of the chip as external inputs/outputs, it is
necessary to configure the Parallel Input/Output controller first. This operation is described in
more detail in Section 3.2.8 “Using the Parallel Input/Output Controller”.
Finally, if an interrupt is to be generated by the peripheral, then the source must be configured
properly in the Nested Vectored Interrupt Controller. Refer to Section 3.2.5 “Using the Nested
Vectored Interrupt Controller” for more information.
3.2.5.1 Purpose
The NVIC manages all internal and external interrupts of the system. It enables the definition of
one handler for each interrupt source, i.e., a function which is called whenever the correspond-
ing event occurs. Interrupts can also be individually enabled or masked, and have several
different priority levels.
In the example software, using the NVIC is required because several interrupt sources are pres-
ent (see Section 3.1.2 “Peripherals”). The NVIC functions are implemented using the “Core
Peripheral Access Layer” from the Cortex Microcontroller Software Interface Standard (CMSIS).
For further details on CMSIS, refer to http://www.arm.com/products/CPUs/CMSIS.html.
12 Application Note
11097A–ATARM–07-Jan-11
Application Note
3.2.5.2 Initialization
Unlike most other peripherals, the NVIC is always clocked and cannot be shut down. Therefore,
there is no enable/disable bit for NVIC clock in the PMC.
For debug purposes, it is good practice to use dummy handlers (i.e., which loop indefinitely) for
all interrupt sources (see Section 3.2.1.1 “Vector Table”). This way, if an interrupt is triggered
before being configured, the debugger is stuck in the handler instead of jumping to a random
address.
3.2.6.1 Purpose
Timer Counters on SAM3N devices can perform several functions, e.g., frequency measure-
ment, pulse generation, delay timing, Pulse Width Modulation (PWM), etc.
In this example, a single Timer Counter (TC) channel provides a fixed-period delay. An interrupt
is generated each time the timer expires, toggling the associated LED on or off. This makes the
LED blink at a fixed rate.
13
11097A–ATARM–07-Jan-11
3.2.6.2 Initialization
In order to reduce power consumption, most peripherals are not clocked by default. Writing the
ID of a peripheral in the Peripheral Clock Enable Register (PMC_PCER) of the Power Manage-
ment Controller activates its clock. This is the first step when initializing the Timer Counter.
The Timer Counter is then disabled, in case it has been turned on by a previous execution of the
program. This is done by setting the CLKDIS bit in the corresponding Channel Control Register
(TC_CCR). In the example, timer channel 0 is used.
The next step is to configure the Channel Mode Register (TC_CMR). TC channels can operate
in two different modes.
• Capture mode, is normally used for performing measurements on input signals.
• Waveform mode, enables the generation of pulses.
In the example, the purpose of the TC is to generate an interrupt at a fixed rate. Actually, such
an operation is possible in both Capture and Waveform modes. Since no signal is being sam-
pled or generated, there is no reason to choose one mode over the other. However, setting the
TC in Waveform mode and outputting the tick on TIOA or TIOB can be helpful for debugging
purpose.
Setting the CPCTRG bit of TC_CMR resets the timer and restarts its clock every time the coun-
ter reaches the value programmed in the TC Register C (TC_RC). Generating a specific delay is
done by choosing the correct value for TC_ RC. It is also possible to choose between several
different input clocks for the channel, which in practice makes it possible to prescale MCK. Since
the timer resolution is 16 bits, using a high prescale factor may be necessary for bigger delays.
Consider the following example: the timer must generate a 500 ms delay with a 48 MHz main
clock frequency. RC must be equal to the number of clock cycles generated during the delay
period. Below are the results with different prescaling factors:
MCK
Clock = --------------, RC = 24000000 × 0.5 = 12000000
2
MCK
Clock = --------------, RC = 6000000 × 0.5 = 3000000
8
MCK
Clock = --------------, RC = 375000 × 0.5 = 187500
128
MCK
Clock = --------------, RC = 46875 × 0.5 = 23437.5
1024
Since the maximum value for RC is 65535, it is clear from these results that using MCK divided
by 1024 or the internal slow clock is necessary for generating long (about 1s) delays. In the
example, a 250 ms delay is used. This means that the slowest possible input clock is selected in
the CMR, and the corresponding value written in RC. The following two operations configure a
250 ms period by selecting the slow clock and dividing its frequency by 4:
TC0->TC_CHANNEL[0].TC_CMR = TC_CMR0_TCCLKS_TIMER_CLOCK5
| TC_CMR0_CPCTRG;
TC0->TC_CHANNEL[0].TC_RC = SLOW_CLOCK >> 2;
14 Application Note
11097A–ATARM–07-Jan-11
Application Note
The last initialization step is to configure the interrupt whenever the counter reaches the value
programmed in TC_ RC. At the TC level, this is easily done by setting the CPCS bit of the Inter-
rupt Enable Register. Refer to Section 3.2.5.3 “Configuring an Interrupt” for more information on
configuring interrupts in the NVIC.
3.2.7.1 Purpose
The primary goal of the System Timer (SysTick) is to generate periodic interrupts. This is most
often used to provide the base tick of an operating system. The SysTick can select its clock
source, in this software example, the core clock (Master Clock) is selected as the SysTick input
clock. The SysTick has a 24-bit counter. The start value to load into the SysTick Current Value
Register (VAL) is called reload value, and is stored in the SysTick Reload Value Register
(LOAD). Each time the counter in VAL reaches 0, an interrupt is generated, and the value stored
in LOAD is loaded into VAL.
The getting started example uses the SysTick to provide a 1 ms time base. Each time the Sys-
Tick interrupt is triggered, a 32-bit counter is incremented. A Wait function uses this counter to
provide a precise way for an application to suspend itself for a specific amount of time.
3.2.7.2 Initialization
Since the SysTick is part of the System Controller, it is continuously clocked. As such, there is
no need to enable its peripheral clock in the PMC.
The first step is to disable the SysTick and select the clock source by setting the SysTick Control
and Status Register (SysTick_CTRL):
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk;
Before starting SysTick, the value in the SysTick Current Value Register (VAL) should be
cleared and reload value should be stored in the SysTick Reload Value Register (LOAD). Given
the SysTick source clock is MCK, in order to generate a 1ms interrupt, the reload value should
be MCK/1000. A partial example follows:
reloadValue = BOARD_MCK/1000;
SysTick->VAL &= ~AT91C_NVIC_STICKCURRENT;
SysTick->LOAD = reloadValue;
The SysTick then can be enabled with the SysTick interrupt enabled by setting CTRL:
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
15
11097A–ATARM–07-Jan-11
SysTick_CTRL_TICKINT_Msk |
SysTick_CTRL_ENABLE_Msk;
The application operation is executed by invoking the CMSIS function, SysTick_Config(), as
shown below:
if ( SysTick_Config( BOARD_MCK / 1000 ) )
{
printf("-F- Systick configuration error\n\r" ) ;
}
The function also enables SysTick interrupt.
3.2.8.1 Purpose
Most pins on SAM3N microcontrollers can either be used by a peripheral function (e.g. USART,
SPI, etc.) or used as generic input/outputs. All those pins are managed by one or more Parallel
Input/Output (PIO) controllers.
A PIO controller enables the programmer to configure each pin as used by the associated
peripheral or as a generic I/O. As a generic I/O, the pin level can be read/written using several
registers of the PIO controller. Each pin can also have an internal pull-up activated individually.
In addition, the PIO controller can detect a status change on one or more pins, optionally trigger-
ing an interrupt whenever this event occurs. Note that the generated interrupt is considered
internal by the NVIC, so it must be configured as level-sensitive (see Section 3.2.5.3 “Configur-
ing an Interrupt”).
In this example, the PIO controller manages two LEDs and two buttons. The buttons are config-
ured to trigger an interrupt when pressed (as defined in Section 3.1.1 “Features”).
16 Application Note
11097A–ATARM–07-Jan-11
Application Note
3.2.8.2 Initialization
There are two steps for initializing the PIO controller.
1. Its peripheral clock must be enabled in the PMC
2. its interrupt source can be configured in the NVIC
17
11097A–ATARM–07-Jan-11
Enabling interrupts on the two pins is done in the Interrupt Enable Register (PIO_IER). However,
the PIO controller interrupt must be configured as described in Section 3.2.5.3 “Configuring an
Interrupt”.
SlowClock
DIV = ------------------------------------------------------------
-–1
2 × CutOffFrequency
For example, 100 ms debounce time, or 10 Hz noise cut-off frequency can be obtained with a
32768 Hz Slow Clock frequency by writing a value of 1637 in PIO_SCDR.
3.2.9.1 Purpose
The Universal Asynchronous Receiver and Transmitter (UART) provides a two-pin UART as
well as several other debug functionalities. The UART is ideal for outputting debug traces on a
terminal, or as an In-System Programming (ISP) communication port. Other features include
chip identification registers, management of debug signals from the ARM core, and so on.
In the example, the UART is used to output a single string of text whenever the application
starts. It is configured with a baudrate of 115200 bps, 8 bits of data, no parity, one stop bit and
no flow control.
18 Application Note
11097A–ATARM–07-Jan-11
Application Note
3.2.9.2 Initialization
Writing the UART ID in the Peripheral Clock Enable Register (PMC_PCER) of the Power Man-
agement Controller activates its clock. This is the first step when initializing the UART. This is
done once before the debug console is used, as follows:
PMC_EnablePeripheral(ID_UART0);
or
PMC->PMC_PCER = 1 << ID_UART0;
It is also necessary to configure its two pins (UTXD and URXD) in the PIO controller. Writing
both pin IDs in the PIO Disable Register (PIO_PDR) of the corresponding PIO controller enables
peripheral control on those pins. However, some PIOs are shared between two different periph-
erals, Peripheral ABCD Select Register (PIO_ABCDSR) is used to switch control between the
two.
PIOA->PIO_ABCDSR[0] &= ~(UTXD|URXD);
PIOA->PIO_ABCDSR[1] &= ~(UTXD|URXD);
PIOA->PIO_PDR = UTXD | URXD;
The next action to perform, is to disable the receiver and transmitter logic, as well as disable
interrupts. This enables smooth reconfiguration of the peripheral in case it had already been ini-
tialized during an execution of the application. Setting bits RSTRX and RSTTX in the UART
Control Register (UART_CR) resets and disables the receiver and transmitter, respectively. Set-
ting all bits of the Interrupt Disable Register (UART_IDR) disables all interrupts coming from the
UART.
The baud rate clock must now be set up. The input clock is equal to MCK divided by a program-
mable factor. The Clock Divisor value is held in the Baud Rate Generate Register
(UART_BRGR). The following values are possible:
Table 3-4. Possible Values for the Clock Divisor field of BRGR
Value Comment
0 Baud rate clock is disabled
1 Baud rate clock is MCK divided by 16
2 to 65535 Baud rate clock is MCK divided by (CD x 16)
The following formula can be used to compute the value of CD given the microcontroller operat-
ing frequency and the desired baud rate:
MCK
CD = ----------------------------------------
16 × Baudrate
For example, a 115200 baud rate can be obtained with a 48 MHz master clock frequency by
writing a value of 26 in CD. Obviously, there is a slight deviation from the desired baudrate;
these values yield a true rate of 115384 bauds. However, it is a mere 1.6% error, with no impact
in practice.
The Mode Register (UART_MR) has two configurable values:
• The Channel Mode in which the UART is operating. Several modes are available for testing
purposes. In the example, only the normal mode is of interest. Setting the CHMODE field to a
null-value selects the normal mode.
• The Parity bit. Even, odd, mark and space parity calculations are supported. In the example,
no parity bit is being used (PAR value of 1xx).
19
11097A–ATARM–07-Jan-11
The UART features its own Peripheral DMA Controller (PDC). It enables faster data transfer and
reduces the processor overhead by taking care of most of the transmission and reception opera-
tions. The PDC is not used in this example, so it should be disabled by setting bits RXTDIS and
TXTDIS in the PDC Transfer Control Register (PERIPH_PTCR).
At this point the UART is fully configured. The last step is to enable the transmitter. The receiver
is not used in this demo application, so it is useless (but not harmful) to enable it as well. The
transmitter is enabled by setting TXEN bit in the UART Control Register.
20 Application Note
11097A–ATARM–07-Jan-11
Application Note
4.1.1 Makefile
The makefile contains rules indicating how to assemble, compile and link the project source files
to create a binary file ready to be downloaded on the target.
The makefile is divided into two parts:
• Variable settings
• Rules implementation
4.1.1.1 Variables
The first part of the makefile contains variables (uppercase), used to set up some environment
parameters, such as the compiler toolchain prefix and program names, and options to be used
with the compiler.
CHIP = sam3n4
BOARD = sam3n_ek
• Defines the chip and board names.
MEMORIES = flash
• Defines the available memory targets for the board.
Note: There is only flash target available on SAM3N-EK board because SRAM memory size is too small
for the program.
TRACE_LEVEL = 4
• Defines trace level used for compilation
OPTIMIZATION = -Os
• Level of optimization used during compilation (-Os optimizes for size).
21
11097A–ATARM–07-Jan-11
OUTPUT=getting_started_$(BOARD)_$(CHIP)
• Defines the outfile name (with board and chip names).
BIN = bin
OBJ = obj
• Defines output directory.
CROSS_COMPILE=arm-none-eabi-
• Defines the cross-compiler toolchain prefix.
LIBRARIES = ../../../../libraries
CHIP_LIB = $(LIBRARIES)/libchip_sam3n
BOARD_LIB = $(LIBRARIES)/libboard_sam3n-ek
LIB_PATH = -L$(CHIP_LIB)/lib
LIB_PATH += -L$(BOARD_LIB)/lib
LIB_PATH+=-L=/lib/thumb2
LIB_PATH+=-L=/../lib/gcc/arm-none-eabi/4.4.1/thumb2
• Defines the library path.
INCLUDES = -I$(CHIP_LIB)
INCLUDES += -I$(BOARD_LIB)
INCLUDES += -I$(LIBRARIES)
• Paths for header files.
CC = $(CROSS_COMPILE)gcc
LD = $(CROSS_COMPILE)ld
SIZE = $(CROSS_COMPILE)size
STRIP = $(CROSS_COMPILE)strip
OBJCOPY = $(CROSS_COMPILE)objcopy
GDB = $(CROSS_COMPILE)gdb
NM = $(CROSS_COMPILE)nm
• Names of cross-compiler toolchain binutils (compiler, symbol list extractor, etc.).
22 Application Note
11097A–ATARM–07-Jan-11
Application Note
CFLAGS += -Wall
CFLAGS += -Dprintf=iprintf
CFLAGS += --param max-inline-insns-single=500 -mcpu=cortex-m3 -mthumb -
ffunction-sections
CFLAGS += -g $(OPTIMIZATION) $(INCLUDES) -D$(CHIP) -
DTRACE_LEVEL=$(TRACE_LEVEL)
• Compiler options:
– -Wall: displays all warnings.
– -Dprintf=iprintf: uses only integer printf function to reduce application size
– --param max-inline-insns-single=500: Sets 500 the maximum number of instructions
in a single function that the tree inliner will consider for inlining.
– -mcpu = cortex-m3: type of ARM CPU core.
– -mthumb: generate code for Thumb instruction set.
– -ffunction-sections: place each function item into its own section in the output file if
the target supports arbitrary sections.
– -g: generate debugging information for GDB usage.
– $(OPTIMIZATION): set optimization option.
– $(INCLUDES): set paths for include files.
– -D$(CHIP): define chip names used for compilation.
– -DTRACE_LEVEL=$(TRACE_LEVEL): define trace level used for compilation
C_OBJECTS=main.o
• List of all object file names.
For more detailed information about GNU Compiler Collection (GCC) options, refer to GCC doc-
umentation available at gcc.gnu.org.
23
11097A–ATARM–07-Jan-11
4.1.1.2 Rules
The second part of the makefile contains rules. Each rule is a line composed of a target name,
and the files needed to create this target.
The following rules create the one object file from the corresponding source files. The option -c
tells GCC to run the compiler and assembler, but not the linker.
main.o: main.c
$(CC) -c $(CFLAGS) main.c -o main.o
The “all” rule is the default rule used by the make command when none is specified on the com-
mand line. It describes how to compile source files and link object files together. The first line
calls the linker with the defined flags, and linker files used with -T option. This generates an elf
format file, which is converted to a binary file without any debug information, by using the objcopy
program. An example of Flash configuration is given below:
4.1.2.1 Header
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
Set the object file format to elf32-littlearm.
OUTPUT_ARCH(arm)
Specify the machine architecture.
24 Application Note
11097A–ATARM–07-Jan-11
Application Note
/* The stack size used by the application. NOTE: you need to adjust */
STACK_SIZE = 2048;
/* Section Definitions */
SECTIONS
{
.text :
{
. = ALIGN(4);
_sfixed = .;
KEEP(*(.vectors .vectors.*))
*(.text .text.* .gnu.linkonce.t.*)
*(.glue_7t) *(.glue_7)
*(.rodata .rodata* .gnu.linkonce.r.*)
*(.ARM.extab* .gnu.linkonce.armextab.*)
. = ALIGN(4);
__init_array_start = .;
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array))
__init_array_end = .;
. = ALIGN(0x4);
KEEP (*crtbegin.o(.ctors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*crtend.o(.ctors))
. = ALIGN(4);
KEEP(*(.fini))
. = ALIGN(4);
__fini_array_start = .;
25
11097A–ATARM–07-Jan-11
KEEP (*(.fini_array))
KEEP (*(SORT(.fini_array.*)))
__fini_array_end = .;
KEEP (*crtbegin.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*crtend.o(.dtors))
. = ALIGN(4);
_efixed = .; /* End of text section */
} > rom
. = ALIGN(4);
_etext = .;
.relocate : AT (_etext)
{
. = ALIGN(4);
_srelocate = .;
*(.ramfunc .ramfunc.*);
*(.data .data.*);
. = ALIGN(4);
_erelocate = .;
} > ram
26 Application Note
11097A–ATARM–07-Jan-11
Application Note
/* stack section */
.stack (NOLOAD):
{
. = ALIGN(8);
_sstack = .;
. = . + STACK_SIZE;
. = ALIGN(8);
_estack = .;
} > ram
. = ALIGN(4);
_end = . ;
}
In the .text section, the _sfixed symbol is set in order to retrieve this address at runtime, then all
.text, and .rodata sections as well as .vectors section found in all object files, are placed here,
the _efixed symbol is set and aligned on a 4-byte address.
The same operation is done with the .relocate and .bss sections.
In the .relocate section, the AT (_etext) command specifies that the load address (the address in
the binary file after link step) of this section is just after the .text section. Thus there is no empty
space between these two sections.
4.1.3 Libraries
The SAM3N software package includes the following libraries:
– libchip_sam3n: chip specific library
– libboard_sam3n-ek: board specific library
– libqtouch: qtouch library
– libfreertos: freertos library
Note: libchip_sam3n and libboard_sam3n-ek should be compiled previously to generate the libraries
which are used by the Getting Started example.
27
11097A–ATARM–07-Jan-11
Follow the steps below to download code into Flash:
• Execute “Enable Flash” to enable Flash access.
• Download the binary “getting_started_sam3n_ek_sam3n4-flash.bin” into the flash.
• Execute “Boot from flash”.
• Shut down SAM-BA and power off the board.
• Power on the board to run the binary.
The code then starts running, and the LEDs are now controlled by two push buttons.
28 Application Note
11097A–ATARM–07-Jan-11
Application Note
Revision History
Change
Request
Doc. Rev Comments Ref.
11097A
First issue
09-Dec-10
29
11097A–ATARM–07-Jan-11
Headquarters International
Product Contact
Literature Requests
www.atmel.com/literature
Disclaimer: The information in this document is provided in connection with Atmel products. No license, express or implied, by estoppel or otherwise, to any
intellectual property right is granted by this document or in connection with the sale of Atmel products. EXCEPT AS SET FORTH IN ATMEL’S TERMS AND CONDI-
TIONS OF SALE LOCATED ON ATMEL’S WEB SITE, ATMEL ASSUMES NO LIABILITY WHATSOEVER AND DISCLAIMS ANY EXPRESS, IMPLIED OR STATUTORY
WARRANTY RELATING TO ITS PRODUCTS INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE, OR NON-INFRINGEMENT. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, CONSEQUENTIAL, PUNITIVE, SPECIAL OR INCIDEN-
TAL DAMAGES (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS INTERRUPTION, OR LOSS OF INFORMATION) ARISING OUT
OF THE USE OR INABILITY TO USE THIS DOCUMENT, EVEN IF ATMEL HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. Atmel makes no
representations or warranties with respect to the accuracy or completeness of the contents of this document and reserves the right to make changes to specifications
and product descriptions at any time without notice. Atmel does not make any commitment to update the information contained herein. Unless specifically provided
otherwise, Atmel products are not suitable for, and shall not be used in, automotive applications. Atmel’s products are not intended, authorized, or warranted for use
as components in applications intended to support or sustain life.
© 2010 Atmel Corporation. All rights reserved. Atmel ®, Atmel logo and combinations thereof, SAM-BA® and others are registered trademarks
or trademarks of Atmel Corporation or its subsidiaries. ARM ®, Thumb ® and the ARMPowered logo® and others are registered trademarks or
trademarks ARM Ltd. Windows ® and others are registered trademarks or trademarks of Microsoft Corporation in the US and/or other countries.
Other terms and product names may be trademarks of others.
11097A–ATARM–07-Jan-11