Chapter 03 - Hongjayeong-02/Basic_SoC_implementation GitHub Wiki
03. Build Process & GNU Toolchain
Goal
Understand what actually happens when an embedded C project is built.
In this chapter:
- Build the Ch02 program without relying on an IDE build button
- Run each GNU ARM toolchain stage manually
- Inspect
.i,.s,.o,.elf, and.hex - Understand compiler options for Cortex-M4
- Inspect generated machine code with
objdump - Understand where compile errors and link errors occur
1. Why Study the Build Process?
STM32CubeIDE์์๋ ๋ณดํต:
Build
๋ฒํผ ํ ๋ฒ์ผ๋ก ํ๋ก๊ทธ๋จ์ด ๋ง๋ค์ด์ง๋ค.
ํ์ง๋ง ์ค์ ๋ด๋ถ์์๋ ์ฌ๋ฌ ๋จ๊ณ๊ฐ ์์๋๋ก ์คํ๋๋ค.
main.c
โ
โผ
Preprocessor
โ
โผ
main.i
โ
โผ
Compiler
โ
โผ
main.s
โ
โผ
Assembler
โ
โผ
main.o
โ
โผ
Linker
โ
โผ
program.elf
โ
โผ
objcopy
โ
โโโ program.hex
โโโ program.bin
์ด ๊ณผ์ ์ ์์์ผ ๋ค์๊ณผ ๊ฐ์ ์ค๋ฅ๊ฐ ์ด๋ ๋จ๊ณ์์ ๋ฐ์ํ๋์ง ํ๋จํ ์ ์๋ค.
syntax error
undefined reference
multiple definition
region FLASH overflowed
section overlaps
์๋ฅผ ๋ค์ด:
undefined reference to `foo`
๋ C ๋ฌธ๋ฒ ์ค๋ฅ๊ฐ ์๋๋ค.
๊ฐ .c ํ์ผ์ ์ ์์ ์ผ๋ก compile๋์์ง๋ง, link ๋จ๊ณ์์ foo์ ์ค์ ์ ์๋ฅผ ์ฐพ์ง ๋ชปํ๋ค๋ ๋ป์ด๋ค.
2. GNU ARM Embedded Toolchain
STM32F439ZI๋ ARM Cortex-M4 ๊ธฐ๋ฐ MCU์ด๋ฏ๋ก ์ผ๋ฐ PC์ฉ GCC๊ฐ ์๋๋ผ ARM target์ฉ cross compiler๋ฅผ ์ฌ์ฉํ๋ค.
๋ํ ๋ช ๋ น:
arm-none-eabi-gcc
arm-none-eabi-as
arm-none-eabi-ld
arm-none-eabi-objcopy
arm-none-eabi-objdump
arm-none-eabi-size
3. What Does arm-none-eabi Mean?
Toolchain prefix:
arm-none-eabi
๋ฅผ ๋ถํดํ๋ฉด ๋ค์๊ณผ ๊ฐ์ด ์ดํดํ ์ ์๋ค.
arm
โ
โโโ Target architecture
none
โ
โโโ No operating-system dependency
eabi
โ
โโโ Embedded Application Binary Interface
์ฆ:
ARM ๊ธฐ๋ฐ bare-metal embedded system์ ์ํ toolchain
์ด๋ผ๊ณ ์ดํดํ๋ฉด ๋๋ค.
PC์์ GCC๋ฅผ ์คํํ์ง๋ง ์์ฑ๋๋ machine code๋ x86์ด ์๋๋ผ ARM Cortex-M4์ฉ ์ฝ๋๋ค.
Development PC
x86/x64
โ
โ arm-none-eabi-gcc
โผ
ARM Machine Code
โ
โผ
STM32F439ZI
์ด๊ฒ์ด Cross Compilation์ด๋ค.
4. Full Build Pipeline
์ด๋ฒ ์ค์ต์์๋ ๋ค์ 5๋จ๊ณ๋ฅผ ์ง์ ์คํํ๋ค.
1. Preprocessing
2. Compilation
3. Assembly
4. Linking
5. Binary/Image Generation
๊ฐ ๋จ๊ณ์ ์ ๋ ฅ๊ณผ ์ถ๋ ฅ:
main.c
โ preprocessing
main.i
โ compilation
main.s
โ assembly
main.o
โ linking
ch03_build.elf
โ objcopy
ch03_build.hex
5. Practice Source Code
Ch03์์๋ Ch02์์ ์ฌ์ฉํ LED blink source๋ฅผ ๊ทธ๋๋ก ์ฌ์ฉํ๋ค.
main.c
#define PERIPH_BASE (0x40000000UL)
#define AHB1PERIPH_BASE (PERIPH_BASE + 0x00020000UL)
#define RCC_BASE (AHB1PERIPH_BASE + 0x3800UL)
#define GPIOB_BASE (AHB1PERIPH_BASE + 0x0400UL)
/* Register mapping */
#define RCC_AHB1ENR (*(volatile unsigned int *)(RCC_BASE + 0x30UL))
#define GPIOB_MODER (*(volatile unsigned int *)(GPIOB_BASE + 0x00UL))
#define GPIOB_ODR (*(volatile unsigned int *)(GPIOB_BASE + 0x14UL))
/* Bit definitions */
#define GPIOBEN (1UL << 1)
#define LD1_PIN (1UL << 0)
static void delay(volatile unsigned int count)
{
while (count--)
{
__asm__("nop");
}
}
int main(void)
{
/* Enable GPIOB clock */
RCC_AHB1ENR |= GPIOBEN;
/* PB0 -> General Purpose Output */
GPIOB_MODER &= ~(0x3UL << (0 * 2));
GPIOB_MODER |= (0x1UL << (0 * 2));
while (1)
{
GPIOB_ODR ^= LD1_PIN;
delay(800000);
}
}
The hardware operation is unchanged from Chapter 02.
The focus of this chapter is:
How does main.c become machine code?
6. Stage 1 โ Preprocessing
Command:
arm-none-eabi-gcc \
-mcpu=cortex-m4 \
-mthumb \
-mfloat-abi=soft \
-E main.c \
-o main.i
Input:
main.c
Output:
main.i
7. What Does the Preprocessor Do?
Preprocessor๋ ์ค์ C compiler๋ณด๋ค ๋จผ์ ๋์ํ๋ค.
์ฃผ์ ์์ :
#include
#define
#if
#ifdef
#ifndef
๋ฑ์ ์ฒ๋ฆฌํ๋ค.
๊ฐ์ฅ ์ค์ํ ์ :
Preprocessor๋ C ๋ฌธ๋ฒ์ ์๋ฏธ๋ฅผ ์ดํดํ๋ compiler๊ฐ ์๋๋ค.
์ฃผ๋ก text substitution์ ์ํํ๋ค.
์๋ฅผ ๋ค์ด:
#define GPIOBEN (1UL << 1)
RCC_AHB1ENR |= GPIOBEN;
๋ preprocessing ํ ๊ฐ๋ ์ ์ผ๋ก:
RCC_AHB1ENR |= (1UL << 1);
์ฒ๋ผ ์นํ๋๋ค.
8. Register Macro Expansion
Ch02์์ ์ฌ์ฉํ:
#define GPIOB_ODR \
(*(volatile unsigned int *)(GPIOB_BASE + 0x14UL))
๋ preprocessing ๋จ๊ณ์์ ์นํ๋๋ค.
๊ทธ๋ฆฌ๊ณ :
#define GPIOB_BASE \
(AHB1PERIPH_BASE + 0x0400UL)
๋ฑ๋ ์ฐ์์ ์ผ๋ก ์นํ๋๋ค.
๊ฒฐ๊ตญ compiler๊ฐ ๋ณด๋ ์ฝ๋๋ ๊ฐ๋ ์ ์ผ๋ก ๋ค์๊ณผ ๊ฐ๊น์์ง๋ค.
(*(volatile unsigned int *)
((0x40000000UL + 0x00020000UL)
+ 0x0400UL
+ 0x14UL))
^= (1UL << 0);
์ฆ #define์ ์๋ก์ด ๋ณ์๋ ํจ์๋ฅผ ๋ง๋๋ ๊ฒ์ด ์๋๋ค.
Source Text
โ
Preprocessor
โ
Expanded Source Text
์ด๋ค.
9. Inspecting main.i
์์ฑ๋ ํ์ผ ํ์ธ:
less main.i
๋๋:
head main.i
.i ํ์ผ์ preprocessing์ด ๋๋ C source๋ค.
์์ง ARM assembly๋ ์๋๊ณ machine code๋ ์๋๋ค.
main.c
โ
โ #define / #include expanded
โผ
main.i
10. Stage 2 โ Compilation
Command:
arm-none-eabi-gcc \
-mcpu=cortex-m4 \
-mthumb \
-mfloat-abi=soft \
-S main.i \
-o main.s
Input:
main.i
Output:
main.s
11. What Does the Compiler Do?
Compiler๋ C ์ธ์ด๋ฅผ target processor์ assembly language๋ก ๋ณํํ๋ค.
C
โ
Compiler
โ
ARM / Thumb Assembly
์๋ฅผ ๋ค์ด C ์ฝ๋:
count--;
๋ architecture์ optimization์ ๋ฐ๋ผ assembly์์:
subs r3, r3, #1
๊ฐ์ instruction์ผ๋ก ๋ฐ๋ ์ ์๋ค.
๊ทธ๋ฆฌ๊ณ :
while (count--)
๊ฐ์ ๊ตฌ์กฐ๋ ์ผ๋ฐ์ ์ผ๋ก:
subtract
compare
branch
๊ณ์ด instruction์ผ๋ก ๊ตฌํ๋๋ค.
12. C Control Flow vs CPU Instructions
C์์๋:
while (count--)
{
__asm__("nop");
}
๋ผ๊ณ ์์ฑํ์ง๋ง CPU๋ while์ด๋ผ๋ ๊ฐ๋
์ ๋ชจ๋ฅธ๋ค.
CPU๊ฐ ์ดํดํ๋ ๊ฒ์:
Load
Subtract
Compare
Branch
๊ฐ์ instruction๋ฟ์ด๋ค.
๊ฐ๋ ์ ์ผ๋ก:
while(count--)
โ
โผ
load count
โ
โผ
subtract
โ
โผ
compare with zero
โ
โผ
branch if not finished
์ด๋ค.
์ด ๋ถ๋ถ์ด C programming๊ณผ Computer Architecture๊ฐ ์ง์ ์ฐ๊ฒฐ๋๋ ์ง์ ์ด๋ค.
13. Inspecting main.s
less main.s
๋๋:
grep -A30 main main.s
์ค์ assembly๋ฅผ ํ์ธํ๋ฉด:
C variable
C loop
C pointer access
๊ฐ Cortex-M4 instruction์ผ๋ก ์ด๋ป๊ฒ ๋ณํ๋๋์ง ๋ณผ ์ ์๋ค.
14. Stage 3 โ Assembly
Command:
arm-none-eabi-gcc \
-mcpu=cortex-m4 \
-mthumb \
-mfloat-abi=soft \
-c main.s \
-o main.o
Input:
main.s
Output:
main.o
15. What Does the Assembler Do?
Assembler๋ assembly instruction์ machine code๋ก ๋ณํํ๋ค.
ARM Assembly
โ
Assembler
โ
Binary Machine Instructions
์:
nop
๊ฐ์ assembly mnemonic์ด ์ค์ CPU๊ฐ ์คํํ binary instruction์ผ๋ก encoding๋๋ค.
ํ์ง๋ง .o ํ์ผ์ ์์ง ์์ ํ ์คํ ์ด๋ฏธ์ง๊ฐ ์๋๋ค.
16. What Is an Object File?
main.o๋ object file์ด๋ค.
Object file์๋ ๋ณดํต ๋ค์ ์ ๋ณด๊ฐ ๋ค์ด์๋ค.
Machine Code
Sections
Symbols
Relocation Information
Debug Information
์ค์ํ ์ :
.o์๋ machine code๊ฐ ์กด์ฌํ์ง๋ง ์์ง ์ต์ข ์ฃผ์๊ฐ ํ์ ๋์ง ์์ symbol์ด ์์ ์ ์๋ค.
์๋ฅผ ๋ค์ด:
foo();
๋ฅผ ํธ์ถํ๋ค๊ณ ํ์.
Compiler์ assembler๋:
foo๋ผ๋ symbol์ ํธ์ถํ๋ค
๋ ์ ๋ณด๋ ๋ง๋ค ์ ์๋ค.
๊ทธ๋ฌ๋ foo()๊ฐ ๋ค๋ฅธ object file์ ์ ์๋์ด ์๋ค๋ฉด ์ค์ ์ฃผ์๋ ์์ง ์ ์ ์๋ค.
main.o
โโโ needs symbol: foo
foo.o
โโโ defines symbol: foo
์ด ๋์ ์ฐ๊ฒฐํ๋ ๋จ๊ณ๊ฐ Linking์ด๋ค.
17. Object File Is Not a Flash Image
.o๋ ๋ฐ๋ก MCU Flash์ ์ธ ํ์ผ์ด ์๋๋ค.
main.o
startup.o
driver.o
...
๊ฐ object file์ ์์ง ๋ถ๋ฆฌ๋์ด ์๋ค.
๋ฐ๋ผ์ ๋ค์ ๋จ๊ณ์์ linker๊ฐ ํฉ์ณ์ผ ํ๋ค.
18. Inspecting main.o
Disassemble:
arm-none-eabi-objdump -d main.o
์ด ๋ช ๋ น์ object file ์์ machine code๋ฅผ ์ฌ๋์ด ์ฝ๊ธฐ ์ฌ์ด assembly ํํ๋ก ๋ค์ ๋ณด์ฌ์ค๋ค.
Machine Code
โ
objdump
โ
Assembly View
์ด ๊ณผ์ ์ Disassembly๋ผ๊ณ ํ๋ค.
19. objdump Example
Notion ์ค์ต์์๋ delay()์:
while (count--)
๊ฐ ์ค์ ๋ก ์ ์์ค์์:
subtract
compare
conditional branch
ํํ์ instruction์ผ๋ก ๋ฐ๋๋ ๊ฒ์ ํ์ธํ๋ค.
์ค์ instruction์ compiler option์ ๋ฐ๋ผ ๋ฌ๋ผ์ง ์ ์์ง๋ง ๋ํ์ ์ผ๋ก:
subs
cmp
bne
๊ฐ์ instruction์ ๋ณผ ์ ์๋ค.
20. Stage 4 โ Linking
Command:
arm-none-eabi-gcc \
-mcpu=cortex-m4 \
-mthumb \
-mfloat-abi=soft \
-T linker.ld \
main.o \
startup.o \
-o ch03_build.elf
Input:
main.o
startup.o
linker.ld
Output:
ch03_build.elf
21. What Does the Linker Do?
Linker์ ์ค์ํ ์ญํ ์ ํฌ๊ฒ ์ธ ๊ฐ์ง๋ค.
1. Combine Object Files
main.o
startup.o
other.o
โ
โผ
Linker
โ
โผ
One Executable Image
2. Resolve Symbols
์:
main.o
โโโ references Reset_Handler
startup.o
โโโ defines Reset_Handler
ํน์ ๋ฐ๋๋ก startup code๊ฐ:
main
symbol์ ์ฐธ์กฐํ๋ค.
Linker๊ฐ ์ค์ ์ฃผ์๋ฅผ ์ฐพ์ ์ฐ๊ฒฐํ๋ค.
3. Place Sections in Memory
.text
.rodata
.data
.bss
.vector_table
๋ฑ์ ์ค์ FLASH / SRAM address์ ๋ฐฐ์นํ๋ค.
์ด ์์น๋ฅผ ์ง์ ํ๋ ๊ฒ์ด:
linker.ld
์ฆ Linker Script๋ค.
22. Why Is a Linker Script Required?
PC ํ๋ก๊ทธ๋จ์ Operating System๊ณผ runtime environment๊ฐ ๋ง์ ๋ถ๋ถ์ ๊ด๋ฆฌํ๋ค.
Bare-metal MCU๋ ๊ทธ๋ ์ง ์๋ค.
์ฐ๋ฆฌ๊ฐ ์ง์ ์๋ ค์ค์ผ ํ๋ค.
์:
FLASH starts here
FLASH size is this
RAM starts here
RAM size is this
.text goes to FLASH
.data initial image goes to FLASH
.data runtime location goes to RAM
.bss goes to RAM
์ด๋ฅผ linker์๊ฒ ์๋ ค์ฃผ๋ ํ์ผ์ด:
linker.ld
์ด๋ค.
Chapter 04์์ ์ง์ ์์ฑํ๋ค.
23. STM32F439ZI Memory Concept
๊ฐ๋ ์ ์ผ๋ก:
FLASH
0x08000000
โ
โโโ Vector Table
โโโ .text
โโโ .rodata
โโโ Initial values for .data
SRAM
0x20000000
โ
โโโ .data
โโโ .bss
โโโ Heap
โโโ Stack
์ฒ๋ผ code์ data๊ฐ ์๋ก ๋ค๋ฅธ memory ์์ญ์ ๋ฐฐ์น๋๋ค.
์ ํํ section placement๋ linker script๊ฐ ๊ฒฐ์ ํ๋ค.
24. Why startup.o Is Needed
Bare-metal MCU์์ processor๋ power-on ์งํ ๋ฐ๋ก main()์ ์คํํ์ง ์๋๋ค.
๋๋ต:
RESET
โ
Vector Table
โ
Initial Stack Pointer
โ
Reset_Handler
โ
Runtime Initialization
โ
main()
๋ฐ๋ผ์ Reset_Handler์ vector table์ ๊ฐ์ง startup code๊ฐ ํ์ํ๋ค.
Chapter 03์์๋ ๊ธฐ์กด startup object๋ฅผ ์ฌ์ฉํ๊ณ , ์์ธํ ๊ตฌํ์ Chapter 04์์ ๋ค๋ฃฌ๋ค.
25. Link Error Example
Suppose:
void foo(void);
int main(void)
{
foo();
}
๊ทธ๋ฐ๋ฐ ์ด๋์๋:
void foo(void)
{
}
๊ฐ ์๋ค๋ฉด compiler๋ prototype์ ์๊ณ ์๊ธฐ ๋๋ฌธ์ compile์ ๊ฐ๋ฅํ๋ค.
ํ์ง๋ง linker๋ ์ค์ foo implementation์ ์ฐพ์ง ๋ชปํ๋ค.
๊ฒฐ๊ณผ:
undefined reference to `foo'
์ฆ:
Compile
PASS
โ
Link
FAIL
์ด๋ค.
26. Compile Error vs Link Error
Compile Error
Examples:
syntax error
undeclared identifier
wrong type
missing semicolon
๋ณดํต:
.c โ .o
๊ณผ์ ์์ ์คํจํ๋ค.
Link Error
Examples:
undefined reference
multiple definition
region overflowed
๋ณดํต:
.o files โ .elf
๊ณผ์ ์์ ์คํจํ๋ค.
์ด ์ฐจ์ด๋ฅผ ์๋ ๊ฒ์ด build debugging์์ ๋งค์ฐ ์ค์ํ๋ค.
27. ELF File
Linking์ด ์ฑ๊ณตํ๋ฉด:
ch03_build.elf
๊ฐ ์์ฑ๋๋ค.
ELF:
Executable and Linkable Format
์ด๋ค.
ELF์๋ ๋จ์ machine code ์ธ์๋ ์ฌ๋ฌ ์ ๋ณด๊ฐ ํฌํจ๋ ์ ์๋ค.
Executable Code
Data
Sections
Symbols
Debug Information
Address Information
๋ฐ๋ผ์ debugger๊ฐ:
main()
uart_init()
line 37
variable x
๋ฑ์ ์ฐพ์ ์ ์๋ค.
28. Inspecting ELF Size
Command:
arm-none-eabi-size ch03_build.elf
์ค์ต ๊ฒฐ๊ณผ:
text data bss
252 0 0
Meaning:
text
Program code and read-only data.
์ฃผ๋ก Flash์ ์์นํ๋ค.
data
์ด๊ธฐ๊ฐ์ด ์๋ global/static variable.
Example:
int count = 10;
์ด๊ธฐ๊ฐ์ Flash image ์์ ์ ์ฅ๋์ด ์๊ณ runtime์๋ RAM์ผ๋ก ๋ณต์ฌ๋๋ค.
bss
์ด๊ธฐ๊ฐ์ด ์๊ฑฐ๋ 0์ผ๋ก ์ด๊ธฐํ๋๋ global/static variable.
Example:
int count;
๋ณดํต Flash image์ ์ค์ 0 ๋ฐ์ดํฐ๋ฅผ ์ ๋ถ ์ ์ฅํ๋ ๋์ :
์ด ์์ญ์ startup์์ 0์ผ๋ก ์ด๊ธฐํํ๋ผ
๋ ์ ๋ณด๋ง ๊ฐ์ง๋ค.
29. Why Is .data = 0 and .bss = 0?
์ด๋ฒ Ch02/Ch03 source๋ global variable์ ๊ฑฐ์ ์ฌ์ฉํ์ง ์๋๋ค.
Registers๋:
#define
macro์ด๊ณ ์ค์ RAM variable์ด ์๋๋ค.
์:
#define GPIOB_ODR \
(*(volatile unsigned int *)0x40020414UL)
๋ RAM ๊ณต๊ฐ์ ์ฐจ์งํ๋ ์ ์ญ ๋ณ์๊ฐ ์๋๋ค.
๋ฐ๋ผ์:
data = 0
bss = 0
์ด ๋์ค๋ ๊ฒ์ด ์์ฐ์ค๋ฝ๋ค.
30. Stage 5 โ Generate Flash Image
Command:
arm-none-eabi-objcopy \
-O ihex \
ch03_build.elf \
ch03_build.hex
Input:
ch03_build.elf
Output:
ch03_build.hex
31. What Does objcopy Do?
ELF์๋ flashing์ ํ์ํ์ง ์์ ์ ๋ณด๋ ๋ง์ด ํฌํจ๋์ด ์๋ค.
์:
debug symbols
section metadata
symbol names
source mapping
Flash programmer๊ฐ ํ์ํ ๊ฒ์ ์ค์ MCU memory์ ๊ธฐ๋กํ content๋ค.
๋ฐ๋ผ์:
ELF
โ
โ objcopy
โผ
Flash Image
๋ก ๋ณํํ๋ค.
32. HEX vs BIN
Intel HEX
ch03_build.hex
Text-based format.
๋ด์ฉ์๋:
Address
Data
Record Type
Checksum
๋ฑ์ด ํฌํจ๋๋ค.
์:
:1000000068030020650100006D0100006F01000021
์ฌ๋์ด text file๋ก ์ด ์ ์๋ค.
Binary
Binary image๋ฅผ ๋ง๋ค๋ ค๋ฉด:
arm-none-eabi-objcopy \
-O binary \
ch03_build.elf \
ch03_build.bin
.bin์ ์์ binary byte stream์ด๋ค.
HEX
โ address information included
BIN
โ raw bytes only
33. Complete Practice Build Script
Notion Ch03์์ ์ฌ์ฉํ ํต์ฌ build sequence:
arm-none-eabi-gcc \
-mcpu=cortex-m4 \
-mthumb \
-mfloat-abi=soft \
-E main.c \
-o main.i
arm-none-eabi-gcc \
-mcpu=cortex-m4 \
-mthumb \
-mfloat-abi=soft \
-S main.i \
-o main.s
arm-none-eabi-gcc \
-mcpu=cortex-m4 \
-mthumb \
-mfloat-abi=soft \
-c main.s \
-o main.o
arm-none-eabi-gcc \
-mcpu=cortex-m4 \
-mthumb \
-mfloat-abi=soft \
-T linker.ld \
main.o startup.o \
-o ch03_build.elf
arm-none-eabi-objcopy \
-O ihex \
ch03_build.elf \
ch03_build.hex
34. Recommended build.sh
The same sequence can be written as:
#!/bin/bash
CPU="-mcpu=cortex-m4"
THUMB="-mthumb"
FLOAT="-mfloat-abi=soft"
echo "[1] Preprocess"
arm-none-eabi-gcc \
$CPU $THUMB $FLOAT \
-E main.c \
-o main.i
echo "[2] Compile"
arm-none-eabi-gcc \
$CPU $THUMB $FLOAT \
-S main.i \
-o main.s
echo "[3] Assemble"
arm-none-eabi-gcc \
$CPU $THUMB $FLOAT \
-c main.s \
-o main.o
echo "[4] Link"
arm-none-eabi-gcc \
$CPU $THUMB $FLOAT \
-T linker.ld \
main.o startup.o \
-o ch03_build.elf
echo "[5] Generate HEX"
arm-none-eabi-objcopy \
-O ihex \
ch03_build.elf \
ch03_build.hex
echo "[6] Size"
arm-none-eabi-size ch03_build.elf
Execute:
chmod +x build.sh
./build.sh
35. Compiler Option โ -mcpu=cortex-m4
-mcpu=cortex-m4
Compiler์๊ฒ target CPU architecture๋ฅผ ์๋ ค์ค๋ค.
STM32F439ZI core:
ARM Cortex-M4
๋ฐ๋ผ์ compiler๋ Cortex-M4๊ฐ ์ง์ํ๋ instruction์ ๊ธฐ์ค์ผ๋ก code๋ฅผ ์์ฑํ๋ค.
์๋ชป๋ CPU option์ ์ ํํ๋ฉด:
- ์ง์ํ์ง ์๋ instruction ์์ฑ
- ์ต์ ํ ๋ฐฉ์ ์ฐจ์ด
- architecture incompatibility
๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์๋ค.
36. Compiler Option โ -mthumb
-mthumb
Thumb instruction set์ ์ฌ์ฉํ๋๋ก ์ง์ ํ๋ค.
Cortex-M series๋ Thumb instruction execution์ ๊ธฐ๋ฐ์ผ๋ก ํ๋ค.
C Source
โ
Thumb Instructions
โ
Cortex-M4
๋ฐ๋ผ์ STM32 firmware build์์๋ ์ผ๋ฐ์ ์ผ๋ก ํ์ํ option์ด๋ค.
37. Compiler Option โ -mfloat-abi
Ch03 practice:
-mfloat-abi=soft
๋ฅผ ์ฌ์ฉํ๋ค.
ํ์ฌ code๋:
GPIO register access
integer operation
bit operation
๋ง ์ฌ์ฉํ๋ฏ๋ก hardware floating-point unit์ ์ฌ์ฉํ ํ์๊ฐ ์๋ค.
38. STM32F439ZI FPU
STM32F439ZI์ Cortex-M4 core๋ hardware floating-point support๋ฅผ ์ ๊ณตํ๋ค.
Floating-point๋ฅผ ์ค์ hardware FPU๋ก ์ฒ๋ฆฌํ๋ ค๋ฉด ์ผ๋ฐ์ ์ผ๋ก ๋ค์๊ณผ ๊ฐ์ option ์กฐํฉ์ ์ฌ์ฉํ ์ ์๋ค.
-mfloat-abi=hard
-mfpu=fpv4-sp-d16
๊ฐ๋ :
soft
โโโ Floating-point ABI does not require hardware FPU instructions
hard
โโโ Hardware FPU calling convention / instructions used
์ค์ํ ์ ์ object files์ libraries๊ฐ ํธํ๋๋ ABI ์ค์ ์ ์ฌ์ฉํด์ผ ํ๋ค๋ ๊ฒ์ด๋ค.
์๋ก ๋ค๋ฅธ floating-point ABI์ object/library๋ฅผ ์์ผ๋ฉด link ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์๋ค.
39. gcc vs as vs ld
GNU toolchain์๋ ๊ฐ๊ฐ ๋ ๋ฆฝ๋ ํ๋ก๊ทธ๋จ์ด ์กด์ฌํ๋ค.
gcc
as
ld
ํ์ง๋ง ์ค์ต์์๋ ๋๋ถ๋ถ:
arm-none-eabi-gcc
driver๋ฅผ ์ฌ์ฉํ๋ค.
gcc driver๋ option์ ๋ฐ๋ผ ๋ด๋ถ์ ์ผ๋ก ํ์ํ tool์ ํธ์ถํ๋ค.
์:
gcc -c main.s
๋ ๋ด๋ถ์ ์ผ๋ก assembler๋ฅผ ์ฌ์ฉํ๋ค.
๊ทธ๋ฆฌ๊ณ :
gcc main.o startup.o -o app.elf
๋ linker๋ฅผ ํธ์ถํ๋ค.
๋ฐ๋ผ์:
GCC๋ ๋จ์ํ C compiler ํ๋๋ง ์๋ฏธํ๋ ๊ฒ์ด ์๋๋ผ build toolchain์ driver ์ญํ ๋ ํ๋ค.
40. Source File to CPU Execution
์ ์ฒด ๊ณผ์ ์ hardware ๊ด์ ๊น์ง ์ฐ๊ฒฐํ๋ฉด:
main.c
โ
โผ
Preprocessor
โ
โผ
Compiler
โ
โผ
ARM Assembly
โ
โผ
Assembler
โ
โผ
Machine Code
โ
โผ
Linker
โ
โผ
Absolute Memory Layout
โ
โผ
ELF
โ
โผ
HEX / BIN
โ
โผ
FLASH
โ
โผ
Cortex-M4 Instruction Fetch
โ
โผ
Execution
์ฆ ์ฐ๋ฆฌ๊ฐ ์์ฑํ C code๊ฐ ์ต์ข ์ ์ผ๋ก๋ Flash memory์ ์ ์ฅ๋ machine instruction์ด ๋๋ค.
41. Build Result
Notion์ ๊ธฐ๋ก๋ Ch03 ๊ฒฐ๊ณผ:
text : 252 bytes
data : 0 bytes
bss : 0 bytes
Ch02์ Makefile build ๊ฒฐ๊ณผ์ ๋์ผํ๋ค.
Ch02
Makefile
โ
โโโ 252 / 0 / 0
Ch03
Manual Toolchain
โ
โโโ 252 / 0 / 0
๊ฐ์ source์ ๊ฐ์ build configuration์ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ๋์ผํ result๊ฐ ๋์จ๋ค.
์ด ์ค์ต์ ํต์ฌ์:
IDE๋ Make๊ฐ ํน๋ณํ binary๋ฅผ ๋ง๋๋ ๊ฒ์ด ์๋๋ผ, ๊ฒฐ๊ตญ ๋์ผํ compiler / assembler / linker๋ฅผ ์์๋๋ก ์คํํ๋ค.
๋ ๊ฒ์ ํ์ธํ ๊ฒ์ด๋ค.
42. Useful Inspection Commands
Preprocessed C
less main.i
Generated Assembly
less main.s
Object Disassembly
arm-none-eabi-objdump -d main.o
ELF Disassembly
arm-none-eabi-objdump -d ch03_build.elf
Section Headers
arm-none-eabi-objdump -h ch03_build.elf
Symbols
arm-none-eabi-nm ch03_build.elf
Program Size
arm-none-eabi-size ch03_build.elf
HEX Preview
head ch03_build.hex
์ด ๋ช ๋ น๋ค์ ๊ฐ์ด ์ตํ๋๋ฉด build/debugging ๋ ๋งค์ฐ ์ ์ฉํ๋ค.
43. Common Error Mapping
Build error๋ฅผ ๋ณด๋ฉด ์ด๋ ๋จ๊ณ๋ฅผ ๋จผ์ ์์ฌํด์ผ ํ๋์ง ์ ๋ฆฌํ๋ฉด:
#include file not found
โ
Preprocessor
syntax error
type error
undeclared identifier
โ
Compiler
invalid instruction
โ
Assembler
undefined reference
multiple definition
FLASH overflow
RAM overflow
โ
Linker
HEX conversion failure
โ
objcopy
44. undefined reference
Example:
undefined reference to `MYX_LWIP_Init'
์ด ์ข ๋ฅ์ error๋ ๋ํ์ ์ธ linker error๋ค.
์๋ฏธ:
Function call exists
โ
Compiler accepts it
โ
Object file references symbol
โ
Linker searches definition
โ
Definition not found
โ
FAIL
๋ฐ๋ผ์ ์ด ์ค๋ฅ์์๋:
C syntax
๋ณด๋ค:
source file included?
object file generated?
function actually defined?
library linked?
๋ฅผ ํ์ธํด์ผ ํ๋ค.
45. multiple definition
๋ object file์ด ๊ฐ์ global symbol์ ์ ์ํ๋ฉด:
file1.o
โโโ foo
file2.o
โโโ foo
linker๊ฐ ์ด๋ ๊ฒ์ ์ฌ์ฉํ ์ง ๊ฒฐ์ ํ ์ ์๋ค.
๋ฐ๋ผ์:
multiple definition of `foo'
๊ฐ ๋ฐ์ํ ์ ์๋ค.
46. region overflowed
Linker script๊ฐ:
FLASH size
RAM size
๋ฅผ ์ ์ํ๋ค.
Program section์ด ํด๋น memory region๋ณด๋ค ์ปค์ง๋ฉด:
region `FLASH' overflowed
๊ฐ์ link error๊ฐ ๋ฐ์ํ๋ค.
๋ฐ๋ผ์ ์ด ์ค๋ฅ๋ compile ๋ฌธ์ ๊ฐ ์๋๋ผ memory placement ๋ฌธ์ ๋ค.
47. Makefile and IDE Relationship
์ด๋ฒ ์ค์ต์์๋ ์ง์ ๋ช ๋ น์ด๋ฅผ ์คํํ์ง๋ง ์ค์ project์์๋ ๋ณดํต:
Makefile
IDE
CMake
Build Script
๋ฑ์ด ๋์ผํ ๋ช ๋ น์ ์๋์ผ๋ก ๊ด๋ฆฌํ๋ค.
Manual Commands
โ
Shell Script
โ
Makefile
โ
IDE Build System
์ถ์ํ ์์ค๋ง ๋ค๋ฅผ ๋ฟ underlying build flow๋ ๊ฐ๋ค.
48. Key Questions
Q1. What is the complete build order?
Preprocess
โ
Compile
โ
Assemble
โ
Link
โ
Generate Flash Image
Q2. What does .i contain?
Preprocessed C source.
#define expanded
#include expanded
Q3. What does .s contain?
Target assembly code generated by the compiler.
For STM32F439ZI:
ARM Cortex-M4 / Thumb assembly
Q4. What does .o contain?
Machine code plus section, symbol and relocation information.
It is not yet the final firmware image.
Q5. What does .elf contain?
Linked executable information including:
- machine code
- section layout
- addresses
- symbols
- optional debug information
Q6. Why generate .hex?
Because a programmer/debugger needs an image describing the bytes to write into MCU memory.
Q7. What is the difference between .elf and .hex?
ELF
โโโ machine code
โโโ symbols
โโโ sections
โโโ addresses
โโโ debug information
HEX
โโโ memory addresses
โโโ data
โโโ checksum
Q8. Why can F439ZI use hardware floating point?
Because the Cortex-M4 implementation in STM32F439ZI includes an FPU.
For hardware-FPU builds, compatible options such as:
-mfloat-abi=hard
-mfpu=fpv4-sp-d16
can be used.
Q9. What stage causes undefined reference?
Linking
Q10. Why learn this if the IDE already builds automatically?
Because understanding the build stages makes errors much easier to diagnose.
Error Message
โ
Identify Build Stage
โ
Identify Responsible File / Tool
โ
Fix Root Cause
49. Key Takeaways
C Source
โ
Preprocessor
โ
Expanded C
โ
Compiler
โ
Assembly
โ
Assembler
โ
Object File
โ
Linker + Linker Script
โ
ELF
โ
objcopy
โ
HEX / BIN
โ
MCU Flash
The most important concepts are:
- A build is not one operation.
- Each intermediate file has a different purpose.
- Compilation and linking are separate processes.
- Object files can contain unresolved symbols.
- The linker resolves symbols and assigns addresses.
- The linker script defines the MCU memory layout.
- ELF is useful for debugging and analysis.
- HEX/BIN are used as programming images.
objdump,nm, andsizeare essential low-level debugging tools.- IDE, Makefile, and shell scripts eventually invoke the same toolchain.