Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Real-time processing with the Philips LPC ARM mcu using GCC and uCOS II RTOS (D.W. Hawkins, 2006)

.pdf
Скачиваний:
85
Добавлен:
12.08.2013
Размер:
365.8 Кб
Скачать

Real-time processing with the Philips LPC ARM microcontroller; using GCC and the MicroC/OS-II RTOS.

Philips 05: Project Number AR1803

D. W. Hawkins (dwh@ovro.caltech.edu)

May 10, 2006

Contents

1

Introduction

3

2

Programmers Model

4

3

ARM GCC

6

 

3.1

Example 1: Basic startup assembler . . . . . . . . . . . . . . . . . . . . . . . . . . .

6

 

3.2

Example 2: A simple C program . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

8

 

3.3

Examples 3(a) and (b): C program stack setup . . . . . . . . . . . . . . . . . . . . .

9

3.4Examples 4(a), (b), and (c): C programs with .bss, .data, and .rodata sections . . 13

3.5 Example 5: LPC2138 processor initialization . . . . . . . . . . . . . . . . . . . . . . 19

3.5.1PLL setup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

3.5.2MAM setup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22

3.5.3 Stacks setup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22

3.6Example 6: Exception handling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25

3.7

Example 7:

I/O pin toggling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

28

3.8

Example 8:

Interrupt context save/restore benchmarking . . . . . . . . . . . . . . .

30

3.9Example 9: Multiple interrupts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32

3.10 Example 10: Interrupt nesting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

35

4 µCOS-II RTOS

39

4.1ARM-GCC port description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39

4.1.1Port header; os cpu.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41

4.1.2Port C-functions; os cpu c.c . . . . . . . . . . . . . . . . . . . . . . . . . . . 41

4.1.3

Port assembler-functions; os

 

cpu

 

a.s . . . . . . . . . . . . . . . . . . . . . .

41

4.1.4

Board-support package; BSP.H,.C . . . . . . . . . . . . . . . . . . . . . . . .

42

4.2Port testing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43

4.2.1Test 1: Task-to-IRQ context switching . . . . . . . . . . . . . . . . . . . . . . 43

4.2.2Test 2: Task-to-task context switching . . . . . . . . . . . . . . . . . . . . . . 44

4.2.3Test 3: IRQ-FIQ interrupt nesting . . . . . . . . . . . . . . . . . . . . . . . . 44

4.2.4Test 4: IRQ interrupt nesting . . . . . . . . . . . . . . . . . . . . . . . . . . . 44

4.3 uCOS-II examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

49

4.3.1

Example 1: Blinking LEDs . . . . . . . . . . . . . . . . . . . . . . . . . . . .

49

4.3.2

Example 2: Serial port echo console . . . . . . . . . . . . . . . . . . . . . . .

49

A ARM GCC

50

A.1 Build procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

50

2

AR1803

May 10, 2006

1 Introduction

The ARM processor is a reduced instruction set computer (RISC) intellectual property (IP) core defined by Advanced RISC Machines, Ltd (ARM). The ARM CPU architectures widely available today are based on the version 4 and 5 architectures [12]. ARM processor cores are used by Intel (StrongARM and XScale processors), Sharp, Atmel, Philips, Analog Devices, and many other semiconductor manufacturers.

The ARM processor can operate with two instruction sets; ARM mode, and THUMB mode. The ARM mode uses a 32-bit instruction set, while THUMB mode uses a 16-bit instruction set. The use of THUMB mode reduces the execution speed of the code, but reduces the memory requirements of the code, so finds use in the microcontroller applications of the processor core.

µCOS-II is a real-time operating system (RTOS) written by Jean Labrosse and supported by his company Micrium. The RTOS is well described in his book [6]. The RTOS defines a standard set of operating system (OS) primitives and the book defines how to port the RTOS to di erent processor architectures. This document describes a port for the ARM processor operating in 32-bit mode for the GNU GCC compiler.

The following references provide additional resources on ARM processors and µCOS-II RTOS:

“ARM system-on-chip architecture”, S. Furber [5].

“ARM Architecture Reference Manual”, D. Seal [12]. Chapters A1 and A2 provide an overview of the ARM architecture and programming model.

“ARM System Developer’s Guide”, A. Sloss et al [13]

“MicroC/OS-II: The real-time kernel”, J. Labrosse [6].

Author’s Note: May 10, 2006.

This document and the associated code were submitted to the Circuit Cellar Philips ARM 2005 contest. The project was selected for a Distinctive Excellence award. At some point Circuit Cellar are going to put the project files up on their web site.

Prior to the ARM 2005 contest I’d never used the ARM processor. My initial objective was to understand the code generated and required by GCC to link microcontroller applications, and then use that knowledge to port the uCOS-II RTOS to the processor. I’d played with the Atmel AVR and WinAVR for the Circuit Cellar Atmel AVR 2004 contest, but had simply used WinAVR, not appreciating the task done by the startup files and the AVR standard library. Many of the examples in this project are stand-alone, in that the code provides the start-up routines and the application code (some of the code in subfolders is repeated for the sake of simplification).

Please excuse the poor makefiles and anything else you find over-simplified, I was just playing and didn’t really anticipate too many people looking at the code. However, it seems alot of the questions asked on the LPC2000 news group could be answered by this document, so feel free to provide feedback, or modified code, and I’ll update the original source and re-release the code as it is updated. I plan to go though and add more sections, and get newlib-lpc up-and-running, but for now, this will have to do.

Feel free to post comments to the LPC2000 news group, I read it.

Cheers,

Dave Hawkins, Caltech. dwh@ovro.caltech.edu.

3

AR1803

 

 

 

 

 

 

 

 

 

 

 

May 10, 2006

 

 

 

 

 

 

 

 

Privileged modes

 

 

 

 

 

 

 

 

 

 

 

 

 

Exception modes

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

User

 

 

System

 

 

Supervisor

 

IRQ

 

FIQ

 

ABORT

 

UNDEFINED

R0

 

 

R0

 

 

R0

 

R0

 

R0

 

R0

 

R0

R1

 

 

R1

 

 

R1

 

R1

 

R1

 

R1

 

R1

R2

 

 

R2

 

 

R2

 

R2

 

R2

 

R2

 

R2

R3

 

 

R3

 

 

R3

 

R3

 

R3

 

R3

 

R3

R4

 

 

R4

 

 

R4

 

R4

 

R4

 

R4

 

R4

R5

 

 

R5

 

 

R5

 

R5

 

R5

 

R5

 

R5

R6

 

 

R6

 

 

R6

 

R6

 

R6

 

R6

 

R6

R7

 

 

R7

 

 

R7

 

R7

 

R7

 

R7

 

R7

R8

 

 

R8

 

 

R8

 

R8

 

R8_fiq

 

R8

 

R8

R9

 

 

R9

 

 

R9

 

R9

 

R9_fiq

 

R9

 

R9

R10

 

 

R10

 

 

R10

 

R10

 

R10_fiq

 

R10

 

R10

R11

 

 

R11

 

 

R11

 

R11

 

R11_fiq

 

R11

 

R11

R12

 

 

R12

 

 

R12

 

R12

 

R12_fiq

 

R12

 

R12

R13 (SP)

 

 

R13 (SP)

 

R13_svc (SP)

 

R13_irq (SP)

 

R13_fiq (SP)

 

R13_abt (SP)

 

R13_und (SP)

R14 (LR)

 

 

R14 (LR)

 

R14_svc (LR)

 

R14_irq (LR)

 

R14_fiq (LR)

 

R14_abt (LR)

 

R14_und (LR)

R15 (PC)

 

 

R15 (PC)

 

 

R15 (PC)

 

R15 (PC)

 

R15 (PC)

 

R15 (PC)

 

R15 (PC)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

CPSR

 

 

CPSR

 

 

CPSR

 

CPSR

 

CPSR

 

CPSR

 

CPSR

 

 

 

 

 

 

SPSR_svc

 

SPSR_irq

 

SPSR_fiq

 

SPSR_abt

 

SPSR_und

Figure 1: ARM programming modes. In ARM-mode the processor can switch between seven operating modes. The processor has a set of banked registers, i.e., the actual register an instruction accesses is dependent on the operating mode. The greyed registers in the figure show the physically di erent registers in each operating mode.

2 Programmers Model

Figure 1 shows the ARM programming model (Chapter A2 [12], p39 [5], p7 [7]), and the seven ARM operating modes. A general purpose operating system such as Linux uses the User mode of the processor for user-space processes, and the Supervisor mode for the operating system kernel. For a real-time OS, such as µCOS-II, the kernel and application tasks run in Supervisor mode. Exception modes need to be dealt with appropriately in either a general purpose OS (by kernel routines) or in an RTOS. The seven processor modes are (pA2-3 [12], pA2-11 [12] has the 5-bit values for each mode);

Mode

Description

User

Normal program execution code

System

Runs privileged operating system tasks

Supervisor

A protected mode for the operating system

IRQ

General-purpose interrupt handling

FIQ

Fast-interrupt handling

Abort

Used to implement virtual memory or memory protection

Undefined

Supports software emulation of coprocessors

In any of the seven operating modes shown in Figure 1, code has access to 16 general-purpose registers, R0 through R15, and a current program status register (CPSR). In exception modes there is an additional register, called the saved program status register (SPSR), which has identical bits to the CPSR. The processor has a set of banked registers, where dependent on the operating mode

4

AR1803

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

May 10, 2006

31

30

29

28

27

26

25

24

23

22

21

20

19

18

17

16

15

14

13

12

11

10

9

8

7

6

5

4

3

 

2

1

0

N

Z

C

V

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

I

F

T

M4

M3

M2

M1

M0

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

FLAGS

 

 

 

 

 

STATUS

 

 

 

 

 

EXTENSION

 

 

 

 

CONTROL

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Figure 2: Control and program status register (CPSR) bits. The defined bits are the flags; negative, zero, carry, and overflow, and the control bits; IRQ disable, FIQ disable, ARM/THUMB instruction mode, and the 5-bit processor operating mode (where the modes are shown in Figure 1).

the physical register accessed can be di erent. For example in fast interrupt mode (FIQ) registers R8 through R14 are unique for that mode so do not need saving through interrupt context switches. Register R13 is conventionally used as the Stack Pointer (pA2-6 [12]), while registers R14 and R15 have special roles as the Link Register (return address), and Program Counter (pA1-3 [12]). The ARM procedure calling standard (APCS) defines the recommended use of the other registers for passing arguments and return variables.

Stack pointer

The stack grows from high-to-low.

Link register

The link register holds the address of the next instruction after a Branch and Link (BL) instruction which is the instruction used to make a subroutine call. At all other times, R14 can be used as a general-purpose register (pA1-3 [12]). To return from a subroutine call, the link register is copied into the program counter register (pA1-4 [12]). If nested of interrupts is used, special care of the link register contents is required (pA2-6 [12]).

Program counter

When an instruction reads the program counter, the value read is the address of the instruction plus 8 (4 bytes if operating in THUMB mode). The program counter is 32-bit aligned (bits 1 and 0 are always zero) in ARM mode, and 16-bit aligned in THUMB mode (bit 0 is zero) (pA1-3 [12]).

Status registers

The CPSR (and SPSR) contains four sections; flags, status, extension, and control. These sections and bits are shown in Figure 2. There are specific instructions for transferring the status registers to and from the general purpose registers.

5

AR1803

May 10, 2006

3 ARM GCC

An embedded systems C-coded application consists of assembly-coded startup code containing processor and run-time environment (eg. stacks) initialization, the C-coded application, staticallylinked library code (newlib and user libraries), and a linker script defining the device memory map and code load and run addresses. The GNU Compiler Collection (GCC) for the ARM processor can be downloaded from www.gnuarm.com, or can be built from source as described in Appendix A. The following sections walk-through increasingly complex examples to demonstrate the GCC tools.

The examples in the following sections are developed for a Keil MCB2130 development board containing a Philips LPC2138 ARM microcontroller. The Keil MC2130 evaluation board contains a set of LEDs connected to pins P1.[16..23]. The examples use the LEDs to provide visual feedback that the example program operates correctly.

3.1Example 1: Basic startup assembler

/ ex1 . s /

/

−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

 

Exception v e c t o r s

−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

/

. t e x t

. arm

. g l o b a l s t a r t s t a r t :

/ Vectors (8 t o t a l ) /

b r e s e t

/ r e s e t /

b l o o p

/ u n defin ed i n s t r u c t i o n /

b l o o p

/ s o f t w a r e i n t e r r u p t /

b l o o p

/ p r e f e t c h a b o r t /

b l o o p

/ data a b o r t /

nop

/ r e s e r v e d f o r t he b o o t l o a d e r checksum /

bl o o p / IRQ /

bl o o p / FIQ /

/ −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

Test code

−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

/

r e s e t :

 

 

 

 

 

 

l d r

r0 ,

IODIR1

l d r

r1 ,

IODIR1

 

 

VALUE

s t r

r1

,

[ r 0 ]

l d r

r0 ,

IOCLR1

s t r

r1

,

[ r 0 ]

l d r

r0 ,

IOSET1

l d r

r1 ,

IOSET1

 

VALUE

s t r

r1

,

[ r 0 ]

l o o p :

b

 

l o o p

6

AR1803

May 10, 2006

/ −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

Constants

−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

/

/ LED c o n t r o l

r e g i s t e r s

/

IOSET1 :

. word

0 xE0028014

IODIR1 :

. word

0 xE0028018

IOCLR1:

. word

0xE002801C

IODIR1

 

VALUE :

. word

0x00FF0000

IOSET1

 

VALUE :

. word

0 x00550000

. end

Example 1 is a short assembler program that sets up basic exception vectors (they drop into an infinite loop), and then turns the MCB2130 even LEDs on (where indexing is LED[7:0]) and the odd LEDs o (a high value on an I/O pin turns an LED on). The example does not setup stacks (since we do not need them). The successful compilation and download of this example checks the compiler and linker setup.

A linker script is used to define the memory map of a processor. If GCC is not passed a linker script as part of the command line arguments, a default linker script is used. The linker script can be displayed by passing -Wl,--verbose to arm-elf-gcc or --verbose to arm-elf-ld. The default linker script defines an entry point symbol called _start and loads to a default address of 0x8000. The example assembler program uses the expected entry symbol _start, and since the Philips LPC microcontroller reset vector is address 0, a command line option, -Ttext=0, is needed to link the .text section to address 0 (note that this just overrides the linker script .text section start address, it does not replace the linker script). The example needs to setup the exception vector table correctly, as the Philips LPC microcontroller expects the reserved exception vector (the old 26-bit ARM processor address exception) to contain a checksum word. The Philips FlashUtils downloader fills in this checksum.

The example is compiled using

arm-elf-gcc -mcpu=arm7tdmi -c ex1.s

and is linked using

arm-elf-ld -Ttext=0 ex1.o -o ex1.elf

The linker -T option links the code starting at physical address 0.

The compilation and link step can be combined using

arm-elf-gcc -mcpu=arm7tdmi -nostartfiles -Ttext=0 ex1.s -o ex1.elf

The -nostartfiles option tells the compiler not to use its startup assembler routine. The executable can be disassembled using

arm-elf-objdump -d ex1.elf

which simply shows the original source. The disassembled code covers addresses 0 through 54h (inclusive), i.e., 58h bytes = 88 bytes. The amount of Flash and SRAM needed by a program can be summarized using

arm-elf-size ex1.elf

 

 

text

data

bss

dec

hex filename

88

0

0

88

58 ex1.elf

7

AR1803

May 10, 2006

A key point to note about this example is that there is only a text section, i.e., the example will only use Flash RAM.

The FlashUtils downloader expects an Intel hex format file. This file is created using

arm-elf-objcopy -O ihex ex1.elf ex1.hex

Start LPC210x_ISP.exe and download the program; the even LEDs should be on, the odd o (LED[0] is closest to the corner of the board).

3.2Example 2: A simple C program

The following startup routine sets up exception vectors, with the reset vector jumping directly to the C coded main application

/ e x 2

 

s t a r t . s /

 

 

 

 

 

. t e x t

 

 

 

 

 

 

 

 

 

 

 

 

. arm

 

 

 

 

 

 

 

 

 

 

 

 

 

. g l o b a l

main

 

 

 

 

 

 

 

 

. g l o b a l

 

 

s t a r t

 

 

 

 

s t a r t :

 

 

 

 

 

 

 

 

 

 

 

 

/ Vectors (8 t o t a l ) /

 

 

 

l d r

pc ,

main

 

 

addr

/ r e s e t /

 

 

 

l d r pc , l o o p

 

a d d r

/ u n defin ed i n s t r u c t i o n /

 

 

 

l d r pc , l o o p

 

a d d r

/ s o f t w a r e i n t e r r u p t /

 

 

 

l d r pc , l o o p

 

a d d r

/ p r e f e t c h a b o r t /

 

 

 

l d r pc , l o o p

 

a d d r

/ data a b o r t /

 

 

nop

 

 

 

 

 

 

 

 

 

/ r e s e r v e d f o r t he b o o t l d r checksum /

 

 

 

l d r

pc ,

l o o p

 

 

a d d r

/ IRQ /

l o o p

l d r

pc ,

l o o p

 

 

a d d r

/ FIQ /

 

 

a d d r :

. word

l o o p

 

main

 

addr :

. word

main

 

l o o p :

b

l o o p

 

 

 

 

 

 

 

 

. end

 

 

 

 

 

 

 

 

 

 

The exception vectors are setup slightly di erently than those in example 1. Instead of branching to the loop address, they load the program counter with the address of the loop.

The main C code is

/ ex2 main . c /

#define IOSET1 ( ( ( volatile unsigned long ) 0 xE0028014 ) ) #define IODIR1 ( ( ( volatile unsigned long ) 0 xE0028018 ) ) #define IOCLR1 ( ( ( volatile unsigned long ) 0xE002801C ) )

int main ( void )

 

{

ou t pu t /

/ Define t he LED pin s P1 . [ 1 6 . . 2 3 ] as

IODIR1 = 0x00FF0000 ;

 

/ Clear a l l pin s /

 

IOCLR1 = 0x00FF0000 ;

 

/ LED [ 7 : 0 ] ; even on ( high ) , odd o f f

( low ) /

8

AR1803

May 10, 2006

IOSET1 = 0 x00550000 ;

while ( 1 ) ; return 0 ;

}

Compilation and disassembly of just the main code using

arm-elf-gcc -mcpu=arm7tdmi -c ex2_main.c arm-elf-objdump -d ex2_main.o

will show assembly code that uses the stack pointer. However, a stack pointer is not setup by ex2_start.s, so instead the code should be compiled with optimization level 2, -O2, as that eliminates the stack references for this particular example. The application can be compiled using

arm-elf-gcc -O2 -mcpu=arm7tdmi -nostartfiles -Ttext=0 \ ex2_start.s ex2_main.c -o ex2.elf

The order of the files here is important, the startup code must come first. Disassembly of the code using

arm-elf-objdump -d ex2.elf

shows the startup code followed by the main code. The code covers addresses 0 through 48h (4Ch bytes). The size of the standard sections in the file are (all the sections can be viewed using arm-elf-objdump -h ex2.elf)

arm-elf-size ex2.elf

 

 

text

data

bss

dec

hex filename

76

0

0

76

4c ex2.elf

As with example 1, the code produces only a text section, so only Flash RAM is used.

Conversion of the elf file into hex format, and then download using FlashUtils produces the same result as example 1.

3.3Examples 3(a) and (b): C program stack setup

The LPC2138 contains 32Kbytes (i.e., 8000h) SRAM starting at address 40000000h. The ARM stack grows down, so the ex3_start.s file initializes the stack pointer to the end of SRAM, i.e., 40008000h, and then jumps to main

/ e x 3 s t a r t . s /

. t e x t

 

 

 

 

. arm

 

 

 

 

. g l o b a l

main

 

. g l o b a l

 

 

s t a r t

s t a r t :

 

 

 

 

/ Vectors (8 t o t a l ) /

b r e s e t

 

 

/ r e s e t /

b l o o p

 

 

/ u n defin ed i n s t r u c t i o n /

b l o o p

 

 

/ s o f t w a r e i n t e r r u p t /

b l o o p

 

 

/ p r e f e t c h a b o r t /

b l o o p

 

 

/ data a b o r t /

nop

 

 

/

r e s e r v e d f o r t he b o o t l o a d e r checksum /

b l o o p

 

 

/

IRQ /

9

AR1803

 

 

 

 

 

 

 

May 10, 2006

b l o o p

/ FIQ /

 

 

/ Setup

t he

s t a c k

p o i n t e r

and then jump t o

main /

r e s e t :

 

 

 

 

 

 

 

 

l d r sp , s t a c k

 

a d d r

 

 

b l

main

 

 

 

 

 

 

 

/ Catch

r et u r n from

main

/

 

l o o p :

b

l o o p

 

 

 

 

/ Constants /

 

 

 

 

/ LPC SRAM

s t a r t s

at

0x40000000 , and t h e r e

i s 32Kb = 8000 h /

s t a c k

 

a d d r :

. word

0 x40008000

 

. end

 

 

 

 

 

 

 

 

The Example 3(a) main application turns on the MCB2130 LEDs as in the previous examples, but uses a function call. A function call requires the use of a stack (the usuage of the stack by the main code in the final executable is shown shortly).

/ ex3a main . c /

#include ” l e d . h”

int main ( void )

{

l e d i n i t ( ) ; l e d ( 0 x55 ) ; while ( 1 ) ; return 0 ;

}

Since the LED routines are used in multiple programs, they are placed in a separate files; a header

/ l e d . h

 

 

 

/

 

 

#ifndef

LED

 

H

 

 

#define LED

 

H

 

 

/ I n i t i a l i z e t he LEDs

/

 

void l e d

 

 

i n i t ( ) ;

 

 

/ Control t he LEDs /

 

 

void l e d ( unsigned long

v a l ) ;

/ Set LEDs /

 

 

void l e d

 

s e t ( unsigned

long

s e t ) ;

/ Clear LEDs /

 

 

void l e d

 

 

c l r ( unsigned

long

c l r ) ;

#endif

10