9. SoC Prgraming using C
9์ฅ SoC Programming using C ๊ฐ์
์๋ฒ ๋๋ SoC ํ๋ก๊ทธ๋๋ฐ์ C ์ธ์ด๋ก ์ํํ๋ ๊ธฐ๋ณธ ๋ฐฉ์. Memory-mapped I/O๋ฅผ ํตํ peripheral ์ ๊ทผ, pointer manipulation, volatile keyword, bit operation, startup sequence, linker script ๋ฑ์ ๋ค๋ฃฌ๋ค.
Memory-Mapped I/O
ARM Cortex-M์์๋ ๋ชจ๋ peripheral์ด ํน์ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์์ ๋งคํ๋์ด ์์. Register์ ์ ๊ทผ = ํด๋น ์ฃผ์์ read/write.
#define GPIO_ODR (*(volatile uint32_t *)0x40020014)
GPIO_ODR = 0x01; // GPIO ์ถ๋ ฅ ์ค์
uint32_t val = GPIO_ODR; // ํ์ฌ ์ํ ์ฝ๊ธฐ
volatile Keyword
- Compiler ์ต์ ํ ๋ฐฉ์ง (์: ๊ฐ์ ์ฃผ์๋ฅผ ๋ ๋ฒ ์ฝ์ ๋ ์๋ต ๊ธ์ง)
- Hardware register๋ ์ธ๋ถ์์ ๋ฐ๋ ์ ์์ผ๋ฏ๋ก ๋ฐ๋์ volatile
volatile uint32_t *GPIO_IDR = (volatile uint32_t *)0x40020010;
while (!(*GPIO_IDR & 0x1)) ; // ๋ฒํผ ๋๋ฆด ๋๊น์ง ๋๊ธฐ
volatile์ด ์์ผ๋ฉด compiler๊ฐ loop ์ต์ ํ๋ก ๋ฌดํ ๋๊ธฐ ๋ฐ์.
Struct ๊ธฐ๋ฐ Register ์ ๊ทผ
๋๊ท๋ชจ peripheral์ struct๋ก ์ ์ (CMSIS style):
typedef struct {
volatile uint32_t MODER; // 0x00
volatile uint32_t OTYPER; // 0x04
volatile uint32_t OSPEEDR; // 0x08
volatile uint32_t PUPDR; // 0x0C
volatile uint32_t IDR; // 0x10
volatile uint32_t ODR; // 0x14
// ...
} GPIO_TypeDef;
#define GPIOA ((GPIO_TypeDef *)0x40020000)
GPIOA->ODR = 0x01;
Bit Operation
Bit Set
GPIOA->ODR |= (1 << 5); // 5๋ฒ bit๋ฅผ 1๋ก
Bit Clear
GPIOA->ODR &= ~(1 << 5); // 5๋ฒ bit๋ฅผ 0์ผ๋ก
Bit Toggle
GPIOA->ODR ^= (1 << 5); // 5๋ฒ bit ๋ฐ์
Bit Check
if (GPIOA->IDR & (1 << 5)) { /* bit 5 is 1 */ }
Multi-bit Field
2-bit field๋ฅผ ๊ฐ val๋ก ์ค์ :
GPIOA->MODER &= ~(0x3 << (pin * 2)); // clear 2 bits
GPIOA->MODER |= (val << (pin * 2)); // set value

Startup Sequence
Reset ์ ํ๋ก์ธ์๊ฐ ์ํํ๋ ์ด๊ธฐํ:
- R13 โ Initial SP (Vector table offset 0x00)
- PC โ Reset handler (offset 0x04)
- Reset handler:
-
.datasection์ Flash์์ RAM์ผ๋ก copy -.bsssection์ 0์ผ๋ก ์ด๊ธฐํ -SystemInit()ํธ์ถ (clock, PLL ์ค์ ) -main()ํธ์ถ
void Reset_Handler(void) {
// Copy .data from Flash to RAM
extern uint32_t _sdata, _edata, _sidata;
uint32_t *src = &_sidata;
uint32_t *dst = &_sdata;
while (dst < &_edata) *dst++ = *src++;
// Zero-init .bss
extern uint32_t _sbss, _ebss;
dst = &_sbss;
while (dst < &_ebss) *dst++ = 0;
SystemInit();
main();
while(1);
}
Linker Script
Memory layout ์ ์:
MEMORY {
FLASH (rx) : ORIGIN <mark class="highlight"><strong><u> 0x08000000, LENGTH </u></strong></mark> 128K
RAM (rwx) : ORIGIN <mark class="highlight"><strong><u> 0x20000000, LENGTH </u></strong></mark> 20K
}
SECTIONS {
.isr_vector : {
KEEP(*(.isr_vector))
} > FLASH
.text : {
*(.text*)
*(.rodata*)
} > FLASH
.data : AT(_sidata) {
_sdata = .;
*(.data*)
_edata = .;
} > RAM
.bss : {
_sbss = .;
*(.bss*)
_ebss = .;
} > RAM
}

CMSIS (Cortex Microcontroller Software Interface Standard)
ARM ํ์ค SW interface:
- Core peripheral access (NVIC, SysTick, SCB)
- Vendor-specific register definitions
- DSP, NN library (option)
์:
#include "stm32f10x.h" // CMSIS device header
int main(void) {
RCC->APB2ENR |= RCC_APB2ENR_IOPCEN; // GPIOC clock enable
GPIOC->CRH = 0x00300000; // PC13 output
while (1) {
GPIOC->ODR ^= (1 << 13); // toggle LED
for (volatile int i = 0; i < 100000; i++); // delay
}
}
Interrupt Handler
CMSIS๋ vector table์ ์๋ ์์ฑ. Handler๋ฅผ ์์ฑ๋ง ํ๋ฉด ์ฐ๊ฒฐ:
void TIM2_IRQHandler(void) {
if (TIM2->SR & TIM_SR_UIF) {
TIM2->SR = ~TIM_SR_UIF; // clear flag
GPIOC->ODR ^= (1 << 13); // toggle LED
}
}
Linker script์์ TIM2_IRQHandler์ ์ฃผ์๊ฐ vector table์ ํด๋น offset์ ๋ฑ๋ก๋จ.
Clock ์ค์
SoC์ clock ์์คํ ์ ๋ณต์ก (HSI, HSE, PLL, AHB/APB prescaler).
void SystemInit(void) {
// Enable HSE
RCC->CR |= RCC_CR_HSEON;
while (!(RCC->CR & RCC_CR_HSERDY));
// Configure PLL
RCC->CFGR = RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL9;
RCC->CR |= RCC_CR_PLLON;
while (!(RCC->CR & RCC_CR_PLLRDY));
// Switch SYSCLK to PLL
RCC->CFGR |= RCC_CFGR_SW_PLL;
}

Debugging Tools
- printf via UART:
syscalls.c์์_write()์ฌ์ ์ - Semihosting: ARM debugger๋ฅผ ํตํด stdout
- SWD (Serial Wire Debug): breakpoint, watchpoint, live register view
- ITM (Instrumentation Trace Macrocell): ๊ณ ์ trace
์ต์ ํ Tips
- Inline: ์งง์ ํจ์๋
static inline์ผ๋ก - volatile์ ๊ผญ ํ์ํ ๊ณณ์๋ง (์ต์ ํ ๋ฐฉํด)
- Cache alignment: DMA buffer๋ cache line์ ์ ๋ ฌ
- -O2 / -Os: gcc ์ต์ ํ ๋ ๋ฒจ, ์๋ฒ ๋๋๋ ํฌ๊ธฐ ์ค์

์ ๋ฆฌ
| ๊ฐ๋ | ํต์ฌ |
|---|---|
| Memory-mapped I/O | Peripheral = ์ฃผ์ |
| volatile | Compiler ์ต์ ํ ๋ฐฉ์ง |
| Struct ์ ๊ทผ | Register group ์ถ์ํ |
| Bit op | Set/Clear/Toggle/Check |
| Startup | Vector table โ Reset handler โ main |
| Linker script | FLASH/RAM layout ์ ์ |
| CMSIS | ARM ํ์ค SW interface |
| Interrupt handler | C ํจ์ + Linker ์ฐ๊ฒฐ |
C๋ก SoC ํ๋ก๊ทธ๋๋ฐ์ hardware level์ C pointer๋ก ์ถ์ํํ๋ ์์ . volatile, struct, bit op๋ฅผ ์๋ฌํ๋ฉด ์ด๋ค MCU๋ ์ง์ ์ ์ดํ ์ ์๋ค.

Comments (0)
No comments yet. Be the first to comment!
Please to write a comment.