# STM32 Startup code 분석 (2부) \# 본 글은 ARM Cortex-M serise의 Interrupt vector table에 관하여 다룬다. ## 1. Interrupt Vector Table 이란? Interrupt Vector Table, 줄여서 IVT란 'Interrupt Handler'들과 'Interrupt Request'들을 IVT형태로 연관짓는 data structure을 의미한다. 다시 말하자면, Interrupt Vector라고 부르는 IVT의 각 항목은 Interrupt Handler의 주소이다. Cortex-M7의 경우 다음과 같이 Vector Table이 구성된다. ![](https://i.imgur.com/E0g2HZn.png) 출처: PM0253 ## 2. IVT 실제 구성 Startup code에는 system을 초기화하고 main으로 점프하게 해주는 Reset Handler 이외에 IVT를 일종의 함수 포인터의 배열로 정의하는 내용이 있다. 아래의 코드는 STM32H743ZI의 "stm32h743zitx.s"에서 발췌한 코드이다. ``` /****************************************************************************** * * The STM32H743ZITx vector table. Note that the proper constructs * must be placed on this to ensure that it ends up at physical address * 0x0000.0000. * ******************************************************************************/ .section .isr_vector,"a",%progbits .type g_pfnVectors, %object .size g_pfnVectors, .-g_pfnVectors g_pfnVectors: .word _estack .word Reset_Handler .word NMI_Handler .word HardFault_Handler .word MemManage_Handler .word BusFault_Handler .word UsageFault_Handler .word 0 .word 0 .word 0 .word 0 .word SVC_Handler .word DebugMon_Handler .word 0 .word PendSV_Handler .word SysTick_Handler .word WWDG1_IRQHandler /* Window Watchdog interrupt */ .word PVD_PVM_IRQHandler /* PVD through EXTI line */ .word RTC_TAMP_STAMP_CSS_LSE_IRQHandler /* RTC tamper, timestamp */ .word RTC_WKUP_IRQHandler /* RTC Wakeup interrupt */ .word FLASH_IRQHandler /* Flash memory */ .word RCC_IRQHandler /* RCC global interrupt */ .word EXTI0_IRQHandler /* EXTI Line 0 interrupt */ .word EXTI1_IRQHandler /* EXTI Line 1 interrupt */ .word EXTI2_IRQHandler /* EXTI Line 2 interrupt */ . . . (후략) ``` ### 2-1. '.section .isr_vector, "a", %progbits' Section directives의 syntax는 보통 다음과 같이 구성된다. ``` .section name [, "flags" [, entry_size] [, group_name [, linkage]] [, link_order_symbol] [, unique, unique_id] ] ``` 출처: https://www.keil.com/support/man/docs/armclang_ref/armclang_ref_bpl1510589893923.htm Section flag들 중에서 'a'는 allocatable, 즉, 할당 가능한 section이라는 의미를 갖는다. '%progbits'는 초기화된 data와 instruction 혹은 instruction만을 section이 담는다는 의미를 갖는다. .isr_vector는 Linker script에 의해 실제 메모리에 위치하게 되는데 해당 내용은 "stm32h743zitx_FLASH.ld"에서 발췌한 것이다. ``` (전략) . . . SECTIONS { /* The startup code goes first into FLASH */ .isr_vector : { . = ALIGN(4); KEEP(*(.isr_vector)) /* Startup code */ . = ALIGN(4); } >FLASH . . . } (후략) ``` 즉 해당 section은 FLASH memory에 각각 4byte(1byte씩 4개의 메모리 공간에)로 할당된다는 것을 알 수 있다. ### 2-2. '.type g_pfnVectors, %object' '.type'이라는 directive는 symbol(위의 상황에서는 g_pfnVectors)의 type을 선정한다. 그 type은 %object, 즉, data object(?)이다. ### 2-3. '.size g_pfnVectors, .-g_pfnVectors' '.size'라는 directive는 symbol의 size를 설정한다. ELF target의 경우 다음과 같은 syntax를 갖는다. ``` .size name .expression ``` '.'의 의미를 현재의 주소로 할 수 있다고(https://hackmd.io/w3nIjCDAS4SEdkNJb3gyCQ)하여 위의 의미를 해석하면 g_pfnVectors라는 symbol의 size를 현재 주소에서 g_pfnVector의 시작주소 값을 뺀 값으로 하겠다는 의미이다.