December 17, 2018

디바이스마트 미디어:

[18호]JK전자와 함께하는 ARM 완전정복(4)-1

jk전자 JK전자와 함/께/하/는 ARM 완전 정복

Ⅱ.ARM Applications – 2부

글 | JK전자

자료는 ARM을 처음 접하는 입문자로서 S/W 엔지니어 혹은 H/W 엔지니어를 대상으로 하였습니다. 처음에는 Cortex-M3 구조를 목표로 하였으나 전통적인 ARM(주로 ARM7, ARM9)의 구조에 대해서 먼저 이야기한 다음 Cortex-M3 구조에 대해서 하기로 마음을 고쳐 먹었습니다. Cortex-M3도 ARM 이기 때문에 전통적인 ARM의 구조에 대해서 잘 이해하고 Cortex-M3 구조와 비교해 보면서 공부한다면 큰 도움이 될 것입니다.

ARM Architecture 강의에서는 특정 CPU(S3C2440, STM32Fxx) 에 대한 내용 보다는 ARM Core의 이론적인 구조 자체에 대해서 많은 설명을 하였습니다. 이번 강의에서는 Samsung의 ARM9 CPU S3C2440 개발보드를 이용해서 실제 실습을 통해서 ARM에 대해서 공부해 보도록 하겠습니다.
I. ARM Architecture ~ IV. Cortex-M3 Applications 까지 분명 쉽지 않은 지루하고도 먼 여행이 되겠지만 ARM을 공부하는 임베디드 관련 엔지니어라면 언젠가는 한 번은 넘어야 하는 산이라 생각됩니다. 부디 이 자료가 ARM을 정복하는데 조금이라도 도움이 되시길 바랍니다.

 

강의 전체 로드맵

I. ARM Architecture | 임베디드 시스템 개론에 대한 설명과 ARM7, ARM9 의 구조에 대해서 설명합니다.
II. ARM Applications | 삼성의 S3C2440(ARM9) 개발보드(S3C2440 Mini 개발보드)를 이용해서 어셈블리어와 UART, GPIO 등을 실습합니다.
III. Cortex-M3 Architecture | Cortex-M3의 특징과 구조에 대해서 설명합니다.
IV. Cortex-M3 Applications | STM32F103VCT6 Dragon 개발보드를 이용해서 GPIO, LCD, SPI, UART, MP3, SDIO, I2C 등을 실습합니다.

이 강의 자료에 대한 모든 질의사항은 http://cafe.naver.com/avrstudio의 ARM Architecture Q&A게시판에 글을 남겨 주시거나 jk@deviceshop.net로 메일을 보내주시기 바랍니다. 가급적이면 여러 사람이 질문에 대한 답변을 공유할 수 있도록 네이버 카페 게시판을 이용해주셨으면 합니다. 감사합니다.

Ⅱ. ARM Applications 2부 목차

5. S3C2440 개발보드 실습
5.1 S3C2440 Startup 코드 분석
5.2 GPIO Output(LED On/Off)
5.3 GPIO Input(KEY Input) – Polling
5.4 GPIO Input(KEY Input) – Interrupt
5.5 TIMER
5.6 PWM Buzzer
5.7 UART

5장에서는 우리가 실습에 사용할 Mini2440 개발보드를 가지고 지금까지 이론으로만 공부했던 어셈블리어와 C언어를 이용해서 주변 장치들을 제어하는 실습을 해보도록 하겠습니다. 실제 타켓보드에 내가 작성한 프로그램을 다운로드하여 동작을 확인하는 일은 항상 가슴이 설레입니다.

5. S3C2440 개발보드 실습

5.1 S3C2440 Startup 코드 분석
ARM 개발보드의 부트코드(Startup)에는 지금까지 이론으로 배웠던 내용들이 거의 모두 포함이 되어 있습니다. 부트 코드만 잘 분석해도 CPU의 50% 이상은 알고 있다고 해도 과언이 아닙니다. 부트코드 기능을 간략하게 요약해 보면 아래와 같습니다.

- Clock & Power Initialization
- Setup each exception handler
- Memory (SDRAM) Initialization
- Peripheral Initialization
- Stack Initialization for each Processor Mode
- Interrupt Handler Setup
- Segment Initialization
- Jump to User Application

이제부터 부팅이 되는 순서대로 실제 코드를 분석해 보도록 하겠습니다.

(1) Exception Vector Table

__program_start
b ResetHandler
b HandlerUndef ;handler for Undefined mode
b HandlerSWI ;handler for SWI interrupt
b HandlerPabort ;handler for PAbort
b HandlerDabort ;handler for DAbort
b . ;reserved
b HandlerIRQ ;handler for IRQ interrupt
b HandlerFIQ ;handler for FIQ interrupt

CPU에 전원이 인가되면 처음으로 시작되는 Vector Table (0×0000 0000)입니다.

(2) Watchdog Disable
Watchdog가 무엇일까요? 직역을 하면 “지키는 개” 이런 뜻이네요. Watchdog는 보통 S/W적으로 설정한 시간동안 Kick(집지키는 개를 한번씩 차주어야 잠을 자지 않겠죠.)을 해주지 않으면 CPU를 Reset 시키는 기능으로 주로 사용합니다. 왜 이런 기능이 필요한 걸까요? 우리가 자주 사용하는 스마트폰을 예로 들어 보도록 하겠습니다. 스마트폰 사용중에 어떤 App을 실행시켰는데 그 이후로 스마트폰이 그 App때문에 터치도 되지않고, 전원 버튼도 입력이 되지 않게 먹통이 되었다고 가정을 하면 배터리를 분리시킨 후 다시 연결하는 방법 이외에는 방법이 없습니다. 이때 만약 Watchdog가 활성화 되어 있다면 스마트폰이 먹통이 되는 순간 S/W적으로 설정한 시간동안 Kick이 없으면 스마트폰이 Reset(재부팅)이 되어 다시 사용할 수 있는 상태가 될 것입니다. 배터리를 분리하는 것보다는 낫겠죠.
그리고 부트코드에서 Watchdog Disable 하는 것은 부팅이 완료되기도 전에 Watchdog에 의해서 CPU가 Reset이 되는 것을 방지하기 위해서 하는 것입니다.

18feajkarm001

0×5300 0000 번지의 SFR 레지스터를 제어하면 WTCON을 설정할 수 있습니다. 실제로는 5번 비트만 “0 = Disable” 해도 됩니다.

ResetHandler
ldr r0,=WTCON ;watch dog disable
ldr r1,=0×0
str r1,[r0]

(3) Interrupt Disable

부팅 중에 예측하지 못하는 인터럽트가 발생하지 않도록 Disable 하는 것이 안전합니다.

CPSR.I(1), CPSR.F(1) : 부팅 시에 “1″ 로 마스킹 되어 있습니다.

- S3C2440 CPU Level의 Interrupt Controller를 Disable 합니다.
Interrupt Mask Register
Interrupt SubMask Register

아래 그림은 S3C2440 CPU의 인터럽트 컨트롤러 블럭도입니다. “S3C2440 CPU Level 의 Interrupt Controller를 Disable” 한다는 것은 아래 블럭도에서 바로 “SUBMASK”, “MASK”를 Disable(“1” 로 Mask) 한다는 것입니다.

18feajkarm041

18feajkarm002

ldr r0,=INTMSK
ldr r1,=0xffffffff ;all interrupt disablestr r1,[r0] ldr r0,=INTSUBMSK
ldr r1,=0x3ff ;all sub interrupt disable
str r1,[r0]

 

(4) PLL 설정
우리가 사용하는 S3C2440 Mini 개발보드는 외부 Crystal로 12MHz를 사용합니다.
Input Frequency가 12MHz 일때, FCLK:HCLK:PCLK = 400MHz : 100MHz : 40MHz, 즉 1:4:8 비율로 분주가 되도록 설정합니다.

(4.1) Clock Divider Control Register(CLKDIVIN) 설정

18feajkarm003

 

18feajkarm004

CLKDIV_VAL 값이 “b00101”으로 세팅이 되어 있어서 FCLK:HCLK:PCLK = 1:4:8 비율로 분주가 되도록 설정이 됩니다.
최종적으로는 12MHz의 입력주파수를 받아서 동작 주파수가 400MHz가 되도록 설정합니다.

(4.2) UPLL Control Register(USB CLK) 설정

18feajkarm005
Upll = (m * Fin) / (p * 2s)
m = (MDIV + 8), p = (PDIV + 2), s = SDIV

Fin = FCLK 입력으로 들어오는 Crystal 주파수 12MHz
UPLL = ((56+8)*12) / ((2+2)*2*2) = 48MHz

18feajkarm006
UPLL은 USB컨트롤러에서 사용할 CLK으로 결국은 12MHz Crystal 입력을 받아서 48MHz를 만들어서 사용하고 있습니다.

(4.3) MPLL Control Register(Main CLK) 설정

Mpll = (2 * m * Fin) / (p * 2s)
m = (MDIV + 8), p = (PDIV + 2), s = SDIV
MPLL = (2*(92+8)*12) / ((1+2)*2*1) = 400MHz

MPLL은 결국은 12MHz Crystal 입력을 받아서 FCLK = 400MHz, HCLK = 100MHz, PCLK = 50MHz를 만들어서 사용하고 있습니다. HCLK과 PCLK의 계산은 CLKDIV 레지스터 설정을 FCLK:HCLK:PCLK = 1:4:8 비율로 분주비를 설정했기 때문에 자동으로 계산이 됩니다.
- 참조로 PLL 계산 방식은 S3C2440 Datasheet를 참조하시기 바랍니다.

ldr r0,=CLKDIVN ; 0x4C000014
ldr r1,=CLKDIV_VAL ; CLKDIV_VAL=5 —> 1:4:8
str r1,[r0];Configure UPLL
ldr r0,=UPLLCON ; 0x4C000008
ldr r1,=((U_MDIV<<12)+(U_PDIV<<4)+U_SDIV) ; U_MDIV=56, U_PDIV=2, U_SDIV=2
str r1,[r0];Configure MPLL
ldr r0,=MPLLCON
ldr r1,=((M_MDIV<<12)+(M_PDIV<<4)+M_SDIV)
str r1,[r0]

 

(5) Internal Bus Mode

     bl MMU_SetAsyncBusMode

- Synchronous : Core Clock System Clock(HCLK)에 동기화 되어 사용

- Asynchronous : System Clock(HCLK)과 관계없이 Free Running Clock(FCLK)을 이용

우리는 FCLK을 이용할 것이기 때문에 MMU_SetAsyncBusMode 함수를 호출하였습니다.

(6) Memory System 초기화
시스템에 연결된 FLASH, SDRAM, I/O Device 등과 같은 장치들을 제어하기 위해서 Memory Controller를 초기화해야 합니다.

- Access Timing
- Data Bus Width
- Wait Cycle
- Refresh Rate
- Bank Memory Size

소스 코드들이 꽤 알아먹기 힘든 코드들이네요. 복잡해 보이지만 하는 일은 BWSCON 주소의 SFR에 SMRDATA의 4Byte(32-bit) 데이터들을 루프를 돌면서 Write 하는 것입니다.

- SMRDATA : 메모리 컨트롤러 SFR에 기록할 내용들을 4Byte 길이로 해서 테이블 형태로 데이터를 순차적으로 가지고 있습니다.
- BWSCON : S3C2440 메모리 컨트롤러의 SFR 주소입니다.

소스 파일의 memcfg.inc에 다음과 같이 정의되어 있습니다.
;BWSCON
DW8 EQU (0×0)
DW16 EQU (0×1)
DW32 EQU (0×2)

WAIT EQU (0×1<<2)
UBLB EQU (0×1<<3)

B1_BWSCON EQU (DW32)
B2_BWSCON EQU (DW16)
B3_BWSCON EQU (DW16+WAIT+UBLB)
B4_BWSCON EQU (DW16) ; N.C.
B5_BWSCON EQU (DW16) ; N.C.
B6_BWSCON EQU (DW32) ; MINI2440 SDRAM (K4S281632C)-2M*16bit*4Bank*2, SDRAM(K4S561632C) 32MBx2, 32-bit
B7_BWSCON EQU (DW32) ; N.C.

SMRDATA의 맨 첫번째 데이터들이 무엇을 의미하는 것일까요?

(0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28)) –> (0+(0×2<<4)+(0×1<<8)+(0xD<<12)+(0×1<<16)+(0×1<<20)+(0×2<<24)+(0×2<<28))

상위 비트부터 살펴보도록 하겠습니다.

- (0×2<<28) = DW7[29:28] = Bank7에는 어떤 Memory 디바이스도 연결되어 있지 않습니다. 사실은 무의미한 코드입니다.

18feajkarm007
- (0×2<<24) = DW6[25:24] = Bank6은 SDRAM이 연결되어 있는 메모리 뱅크입니다. 데이터 라인은 32bit(2b10) 입니다.

18feajkarm008

- (0×1<<20) = DW5[21:20] = N.C(Not connected)

18feajkarm009
- (0×1<<16) = DW4[17:16] = N.C(Not connected)

18feajkarm010
- (0xD<<12) = ST3[15], WS3[14], DW3[13:12] = 16-bit DM9000 Ehternet 컨트롤러 설정입니다.

18feajkarm011

- (0×1<<8) = DW2[9:8] = N.C(Not connected)

18feajkarm012
- (0×2<<4) = DW1[5:4] = N.C(Not connected)

18feajkarm013
- (0×0) = DW0[2:1] = Read only 영역으로 OM[1:0] 핀에 의해서 결정됩니다. 우리가 사용하는 개발보드는 16bit Data width의 NOR Flash 입니다.

18feajkarm013
나머지 데이터 설정값들도 Datasheet를 참조해서 분석해 보시기 바랍니다.

;Set memory control registers
ldr r0,=SMRDATA
ldr r1,=BWSCON ; 0×48000000
add r2, r0, #52 ;End address of SMRDATA
L5
ldr r3, [r0], #4
str r3, [r1], #4
cmp r2, r0
bne L5.
.
.
LTORG
SMRDATA DATA
DCD (0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28))
DCD ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC)) ;GCS0
DCD ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC)) ;GCS1
DCD ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC)) ;GCS2
DCD ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC)) ;GCS3
DCD ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC)) ;GCS4
DCD ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC)) ;GCS5
DCD ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN)) ;GCS6
DCD ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN)) ;GCS7
DCD ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)
DCD 0×32 ;SCLK power saving mode, BANKSIZE 128M/128M DCD 0×30 ;MRSR6 CL=3clk
DCD 0×30 ;MRSR7 CL=3clk
DATA

JK전자와 함께하는 ARM 완전정복(4)-2 에서 계속 됩니다.

Leave A Comment

*