Transcript uCOS - SJTU

Embedded Systems
GNU tool
Reference
Book (1)
Reference
Book (2)
Useful Links

http://www.sthoward.com/docs/
– Some GNU Documents

www.gnu.org
– All about GNU

http://263.aka.org.cn/Lectures/
– Lecture on Linux & GNU
Outline
Overview
 Toolchain
 Source
 RT
Programming
Embedded System
Memory
Data out
Data in
Processor
Control in
Control out
From Source to Machine Code
*.c
*.cpp
Assembler
Compiler
1010101001
1010101001
1010101001
10101001
10101001
10101001
Lib
101001
1010101
*.s
1010101001
1010101001
10101001
10101001
Linker
Executable Binary
Simple Example
Source Files
 hello.c
C source, contain function main()

disp_dat.c
C source, functions in it is called by main() of hello.c

startup.s
Start up code for embedded board

hello.lds

Link description file

Makefile

Commands to build them all
forward
Code of hello.c
int main()
{
char a = ‘a’;
char b = ‘b’;
disp_dat(a);
disp_dat(b);
while (1); // loop forever
return (0); // never comes here
}
Code of disp_dat.c
void disp_dat(U8 data)
{
// Wait until send buffer empty
while (!((*((volatile U32 *)(0x207098))) & 1));
// send on character into send buffer
(*((volatile U32 *)(0x207040))) = (U16)data;
}
Makefile
hello: hello.o disp_dat.o startup.o
arm-linux-ld –o hello –T hello.lds \
hello.o
\
disp_dat.o\
startuop.o
hello.o: hello.c
arm-linux-gcc –c hello.c
disp_dat.o: disp_dat.c
arm-linux-gcc –c disp_dat.c
stratup.o: startup.s
arm-linux-gcc –c startup.s
will explain later
Use command
“make”
to automatically execute the steps listed in Makefile
forward
Download Code To ROM
Outline
 Overview
Toolchain
 Source
File
 RT Programming
CDK
Cross Development Kits
 Toolchain

– C/C++ Compiler
– Assembler
– Linker
– Runtime Lib
Components of Toolchain
Cross-Compiler
gcc
libc
Linux Kernel
Headers
Binutil
Cross-Assembler
as
Cross-Linker
ld
Cross-Archiver
ar
…
ranlib
ranlib
Build Toolchain
Build Binary tools
Build GCC for the 1st time
(without Glibc)
Build Glibc
(Need kernel head file)
Build GCC for the 2nd
time
(With Glibc)
Build uGlibc for embedded
development
Build GDB
C/C++ Compiler
C/C++
source
Code
10011100
10001011
11101110
11111110
*.c, *.cpp, *.cxx
*.o, *.obj
*.h. *.hpp, *.hxx
Example:
• object file is not intended to be
executed directly
• The structure of the file is usually
COFF or ELF
arm-linux-gcc –c hello.c
hello.c  hello.o
Assembler
ASM code
*.a, *.s, *.asm
Example:
10011100
10001011
11101110
11111110
*.o, *.obj
arm-linux-gcc –c startup.s
startup.s  startup.o
(note that gcc will automatically call assembler
according to the postfix of *.s)
What’s in object File?
Data:
1001001
1011100
1111100
Text:
1111001
1011111
1111101
BSS:
1100001
1111111
1111101
Binary Data
Blocks in it
Object File Example
… …
Sections:
Idx Name
0 .text
1 .data
2 .bss
3 .stab
4 .stabstr
5 .comment
objdump –x file.o
Size
00000160
CONTENTS,
00000004
CONTENTS,
00000000
ALLOC
000003fc
CONTENTS,
00000557
CONTENTS,
00000026
CONTENTS,
VMA
LMA
00000000 00000000
ALLOC, LOAD, RELOC,
00000000 00000000
ALLOC, LOAD, DATA
00000000 00000000
File off
00000034
READONLY,
00000194
Algn
2**2
CODE
2**2
00000198
2**0
00000000 00000000 00000198
RELOC, READONLY, DEBUGGING
00000000 00000000 00000594
READONLY, DEBUGGING
00000000 00000000 00000aeb
READONLY
2**2
SYMBOL TABLE:
00000000 l
df *ABS* 00000000 Helloworld.c
… …
2**0
2**0
Function of linker (LD)
Linker
Data:
BSS:
1001001
1100001
1011100
1111111
Data:
BSS:
1111100
1001001 1111101
1100001
1011100
1111111
BSS:
Text: Data:
1111100
1111101
1100001
11110011001001
1011100
1111111
1011111
Text:
1111100
1111101
1111101
1111001
1011111
Text:
1111101
1111001
1011111
1111101
Object files, *.o
*.lds
Link
description
file
Data:
1001001
1011100
1111100
1110111
1011000
0001000
BSS:
1100001
1111111
1111101
1100000
Text:
1111001
1011111
1111101
1101101
1111011
1110111
Executable files
*.exe, *.elf
Function of linker (contd.)
Combine Data Blocks
 Fill Symbol Address


The work is under control of file
*.lds
Outline
 Overview
 Toolchain
Source
 RT
File
Programming
With/Without OS
Without OS
With OS
Startup.s
Main.c
Main.c
lds
Makefile
Makefile
Tasks of Startup Code
Disable all INT
2. Init Memory & Hardware
3. Copy Data from ROM  RAM
4. Initialize Data Area
5. Initialize StacK
6. Enable interrupts.
7. Call main( ).
1.
backward
Name of Startup code
startup.asm
 startup.s
 startup.a51
 start.asm
 start.s
 start.a51
 crt0.s

– C Runtime
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ exception vectors
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
.globl Helloworld_start
Helloworld_start:
b
reset
b
UNDEF_Handler
b
SWI_Handler
b
PABT_Handler
b
DABT_Handler
b
NULL_Handler
b
IRQ_Handler
b
FIQ_Handler
Example
startup.s (1)
Interrupt
vectors
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ Define stack position
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
.extern Helloworld_end
Example
startup.s (2)
.equ
UND_STACK_START,
__STACK_START
+ 0x400
@ 1kB
.equ
SVC_STACK_START,
__STACK_START
+ 0x800
@ 1kB
.equ
ABT_STACK_START,
__STACK_START
+ 0xc00
@ 1kB
.equ
IRQ_STACK_START,
__STACK_START
+ 0x1000
@ 1kB
.equ
FIQ_STACK_START,
__STACK_START
+ 0x1400
@ 1kB
.equ
SYS_STACK_START,
__STACK_START
+ 0xFFF0
@
UND_SP: .long
UND_STACK_START
SVC_SP: .long
SVC_STACK_START
ABT_SP: .long
ABT_STACK_START
IRQ_SP: .long
IRQ_STACK_START
FIQ_SP: .long
FIQ_STACK_START
SYS_SP: .long
SYS_STACK_START
Define points to the
beginning of the stack
Example
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@
startup.s
(3)
@ Reset handler
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@
reset:
@ Init SDRAM
LDR
r1, =0x221000
STR
…
r3, [r1]
LDR
r3, =0x8212C267;
STR
r3, [r1]
Reset interrupt
routine
(init SDRAM)
Example startup.s (4)
@ setup IRQ stack
mrs
r0,
cpsr
bic
r0,
r0,
#0x1f
orr
r0,
r0,
#0x12
msr
cpsr,
r0
ldr
r13,
=IRQ_SP
ldr
sp,
[r13]
…
@ setup SVC stack
@ set CPSR to IRQ mode
@ setup sp_irq
Reset interrupt routine
(init stacks)
mrs
bic
orr
msr
r0,
r0,
r0,
cpsr,
cpsr
r0,
r0,
r0
ldr
ldr
r13,
sp,
=SVC_SP
[r13]
bl
init_sect
b
main
#0xff
#0x13
@ set CPSR to SVC mode
@ setup sp_svc
(call function to init
data area)
@ C main code
(Jump to main)
Compile All With Command
Line
gcc -g –Wall –T hello.lds –o hello\
hello.c
\
disp_dat.c
\
startup.s
The same function of Makefile
(so why we use Makefile?)
backward
forward
Format of Several Widely Used
Output File

ELF
– Include Symbol table and relocation information

Binary Image
– Only include machine code

Intel Hex File
– ASCII file, for programmer to download code

Motorola S Record File
– Another ASCII file format for programmer
Generating Output Files

Gcc generate ELF file by default
 Objcopy
– Motorola Srecord File
objcopy –O srec hello.elf hello.srec
– Intel HEX file
objcopy –O ihex hello.elf hello.hex
– Binary File
objcopy –O binary hello.elf hello.bin

Objdump
– Display disassemble data
objdump –S hello.elf
– Display section and symbol table location
objdump –x hello.elf`
LDS File
Linker
Data:
BSS:
1001001
1100001
1011100
1111111
Data:
BSS:
1111100
1001001 1111101
1100001
1011100
1111111
BSS:
Text: Data:
1111100
1111101
1100001
11110011001001
1011100
1111111
1011111
Text:
1111100
1111101
1111101
1111001
1011111
Text:
vect:
1111101
1111001
1111001
1011111
1011111
1111101
1111101
Object files
*.lds
Ld
script
Data:
1001001
1011100
1111100
1110111
1011000
0001000
BSS:
1100001
1111111
1111101
1100000
Text:
1111001
1011111
1111101
1101101
1111011
1110111
Executable files
LDS File (code example)
ENTRY(_start)
/* list of
MEMORY
{
vect
rom
ram
sram
}
ROM
our memory sections */
:
:
:
:
o
o
o
o
=
=
=
=
0,
l
0x400,
l
0x400000, l
0xfffff000,l
=
=
=
=
CPU
SRAM
1k
127k
128k
4k
RAM
LDS File (MEMORY command )

MEMORY command
– Target system's memory map
– Used in the SECTIONS
– Syntax
MEMORY
{
name : o = origin, l = length
name : o = origin, l = length
...
}
SECTIONS
{
LDS File (1)
.vect :
{
__vect_start = .;
*(.vect);
__vect_end = .;
} > vect
.text :
{
__text_start = .;
*(.text)
*(.strings)
__text_end = .;
} > rom
}
.bss :
{
__bss_start = . ;
*(.bss)
*(COMMON)
__bss_end = . ;
} > ram
LDS File (2)
.Data:
.BSS:
1001001
1100001
1011100
1111111
.Data: 1111101
.BSS:
1111100
1001001
1100001
.Text: 1011100
1111111
.Data: 1111101
.BSS:
1111001
1111100
1001001
1100001
1011111
Text: 1011100
1111111
1111101
1111001
1111100
1111101
1011111
.Text:
1111101
1111001
1011111
.vect:
1111101
1111001
Object files
.Data:
1001001
1011100
1111100
1110111
1011000
1111100
1110111
1111100
1110111
0001000
1111111
.BSS:
1100001
1111111
1111101
1100000
.Text:
1111001
1011111
1111101
1101101
1011111
1111101
1101101
1011111
1111101
1101101
1011111
1111101
1101101
1111011
.vect:
1111001
Executable files
LDS File (3)
Data:
1001001
1011100
1111100
1110111
1011000
0001000
ROM
BSS:
1100001
1111111
1111101
1100000
Text:
1111001
1011111
1111101
1101101
1111011
1110111
Executable files
RAM
Memory
are
spitted
into
sections
Sections
{ … …
/* initialized data */
.init : AT (__text_end)
{
__data_start = .;
*(.data)
__data_end = .;
} > ram
/* application stack */
.stack :
{
__stack_start = .;
*(.stack)
__stack_end = .;
} > ram
}
LDS File
(Section
Command)
LDS File (AT directive )
Data:
1001001
1011100
1111100
1110111
1011000
0001000
BSS:
1100001
1111111
1111101
1100000
Text:
1111001
1011111
1111101
1101101
1111011
1110111
Executable files
ROM
Initialization
data is stored
in the ROM
RAM
ROM
Executable
Code
Constant
Data
Init Table For
Global Data
RAM
Program
Stack
Global data &
Static Data
*.lds
Initialization
Data Section
.init : AT (__text_end)
{
__data_start = .;
*(.data)
__data_end = .;
} > ram
*.c
int global_dat=1234;
void main()
{
disp_dat(global_dat)
}
If global_dat not initialized, will
print out wrong result
Function to Initialize Sections (1)
// init sections, run it before main()
void init_sect(void)
{
extern void *__TEXT_END;
extern void *__DATA_START, *__DATA_END;
extern void *__BSS_START, *__BSS_END;
.init : AT (__text_end)
{
__data_start = .;
*(.data)
__data_end = .;
} > ram
char *src = (char*)(&__TEXT_END);
char *dst = (char*)(&__DATA_START);
// ROM has data at end of text; copy it.
while (dst < (char*)(&__DATA_END))
*dst++ = *src++;
// Zero bss
for (dst = (char*)(&__BSS_START);
dst < (char*)(&__BSS_END);
dst++)
*dst = 0;
}
…
Function to
Initialize
Sections (2)
Sections {
…
. = ALIGN(2);
.text :
{
__TEXT_START = .;
*(.text);
__TEXT_END = .;
} > ROM
MEMORY
{
VECT : o = 0x00000000, l = 0x00001000
ROM
: o = 0x00001000, l = 0x00010000
RAM
: o = 0x08000000, l = 0x00010000
}
}
. = ALIGN(2);
.init : AT(__TEXT_END)
{
__DATA_START = .;
*(.data);
__DATA_END = .;
} > RAM
. = ALIGN(2);
.bss :
{
__BSS_START = .;
*(.bss);
__BSS_END = .;
} > RAM
…
…
End of Startup file (3)
In the end of Start.s file
@ setup SVC stack
mrs
r0,
cpsr
bic
r0,
r0,
#0xff
orr
r0,
r0,
#0x13
msr
cpsr,
r0
ldr
r13,
=SVC_SP
ldr
sp,
[r13]
bl
init_sect
b
main
@ set CPSR to SVC mode
@ setup sp_svc
@ C main code
Running
Mode

ROM Mode
ROM
Executable
Code &
Constant
Data
RAM
Stack &
Changing
Data
ROM
Boot loader
&
Code Image
RAM

RAM Mode
Require a copy function in
bootloader to move ROM
image into RAM
Executable
Code,
Stack &
Changing
Data
Running Mode (contd.)

ROM Mode
–
–
–
–

Simple
Require smaller memory
Fixed code address
Relative Small Code
RAM Mode
–
–
–
–
Complex
Re-locatable code
Faster
Large Code (SDRAM)
RAM Mode
Task of Bootloader
• Init Basic System
Bootloader
Code Image
(Maybe Compressed)
• Init RAM System
ROM
• Copy (de-compress)
ROM Image into
RAM
RAM
• Init .DATA section
• Jump To RAM to
Run Code
Library File (1)

Why use Library Files?
– Share code with others

How to build a library?
ar -r ./mylib.a disp_dat.o sum_dat.o
This command add 2 *.o files into library *.a (create the library
if not found)

How to assign a Library for code building?
gcc -o hello hello.o mylib.a

What’s the standard library?
– glibc
– uclibc
– newlib
Library
File (2)
Library File
1011010101
1010101111
110101111
0000111111
000101111
1110101011
110101111
1111111111
Executable File A
Executable File B
111010111
111001000
111000000
010100000
111000000
010100000
111010111
111001000
111000000
010100000
110101111
111010111
000101111
111001000
111000000
010100000
111010111
110101111
111001000
111000000
010100000
111000000
110101111
010100000
000101111
111010111
111001000
111000000
010100000
111010111
111001000
111000000
010100000
Using GCC (1)

Function Of GCC
– Compile and link Source File

C++
Input File Name
– *.c, *.C, *.cxx, *,cpp, *.hxx, *.hpp, *.h, *.s,
*.S
– Gcc find file type by ther suffix, and will
automatically call related tool
– Any file name with no recognized suffix is
send to linker directly
Gcc example (GCC options)
gcc -o –g hello hello.o mylib.a
 gcc -c –g –O3 –Wall hello.c

Makefile

Why using make command?
– Execute a script, save time
– Explore file dependence, shorten the
compile time
– Provide extra code maintains script
•
•
•
•
Clean built object file
Install output file into desired directory
Build a software in different compile option
..
Example
hello.h
void disp(int c);
hello.c
#include “hello.h”
int main()
{
disp(3);
return 0;
}
disp_dat.c
#include <stdio.h>
void disp(int c)
{
printf(“%d\n”, c);
}
gcc –o hello hello.c disp_dat.c
File Dependence
hello.h
hello.o
hello
gcc
ld
hello.c
disp_dat.o
gcc
disp_dat.c
hello: hello.o disp_dat.o
ld –o hello hello.o disp_dat.o
Makefile
hello.o: hello.c hello.h
gcc –c hello.c
disp_dat.o: disp_dat.c
gcc –c disp_dat.c
make
Details of make and Makefile (1)
# Define macros for name of compiler
CC = gcc
# Define a macr o for the CC flags
CCFLAGS = -D_DEBUG -g -m486
# A rule for building a object file
test.o: test.c test.h
$(CC) -c $(CCFLAGS) test.c
gcc –c –D_DEBUG –g –m486
Details of make and Makefile (2)
clean:
rm -f *.o
rm -f hello_mxl
Detail of make & Makefile (3)
CC
AS
LD
OBJDUMP
BIN
=
=
=
=
=
arm-elf-linux-gcc
arm-elf-linux-gcc
arm-elf-linux-ld
arm-elf-linux-objdump
arm-elf-linux-objcopy
CPFLAGS = -Wall -pipe -g
Detail of
make &
Makefile
(4)
CSRC
ASRC
OBJ
=
=
=
os_cpu.c ucos_ii.c mx1.c dataproc.c init_sect.c
os_cpu_a.s start.s
ucos_ii.o os_cpu_a.o os_cpu.o
\
start.o mx1.o dataproc.o init_sect.o
all: ucos_ii.elf
.c.o:
$(CC) -c $(CPFLAGS) -I$(INCDIR)
$<
$(AS) -c $(ASFLAGS) -I$(INCDIR)
$<
.s.o:
ucos_ii.elf: $(OBJ)
$(LD) $(LDFLAGS) $(OBJ) -o ucos_ii.elf
$(OBJDUMP) -S ucos_ii.elf >> ucos_ii.dasm
$(READELF) -a ucos_ii.elf >> ucos_ii.r
$(NM)
ucos_ii.elf >> ucos_ii.n
clean:
rm
rm
rm
rm
rm
rm
rm
-f
-f
-f
-f
-f
-f
-f
*.o
*.map
*.elf
*.dasm
*~
*.n
*.r
Other GNU Tools

Tar
– tar xvfz foo.tar.gz
– tar cvfz foo.tgz /opt/code

Objdump
– objdump –S foo.elf
– objdump –x foo.elf

Gdb