realview compilation tools developer...

206
Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK RealView ® Compilation Tools 버전 3.1 개발자 설명서

Upload: others

Post on 04-Mar-2020

7 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

RealView® Compilation Tools버전 3.1

개발자 설명서

Copyright © 2002-2007 ARM Limited. All rights reserved.ARM DUI 0203HK

Page 2: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

RealView Compilation Tools개발자 설명서

Copyright © 2002-2007 ARM Limited. All rights reserved.

릴리스 정보

이 설명서에서 변경된 내용은 다음과 같습니다.

소유권 고지 사항

® 또는 ™ 표시가 있는 단어와 로고는 ARM Limited 소유의 등록 상표 또는 상표입니다. 이 설명서에 언급된 기타 브랜드와 이름은 해당 소유자의 상표일 수 있습니다.

이 설명서에 포함된 전체 또는 일부 정보나 설명된 제품은 해당 저작권 소유자의 사전 서면 승인 없이는 어떤 형태로도 개조되거나 복제될 수 없습니다.

이 설명서에 설명된 제품은 지속적으로 개발 및 개선될 수 있습니다. 이 설명서에 포함된 모든 제품 명세와 해당 사용법은 ARM의 신뢰하에 제공됩니다. 그러나 ARM에서는 상품성 또는 특정 목적에의

적합성을 비롯하여 그 밖의 묵시적이거나 명시적인 모든 보증을 부인합니다.

이 설명서는 제품 사용자를 지원하는 용도로만 만들어졌습니다. ARM Limited는 이 설명서 정보의 사용, 정보의 오류나 누락 또는 제품의 잘못된 사용에 따른 어떠한 손실이나 손상도 책임지지 않습니다.

ARM이라는 단어가 사용되는 경우 "ARM이나 해당하는 자회사"를 의미합니다.

기밀 상태

이 설명서는 기밀 문서가 아닙니다. 이 설명서의 사용, 복사 및 공개에 대한 권한은 ARM과 ARM으로부

터 이 설명서를 제공받은 당사자가 동의한 계약 조건에 따라 라이센스 제한의 적용을 받을 수 있습니다.

제품 상태

이 설명서의 정보는 개발이 완료된 제품에 대한 최종 정보입니다.

웹 주소

http://www.arm.com

변경 내역

날짜 발행판 기밀 상태 변경 내용

2002년 8월 A 기밀 문서 아님 릴리스 1.2

2003년 1월 B 기밀 문서 아님 릴리스 2.0

2003년 9월 C 기밀 문서 아님 RVDS 버전 2.0용 릴리스 2.0.1

2004년 1월 D 기밀 문서 아님 RVDS 버전 2.1용 릴리스 2.1

2004년 12월 E 기밀 문서 아님 RVDS 버전 2.2용 릴리스 2.2

2005년 5월 F 기밀 문서 아님 RVDS 버전 2.2 SP1용 릴리스 2.2

2006년 3월 G 기밀 문서 아님 RVDS 3.0용 릴리스 3.0

2007년 3월 H 기밀 문서 아님 RVDS 버전 3.1용 릴리스 3.1

ii Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 3: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

목차RealView Compilation Tools개발자 설명서

서문설명서 개요 .................................................................................................. viii

사용자 의견 ................................................................................................... xii

1장 소개1.1 RVCT 개요 .................................................................................................. 1-21.2 ARM 프로세서용 소프트웨어 개발 .............................................................. 1-3

2장 임베디드 소프트웨어 개발2.1 임베디드 소프트웨어 개발 개요 .................................................................. 2-22.2 타겟 시스템이 없을 경우의 기본 컴파일 도구 동작 ..................................... 2-42.3 타켓 하드웨어에 맞게 C 라이브러리 조정 ................................................. 2-12

2.4 타켓 하드웨어에 맞게 이미지 메모리 맵 조정 ........................................... 2-162.5 리셋 및 초기화 .......................................................................................... 2-272.6 기타 메모리 맵 고려 사항 .......................................................................... 2-37

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. iii

Page 4: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

목차

3장 위치 독립적인 코드 및 데이터 작성3.1 위치 독립성 ................................................................................................. 3-23.2 읽기 전용 위치 독립성 ................................................................................ 3-33.3 읽기/쓰기 위치 독립성 ................................................................................ 3-5

4장 ARM과 Thumb의 인터워킹4.1 인터워킹 개요 ............................................................................................. 4-24.2 어셈블리 언어 인터워킹 .............................................................................. 4-7

4.3 C/C++ 인터워킹 및 비니어 ....................................................................... 4-134.4 비니어를 사용한 어셈블리 언어 인터워킹 ................................................ 4-18

5장 C, C++ 및 어셈블리 언어 조합5.1 인라인 및 임베디드 어셈블러 사용 ............................................................. 5-25.2 어셈블리 코드에서 C 전역 변수 액세스 ...................................................... 5-45.3 C++에서 C 헤더 파일 사용 ......................................................................... 5-6

5.4 C, C++ 및 ARM 어셈블리 언어 간 호출 ...................................................... 5-8

6장 프로세서 예외 처리6.1 프로세서 예외 개요 ..................................................................................... 6-26.2 프로세서 상태 확인 ..................................................................................... 6-66.3 예외 발생 및 종료 ....................................................................................... 6-8

6.4 예외 처리 .................................................................................................. 6-136.5 예외 처리기 설치 ...................................................................................... 6-146.6 SVC 처리기 .............................................................................................. 6-196.7 인터럽트 처리기 ....................................................................................... 6-29

6.8 리셋 처리기 ............................................................................................... 6-406.9 정의되지 않은 명령어 처리기 ................................................................... 6-416.10 프리페치 어보트 처리기 ............................................................................ 6-42

6.11 데이터 어보트 처리기 ............................................................................... 6-436.12 시스템 모드 ............................................................................................... 6-44

7장 Cortex-M3 프로세서 예외 처리7.1 Cortex-M3 프로세서 예외 ........................................................................... 7-27.2 예외 테이블 기록 ...................................................................................... 7-117.3 예외 처리기 기록 ...................................................................................... 7-13

7.4 예외 테이블 배치 ...................................................................................... 7-147.5 시스템 제어 공간 레지스터 구성 ............................................................... 7-157.6 개별 IRQ 구성 ........................................................................................... 7-17

7.7 관리자 호출 ............................................................................................... 7-187.8 시스템 타이머 ........................................................................................... 7-20

iv Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 5: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

목차

7.9 다른 ARM 프로세서용으로 작성된 예외 처리 코드 이식 ........................... 7-22

8장 디버그 통신 채널8.1 디버그 통신 채널 개요 ................................................................................. 8-2

8.2 타겟에서의 데이터 전송 .............................................................................. 8-38.3 폴링 방식 디버그 통신 ................................................................................. 8-48.4 인터럽트 구동 디버그 통신 ......................................................................... 8-8

8.5 Thumb 상태에서 액세스 .............................................................................. 8-9

부록 A 세미호스팅A.1 세미호스팅 개요 .......................................................................................... A-2A.2 세미호스팅 구현 .......................................................................................... A-6

A.3 세미호스팅 작업 .......................................................................................... A-8A.4 디버그 에이전트 상호작용 SVC ................................................................ A-24

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. v

Page 6: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

목차

vi Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 7: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

서문

이 서문에서는 RealView Compilation Tools 개발자 설명서를 소개합니다. 여기에는 다음 단원이 포함되어 있습니다.

• viii페이지의 설명서 개요

• xii페이지의 사용자 의견

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. vii

Page 8: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

서문

설명서 개요

이 설명서에는 ARM® 계열의 RISC(Reduced Instruction Set Computing) 프로세서용 코드를 개발할 때 발생하는 특정 문제의 해결에 도움이 되는 정보가 포함되어 있습니다. 이 설명서의 각 장과 사용된 예제에서는 사용자가 최신 릴리스의 RealView® Compilation Tools(RVCT)를 사용하여 코드를 개발한다고 가정합니다.

대상 독자

이 설명서는 ARM 아키텍처 기반 프로세서용 코드를 작성하려는 모든 개발자를 위한 것입니다. 여기에서는 사용자가 경험 있는 소프트웨어 개발자이고 RealView Compilation Tools 핵심 설명서에 설명된 ARM 개발 도구에 익숙하다고 가정합니다.

설명서 사용

이 설명서는 다음 장으로 구성되어 있습니다.

1장 소개

이 장에서는 RVCT에 대해 간략히 소개합니다.

2장 임베디드 소프트웨어 개발

이 장에서는 RVCT를 사용하여 임베디드 응용프로그램을 개발하는 방법을 자세히 설명합니다. 또한 타겟 시스템이 없을 때의 기본 RVCT 동작과 C 라이브러리 및 이미지 메모리 맵을 타겟 시스템에 맞게 조정하는 방법에 대해 설명합니다.

3장 위치 독립적인 코드 및 데이터 작성

이 장에서는 Procedure Call Standard for the ARM Architecture(AAPCS)를 사용하는 위치 독립적인 코드 및 데이터를 작성하는 방법을 자세히 설명합니다.

4장 ARM과 Thumb의 인터워킹

이 장에서는 Thumb 명령어 세트를 구현하는 프로세서를 위한 코드를 작성할 때 ARM 상태와 Thumb 상태 사이에서 전환하는 방법을 자세히 설명합니다.

viii Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 9: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

서문

5장 C, C++ 및 어셈블리 언어 조합

이 장에서는 C, C++ 및 ARM 어셈블리 언어가 조합된 코드를 작성하는 방법을 자세히 설명합니다. C와 C++에서 ARM 인라인 및 임베디드 어셈블러를 사용하는 방법에 대해서도 설명합니다.

6장 프로세서 예외 처리

이 장에서는 Cortex-M1 또는 Cortex-M3 프로세서 이외의 ARM 프로세서에서 지원하는 다양한 유형의 예외를 처리하는 방법을 자세히 설명합니다.

7장 Cortex-M3 프로세서 예외 처리

이 장에서는 Cortex-M3 프로세서에서 지원하는 다양한 유형의 예외를 처리하는 방법을 자세히 설명합니다.

8장 디버그 통신 채널

이 장에서는 DCC(디버그 통신 채널)를 사용하는 방법을 자세히 설명합니다.

부록 A 세미호스팅

이 부록에서는 ARM 타겟에서 실행 중인 코드가 ARM 디버거를 실행 중인 호스트 컴퓨터의 I/O 기능을 사용할 수 있도록 하는 세미호스팅 메커니즘에 대해 자세히 설명합니다.

이 설명서에서는 ARM 소프트웨어가 기본 위치에 설치되어 있다고 가정합니다. 예를 들어 Windows의 경우 기본 위치는 volume:\Program Files\ARM일 수 있습니다. 경로 이름을 참조할 때 install_directory는 이 위치를 가리키는 것으로 가정합니다. 예를 들어 경로는 install_directory\Documentation\...과 같을 수 있습니다. ARM 소프트웨어를 다른 위치에 설치한 경우에는 이 위치를 변경해야 합니다.

표기 규칙

이 설명서에서는 고정 폭 글꼴다음과 같은 표기 규칙을 사용합니다.

고정 폭 글꼴 명령, 파일 및 프로그램 이름, 소스 코드와 같이 키보드로 입력할 수 있는 텍스트를 나타냅니다.

고정 폭 글꼴 명령 또는 옵션 대신 사용할 수 있는 약어를 나타냅니다. 밑줄이 그어진 텍스트는 전체 명령이나 옵션 이름 대신 입력할 수 있습니다.

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. ix

Page 10: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

서문

고정 폭 기울임 글꼴

명령 및 함수의 인수를 나타냅니다. 인수는 특정 값으로 대체할 수 있습니다.

고정 폭 굵은 글꼴

외부 예제 코드가 사용될 경우 언어 키워드를 나타냅니다.

기울임 글꼴

중요한 사항을 강조 표시하고, 특수 용어를 소개하며, 내부 상호 참조 및 인용 부분을 나타냅니다.

굵은 글꼴 메뉴 이름과 같은 인터페이스 요소를 강조 표시합니다. 적절한 경우 설명 목록의 내용을 강조할 때와 ARM 프로세서 신호 이름을 표시할 때도 사용됩니다.

추가 정보

이 단원에는 ARM 계열 프로세서용 코드를 개발하는 데 대한 추가 정보를 제공하는 ARM Limited 및 타사 게시물 목록이 나와 있습니다.

ARM에서는 이 설명서의 내용을 정기적으로 업데이트하고 수정합니다. http://www.arm.com에서 정오표, 추가 목록 및 ARM FAQ를 참조하십시오.

ARM 게시물

이 설명서에는 ARM 계열 프로세서용 응용프로그램 개발에 대한 일반적인 정보가 포함되어 있습니다. 다른 구성요소에 대한 자세한 내용은 RVCT 설명서 제품군의 다음 설명서를 참조하십시오.

• RVCT 핵심 설명서(ARM DUI 0202)

• RVCT 컴파일러 사용 설명서(ARM DUI 0205)

• RVCT 컴파일러 참조 설명서(ARM DUI 0348)

• 라이브러리 및 부동 소수점 지원 설명서(ARM DUI 0349)

• RVCT 링커 및 유틸리티 설명서(ARM DUI 0206)

• RVCT 어셈블러 설명서(ARM DUI 0204)

• RealView Development Suite 용어집(ARM DUI 0324)

ARM에서 지원하는 기본 표준, 소프트웨어 인터페이스 및 기타 표준에 대한 자세한 내용은 install_directory\Documentation\Specifications\...에서 볼 수 있습니다.

x Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 11: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

서문

또한 ARM 제품과 관련된 구체적인 내용은 다음 설명서를 참조하십시오.

• ARM6-M 아키텍처 참조 문서(ARM DDI 0419)

• ARM7-M 아키텍처 참조 문서(ARM DDI 0403)

• ARM 아키텍처 참조 문서, ARMv7-A 및 ARMv7-R 에디션(ARM DDI 0406)

• ARM Architecture Reference Manual Thumb®-2 Supplement(ARM DDI 0308)

• ARM Architecture Reference Manual Security Extensions Supplement(ARM DDI 0309)

• ARM Architecture Reference Manual Thumb-2 Execution Environment Supplement(ARM DDI 0376)

• ARM Architecture Reference Manual Advanced SIMD Extensions and VFPv3 Supplement(ARM DDI 0268)

• ARM 참조 주변 기기 사양(ARM DDI 0062)

• 하드웨어 장치에 대한 ARM 데이터시트 또는 기술 참조 문서

기타 게시물

ARM 아키텍처에 대한 소개는 ARM System Developer's Guide: Designing and Optimizing System Software(Andrew N. Sloss 등 저, 씨랩시스 역, 사이텍미디어, 2005년, ISBN 8955508395)를 참조하십시오.

ARM 프로세서 코어를 사용하는 시스템온칩(SoC) 디자이너와 ARM을 사용하여 작업하는 엔지니어에게 필수적인 안내서를 보려면 ARM system-on-chip 구조(Steve Furber 저, 나종화 등 역, 홍릉과학출판사, 2005년, ISBN 8972833592)를 참조하십시오.

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. xi

Page 12: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

서문

사용자 의견

RealView Compilation Tools와 해당 설명서에 대한 의견이 있으시면 ARM Limited에 알려 주시기 바랍니다.

RealView Compilation Tools에 대한 사용자 의견

RVCT와 관련된 문제가 있으시면 해당 공급업체에 문의하십시오. 문의 시 다음 사항을 함께 알려 주시면 보다 신속하고 유용한 답변을 받으실 수 있습니다.

• 사용자 이름 및 회사

• 제품 일련 번호

• 사용 중인 릴리스 정보

• 실행 중인 플랫폼의 세부 사항(예: 하드웨어 플랫폼, 운영 체제 유형 및 버전)

• 문제를 재현하는 작은 독립 실행형 코드 샘플

• 의도한 결과와 실제로 발생한 결과에 대한 명확한 설명

• 사용한 명령(명령 행 옵션 포함)

• 문제를 보여 주는 샘플 출력

• 도구의 버전 문자열(버전 번호 및 날짜 포함)

설명서에 대한 사용자 의견

이 설명서에 오류나 누락이 있으면 다음 사항을 기재하여 [email protected]으로 전자 메일을 보내 주시기 바랍니다.

• 설명서 제목

• 설명서 번호

• 문의 내용에 해당하는 페이지 번호

• 문제에 대한 간략한 설명

추가 및 향상되었으면 하는 기능에 대한 일반적인 제안도 환영합니다.

xii Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 13: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

1장 소개

이 장에서는 이 설명서에 대해 소개하고 RealView® Compilation Tools(RVCT)를 사용하여 코드를 개발하는 방법을 설명합니다. 여기에는 다음 단원이 포함되어 있습니다.

• 1-2페이지의 RVCT 개요

• 1-3페이지의 ARM 프로세서용 소프트웨어 개발

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 1-1

Page 14: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

소개

1.1 RVCT 개요

RVCT는 응용 프로그램과 지원 설명서 및 예제로 구성된 제품군으로서, ARM® 계열의 RISC 프로세서용 응용 프로그램을 작성하는 데 사용할 수 있습니다. RVCT를 사용하여 C, C++ 및 ARM 어셈블리 언어 프로그램을 빌드할 수 있습니다.

이 설명서에는 ARM 기반의 시스템을 위한 코드를 개발할 때 발생하는 특정 문제의 해결에 도움이 되는 정보가 포함되어 있습니다. 이 설명서의 각 장과 사용된 예제에서는 사용자가 최신 릴리스의 RVCT를 사용하여 코드를 개발한다고 가정합니다.

이전 릴리스의 RVCT에서 업그레이드하는 경우에는 RealView Compilation Tools 핵심 설명서에서 이 릴리스의 새 기능과 향상된 기능에 대한 정보를 읽어 보십시오.

RVCT를 처음 사용하는 경우 다양한 ARM 도구의 개요 및 개발 프로젝트에 이들 도구를 함께 사용하는 방법에 대해 소개하는 RealView Compilation Tools 핵심 설명서를 참조하십시오.

이전 릴리스의 RVCT에 대한 자세한 내용은 RealView Compilation Tools 핵심 설명서의 부록 A를 참조하십시오.

RVCT 설명서 제품군에서 ARM 어셈블러, 컴파일러 및 지원 소프트웨어에 대한 정보를 제공하는 다른 설명서의 목록을 보려면 x페이지의 ARM 게시물을 참조하십시오.

1.1.1 예제 사용

이 설명서에서는 RealView Development Suite와 함께 제공되는 예제를 참조합니다. 이러한 예제는 주 예제 디렉토리인 install_directory\RVDS\Examples에 있습니다. 제공되는 예제에 대한 간략한 설명은 RealView Compilation Tools 핵심 설명서를 참조하십시오.

1-2 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 15: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

소개

1.2 ARM 프로세서용 소프트웨어 개발

이 설명서에서는 가장 일반적인 ARM 프로그래밍 작업 중 일부에 대한 정보와 예제 코드를 제공합니다. 여기에는 ARM 아키텍처를 다루는 개발자를 위한 다음과 같은 내용이 포함되어 있습니다.

1.2.1 임베디드 소프트웨어 개발

ARM 아키텍처 기반 시스템용으로 작성된 대부분의 응용 프로그램은 ROM에 포함되고 리셋 시 실행되는 임베디드 응용 프로그램입니다. 임베디드 운영 체제 또는 운영 체제 없이 재설정할 때 실행되는 임베디드 응용 프로그램을 작성할 때는 다음과 같은 여러 가지 요소를 고려해야 합니다.

• 주소를 다시 매핑해야 합니다. 예를 들어 ROM이 주소 0x0000에 있는 상태에서 초기화한 다음 주소 0x0000에 RAM을 다시 매핑합니다.

• 환경과 응용 프로그램을 초기화해야 합니다.

• 임베디드 실행 가능 이미지를 링크하여 코드와 데이터를 메모리의 특정 위치에 배치해야 합니다.

일반적으로 ARM 코어는 리셋 시 주소 0x0000에서 명령어 실행을 시작합니다. 따라서 임베디드 시스템의 경우에는 시스템 리셋 시 주소 0x0000에 ROM이 있어야 합니다. 그러나 일반적으로 ROM은 RAM에 비해 속도가 느리고 8비트 또는 16비트 단위로만 구성된 경우가 많습니다. 이 경우 예외 처리 속도가 영향을 받습니다. 주소 0x0000에 ROM이 있으면 예외 벡터를 수정할 수 없습니다. 이 문제를 해결하는 일반적인 방법은 ROM을 RAM에 다시 매핑하고 시스템 시작 후 ROM에서 RAM으로 예외 벡터를 복사하는 것입니다. 자세한 내용은 2-29페이지의 ROM/RAM 재매핑을 참조하십시오.

리셋 후 임베디드 응용 프로그램이나 운영 체제에서는 다음과 같이 시스템을 초기화해야 합니다.

• 예외 벡터, 스택 및 I/O 주변 기기와 같은 실행 환경을 초기화합니다.

• 응용 프로그램을 초기화합니다. 예를 들면 0이 아닌 쓰기 가능 데이터의 초기값을 쓰기 가능 데이터 영역에 복사하고 ZI 데이터 영역을 0으로 초기화합니다.

자세한 내용은 2-27페이지의 초기화 시퀀스를 참조하십시오.

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 1-3

Page 16: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

소개

임베디드 시스템에는 복잡한 메모리 구성이 구현된 경우가 많습니다. 예를 들어 임베디드 시스템에서 인터럽트 처리기 및 스택과 같이 성능이 중요한 코드에는 빠른 32비트 RAM이 사용되고, 응용 프로그램 RW 데이터에는 느린 16비트 RAM이 사용되며, 일반적인 응용 프로그램 코드에는 ROM이 사용될 수 있습니다. 링커의 스캐터 로딩 메커니즘을 사용하면 복잡한 시스템에 적합한 실행 가능 이미지를 생성할 수 있습니다. 예를 들어 스캐터 로딩 설명 파일에서 개별 코드 및 데이터 영역의 로드 주소와 실행 주소를 지정할 수 있습니다. 임베디드 응용 프로그램에 영향을 주는 세미호스팅 등의 기타 문제에 대한 자세한 내용과 일련의 작업 예제는 2장 임베디드 소프트웨어 개발을 참조하십시오.

1.2.2 ARM 코드와 Thumb 코드의 인터워킹

Thumb 16비트 명령어 세트를 지원하는 ARM 프로세서를 위한 코드를 작성할 경우 필요에 따라 ARM 코드와 Thumb 코드를 함께 사용할 수 있습니다. C 또는 C++ 코드를 작성할 경우 --apcs /interwork 옵션을 사용하여 컴파일해야 합니다. Thumb 상태에서 ARM 함수가 호출되거나 ARM 상태에서 Thumb 함수가 호출될 경우 링커에서는 이를 감지하고 호출 및 복귀 시퀀스를 변경하거나 필요에 따라 프로세서 상태를 변경하도록 인터워킹 비니어를 삽입합니다.

참고

Thumb 함수에 대한 절대 주소를 사용하려면 4-16페이지의 Thumb 상태의 함수에 대한 포인터를 참조하십시오.

어셈블리 언어 코드를 작성할 경우에는 Procedure Call Standard for the ARM Architecture(AAPCS)의 인터워킹 변형 표준을 준수해야 합니다. 타겟 아키텍처 버전에 따라 여러 가지 방법으로 프로세서 상태를 변경할 수 있습니다. 자세한 내용은 4장 ARM과 Thumb의 인터워킹을 참조하십시오.

1.2.3 C, C++ 및 어셈블리 언어 조합

개별적으로 컴파일되고 어셈블된 C, C++ 및 ARM 어셈블리 언어 모듈을 프로그램에 함께 사용할 수 있습니다. 또한 C 또는 C++ 코드 내에 작은 어셈블리 언어 루틴을 작성할 수 있습니다. 이러한 루틴은 ARM 컴파일러의 인라인 또는 임베디드 어셈블러를 사용하여 컴파일됩니다. 그러나 인라인 또는 임베디드 어셈블러를 사용할 경우 작성할 수 있는 어셈블리 언어 코드에는 여러 가지 제한이 있습니다. 이러한 제한에 대해서는 컴파일러 사용 설명서의 6장 인라인 및 임베디드 어셈블러 사용에서 설명합니다.

1-4 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 17: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

소개

또한 5장 C, C++ 및 어셈블리 언어 조합에서는 C, C++ 및 어셈블리 언어 모듈 간의 호출 방법에 대한 일반적인 지침과 예제를 제공합니다.

1.2.4 프로세서 예외 처리

ARM 프로세서에서는 다음과 같은 예외 유형을 인식합니다.

리셋 프로세서 리셋 핀이 어설션될 때 발생합니다. 이 예외는 전원 켜짐 신호가 전달되거나 프로세서가 전원이 켜졌을 때와 같은 상태로 재설정되는 경우에만 발생합니다. 소프트 리셋은 리셋 벡터(0x0000)로 분기함으로써 수행할 수 있습니다.

정의되지 않은 명령어

프로세서 및 연결된 보조 프로세서 모두에서 현재 실행 중인 명령어를 인식할 수 없는 경우에 발생합니다.

관리자 호출(SVC - 이전의 SWI)

SVC는 사용자 정의 인터럽트 명령어입니다. 이 명령어는 사용자 모드에서 실행되는 프로그램이 RTOS 함수와 같이 관리자 모드에서 실행되며 권한이 필요한 작업을 요청할 수 있도록 합니다.

프리페치 어보트

프로세서가 잘못된 주소에서 프리페치된 명령어를 실행하려고 할 때 발생합니다. 잘못된 주소는 메모리가 존재하지 않는 주소이거나 메모리 관리 하위 시스템에서 현재 모드의 프로세서가 액세스할 수 없는 것으로 확인된 주소입니다.

데이터 어보트

데이터 전송 명령어가 잘못된 주소에서 데이터를 로드하거나 저장하려고 할 때 발생합니다.

인터럽트(IRQ)

프로세서 외부 인터럽트 요청 핀이 어셜션(LOW)되고 CPSR의 I 비트가 지워진 경우에 발생합니다.

고속 인터럽트(FIQ)

프로세서 외부 고속 인터럽트 요청 핀이 어셜션(LOW)되고 CPSR의 F 비트가 지워진 경우에 발생합니다. 이 예외는 일반적으로 인터럽트 지연을 최소로 유지해야 하는 경우에 사용됩니다.

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 1-5

Page 18: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

소개

고속 인터럽트는 Cortex-M1 또는 Cortex-M3 프로세서에서 사용할 수 없으며 모든 인터럽트에는 프로그래밍할 수 있는 우선순위 수준이 있습니다. 자세한 내용은 7장 Cortex-M3 프로세서 예외 처리를 참조하십시오.

일반적으로 임베디드 응용 프로그램과 같이 운영 체제를 사용하지 않고 예외를 처리하는 응용 프로그램을 작성할 경우 각 예외 유형에 대한 처리기를 작성해야 합니다.

SVC 또는 IRQ 인터럽트와 같은 예외 유형에 둘 이상의 원인이 있을 수 있는 경우 각 원인에 대한 예외 처리기를 연결할 수 있습니다.

Thumb 명령어를 지원하는 대부분의 프로세서에서는 예외가 처리되면 프로세서가 ARM 상태로 전환됩니다. 따라서 ARM 코드에서 예외 처리기를 작성할 수도 있고 비니어를 사용하여 Thumb 상태로 전환할 수도 있습니다. 자세한 내용은 6-10페이지의 복귀 주소 및 복귀 명령어를 참조하십시오.

Cortex-M1 및 Cortex-M3 프로세서에서는 ARM 명령어가 지원되지 않으며 프로세서가 예외를 처리할 때 Thumb 상태로 유지됩니다.

Thumb-2 명령어를 지원하는 다른 프로세서에서는 프로세서가 Thumb 상태로 전환되고 전체적으로 Thumb-2 코드로 구성된 처리기를 실행할 수 있습니다. 예외를 시작하기 위한 ARM 또는 Thumb 상태는 CP15 레지스터 1의 TE 비트를 사용하여 선택됩니다. 이 비트는 코어 HIGH에 TEINIT 입력을 입력하여 리셋 시 설정될 수 있습니다. 자세한 내용은 해당 프로세서의 기술 참조 문서를 참조하십시오.

1.2.5 AAPCS 사용

Procedure Call Standard for the ARM Architecture(AAPCS)에는 개별적으로 컴파일되고 어셈블된 여러 모듈을 함께 사용할 수 있도록 하기 위해 따라야 하는 레지스터 사용 방법 및 스택 규칙이 정의되어 있습니다. 기본 표준에 대한 여러 가지 변형도 정의되어 있습니다. ARM 컴파일러에서는 항상 선택한 AAPCS 변형 표준을 준수하는 코드를 생성합니다. 링커에서는 필요할 경우 함께 링크할 적절한 표준 C 또는 C++ 라이브러리를 선택합니다.

ARM 프로세서를 위한 코드를 개발할 때는 적절한 AAPCS 변형을 선택해야 합니다. 예를 들면 다음과 같습니다

• ARM 상태와 Thumb 상태 간에 인터워킹하는 코드를 작성하려면 컴파일러와 어셈블러에서 --apcs /interwork 옵션을 선택해야 합니다.

1-6 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 19: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

소개

• C 또는 C++로 코드를 작성하려면 먼저 컴파일된 각 모듈에 대해 호환 가능한 AAPCS 옵션을 선택해야 합니다.

• 어셈블리 언어 루틴을 직접 작성하려면 적절한 AAPCS 변형 표준을 준수해야 합니다.

자세한 내용은 install_directory\Documentation\Specifications\...에 있는 Procedure Call Standard for the ARM Architecture 사양(aapcs.pdf)을 참조하십시오.

참고

C와 어셈블리 언어를 함께 사용하려면 AAPCS의 관련 사항을 이해하고 있어야 합니다.

1.2.6 레거시 개체 및 라이브러리와의 호환성

이전 릴리스의 RVCT에서 업그레이드하려면 RealView Compilation Tools 핵심 설명서의 차이점 장에서 RVCT의 새 릴리스와 이전 릴리스 간 호환성에 대한 자세한 내용을 읽어 보십시오.

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 1-7

Page 20: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

소개

1-8 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 21: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

2장 임베디드 소프트웨어 개발

이 장에서는 타겟 시스템이 있는 상태나 없는 상태에서 RealView® Compilation Tools(RVCT)를 사용하여 임베디드 응용 프로그램을 개발하는 방법을 설명합니다. 여기에는 다음 단원이 포함되어 있습니다.

• 2-2페이지의 임베디드 소프트웨어 개발 개요

• 2-4페이지의 타겟 시스템이 없을 경우의 기본 컴파일 도구 동작

• 2-12페이지의 타켓 하드웨어에 맞게 C 라이브러리 조정

• 2-16페이지의 타켓 하드웨어에 맞게 이미지 메모리 맵 조정

• 2-27페이지의 리셋 및 초기화

• 2-37페이지의 기타 메모리 맵 고려 사항

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 2-1

Page 22: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

임베디드 소프트웨어 개발

2.1 임베디드 소프트웨어 개발 개요

대부분의 임베디드 응용 프로그램을 처음 개발할 때는 최종 제품에서 사용할 수 있는 리소스와는 다른 리소스를 사용하는 프로토타입 환경에서 작업이 수행됩니다. 따라서 개발 또는 디버깅 환경의 기능에 의존하는 시스템으로부터 타겟 하드웨어에서 독립적으로 실행되는 시스템으로 임베디드 응용 프로그램을 이동하는 것과 관련된 프로세스를 고려해야 합니다.

RVCT를 사용하여 임베디드 소프트웨어를 개발할 때 고려해야 할 사항은 다음과 같습니다.

• C 라이브러리에서 하드웨어를 사용하는 방식

• 일부 C 라이브러리 기능은 디버그 환경 리소스를 사용하여 실행됩니다. 디버그 환경 리소스를 사용하는 경우 타겟 하드웨어를 사용하도록 이 기능을 다시 구현해야 합니다.

• RVCT에는 기본적으로 특정 타겟의 메모리 맵에 대한 정보가 없습니다. 따라서 타겟 하드웨어의 메모리 레이아웃에 맞게 이미지 메모리 맵을 조정해야 합니다.

• 주 응용 프로그램을 실행하려면 먼저 임베디드 응용 프로그램에서 몇 가지 초기화 작업을 수행해야 합니다. 전체 초기화 시퀀스에는 RVCT C 라이브러리 초기화 루틴뿐 아니라 사용자가 구현하는 코드도 필요합니다.

2.1.1 예제 코드

이 장에서 다루는 내용을 쉽게 이해할 수 있도록 관련 예제 프로젝트가 제공되어 있습니다. 이 장에서 설명된 Dhrystone 빌드에 대한 코드는 주 예제 디렉토리의 ...\emb_sw_dev에 있습니다. 각 빌드는 별도의 디렉토리에 있으며 이 장의 이후 단원에서 설명하는 기술의 예제를 제공합니다. 각 빌드에 대한 자세한 내용은 다음을 참조하십시오.

• 2-11페이지의 빌드 1의 예제 코드

• 2-14페이지의 빌드 2의 예제 코드

• 2-23페이지의 빌드 3의 예제 코드

• 2-36페이지의 빌드 4의 예제 코드

• 2-38페이지의 빌드 5의 예제 코드

Dhrystone 벤치마킹 프로그램은 예제 프로젝트에 대한 코드 베이스를 제공합니다. Dhrystone이 선택된 것은 이 장에서 설명하는 대부분의 개념을 보여 줄 수 있기 때문입니다.

2-2 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 23: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

임베디드 소프트웨어 개발

예제 프로젝트는 ARM® Integrator™ 개발 플랫폼에서 실행되도록 조정되었습니다. 그러나 예제에서 보여 주는 원칙은 모든 타겟 하드웨어에 적용됩니다.

참고

이 장에서는 Dhrystone 프로그램에 대해서만 설명하는 것이 아니라 이 프로그램이 완전한 독립 실행형 시스템에서 실행되도록 하기 위해 수행해야 하는 단계에 대해서도 설명합니다. 벤치마킹 도구로서의 Dhrystone에 대한 자세한 내용은 Application Note 93 - Benchmarking with ARMulator®를 참조하십시오. ARM Application Notes는 ARM 웹 사이트(http://www.arm.com)의 Documentation 영역에서 다운로드할 수 있습니다.

Integrator에서 Dhrystone 빌드 실행

이 장에 설명하는 Dhrystone을 Integrator에서 실행하려면 다음을 수행해야 합니다.

• ROM/RAM 재매핑을 수행합니다. 이렇게 하려면 스위치 1과 4를 ON으로 설정하여 부트 모니터를 실행한 다음 보드를 재설정합니다.

• top_of_memory를 0x40000으로 설정하거나 DIMM 메모리 모듈에 맞춥니다. 이렇게 하지 않으면 기본 설정이 0x80000인 스택이 잘못된 메모리에 있게 될 수 있습니다.

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 2-3

Page 24: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

임베디드 소프트웨어 개발

2.2 타겟 시스템이 없을 경우의 기본 컴파일 도구 동작

임베디드 응용 프로그램의 소프트웨어에 대한 작업을 시작할 때는 타겟 하드웨어의 전체 기술 사양을 알지 못할 수 있습니다. 예를 들면 타겟 주변 기기나 메모리 맵, 심지어는 프로세서 자체에 대한 세부 사항을 모를 수 있습니다.

이러한 세부 사항을 알 수 없는 상태에서도 소프트웨어 개발을 진행할 수 있도록 컴파일 도구에는 응용 프로그램 코드를 즉시 빌드하고 디버깅할 수 있게 해 주는 기본 동작이 포함되어 있습니다. 이러한 기본 동작을 알고 있으면 기본 빌드에서 완전한 독립 실행형 응용 프로그램으로 이동하는 데 필요한 단계를 올바르게 파악할 수 있으므로 유용합니다.

2-4 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 25: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

임베디드 소프트웨어 개발

2.2.1 세미호스팅

ARM C 라이브러리에서 일부 ISO C 기능은 호스트 디버깅 환경을 통해 지원됩니다. 이 기능을 제공하는 메커니즘을 세미호스팅이라고 합니다.

세미호스팅은 ARMv7 시스템에서 BKPT 명령어를 사용하여 구현되고, ARM 이전의 시스템에서는 SVC 명령어를 사용하여 정의된 관리자 호출 연산을 통해 구현됩니다.

세미호스팅이 실행되면 디버그 에이전트에서는 이를 식별하고 프로그램 실행을 일시 중단합니다. 그런 다음 디버그 에이전트에서 세미호스팅 작업이 처리되고 코드 실행이 다시 시작됩니다. 따라서 호스트 자체에서 수행되는 작업은 프로그램에 투명합니다.

그림 2-1에서는 문자열을 디버거 콘솔에 출력하는 세미호스팅 작업의 예를 보여 줍니다.

그림 2-1 세미호스팅 작업의 예

참고

자세한 내용은 부록 A 세미호스팅을 참조하십시오.

����������������� ����������������������������������������� ������������������� !"#�$���������������������������

%������������

���������������� �&�����&�����&������������� ��'��� ��&�� ���&� �����������

����������������� ��� ��&���&�� ������& �(��� &����������

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 2-5

Page 26: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

임베디드 소프트웨어 개발

2.2.2 C 라이브러리 구조

개념적으로 C 라이브러리는 ISO C 언어 사양에 포함된 함수와 ISO C 언어 사양을 지원하는 함수로 나눌 수 있습니다. 그림 2-2에서는 이에 대해 보여 줍니다.

그림 2-2 C 라이브러리 구조

일부 ISO C 기능은 장치 드라이버 수준의 호스트 디버깅 환경에서 지원됩니다.

예를 들어 RVCT C 라이브러리는 디버거 콘솔 창에 출력하는 방식으로 ISO C printf() 계열의 함수를 구현합니다. 이 기능은 __sys_write()를 호출하면 제공됩니다. 이 함수는 세미호스팅 호출을 실행하여 콘솔에 문자열을 출력하는 지원 함수입니다.

)����

����*�����

�����&������

��+���&� ���

��&��

����&� ����������,����%����

��-����.

/������� ��������..������������(����������(���01

,�'�������'�����'���2 �� ���&� �����(����������33 . 3�����01

)�����������.�&�������������'��������

2-6 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 27: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

임베디드 소프트웨어 개발

2.2.3 기본 메모리 맵

메모리 맵이 설명되어 있지 않은 이미지에서 링커는 그림 2-3에서처럼 기본 메모리 맵에 따라 코드와 데이터를 배치합니다.

링커에서는 Cortex-M1 및 Cortex-M3에 기본 맵과 동일하지 않은 고정 메모리 맵이 있는 경우에도 Cortex-M1 및 Cortex-M3 모델에 이 기본 메모리 맵을 사용합니다. 기본 메모리 맵을 사용하는 Cortex-M1 및 Cortex-M3 프로세서의 모델은 작동하지만 이러한 시스템을 빌드할 수는 없습니다. Cortex-M1 및 Cortex-M3 고정 메모리 맵에 대한 자세한 내용은 2-25페이지의 ARMv6-M 및 ARMv7-M 메모리 맵을 참조하십시오.

그림 2-3 기본 메모리 맵

기본 메모리 맵은 다음과 같이 설명할 수 있습니다.

• 이미지는 링크되어 주소 0x8000에서 로드되고 실행됩니다. 모든 RO(읽기 전용) 섹션이 먼저 배치되고 그 다음에 RW(읽기- 쓰기) 섹션, ZI(0으로 초기화됨) 섹션 순으로 배치됩니다.

• 힙은 ZI 섹션의 바로 위에 배치되므로 정확한 위치는 링크 타임에 결정됩니다.

4)

56

5�

�7%�8

9:%;

/�������&� ����

,�����������+�����

���

������

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 2-7

Page 28: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

임베디드 소프트웨어 개발

• 스택 기준 위치는 응용 프로그램 시작 중에 세미호스팅 작업을 통해 제공됩니다. 이 세미호스팅 작업에서 반환되는 값은 디버그 환경에 따라 다릅니다.

— RealView ARMulator ISS(RVISS)는 구성 파일 peripherals.ami에 설정된 값을 반환합니다. 기본값은 0x08000000입니다.

— RealView ICE는 디버거 내부 변수 top_of_memory의 값을 반환합니다. 기본값은 0x00080000입니다.

2-8 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 29: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

임베디드 소프트웨어 개발

2.2.4 링커 배치 규칙

링커는 그림 2-4와 같은 일련의 규칙에 따라 메모리 내부 코드와 데이터를 배치할 위치를 결정합니다.

그림 2-4 링커 배치 규칙

이미지는 먼저 특성별로 구성되며, RO가 최하위 메모리 주소에 배치되고 그 다음에 RW, ZI 순으로 구성됩니다. 각 특성 내에서 코드가 데이터보다 먼저 배치됩니다.

여기서 링커는 이름에 따라 사전순으로 입력 섹션을 배치합니다.. 입력 섹션 이름은 어셈블러 AREA 지시문에 해당합니다.

입력 섹션에서 개별 개체의 코드와 데이터는 링커 명령 행에 지정된 개체 파일의 순서에 따라 배치됩니다.

코드 및 데이터의 정확한 배치를 위해 이러한 규칙을 사용하지 않는 것이 좋습니다. 대신 스캐터 로딩 메커니즘을 사용하여 코드 및 데이터의 배치를 제어해야 합니다. 자세한 내용은 2-16페이지의 타켓 하드웨어에 맞게 이미지 메모리 맵 조정을 참조하십시오.

참고

링커 및 유틸리티 설명서에서 5-2페이지의 스캐터 로딩 개요를 참조하십시오.

4)

56

5�

,%7%

��,:

<

%

�������%(����(���!��

�������%(����(��� ��

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 2-9

Page 30: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

임베디드 소프트웨어 개발

2.2.5 응용 프로그램 시작

대부분의 임베디드 시스템에서 초기화 시퀀스는 주 작업이 실행되기 전에 시스템을 설정하기 위해 실행됩니다.

그림 2-5에서는 기본 초기화 시퀀스를 보여 줍니다.

그림 2-5 기본 초기화 시퀀스

초기화 시퀀스는 크게 세 가지 기능 블록으로 나눌 수 있습니다. __main은 __scatterload로 직접 분기됩니다. 또한 __scatterload는 런타임 이미지 메모리 맵을 설정하고 __rt_entry(런타임 진입)는 C 라이브러리를 초기화합니다.

__scatterload는 코드 및 데이터를 복사하고 필요한 경우 RW 데이터의 압축을 풀고 ZI 데이터를 0으로 초기화합니다.

__scatterload는 __rt_entry로 분기되어 응용 프로그램 스택과 힙을 설정하고, 라이브러리 함수 및 해당 함수의 정적 데이터를 초기화하고, 전역으로 선언된 개체의 생성자를 호출합니다(C++만 해당).

��-����.

33 ��������������������.*������� �56���

����������=�������������=�����

2�:5���,:

���01������������ � ��&�����+������������������+���������.�����������������=���������

33��3����.���������� ������������� ��+�������������&������������������=�������.�(������� ����������������>��'��������������� ������� �0�??1

����������:����(�����������

33���

)�������.�����

��

����

�������������.����>����������

2-10 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 31: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

임베디드 소프트웨어 개발

그런 다음 __rt_entry가 응용 프로그램 진입점인 main()으로 분기됩니다. 주 응용 프로그램의 실행이 완료되면 __rt_entry는 라이브러리를 종료한 다음 제어권을 디버거에 다시 넘겨줍니다.

함수 레이블 main()에는 특별한 의미가 있습니다. main() 함수가 있으면 링커가 __main 및 __rt_entry의 초기화 코드에서 링크됩니다. main() 레이블이 붙은 함수가 없으면 초기화 시퀀스가 링크되지 않으므로 일부 표준 C 라이브러리 기능이 지원되지 않습니다. __main과 다른 시작 심볼을 통해 C 라이브러리를 사용하는 데 대한 자세한 내용은 링커 및 유틸리티 설명서의 2-17페이지의 이미지 내용 제어에서 --[no_]startup symbol을 참조하십시오.

2.2.6 빌드 1의 예제 코드

빌드 1은 Dhrystone 벤치마크의 기본 빌드입니다. 따라서 이 단원에 설명된 기본 RVCT 동작을 따릅니다. 자세한 내용은 2-3페이지의 Integrator에서 Dhrystone 빌드 실행과 주 예제 디렉토리의 ...\emb_sw_dev\build1에 있는 예제 빌드 파일을 참조하십시오.

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 2-11

Page 32: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

임베디드 소프트웨어 개발

2.3 타켓 하드웨어에 맞게 C 라이브러리 조정

기본적으로 C 라이브러리는 세미호스팅을 사용하여 장치 드라이버 수준 기능을 제공하므로 호스트 컴퓨터가 입력 및 출력 장치 역할을 할 수 있습니다. 이는 개발 하드웨어가 최종 시스템의 입력 및 출력 기능을 빠짐없이 갖추지 못한 경우가 많으므로 유용합니다.

2.3.1 C 라이브러리 타겟 조정

타켓 하드웨어를 사용하며 C 라이브러리의 구현을 위해 이미지에 자동으로 링크되는 C 라이브러리 함수를 구현할 수 있습니다. 그림 2-6에서는 C 라이브러리 타겟 조정이라고 하는 이 과정을 보여 줍니다.

그림 2-6 C 라이브러리 타겟 조정

예를 들어 UART와 같은 주변 I/O 장치가 있는 경우 디버거 콘솔에 출력하는 fputc()의 라이브러리 구현을 무시하고 UART로 출력하는 라이브러리를 구현할 수 있습니다. fputc()의 이러한 구현은 최종 이미지에 링크되므로 printf() 계열의 함수 전체가 UART로 출력하게 됩니다.

)����

)���*�����

����&� ���������

)����

)���*�����

5������

,����%����

��-����. 2 ������

7����9�����

2-12 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 33: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

임베디드 소프트웨어 개발

예제 2-1에서는 fputc()의 구현 예제를 보여 줍니다. 이 예제에서는 직렬 출력 함수 sendchar()이 별도의 소스 파일에 구현되어 있다고 가정하고 fputc()의 입력 문자 매개변수를 이 함수로 리디렉션합니다. 이러한 방식으로 fputc()는 타켓 종속 출력과 C 라이브러리 표준 출력 함수 간의 추상 계층 역할을 합니다.

예제 2-1 fputc()의 구현

extern void sendchar(char *ch);

int fputc(int ch, FILE *f){ /* e.g. write a character to an UART */ char tempch = ch; sendchar(&tempch); return ch;}

2.3.2 C 라이브러리 세미호스팅 사용 안 함

독립 실행형 응용 프로그램에서는 대개 세미호스팅 작업을 지원할 필요가 없습니다. 따라서 C 라이브러리 세미호스팅 함수가 응용 프로그램에 링크되지 않도록 해야 합니다.

세미호스팅을 사용하는 함수가 C 라이브러리에서 링크되지 않도록 하려면 __use_no_semihosting 심볼을 가져와야 합니다. 다음과 같은 방법으로 프로젝트의 C 또는 어셈블러 소스 파일에서 이 심볼을 가져올 수 있습니다.

• C 모듈에서 #pragma 지시문을 사용합니다.

#pragma import(__use_no_semihosting)

• 어셈블러 모듈에서 IMPORT 지시문을 사용합니다.

IMPORT __use_no_semihosting

세미호스팅을 사용하는 함수가 아직 링크되어 있으면 링커에서 오류가 보고됩니다.

이러한 함수를 확인하려면 --verbose 옵션을 사용하여 링크합니다. 결과 출력에서 C 라이브러리 함수는 __I_use_semihosting으로 태그가 지정됩니다. 예를 들면 다음과 같습니다.

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 2-13

Page 34: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

임베디드 소프트웨어 개발

Loading member sys_exit.o from c_a__un.l. definition: _sys_exit reference : __I_use_semihosting

이러한 함수(이 예제의 경우 _sys_exit)는 개발자가 구현해야 합니다.

참고

링커에서 응용 프로그램 코드의 세미호스팅 함수는 보고되지 않습니다. 이러한 유형의 함수가 C 라이브러리에서 링크된 경우에만 오류가 발생합니다.

세미호스팅을 사용하는 C 라이브러리 함수의 전체 목록은 부록 A 세미호스팅을 참조하십시오.

2.3.3 빌드 2의 예제 코드

Dhrystone 벤치마크의 빌드 2에서는 클럭킹 및 문자열 I/O에 Integrator 플랫폼의 하드웨어를 사용합니다. 자세한 내용은 주 예제 디렉토리의 ...\emb_sw_dev\build2에 있는 예제 빌드 파일을 참조하십시오.

빌드 2에서는 예제 프로젝트의 빌드 1이 다음과 같이 변경되었습니다.

C 라이브러리 타겟 조정

타겟이 조정된 ISO C 함수 계층이 추가되었습니다. 이러한 함수로는 표준 I/O 함수 및 클럭 기능과 몇 가지 추가 오류 신호 및 프로그램 종료 함수가 있습니다.

타켓 종속 장치 드라이버

타켓 하드웨어 주변 기기와 직접 상호 작용하는 장치 드라이버 계층이 추가되었습니다.

자세한 내용은 2-3페이지의 Integrator에서 Dhrystone 빌드 실행을 참조하십시오.

이 프로젝트에는 __use_no_semihosting심볼을 가져오지 않습니다. 이는 C 라이브러리를 초기화하는 동안 세미호스팅 호출이 실행되어 응용 프로그램 스택 및 힙 위치가 설정되기 때문입니다. 스택 및 힙 설정의 타겟 조정에 대한 자세한 내용은 2-21페이지의 스택 및 힙 배치를 참조하십시오.

2-14 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 35: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

임베디드 소프트웨어 개발

참고

출력을 보려면 터미널 또는 터미널 에뮬레이터를 직렬 포트 A에 연결해야 합니다. 직렬 포트는 38400보드, 패리티 없음, 1 정지 비트 및 흐름 제어 없음으로 설정해야 합니다. 또한 터미널에서 받는 줄 끝에 줄 바꿈이 추가되고 입력된 문자가 터미널 창에 표시되도록 구성해야 합니다.

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 2-15

Page 36: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

임베디드 소프트웨어 개발

2.4 타켓 하드웨어에 맞게 이미지 메모리 맵 조정

세미호스팅 기능이 없는 최종 임베디드 시스템에서는 대개 기본 메모리 맵을 사용할 필요가 없습니다. 타겟 하드웨어에는 일반적으로 각기 다른 주소 범위에 있는 메모리 장치가 여러 개 있습니다. 이러한 장치를 최대한 사용하려면 로드 및 런타임에 별도의 메모리 뷰가 있어야 합니다.

2.4.1 스캐터 로딩

스캐터 로딩을 사용하면 스캐터 로딩 설명 파일이라고 하는 텍스트 형식의 설명 파일에서 코드 및 데이터의 메모리 내 로드 타임 및 런타임 위치를 설명할 수 있습니다. 이 파일은 명령 행에서 --scatter 옵션을 사용하여 링커에 전달됩니다. 예를 들면 다음과 같습니다.

armlink --scatter scat.txt file1.o file2.o

스캐터 로딩 설명 파일은 주소가 지정된 메모리 영역에서 로드 타임 및 런타임에 코드 및 데이터를 배치해야 하는 위치를 링커에 알려 줍니다.

스캐터 로딩 영역

스캐터 로딩 영역은 다음 두 범주로 나뉩니다.

• 리셋 및 로드 시에 응용 프로그램 코드 및 데이터를 포함하는 로드 영역

• 응용 프로그램이 실행되는 동안 코드와 데이터를 포함하는 실행 영역. 응용 프로그램이 시작될 때 각 로드 영역에서 실행 영역이 하나 이상 만들어집니다.

이미지의 모든 코드와 데이터는 정확히 하나의 로드 영역과 하나의 실행 영역에 포함됩니다.

시작할 때 __main의 C 라이브러리 초기화 코드에서는 이미지 로드 뷰에서 실행 뷰로 이동하는 데 필요한 코드와 데이터를 복사하고 0으로 초기화합니다.

2-16 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 37: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

임베디드 소프트웨어 개발

2.4.2 스캐터 로딩 설명 파일 구문

스캐터 로딩 설명 파일 구문은 스캐터 로딩 자체에서 제공되는 기능을 반영합니다. 그림 2-7에서는 이 파일 구문을 보여 줍니다.

그림 2-7 스캐터 로딩 설명 파일 구문

영역은 영역 이름 및 시작 주소와 그 밖의 여러 요소를 포함하는 헤더 태그로 정의됩니다. 필요한 경우 최대 길이와 다양한 특성을 추가할 수 있습니다.

영역의 내용은 영역 유형에 따라 다릅니다.

• 로드 영역에는 최소한 하나의 실행 영역이 있어야 합니다. 실제로 각 로드 영역에는 대개 여러 개의 실행 영역이 있습니다.

• 실행 영역은 EMPTY 특성을 사용하여 선언되지 않은 경우 최소한 하나의 코드 또는 데이터 섹션이 있어야 합니다. EMPTY 특성이 설정되지 않은 영역에는 일반적으로 소스 또는 라이브러리 개체 파일이 포함되어 있습니다. 와일드카드(*) 구문을 사용하면 스캐터 로딩 설명 파일의 다른 곳에서 특정 특성이 지정되지 않은 모든 섹션을 그룹화할 수 있습니다.

참고

스캐터 로딩 설명 파일 구문에 대한 자세한 내용은 링커 및 유틸리티 설명서에서 5장 스캐터 로딩 설명 파일 사용을 참조하십시오.

�@35:A)�B��������������������C����������� ��(�������D

�����(������� ��������

������������&������

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 2-17

Page 38: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

임베디드 소프트웨어 개발

2.4.3 스캐터 로딩 설명 파일 예제

그림 2-8에서는 간단한 스캐터 로딩 예제를 보여 줍니다.

그림 2-8 간단한 스캐터 로딩 예제

이 예제에는 주소 0x0000에서 시작하여 모든 코드와 데이터를 포함하는 로드 영역이 하나 있습니다. 이 로드 영역에서 실행 영역이 두 개 만들어집니다. 한 영역에는 로드 위치와 동일한 주소에서 실행되는 모든 RO 코드와 데이터가 들어 있습니다. 다른 영역은 주소 0x10000에 있으며 모든 RW 및 ZI 데이터를 포함합니다.

예제 2-2에서는 그림 2-8의 메모리 맵을 설명하는 설명 파일을 보여 줍니다.

예제 2-2 간단한 스캐터 로딩 설명 파일

ROM_LOAD 0x0000 0x4000{ ROM_EXEC 0x0000 0x4000; Root region { * (+RO); All code and constant data }

56

5� 5�

4)

56

/������&=���

��.*�������

-������� :������������������

5%�

�������

�������

5%�

�������

������

5��

������

������

5��

������

2-18 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 39: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

임베디드 소프트웨어 개발

RAM 0x10000 0x8000 { * (+RW, +ZI); All non-constant data }}

2.4.4 스캐터 로딩 설명 파일에 개체 배치

대부분의 이미지에서는 2-18페이지의 예제 2-2에서처럼 모든 특성을 함께 그룹화하지 않고 특정 코드 및 데이터 섹션의 배치를 제어합니다. 이렇게 하려면 와일드카드 구문만 사용하는 것이 아니라 설명 파일에서 개별 개체를 직접 지정합니다.

참고

설명 파일 실행 영역의 개체 순서는 출력 이미지에서의 개체 순서에 영향을 주지 않습니다. 2-9페이지의 링커 배치 규칙에서 설명한 링커 배치 규칙은 각 실행 영역에 적용됩니다.

표준 링커 배치 규칙을 무시하려면 스캐터 로딩 지시문 +FIRST 및 +LAST를 사용합니다. 예제 2-3에서는 실행 영역의 시작 부분에 벡터 테이블을 배치하는 스캐터 로딩 설명 파일을 보여 줍니다. 이 예제에서 vectors.o의 Vect 영역은 주소 0x0000에 배치됩니다.

예제 2-3 섹션 배치

ROM_LOAD 0x0000 0x4000{ ROM_EXEC 0x0000 0x4000 { vectors.o (Vect, +FIRST) * (+RO) } ; more exec regions...}

스캐터 로딩 설명 파일에 개체를 배치하는 데 대한 자세한 내용은 링커 및 유틸리티 설명서에서 5장 스캐터 로딩 설명 파일 사용을 참조하십시오.

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 2-19

Page 40: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

임베디드 소프트웨어 개발

2.4.5 루트 영역

루트 영역은 해당 실행 주소와 동일한 로드 주소를 갖는 실행 영역입니다. 각 스캐터 로딩 설명 파일에는 루트 영역이 하나 이상 있어야 합니다.

스캐터 로딩을 사용할 경우 코드와 데이터를 복사하거나 0으로 초기화하는 경우처럼 실행 영역을 만들어야 하는 코드와 데이터를 다른 위치에 복사할 수 없다는 제한 사항이 있습니다. 따라서 루트 영역에 다음 섹션을 추가해야 합니다.

• 코드와 데이터를 복사하는 코드가 포함된 __main.o 및 __scatter*.o

• 압축 해제를 수행하는 __dc*.o

• 복사하거나 압축을 해제할 코드 및 데이터의 주소가 포함된 Region$$Table 섹션

그러나 이러한 섹션은 InRoot$$Sections를 사용하여 설명할 수 있습니다.

이러한 섹션은 읽기 전용으로 정의되어 있기 때문에 * (+RO) 와일드카드 구문을 기준으로 그룹화됩니다. 따라서 * (+RO)가 루트가 아닌 영역에 지정된 경우 루트 영역에 이러한 섹션을 명시적으로 선언해야 합니다. 예제 2-4에서는 이 방법을 보여 줍니다.

예제 2-4 루트 영역 지정

ROM_LOAD 0x0000 0x4000{ ROM_EXEC 0x0000 0x4000 ; root region { vectors.o (Vect, +FIRST) ; Vector table * (InRoot$$Sections) ; All library sections that must be in a ; root region, for example, __main.o, ; __scatter*.o, __dc*.o, and * Region$$Table } RAM 0x10000 0x8000 { * (+RO, +RW, +ZI) ; all other sections }}

__main.o, __scatter.o, __dc*.o 및 Region$$Table을 루트 영역에 추가하지 못하면 링커에서 오류 메시지가 생성됩니다.

2-20 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 41: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

임베디드 소프트웨어 개발

2.4.6 스택 및 힙 배치

스캐터 로딩을 사용할 경우 코드와 정적으로 할당된 데이터를 이미지에 배치할 방식을 지정할 수 있습니다. 응용 프로그램 스택 및 힙은 C 라이브러리를 초기화하는 동안 설정됩니다. __user_initial_stackheap() 함수를 다시 구현하여 스택 및 힙 배치를 조정할 수 있습니다. 또는 특별하게 명명된 ARM_LIB_HEAP 및 ARM_LIB_STACK 실행 영역을 사용할 수 있습니다. 자세한 내용은 링커 및 유틸리티 설명서에서 5-3페이지의 스캐터 로딩 설명 파일을 통한 스택 및 힙 지정을 참조하십시오.

2.4.7 런타임 메모리 모델

제공되는 런타임 메모리 모델에는 다음 두 가지가 있습니다. 두 런타임 메모리 모델 모두에서 스택 증가는 확인되지 않습니다.

참고

이 두 예제는 모두 Integrator 시스템에 적합합니다.

단일 영역 모델

기본 모델인 단일 영역 모델에서 응용 프로그램 스택과 힙은 같은 메모리 영역에서 서로 반대 방향으로 늘어납니다. 이 경우 새 힙 공간이 할당되면(예: malloc()가 호출되는 경우) 스택 포인터의 값을 기준으로 힙이 확인됩니다.

2-22페이지의 그림 2-9와 2-22페이지의 예제 2-5에서는 간단한 단일 영역 모델을 구현하는 __user_initial_stackheap()의 예제를 보여 줍니다. 여기서 스택은 주소 0x40000에서 시작하여 아래쪽으로 늘어나고 힙은 주소 0x20000에서 시작하여 위쪽으로 늘어납니다.

루틴은 레지스터 r0 및 r1로 적절한 값을 로드한 다음 복귀합니다. 단일 영역 모델에서는 힙 한계가 사용되지 않으므로 레지스터 r2는 변경되지 않습니다. 레지스터 r3은 사용되지 않습니다.

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 2-21

Page 42: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

임베디드 소프트웨어 개발

그림 2-9 단일 영역 모델

예제 2-5 단일 영역 모델 루틴

EXPORT __user_initial_stackheap

__user_initial_stackheap LDR r0, =0x20000 ;HB LDR r1, =0x40000 ;SB ; r2 not used (HL) ; r3 not used MOV pc, lr

이중 영역 모델

시스템을 설계할 때 스택과 힙을 개별 메모리 영역에 배치해야 하는 경우가 있습니다.

예를 들어 스택 전용으로 예약하려는 작은 고속 RAM 블록이 있을 수 있습니다. 이중 영역 모델을 사용할 것임을 링커에 알리려면 어셈블러 IMPORT 지시문을 사용하여 __use_two_region_memory 심볼을 가져와야 합니다. 그러면 힙은 전용 힙 한계를 기준으로 확인됩니다. 이 한계는 __user_initial_stackheap()을 통해 설정됩니다.

2-23페이지의 그림 2-10과 2-23페이지의 예제 2-6에서는 이중 영역 모델을 구현하는 예제를 보여 줍니다.

이 예제에서 힙은 0x28000000에서 0x28080000 방향으로 늘어나고 스택은 0x40000에서 시작하여 아래로 늘어납니다.

�7%�8

9:%; �������

��������<

9<

2-22 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 43: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

임베디드 소프트웨어 개발

그림 2-10 이중 영역 모델

예제 2-6 이중 영역 모델 루틴

IMPORT __use_two_region_memory EXPORT __user_initial_stackheap

__user_initial_stackheap LDR r0, =0x28000000 ;HB LDR r1, =0x40000 ;SB LDR r2, =0x28080000 ;HL

; r3 not used MOV pc, lr

2.4.8 빌드 3의 예제 코드

예제의 빌드 3에서는 스캐터 로딩을 구현하며, 다시 구현된 __user_initial_stackheap()을 포함합니다. 자세한 내용은 주 예제 디렉토리의 ...\emb_sw_dev\build3에 있는 예제 빌드 파일을 참조하십시오.

빌드 3에서는 예제 프로젝트의 빌드 2가 다음과 같이 수정되었습니다.

스캐터 로딩

간단한 스캐터 로딩 설명 파일이 링커에 전달됩니다.

타겟이 조정된 __user_initial_stackheap()

단일 영역 또는 이중 영역 구현 중 하나를 선택할 수 있습니다. 기본 빌드에서는 단일 영역을 사용합니다. 어셈블할 때 TWO_REGION_MODEL을 정의하면 이중 영역 구현을 선택할 수 있습니다.

9:%; ����������

����������

�7%�8 ��������<

9<

9-

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 2-23

Page 44: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

임베디드 소프트웨어 개발

C 라이브러리 세미호스팅 사용 안 함

이미지에 C 라이브러리 세미호스팅 기능이 더 이상 없으므로 __use_no_semihosting 심볼을 빌드 3으로 가져옵니다.

참고

clock()에 세미호스팅을 사용하지 않도록 하기 위해 이 심볼은 Integrator AP에서 RTC(실시간 클럭)를 읽도록 타겟이 조정되었습니다. RTC는 최소 단위가 초이므로 Dhrystone의 결과는 정확하지 않습니다. 이 메커니즘은 빌드 4에서 향상됩니다(2-36페이지의 빌드 4의 예제 코드 참조).

Integrator AP에서 이 빌드를 실행하려면 ROM/RAM 재매핑을 수행해야 합니다. 이렇게 하려면 스위치 1과 4를 ON으로 설정하여 부트 모니터를 실행합니다.

자세한 내용은 2-3페이지의 Integrator에서 Dhrystone 빌드 실행을 참조하십시오.

참고

ARM7 코어 기반의 타겟을 사용할 경우 벡터 캐치와 세미호스팅을 모두 사용하지 않도록 설정해야 합니다. 그렇지 않으면 디버거에서는 주소 0x0 및 0x1C 사이에서의 명령어 실행을 예외로 해석하고 대화 상자에서 이를 보고합니다. 벡터 캐치와 세미호스팅을 사용하지 않도록 설정하는 방법에 대한 자세한 내용은 디버거 설명서를 참조하십시오.

2-24 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 45: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

임베디드 소프트웨어 개발

2.4.9 ARMv6-M 및 ARMv7-M 메모리 맵

대부분의 이전 ARM 코어와 달리 ARMv6-M 및 ARMv7-M 프로세서 기반 장치의 메모리 맵에 대한 전체적인 레이아웃은 고정되어 있습니다. 따라서 이러한 프로세서 기반의 서로 다른 시스템 간에 소프트웨어를 더욱 쉽게 이식할 수 있습니다.

표 2-1에서는 이러한 메모리 맵의 주요 부분을 보여 줍니다.

SRAM 및 주변 기기 영역에는 각각 비트 밴드 기능이 있습니다. 비트 밴드 별칭이라고 하는 다른 주소에서 비트 밴드 영역의 각 비트에 개별적으로 액세스할 수 있습니다. 예를 들어 0x20000001에 있는 워드의 비트[13]에 액세스하려면 주소 0x2200002D를 사용할 수 있습니다.

표 2-2에서는 SRAM 및 주변 기기 메모리 영역에 있는 비트 밴드 영역과 별칭을 보여 줍니다.

표 2-1

메모리 영역 설명 액세스 수단 주소 범위

코드 일반적으로 플래시 SRAM 또는 ROM ICode 및 Dcode 버스 0x00000000-0x1FFFFFFF

SRAM 비트 밴딩 기능이 포함된 칩 내부 SRAM 시스템 버스 0x20000000-0x3FFFFFFF

주변 기기 비트 밴딩 기능이 포함된 일반 주변 기기 시스템 버스 0x40000000-0x5FFFFFFF

외부 RAM 외부 메모리 시스템 버스 0x60000000-0x9FFFFFFF

외부 장치 외부 주변 기기 또는 공유 메모리 시스템 버스 0xA0000000-0xDFFFFFFF

전용 주변 기기 버스 시스템 장치(2-26페이지의 표 2-3 참조) 시스템 버스 0xE0000000-0xE00FFFFF

공급업체용 - - 0xE0100000-0xfFFFFFFF

표 2-2

메모리 영역 설명 주소 범위

SRAM 비트 밴드 영역 0x20000000-0x200FFFFF

비트 밴드 별칭 0x22000000-0x23FFFFFF

주변 기기 비트 밴드 영역 0x40000000-0x400FFFFF

비트 밴드 별칭 0x42000000-0x43FFFFFF

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 2-25

Page 46: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

임베디드 소프트웨어 개발

표 2-3에서는 전용 주변 기기 버스 메모리 영역에 있는 하위 부분을 보여 줍니다.

표 2-3

메모리 영역 설명 주소 범위

전용 주변 기기 버스, 외부 ITM 0xE0000000-0xE0000FFF

DWT 0xE0001000-0xE0001FFF

FPB 0xE0002000-0xE0002FFF

예약되어 있음 0xE0003000-0xE000DFFF

시스템 제어 공간 0xE000E000-0xE000EFFF

예약되어 있음 0xE000F000-0xE003FFFF

전용 주변 기기 버스, 내부 TPIU 0xE0040000-0xE0040FFF

ETM 0xE0041000-0xE0041FFF

외부 PPB 0xE0042000-0xE00FEFFF

ROM 테이블 0xE00FF000-0xE00FFFFF

2-26 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 47: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

임베디드 소프트웨어 개발

2.5 리셋 및 초기화

지금까지 이 장에서는 C 라이브러리 초기화 루틴의 진입점인 __main에서 실행이 시작된다고 가정했습니다. 실제로 타겟 하드웨어의 모든 임베디드 응용 프로그램은 시작될 때 시스템 수준 초기화를 수행합니다. 이 단원에서는 이 작업에 대해 자세히 설명합니다.

2.5.1 초기화 시퀀스

그림 2-11에서는 ARM 아키텍처 기반의 임베디드 시스템에 사용할 수 있는 초기화 시퀀스를 보여 줍니다.

그림 2-11 초기화 시퀀스

리셋 처리기는 시스템이 시작될 때 바로 실행됩니다. $Sub$$main() 레이블이 붙은 코드 블록은 주 응용 프로그램이 시작되기 바로 전에 실행됩니다.

리셋 처리기는 어셈블러에서 코딩된 짧은 모듈로서, 시스템이 재설정될 때 실행됩니다. 최소한 리셋 처리기는 응용 프로그램이 실행되는 모드의 스택 포인터를 초기화합니다. 캐시, TCM(Tightly Coupled Memory), MMU(Memory Management Unit), MPU(Memory Protection Unit)와 같은 지역 메모리 시스템이 있는 코어의 경

��-����. 2�:5���,:

33� ��3������3 ��+&�01���������� ������������� ��+�������������&�

���01������������ � ��&�����+���������+������������������.��������=������������������

E���EE���01������������������&� ���������������������

�� ���&����������������������=�� ��+������� �������������(��������2*�;2���������� ������&�*���������������7��

!

#

$

F

G

33��3����.�����������������=�������.����������(������� ����������������>��'��������������� ������� �0�??1

����������:����(�����������

33���

"

���

���33 ��������������������.*������� �56���������������.����>��������������������=�������������=�������

)�������.�����

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 2-27

Page 48: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

임베디드 소프트웨어 개발

우, 초기화 프로세스의 이 단계에서 몇 가지 구성 작업이 수행되어야 합니다. 실행 후 리셋 처리기는 일반적으로 __main으로 분기되어 C 라이브러리 초기화 시퀀스를 시작합니다.

인터럽트 활성화와 같이 일반적으로 C 라이브러리 초기화 코드의 실행이 완료된 후에 수행되는 몇 가지 시스템 초기화 구성요소가 있습니다. $Sub$$main() 레이블이 붙은 코드 블록에서는 주 응용 프로그램의 실행이 시작되기 바로 전에 이러한 작업을 수행합니다.

초기화 시퀀스의 다양한 구성요소에 대한 자세한 내용은 벡터 테이블을 참조하십시오.

2.5.2 벡터 테이블

모든 ARM 시스템에는 벡터 테이블이 있습니다. 벡터 테이블은 초기화 시퀀스의 구성요소는 아니지만 예외를 처리하는 데 필요합니다.

참고

이 단원은 ARMv6-M 또는 ARMv7-M 프로세서에는 적용되지 않습니다. 이러한 프로세서의 벡터 테이블에 대한 자세한 내용은 7-6페이지의 벡터 테이블을 참조하십시오.

예제 2-7의 코드에서는 다른 모듈에 코딩되어 있는 여러 가지 예외 처리기를 가져옵니다. 벡터 테이블은 예외 처리기에 대한 분기 명령어 목록입니다.

FIQ 처리기는 주소 0x1C에 직접 배치됩니다. 이 경우 FIQ 처리기로의 분기를 실행하지 않아도 되므로 FIQ 응답 시간이 최적화됩니다.

예제 2-7 벡터 테이블 코드

PRESERVE8

AREA Vectors, CODE, READONLY IMPORT Reset_Handler; import other exception handlers ; ... ENTRY B Reset_Handler B Undefined_Handler B SVC_Handler B Prefetch_Handler B Abort_Handler

2-28 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 49: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

임베디드 소프트웨어 개발

NOP ; Reserved vector B IRQ_Handler B FIQ_Handler END

참고

벡터 테이블은 ENTRY 레이블로 표시됩니다. 이 레이블은 해당 코드가 사용 가능한 진입점임을 링커에 알리므로 링크 타임에 이미지에서 이 레이블을 제거할 수 없습니다. 링커 옵션 --entry를 사용하여 사용 가능한 이미지 진입점 중 하나를 응용 프로그램의 실제 진입점으로 선택해야 합니다. 자세한 내용은 링커 및 유틸리티 설명서에서 2-17페이지의 이미지 내용 제어를 참조하십시오.

2.5.3 ROM/RAM 재매핑

시스템에서 실행할 첫 번째 명령어의 주소인 0x0000에 있는 메모리 종류를 고려해야 합니다.

참고

이 단원에서는 ARM 코어가 0x0000에서 명령어 가져오기를 시작한다고 가정합니다. ARM 코어 기반의 시스템에서는 일반적으로 이 주소에서 명령어를 가져오기 시작합니다. 그러나 일부 ARM 코어의 경우 0xFFFF0000에서 명령어 가져오기를 시작하도록 구성할 수 있습니다.

시작할 때 0x0000에 올바른 명령어가 있어야 하므로 리셋 시에 0x0000에 비휘발성 메모리가 있어야 합니다.

이렇게 구성하는 한 가지 방법은 ROM을 0x0000에 배치하는 것입니다. 그러나 이 구성에는 몇 가지 단점이 있습니다. ROM의 액세스 속도는 일반적으로 RAM의 액세스 속도보다 느리지만 예외 처리기로 분기할 때 성능이 지나치게 저하되는 경우에는 시스템에 문제가 생길 수 있습니다. 또한 ROM에서 벡터 테이블을 배치할 경우 런타임에 벡터 테이블을 수정할 수 없습니다.

2-30페이지의 그림 2-12에서는 다른 방법을 보여 줍니다. ROM이 주소 0x10000에 배치되지만 리셋 시 이 메모리는 메모리 컨트롤러에 의해 0으로 별칭이 지정됩니다. 리셋 후 리셋 처리기의 코드는 ROM의 실제 주소로 분기됩니다. 그런 다음 메모리 컨트롤러는 별칭이 지정된 ROM을 제거하므로 RAM이 주소 0x0000에 표시됩니다. __main에서는 벡터 테이블이 RAM의 0x0000으로 복사되므로 예외를 처리할 수 있게 됩니다.

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 2-29

Page 50: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

임베디드 소프트웨어 개발

그림 2-12 ROM/RAM 재매핑

예제 2-8에서는 ARM 어셈블러 모듈에서 ROM/RAM 재매핑을 구현하는 방법을 보여 줍니다. 여기에 표시된 상수는 Integrator 플랫폼에서 사용할 수 있는 상수이지만 유사한 방식으로 ROM/RAM 재매핑을 구현하는 모든 플랫폼에서 같은 방법을 적용할 수 있습니다.

예제 2-8 ROM/RAM 재매핑

; --- Integrator CM control regCM_ctl_reg EQU 0x1000000C ; Address of CM Control RegisterRemap_bit EQU 0x04 ; Bit 2 is remap bit of CM_ctl

ENTRY

; Code execution starts here on reset; On reset, an alias of ROM is at 0x0, so jump to 'real' ROM. LDR pc, =Instruct_2

Instruct_2

5� ���9����� 5� ���9����� 5� ���9�����

5� ���9����� 5� ���9����� ������

�������

�������

5��

������

������

%�� ��5��

�������

�������

5��

������

������

5%�

! "

<���&������5��

5���'�%��

2-30 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 51: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

임베디드 소프트웨어 개발

; Remap by setting Remap bit of the CM_ctl register LDR r1, =CM_ctl_reg LDR r0, [r1] ORR r0, r0, #Remap_bit STR r0, [r1]

; RAM is now at 0x0.; The exception vectors must be copied from ROM to RAM (in __main)

; Reset_Handler follows on from here

첫 번째 명령어는 별칭이 지정된 ROM에서 실제 ROM으로 점프하는 명령어입니다. 이 작업은 실제 ROM 주소에 Instruct_2 레이블이 있기 때문에 수행 가능합니다.

이 단계 후에는 Integrator 코어 모듈 제어 레지스터의 재매핑 비트를 반전시킴으로써 ROM의 별칭이 제거됩니다.

이 코드는 일반적으로 시스템 리셋 직후에 실행됩니다. C 라이브러리 초기화 코드를 실행하려면 먼저 재매핑을 완료해야 합니다.

참고

MMU가 있는 시스템에서 재매핑은 시스템 시작 시 MMU 구성을 통해 구현할 수 있습니다.

2.5.4 지역 메모리 설정 고려 사항

대부분의 ARM 코어에는 MMU 또는 MPU와 같은 칩 내부 메모리 시스템이 있습니다. 이러한 장치는 일반적으로 시스템을 시작하는 동안 설정되고 활성화됩니다. 따라서 지역 메모리 시스템이 있는 코어의 경우 초기화 시퀀스에서 특별히 고려해야 할 사항이 있습니다.

이 장에서 설명한 대로 __main의 C 라이브러리 초기화 코드는 이미지의 실행 시 메모리 맵을 설정합니다. 따라서 __main으로 분기하기 전에 프로세서 코어의 런타임 메모리 뷰를 설정해야 합니다. 즉, 모든 MMU 또는 MPU를 리셋 처리기에서 설정하고 활성화해야 합니다.

또한 대개는 코드 및 데이터를 TCM으로 스캐터 로드하므로 __main으로 분기하기 전에(일반적으로 MMU/MPU를 설정하기 전에) TCM도 활성화해야 합니다. TCM이 활성화된 경우 TCM으로 마스킹된 메모리에 액세스할 필요가 없다는 점에 유의하십시오.

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 2-31

Page 52: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

임베디드 소프트웨어 개발

또한 __main으로 분기하기 전에 캐시가 활성화된 경우 캐시 일관성 문제가 있을 수 있습니다. __main의 코드는 해당 로드 주소의 코드 영역을 해당 실행 주소로 복사하며, 본질적으로 명령어를 데이터로 처리합니다. 그 결과 일부 명령어는 데이터 캐시에 캐시될 수 있으며 이 경우 명령어가 명령어 경로에 표시되지 않습니다.

이러한 일관성 문제가 발생하지 않도록 하려면 C 라이브러리 초기화 시퀀스의 실행이 완료된 후에 캐시를 활성화합니다.

2.5.5 스캐터 로딩 및 메모리 설정

ROM/RAM 재매핑이나 MMU 구성을 통해 코어의 리셋 시 메모리 뷰가 변경된 시스템에서 스캐터 로딩 설명 파일은 재매핑이 수행된 이후의 이미지 메모리 맵을 설명해야 합니다.

예제 2-9의 설명 파일은 2-29페이지의 ROM/RAM 재매핑의 예제를 재매핑한 결과와 관련이 있습니다.

예제 2-9

ROM_LOAD 0x10000 0x8000{ ROM_EXEC 0x10000 0x8000 { reset_handler.o (+RO, +FIRST) ; executed on hard reset ... }

RAM 0x0000 0x4000 { vectors.o (+RO, +FIRST) ; vector table copied ; from ROM to RAM at zero ... }}

로드 영역 ROM_LOAD는 0x10000에 배치됩니다. 이 주소는 재매핑이 수행된 후의 코드 및 데이터 로드 주소를 나타내기 때문입니다.

2-32 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 53: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

임베디드 소프트웨어 개발

2.5.6 스택 포인터 초기화

리셋 처리기는 적어도 응용 프로그램에서 사용하는 모든 실행 모드의 스택 포인터에 초기값을 지정해야 합니다.

2-33페이지의 예제 2-10에서 스택은 stack_base에 있습니다. 이 심볼은 하드 코딩된 주소일 수도 있고, 별도의 어셈블러 소스 파일에 정의되어 스캐터 로딩 설명 파일에서 찾을 수도 있습니다. 이 작업을 수행하는 방법에 대한 자세한 내용은 링커 및 유틸리티 설명서에서 5-3페이지의 스캐터 로딩 설명 파일을 통한 스택 및 힙 지정을 참조하십시오.

예제 2-10 스택 포인터 초기화

Len_FIQ_Stack EQU 256Len_IRQ_Stack EQU 256:Reset_Handler :; stack_base could be defined above, or located in a scatter fileLDR r0, stack_base ;

; Enter each mode in turn and set up the stack pointerMSR CPSR_c, #Mode_FIQ:OR:I_Bit:OR:F_BitMOV sp, r0

MSR CPSR_c, #Mode_IRQ:OR:I_Bit:OR:F_BitSUB r0, r0, #Len_FIQ_StackMOV sp, r0

MSR CPSR_c, #Mode_SVC:OR:I_Bit:OR:F_BitSUB r0, r0, #Len_IRQ_StackMOV sp, r0; Leave core in SVC mode

예제 2-10에서는 FIQ 및 IRQ 모드에 대해 256바이트의 스택을 할당하지만 다른 실행 모드에 대해서도 동일하게 할당할 수 있습니다. 스택 포인터를 설정하려면 인터럽트가 비활성화된 상태에서 각 모드로 전환하고 스택 포인터에 적절한 값을 할당합니다.

리셋 처리기에서 설정된 스택 포인터 값은 C 라이브러리 초기화 코드에 의해 __user_initial_stackheap()에 매개 변수로 자동 전달됩니다. 따라서 __user_initial_stackheap()으로 이 값을 수정하지 않아야 합니다.

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 2-33

Page 54: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

임베디드 소프트웨어 개발

예제 2-11에서는 예제 2-10에 표시된 스택 포인터 설정과 함께 사용할 수 있는 __user_initial_stackheap()의 구현을 보여 줍니다.

예제 2-11

IMPORT heap_base EXPORT __user_initial_stackheap

__user_initial_stackheap

; heap base could be hard-coded, or placed by description file LDR r0,=heap_base ; r1 contains SB value BX lr

2.5.7 하드웨어 초기화

일반적으로 모든 시스템 초기화 코드는 주 응용 프로그램에서 분리하는 것이 좋습니다. 그러나 캐시 및 인터럽트 활성화와 같은 몇 가지 시스템 초기화 구성요소는 C 라이브러리 초기화 코드를 실행한 후에 수행되어야 합니다.

$Sub 및 $Super 함수 래퍼 심볼을 사용하면 주 응용 프로그램을 시작하기 직전에 실행되는 루틴을 삽입할 수 있습니다. 이 메커니즘을 사용하면 소스 코드를 변경하지 않고도 함수를 확장할 수 있습니다.

예제 2-12에서는 $Sub 및 $Super를 이러한 방식으로 사용하는 방법을 보여 줍니다. 링커에서는 main()에 대한 함수 호출을 $Sub$$main()에 대한 호출로 바꿉니다. 이 호출을 통해 캐시를 활성화하는 루틴과 인터럽트를 활성화하는 다른 루틴을 호출할 수 있습니다.

코드는 $Super$$main()을 호출하여 실제 main()으로 분기됩니다.

참고

자세한 내용은 링커 및 유틸리티 설명서에서 4-21페이지의 $Super$$ 및 $Sub$$를 사용하여 심볼 정의 재정의를 참조하십시오.

2-34 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 55: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

임베디드 소프트웨어 개발

예제 2-12 $Sub 및 $Super 사용

extern void $Super$$main(void);

void $Sub$$main(void){ cache_enable(); // enables caches int_enable(); // enables interrupts $Super$$main(); // calls original main()}

2.5.8 실행 모드 고려 사항

주 응용 프로그램을 실행할 모드를 고려해야 합니다. 선택한 모드는 시스템 초기화를 구현하는 방식에 영향을 줍니다.

시작할 때 리셋 처리기와 $Sub$$main 모두에서 구현할 수 있는 기능의 대부분은 칩 내부 메모리 조작과 같은 권한 모드에서 실행되어 인터럽트를 활성화하는 동안에만 수행할 수 있습니다.

응용 프로그램을 권한 모드에서 실행할 경우에는 이것이 문제가 되지 않습니다. 리셋 처리기를 종료하기 전에 해당 모드로 변경하십시오.

그러나 사용자 모드에서 응용 프로그램을 실행하려는 경우에는 권한 모드에서 필요한 작업을 완료한 후에만 사용자 모드로 변경할 수 있습니다. 이 작업을 수행하기에 가장 적합한 위치는 $Sub$$main()입니다.

참고

__user_initial_stackheap()은 응용 프로그램 모드 스택을 설정해야 합니다. 따라서 사용자 모드 레지스터를 사용하는 시스템 모드에서 리셋 처리기를 종료해야 합니다. 그러면 __user_initial_stackheap()이 시스템 모드에서 실행되며 사용자 모드로 전환될 때 응용 프로그램 스택과 힙도 설정됩니다.

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 2-35

Page 56: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

임베디드 소프트웨어 개발

2.5.9 빌드 4의 예제 코드

예제의 빌드 4는 Integrator 플랫폼에서 독립 실행형으로 실행할 수 있습니다. 자세한 내용은 주 예제 디렉토리의 ...\emb_sw_dev\build4에 있는 예제 빌드 파일을 참조하십시오.

빌드 4에서는 예제 프로젝트의 빌드 3이 다음과 같이 수정되었습니다.

벡터 테이블

벡터 테이블이 프로젝트에 추가되었고 스캐터 로딩 설명 파일에 의해 배치되었습니다.

리셋 처리기

리셋 처리기가 init.s에 추가되었습니다. 각각 TCM 설정과 MMU 설정을 담당하는 두 가지 개별 모듈이 ARM926EJ-S™ 빌드에 포함되었습니다. 이러한 모듈은 코어가 있는 Integrator 시스템에서 실행되는 ARM7TDMI® 빌드에서는 제외됩니다. ROM/RAM 재매핑은 리셋 직후에 수행됩니다.

$Sub$$main()

ARM926EJ-S 빌드의 경우 캐시는 주 응용 프로그램으로 전환되기 전에 $Sub$$main()에서 활성화됩니다.

임베디드 설명 파일

재매핑 후 메모리 뷰를 반영하는 임베디드 설명 파일이 사용됩니다.

이러한 두 빌드의 빌드 파일은 주소 0x24000000에서 Integrator AP 응용 프로그램 플래시로 다운로드하는 데 적합한 이진 파일을 생성합니다.

Integrator AP 마더보드의 타이머를 사용하여 정확한 타이머가 구현됩니다. 이 타이머가 IRQ를 생성하며 10밀리초마다 카운터를 늘리는 처리기가 설치됩니다.

2-36 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 57: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

임베디드 소프트웨어 개발

2.6 기타 메모리 맵 고려 사항

이 장의 이전 단원에서는 스캐터 로딩 설명 파일에서의 코드 및 데이터 배치에 대해 설명했습니다. 그러나 타겟 하드웨어 주변 기기의 위치와 스택 및 힙 한계는 소스 또는 헤더 파일에 하드 코딩되어 있다고 가정했습니다. 타겟의 메모리 맵과 관련된 모든 정보를 설명 파일에 배치하고 소스 코드에서 절대 주소에 대한 모든 참조를 제거하는 것이 좋습니다.

2.6.1 스캐터 로딩 설명 파일에 타겟 주변 기기 배치

일반적으로 주변 기기 레지스터의 주소는 프로젝트 소스 또는 헤더 파일에 하드 코딩됩니다. 주변 기기 레지스터에 매핑되는 구조체를 선언하고 이러한 구조체를 설명 파일에 배치할 수도 있습니다.

예를 들어 타겟에는 두 가지 메모리 매핑 32비트 레지스터를 사용하는 타이머 주변 기기가 있을 수 있습니다. 예제 2-13에서는 이러한 레지스터에 매핑되는 C 구조체를 보여 줍니다.

예제 2-13 주변 기기 레지스터에 매핑

__attribute__ ((zero_init)) struct { volatile unsigned ctrl; /* timer control */ volatile unsigned tmr; /* timer value */} timer_regs;

메모리 맵의 특정 주소에 이 구조체를 배치하려면 이 구조체를 저장할 새 실행 영역을 만듭니다.

예제 2-14에서 보여 주는 설명 파일은 0x40000000에 timer_regs 구조체를 배치합니다.

이러한 레지스터의 내용은 응용 프로그램을 시작할 때 0으로 초기화되지 않아야 합니다. 0으로 초기화되면 시스템의 상태가 변경될 수 있기 때문입니다. 실행 영역을 UNINIT 특성으로 표시하면 해당 영역에 있는 ZI 데이터가 0으로 초기화되지 않습니다.

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 2-37

Page 58: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

임베디드 소프트웨어 개발

예제 2-14 매핑된 구조체 배치

ROM_LOAD 0x24000000 0x04000000{ ; ... TIMER 0x40000000 UNINIT { timer_regs.o (+ZI) } ; ...}

2.6.2 빌드 5의 예제 코드

예제의 빌드 5는 빌드 4와 같지만 모든 타겟 메모리 맵 정보가 스캐터 로딩 설명 파일에 있다는 점이 다릅니다.

스캐터 로딩 설명 파일 심볼

스택, 힙 및 주변 기기를 배치하는 심볼은 어셈블러 모듈에 선언되었습니다.

업데이트된 스캐터 로딩 설명 파일

빌드 4에서 임베드된 설명 파일이 스택, 힙, 데이터 TCM 및 주변 기기를 배치하도록 업데이트되었습니다.

자세한 내용은 주 예제 디렉토리의 ...\emb_sw_dev\build5에 있는 예제 빌드 파일을 참조하십시오.

2-38 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 59: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

3장 위치 독립적인 코드 및 데이터 작성

이 장에서는 Procedure Call Standard for the ARM Architecture(AAPCS)를 사용하는 위치 독립적인 코드 및 데이터의 작성 방법을 자세히 설명합니다. 여기에는 다음 단원이 포함되어 있습니다.

• 3-2페이지의 위치 독립성

• 3-3페이지의 읽기 전용 위치 독립성

• 3-5페이지의 읽기/쓰기 위치 독립성

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 3-1

Page 60: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

위치 독립적인 코드 및 데이터 작성

3.1 위치 독립성

ARM® 및 Thumb® 명령어 세트는 모두 BL과 같은 PC 기준 명령어를 사용하여 위치 독립적, 즉 재배치 가능한 코드를 지원합니다.

참고

이러한 코드는 링커에서 만들어지는 이미지 유형인 재배치 가능 ELF와는 다릅니다.

재배치 가능한 어셈블러 코드를 작성할 수 있지만 이때 코드에 주소 상수는 포함하지 말아야 합니다. 코드를 참조하는 데 사용되는 리터럴 주소는 PC 기준 오프셋이어야 합니다. PC 값은 주소에 액세스하기 전에 ADD 명령어를 사용하여 계산됩니다.

코드와 데이터 모두를 위치 독립적으로 작성할 수 있습니다.

• 코드가 다른 주소에서 실행되도록 하려면 해당 코드를 위치 독립적이거나 재배치 가능하게 작성해야 합니다. 그러나 이 코드에서는 고정 주소에 있는 정적 데이터의 단일 세트에만 액세스할 수 있습니다.

• 위치 독립적인 데이터를 사용하려면 모든 데이터 액세스가 정적 기준 레지스터 sb를 기준으로 수행되어야 합니다. 위치 독립적인 데이터는 공유 라이브러리 메커니즘을 구현하는 데 사용됩니다.

RVCT에서는 C와 어셈블러(C++는 제외)의 위치 독립적인 코드 및 데이터가 지원되며 이를 통해 재배치 가능 또는 재진입 코드를 작성할 수 있습니다. 이 장의 나머지 부분에는 이러한 코드 작성 방법에 대한 정보가 포함되어 있습니다.

자세한 내용은 다음 항목을 참조하십시오.

• 컴파일러 사용 설명서에 있는 2-25페이지의 위치 독립 한정자

• 라이브러리 및 부동 소수점 지원 설명서에 있는 2-5페이지의 재진입 및 스레드 안전성 코드 작성

3.1.1 AAPCS 사용

Procedure Call Standard for the ARM Architecture(AAPCS)는 ABI(응용 프로그램 바이너리 인터페이스) for the ARM Architecture(기본 표준)(BSABI) 사양에 포함되어 있습니다. AAPCS를 준수하는 코드를 작성하여 별도로 컴파일되고 어셈블된 모듈을 함께 사용할 수 있습니다.

자세한 내용은 install_directory\Documentation\...에 있는 AAPCS 사양을 참조하십시오.

3-2 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 61: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

위치 독립적인 코드 및 데이터 작성

3.2 읽기 전용 위치 독립성

프로그램의 읽기 전용 세그먼트가 모두 위치 독립적일 때 해당 프로그램을 ROPI(읽기 전용 위치 독립적) 프로그램이라고 합니다.

ROPI 세그먼트는 PIC(위치 독립적 코드)인 경우가 많지만 읽기 전용 데이터이거나 PIC와 읽기 전용 데이터의 조합일 수도 있습니다.

참고

ROPI는 C++용으로는 지원되지 않으므로 AAPCS에 포함되어 있지 않습니다. 그러나 컴파일러 또는 어셈블러 옵션 --apcs /ropi를 사용하면 ROPI용 C 코드나 어셈블러 코드를 컴파일할 수 있습니다.

ROPI 옵션을 선택할 경우 사용자가 직접 메모리의 특정 위치에 있는 코드를 로드하지 않아도 됩니다. 따라서 이 옵션은 다음과 같은 루틴에 특히 유용합니다.

• 런타임 이벤트에 대한 응답으로 로드되는 루틴

• 상황에 따라 다른 루틴의 다양한 조합과 함께 메모리로 로드되는 루틴

• 실행 중 다른 주소에서 매핑되는 루틴

3.2.1 ROPI를 포함한 레지스터 사용

AAPCS에 정의된 대로 레지스터 사용 방법은 ROPI 포함 여부에 관계없이 동일합니다.

자세한 내용은 install_directory\Documentation\Specifications\...에 있는 Procedure Call Standard for the ARM Architecture 사양(aapcs.pdf)을 참조하십시오.

3.2.2 ROPI용 C 및 어셈블러 코드 작성

ROPI용 C 및 어셈블러 코드를 작성하려면 다음 조건을 충족해야 합니다.

• ROPI 세그먼트의 코드에서 동일한 ROPI 세그먼트의 심볼에 대한 모든 참조는 PC를 기준으로 해야 합니다. AAPCS에는 읽기 전용 세그먼트에 대한 다른 기준 레지스터가 정의되어 있지 않습니다. ROPI 세그먼트에 있는 항목의 주소를 다른 ROPI 세그먼트의 항목에 할당할 수는 없습니다.

• ROPI 세그먼트의 코드에서 다른 ROPI 세그먼트의 심볼에 대한 모든 참조는 PC를 기준으로 해야 합니다. 두 세그먼트는 서로 상대적으로 고정되어 있어야 합니다.

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 3-3

Page 62: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

위치 독립적인 코드 및 데이터 작성

• ROPI 세그먼트에서 그 밖의 모든 참조는 다음 중 하나여야 합니다.

— 절대 주소

— 쓰기 가능 데이터에 대한 sb 기준 참조(3-5페이지의 읽기/쓰기 위치 독립성 참조)

• ROPI 세그먼트에 있는 심볼의 주소를 지정하는 읽기/쓰기 워드는 ROPI 세그먼트가 이동될 때마다 조정되어야 합니다.

3.2.3 코드 링크

링커 명령 행 옵션 --ropi를 사용하여 읽기 전용 출력 섹션이 포함된 로드 및 실행 영역을 위치 독립적으로 만들 수 있습니다. 일반적으로 각 읽기 전용 입력 섹션은 읽기 전용 위치 독립적이어야 합니다. 자세한 내용은 링커 및 유틸리티 설명서를 참조하십시오.

3.2.4 FPIC 주소 지정

상대 주소 참조가 프로그램이 로드된 위치와는 독립적인, 읽기 전용의 위치 독립적 코드를 생성하려면 /fpic 한정자를 사용합니다. 상대 주소 지정은 코드에서 System V 공유 라이브러리를 사용하는 경우에만 구현됩니다. 코드에서 공유 개체를 사용하는 경우에는 /fpic를 사용하여 컴파일할 필요가 없습니다.

RVCT의 System V 공유 라이브러리 지원에 대한 자세한 내용은 링커 및 유틸리티 설명서에서 6장 BPABI 및 System V 공유 라이브러리와 실행 가능 파일을 참조하십시오.

3.2.5 코드 예제

위치 독립적인 코드 작성에 대한 자세한 내용은 RealView Development Suite와 함께 제공되는 PIC-PID 예제를 참조하십시오. 이 예제는 주 예제 디렉토리의 install_directory\RVDS\Examples\picpid에 있습니다.

이 예제는 ROM의 고정 주소에 있는 커널과 커널 기능을 확장하는 응용 프로그램 모듈 모음으로 구성되어 있습니다. 응용 프로그램 모듈은 커널이 로드된 후에 메모리로 로드됩니다. 그러나 모듈이 링크되는 시점에서는 모듈이 로드될 주소를 알 수 없습니다. 따라서 모듈은 위치 독립적(ROPI, PIC)이어야 합니다.

이 예제에는 소스 코드, 매이크파일 및 배치 파일과 다양한 모듈의 컴파일 및 링크 방법에 대한 세부 설명이 포함되어 있습니다. 자세한 내용은 readme.txt를 참조하십시오.

3-4 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 63: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

위치 독립적인 코드 및 데이터 작성

3.3 읽기/쓰기 위치 독립성

프로그램의 읽기/쓰기 세그먼트가 모두 위치 독립적일 때 해당 프로그램을 RWPI(읽기/쓰기 위치 독립적) 프로그램이라고 합니다.

RWPI 세그먼트는 대개 PID(위치 독립적 데이터)입니다.

RWPI는 AAPCS 변형입니다. 컴파일러 또는 어셈블러 옵션 --apcs /rwpi를 사용할 경우 사용자가 직접 메모리의 특정 데이터 위치로 이동하지 않아도 됩니다. 따라서 이 옵션은 재진입 루틴을 위해 여러 개의 인스턴스를 생성해야 하는 데이터에 특히 유용합니다.

자세한 내용은 install_directory\Documentation\Specifications\...에 있는 Procedure Call Standard for the ARM Architecture 사양(aapcs.pdf)을 참조하십시오.

3.3.1 재진입 루틴

재진입 루틴은 여러 프로세스에서 동시에 스레드될 수 있습니다. 각 프로세스에는 루틴의 읽기/쓰기 세그먼트에 대한 고유한 복사본이 사용됩니다. 각 복사본은 서로 다른 정적 기준 레지스터(sb) 값으로 주소가 지정됩니다.

3.3.2 RWPI를 포함한 레지스터 사용

레지스터 r9는 정적 기준 레지스터(sb)로서, 외부에서 볼 수 있는 루틴이 호출될 때마다 적절한 정적 데이터 세그먼트의 기본 주소를 가리켜야 합니다.

sb를 사용하지 않는 루틴에서는 r9를 다른 용도로 사용할 수 있습니다. 이 경우에는 루틴에 진입할 때 sb의 내용을 저장하고 루틴에서 나가기 전에 이 내용을 복원해야 합니다. 외부 루틴을 호출하기 전에도 이 내용을 복원해야 합니다.

그 밖의 모든 면에서 레지스터 사용 방법은 RWPI 포함 여부에 관계없이 동일합니다.

3.3.3 위치 독립적 데이터의 주소 지정

RWPI 세그먼트는 처음으로 사용하기 전까지는 위치를 변경할 수 있습니다. RWPI 세그먼트에 있는 심볼의 주소는 다음과 같이 계산됩니다.

1. 링커에서는 세그먼트의 고정 위치에서 시작하여 읽기 전용 오프셋을 계산합니다. 일반적으로 이 고정 위치는 프로그램에서 가장 낮은 주소가 지정된 RWPI 세그먼트의 첫 번째 바이트입니다.

2. 런타임에 이 값이 오프셋으로 사용되고 여기에 정적 기준 레지스터(sb)의 내용이 더해집니다.

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 3-5

Page 64: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

위치 독립적인 코드 및 데이터 작성

3.3.4 RWPI용 어셈블리 언어 작성

sb 값에 고정(읽기 전용) 오프셋을 더하여 읽기 전용 세그먼트에서 RWPI 세그먼트에 대한 참조를 만들 수 있습니다. 자세한 내용은 어셈블러 설명서의 지시문 참조 장에서 DCDO를 참조하십시오.

3.3.5 코드 링크

링커 명령 행 옵션 --rwpi를 사용하여 RW 및 ZI 출력 섹션이 포함된 로드 및 실행 영역을 위치 독립적으로 만들 수 있습니다. 이 옵션에는 --rw-base 값이 필요합니다. --rw-base 값을 지정하지 않으면 --rw-base 0으로 간주됩니다. 일반적으로 각 쓰기 가능 입력 섹션은 RWPI여야 합니다. 자세한 내용은 링커 및 유틸리티 설명서에서 2-12페이지의 이미지에 대한 메모리 맵 정보 지정을 참조하십시오.

3.3.6 코드 예제

위치 독립적인 코드 작성에 대한 자세한 내용은 RealView Development Suite와 함께 제공되는 PIC-PID 예제를 참조하십시오. 이 예제는 주 예제 디렉토리의 install_directory\RVDS\Examples\picpid에 있습니다.

이 예제는 ROM의 고정 주소에 있는 커널과 커널 기능을 확장하는 응용 프로그램 모듈 모음으로 구성되어 있습니다. 모듈에서는 동시에 여러 개의 인스턴스가 생성될 수 있는 명명된 서비스 세트를 구현합니다. 각 서비스는 커널을 통해 서로 호출할 수 있습니다. 서비스가 호출되면 커널에서는 정적 데이터의 인스턴스를 만든 다음 해당 서비스에 제어권을 전달합니다. 그러나 이후에 서비스에서 커널을 다시 호출할 수도 있습니다. 따라서 모듈에는 위치 독립적 데이터(RWPI, PID)가 포함되어야 합니다.

이 예제에는 소스 코드, 매이크파일 및 배치 파일과 다양한 모듈의 컴파일 및 링크 방법에 대한 세부 설명이 포함되어 있습니다. 자세한 내용은 readme.txt를 참조하십시오.

3-6 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 65: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

4장 ARM 과 Thumb 의 인터워킹

이 장에서는 Thumb 명령어 세트를 구현하는 프로세서를 위한 코드를 작성할 때 ARM® 상태와 Thumb® 상태 사이에서 전환하는 방법을 설명합니다. 여기에는 다음 단원이 포함되어 있습니다.

• 4-2페이지의 인터워킹 개요

• 4-7페이지의 어셈블리 언어 인터워킹

• 4-13페이지의 C/C++ 인터워킹 및 비니어

• 4-18페이지의 비니어를 사용한 어셈블리 언어 인터워킹

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 4-1

Page 66: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

ARM과 Thumb의 인터워킹

4.1 인터워킹 개요

인터워킹을 통해 ARM 코드와 Thumb 코드를 함께 사용하여 다음을 수행할 수 있습니다.

• ARM 루틴에서 Thumb 상태 호출자로 복귀할 수 있습니다.

• Thumb 루틴에서 ARM 상태 호출자로 복귀할 수 있습니다.

즉, 인터워킹용 코드를 컴파일하거나 어셈블하면 코드에서는 사용되는 명령어 세트에 관계없이 다른 모듈의 루틴을 호출할 수 있습니다.

Thumb 상태에서 ARM 함수가 호출되거나 ARM 상태에서 Thumb 함수가 호출되면 ARM 링커에서는 이를 감지하고 호출 및 복귀 명령어를 변경하거나 비니어라는 작은 코드 세그먼트를 삽입하여 필요한 대로 프로세서 상태를 변경합니다.

ARMv5T 이상의 아키텍처에서는 추가 명령어를 사용하지 않고도 프로세서 상태를 변경할 수 있는 방법이 제공됩니다. 일반적으로 ARMv5T 프로세서에서는 인터워킹과 관련된 비용이 들지 않습니다.

참고

ARMv5T 및 이후 버전용으로 컴파일하면 자동으로 인터워킹이 사용되는 것으로 간주되어 인터워킹을 수행하는 코드가 항상 생성됩니다. 그러나 ARMv5TE용으로 빌드된 어셈블리 코드에는 인터워킹이 포함되지 않으므로 어셈블리 코드를 빌드할 때 --apcs /interwork 어셈블러 옵션을 사용해야 합니다.

4.1.1 AAPCS 사용

필요한 경우 ARM 코드와 Thumb 코드를 함께 사용할 수 있습니다. 단,두 코드가 AAPCS의 요구 사항을 준수해야 합니다. 자세한 내용은 install_directory\Documentation\Specifications\...에 있는 Procedure Call Standard for the ARM Architecture 사양(aapcs.pdf)을 참조하십시오.

ARM 어셈블리 언어 모듈을 작성하려면 코드가 AAPCS를 준수하는지 확인해야 합니다. 여러 개의 소스 파일을 함께 링크하려면 모든 파일에서 호환되는 AAPCS 옵션을 사용해야 합니다. 호환되지 않는 옵션이 사용된 경우에는 링커에서 오류 메시지가 생성됩니다.

4-2 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 67: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

ARM과 Thumb의 인터워킹

4.1.2 인터워킹을 사용하는 경우

Thumb 명령어를 지원하는 ARM 프로세서를 위한 코드를 작성할 때 응용 프로그램의 대부분이 Thumb 상태에서 실행되도록 하려는 경우가 있습니다. 이렇게 하면 코드 밀도를 최소화할 수 있습니다. 8비트 또는 16비트 메모리를 사용하면 성능을 최대화할 수도 있습니다. 그러나 다음과 같은 이유로 응용 프로그램의 일부는 ARM 상태에서 실행되도록 하려는 경우도 있습니다.

속도 응용 프로그램의 일부 부분에서는 속도가 중요할 수 있습니다. 이러한 섹션은 Thumb 상태보다 ARM 상태에서 실행하는 것이 효율적일 수 있습니다. 일부 경우에는 ARM 명령어가 해당하는 Thumb 명령어보다 효율적일 수 있습니다.

일부 시스템에는 작은 크기의 고속 32비트 메모리가 포함되어 있습니다. ARM 코드는 8비트나 16비트 메모리에서 각 명령어를 가져오는 오버헤드 없이 이 메모리에서 실행될 수 있습니다.

기능

Thumb 명령어는 해당하는 ARM 명령어보다 융통성이 적습니다. Thumb 상태에서는 일부 작업을 수행할 수 없습니다. 다음과 같은 작업을 수행하려면 ARM 상태로 변경해야 합니다.

• CPSR에 액세스하여 인터럽트를 활성화/비활성화하고 모드 변경

• 보조 프로세서에 액세스

• C에서는 지원되지 않는 DSP 수학 명령어 실행

예외 처리

프로세서 예외가 발생하면 프로세서가 자동으로 ARM 상태로 전환됩니다. 따라서 예외 처리기의 첫 번째 부분은 ARM 명령어로 코딩해야 합니다. 이는 예외 처리기가 Thumb 상태로 다시 전환하여 예외의 주요 처리를 수행하는 경우에도 해당됩니다. 이러한 처리 과정의 끝에서는 프로세서를 ARM 상태로 전환하여 처리기에서 주 응용 프로그램으로 복귀해야 합니다.

독립 실행형 Thumb 프로그램

Thumb 명령어를 지원하는 ARM 프로세서는 항상 ARM 상태에서 시작됩니다. 디버거에서 간단한 Thumb 어셈블리 언어 프로그램을 실행하려면 Thumb 상태로 변경한 다음 주 Thumb 루틴을 호출하는 ARM 헤더를 추가합니다. 예제를 보려면 4-9페이지의 ARM 헤더 예제를 참조하십시오.

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 4-3

Page 68: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

ARM과 Thumb의 인터워킹

4.1.3 /interwork 옵션 사용

--apcs /interwork 옵션은 ARM 컴파일러 및 어셈블러에서 사용할 수 있습니다. 이 옵션을 설정하면 다음 작업이 수행됩니다.

• 컴파일러나 어셈블러에서 개체 파일에 인터워킹 특성을 기록합니다.

• 링커에서 하위 루틴 엔트리에 대한 인터워킹 비니어를 제공합니다.

• 어셈블리 언어에서는 BX lr과 같이 호출자의 명령어 세트 상태로 복귀하는 함수 종료 코드를 작성해야 합니다.

• C 또는 C++의 경우 컴파일러에서 호출자의 명령어 세트 상태로 복귀하는 함수 종료 코드를 만듭니다.

• C 또는 C++의 경우 컴파일러에서 간접 또는 가상 호출을 위해 BX 명령어를 사용합니다.

개체 파일에 다음 항목이 들어 있는 경우에 --apcs /interwork 옵션을 사용합니다.

• ARM 코드로 복귀해야 하는 Thumb 하위 루틴

• Thumb 코드로 복귀해야 하는 ARM 하위 루틴

• ARM 코드에 대한 간접 또는 가상 호출을 수행하는 Thumb 하위 루틴

• Thumb 코드에 대한 간접 또는 가상 호출을 수행하는 ARM 하위 루틴

참고

모듈에 #pragma arm 또는 #pragma thumb으로 표시된 함수가 들어 있으면 해당 모듈은 --apcs /interwork로 컴파일해야 합니다. 이렇게 하면 해당 함수를 다른 상태(ARM 또는 Thumb)에서 올바르게 호출할 수 있습니다.

위와 같은 항목이 없으면 /interwork 옵션을 사용할 필요가 없습니다. 예를 들어 개체 파일에 다음 항목이 들어 있으면 /interwork를 사용할 필요가 없습니다.

• 예외로 인해 중단될 수 있는 Thumb 코드. 예외가 발생하면 프로세서가 자동으로 ARM 상태로 전환되므로 비니어가 필요하지 않습니다.

• Thumb 코드에서 예외를 처리할 수 있는 예외 처리 코드. 복귀를 위한 비니어가 필요하지 않습니다.

4-4 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 69: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

ARM과 Thumb의 인터워킹

4.1.4 인터워킹 호출 감지

호출되는 루틴이 인터워킹용으로 빌드되지 않은 직접 ARM/Thumb 인터워킹 호출이 발견되면 링커에서 오류가 생성됩니다. 이 경우 호출되는 루틴을 인터워킹용으로 다시 빌드해야 합니다.

예를 들어 예제 4-1에서는 4-14페이지의 예제 4-3의 ARM 루틴을 --apcs /interwork 옵션을 사용하지 않고 컴파일하고 링크할 경우에 생성되는 오류를 보여 줍니다.

예제 4-1

Error: L6239E: Cannot call ARM symbol 'arm_function' in non-interworking objectarmsub.o from THUMB code in thumbmain.o(.text)

이러한 유형의 오류는 개체 모듈 개체에서 ARM 대 Thumb 또는 Thumb 대 ARM 인터워킹을 필요로 하는 루틴 심볼을 호출했지만 호출되는 루틴이 인터워킹용으로 컴파일되지 않았음을 나타냅니다. 이 경우 해당 심볼이 들어 있는 모듈을 다시 컴파일하고 --apcs /interwork를 지정해야 합니다.

4.1.5 링커에서 생성된 비니어

비니어는 분기에 다음 항목이 관련된 경우 링커에서 자동으로 삽입되는 작은 코드 세그먼트입니다.

• 상태 변경

• 분기 명령어의 범위를 벗어나는 대상

비니어는 원래 분기의 타겟이 되며 나중에 타겟 주소로 분기됩니다.

링커에서는 이전 호출에서 생성된 비니어를 동일한 함수에 대한 후속 호출에서 다시 사용할 수 있습니다. 단, 두 섹션 모두에서 이러한 함수 호출에 도달할 수 있어야 합니다.

비니어를 사용한 인터워킹에 대한 자세한 내용은 다음을 참조하십시오.

• 4-13페이지의 C/C++ 인터워킹 및 비니어

• 4-18페이지의 비니어를 사용한 어셈블리 언어 인터워킹

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 4-5

Page 70: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

ARM과 Thumb의 인터워킹

비니어 유형

다음과 같은 유형의 비니어가 있습니다.

긴 비니어 선택적으로 상태 변경을 수행할 수 있습니다.

짧은 비니어 상태 변경만 수행합니다.

인라인 비니어 상태 변경만 수행하며 비니어되는 함수의 시작 부분에 추가됩니다.

Veneer$$Code 섹션

링커에서는 비니어마다 Veneer$$Code라는 입력 섹션이 하나씩 만들어집니다. *(Veneer$$Code)를 사용하여 스캐터 로딩 설명 파일에 비니어 코드를 추가할 수 있습니다. 그러나 링커에서는 안전한 경우에만 비니어 코드가 추가됩니다.

주소 범위와 관련된 문제나 실행 영역의 크기 제한으로 인해 비니어 입력 섹션이 지정한 영역에 할당되지 않을 수도 있습니다. 비니어를 지정한 영역에 추가할 수 없는 경우 비니어는 해당 비니어를 생성한 재배치된 입력 섹션을 포함하는 실행 영역에 추가됩니다.

자세한 내용은 링커 및 유틸리티 설명서를 참조하십시오.

비니어 사용 최소화

다음과 같은 방법으로 비니어 사용을 최소화할 수 있습니다.

• 호출되는 함수가 호출자 범위 내에 유지되도록 메모리 맵 구조를 지정합니다.

• 호출하는 함수를 범위 내에 유지하여 비니어가 공유되도록 합니다.

• 상태 변경을 최소화합니다.

4-6 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 71: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

ARM과 Thumb의 인터워킹

4.2 어셈블리 언어 인터워킹

어셈블리 언어 소스 파일에는 여러 개의 영역이 포함될 수 있습니다. 이러한 영역은 ELF 섹션에 해당합니다. 각 영역에는 ARM 명령어, Thumb 명령어 또는 둘 모두가 포함될 수 있습니다.

링커를 사용하여 호출자와는 다른 명령어 세트를 사용하는 루틴에 대한 호출과 이 루틴으로부터의 복귀를 지정할 수 있습니다. 이렇게 하려면 BL을 사용하여 루틴을 호출합니다(4-18페이지의 비니어를 사용한 어셈블리 언어 인터워킹 참조).

원하는 경우 명령어 세트를 명시적으로 변경하는 코드를 작성할 수 있습니다. 이렇게 하면 경우에 따라 보다 작거나 빠른 코드를 작성할 수 있습니다.

다음 명령어는 프로세서 상태 변경을 수행합니다.

• BX(분기 및 전환 명령어 참조)

• BLX, LDR, LDM 및 POP(4-11페이지의 ARM 아키텍처 v5T 이상과 인터워킹 참조)

ARM 및 THUMB 지시문은 어셈블러에서 적절한 명령어 세트의 명령어를 어셈블하도록 지정합니다(4-8페이지의 어셈블러 모드 변경 참조).

4.2.1 분기 및 전환 명령어

BX 명령어는 Thumb을 지원하는 코어에서만 사용할 수 있습니다. 이 명령어는 지정된 레지스터에 포함된 주소로 분기하며 주소 범위는 4GB입니다. 분기 주소의 비트 0 값은 실행을 ARM 상태에서 계속할지 아니면 Thumb 상태에서 계속할지 여부를 결정합니다. ARMv5.에서 사용할 수 있는 추가 명령어에 대한 자세한 내용은 4-11페이지의 ARM 아키텍처 v5T 이상과 인터워킹을 참조하십시오.

주소의 비트 0을 이러한 방식으로 사용할 수 있는 이유는 다음과 같습니다.

• 모든 ARM 명령어는 워드로 정렬되므로 ARM 명령어의 주소 비트 0과 1은 사용되지 않습니다.

• 모든 Thumb 명령어는 하프워드로 정렬되므로 Thumb 명령어의 주소 비트 0은 사용되지 않습니다.

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 4-7

Page 72: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

ARM과 Thumb의 인터워킹

구문

BX의 구문은 다음과 같습니다.

Thumb BX Rn

ARM BX{cond} Rn

인수 설명:

Rn 분기할 주소가 들어 있는 r0에서 r15 범위의 레지스터입니다. 이 레지스터의 비트 0 값은 다음과 같이 프로세서 상태를 결정합니다.

• 비트 0이 설정되어 있으면 분기 주소의 명령어가 Thumb 상태에서 실행됩니다.

• 비트 0이 지워져 있으면 분기 주소의 명령어가 ARM 상태에서 실행됩니다.

cond 선택적 조건 코드입니다. ARM 버전의 BX만 조건부로 실행될 수 있습니다.

4.2.2 어셈블러 모드 변경

ARM 어셈블러는 Thumb 코드와 ARM 코드 모두를 어셈블할 수 있습니다. 기본적으로 ARM 어셈블러는 --thumb 옵션을 사용하여 호출되지 않은 경우 ARM 코드를 어셈블합니다.

Thumb을 지원하는 모든 ARM 프로세서는 ARM 상태에서 시작되므로 Thumb 상태로 분기 및 전환하려면 BX 명령어를 사용한 후 다음 어셈블러 지시문을 사용하여 어셈블러에서 어셈블리 모드를 전환하도록 지정해야 합니다.

THUMB 어셈블러에서 다음에 나오는 명령어를 Thumb 명령어로 어셈블하도록 지정합니다. 또한 다음에 나오는 명령어가 없을 경우에도 2바이트 단위로 정렬되도록 합니다.

ARM 어셈블러가 ARM 어셈블 명령어로 복귀하도록 지정합니다. 또한 다음에 나오는 명령어가 없을 경우에도 4바이트 단위로 정렬되도록 합니다.

이러한 지시문에 대한 자세한 내용은 어셈블러 설명서를 참조하십시오.

4-8 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 73: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

ARM과 Thumb의 인터워킹

4.2.3 ARM 헤더 예제

예제 4-2에는 네 개의 코드 섹션이 있습니다. 각 코드 섹션에 대해서는 예제 다음에서 설명합니다.

예제 4-2

PRESERVE8

AREA AddReg,CODE,READONLY ; Name this block of code. ENTRY ; Mark first instruction to call.

; SECTION 1start ADR r0, ThumbProg + 1 ; Generate branch target address ; and set bit 0, hence arrive ; at target in Thumb state. BX r0 ; Branch exchange to ThumbProg.

; SECTION 2 THUMB ; Subsequent instructions are Thumb code.ThumbProg MOVS r2, #2 ; Load r2 with value 2. MOVS r3, #3 ; Load r3 with value 3. ADDS r2, r2, r3 ; r2 = r2 + r3 ADR r0, ARMProg BX r0 ; Branch exchange to ARMProg.

; SECTION 3 ARM ; Subsequent instructions are ARM code.ARMProg MOV r4, #4 MOV r5, #5 ADD r4, r4, r5

; SECTION 4stop MOV r0, #0x18 ; angel_SWIreason_ReportException LDR r1, =0x20026 ; ADP_Stopped_ApplicationExit SVC 0x123456 ; ARM semihosting (formerly SWI) END ; Mark end of this file.

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 4-9

Page 74: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

ARM과 Thumb의 인터워킹

SECTION 1에서는 프로세서를 Thumb 상태로 변경하는 ARM 코드의 간단한 헤더 섹션을 구현합니다. 헤더 코드에서는 다음 명령어를 사용합니다.

• ADR 명령어 - 분기 주소를 로드하고 최하위 비트를 설정합니다. ADR 명령어는 pc+offset+1 값을 갖는 r0을 로드하여 주소를 생성합니다. 이 값은 ThumbProg의 주소에 1을 더한 것입니다.

참고

ADR 명령어는 동일한 섹션 내의 심볼에 사용됩니다. 범위가 큰 경우에는 LDR 의사 명령어를 사용합니다. ADR 및 LDR 명령어에 대한 자세한 내용은 어셈블러 설명서를 참조하십시오.

• BX 명령어 - Thumb 코드로 분기하고 프로세서 상태를 변경합니다.

코드에서 ThumbProg라는 레이블이 붙은 SECTION 2의 앞에는 THUMB 지시문이 있습니다. 이 지시문은 어셈블러에서 다음에 나오는 코드를 Thumb 코드로 처리하도록 지정합니다. Thumb 코드는 두 레지스터의 내용을 더합니다.

이 코드에서는 ADR 명령어를 다시 사용하여 ARMProg 레이블의 주소를 가져오지만 이때 최하위 비트는 지워진 상태로 있습니다. BX 명령어는 상태를 다시 ARM 상태로 변경합니다.

코드에서 ARMProg라는 레이블이 붙은 SECTION 3에서는 두 레지스터의 내용을 더합니다.

자세한 내용은 부록 A 세미호스팅을 참조하십시오.

참고

Thumb 세미호스팅에서는 작업 번호 0xAB를 사용합니다. 이것은 ARM 세미호스팅 번호 0x123456과 다릅니다.

심볼 내보내기

Thumb 명령어를 참조하는 심볼을 내보내면 링커에서는 Thumb 코드에 있는 레이블의 주소에 자동으로 1을 더합니다.

심볼을 내보내지 않을 경우에는 사용자가 직접 Thumb 명령어를 참조하는 심볼에 1을 더해야 합니다. 이는 4-9페이지의 예제 4-2에서 ThumbProg+1에 해당합니다. 모든 참조는 어셈블러에서 확인되며 링커에서는 심볼을 감지하지 못하기 때문에 이 작업이 필요합니다.

4-10 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 75: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

ARM과 Thumb의 인터워킹

예제 빌드

예제를 빌드하고 실행하려면

1. 텍스트 편집기를 사용하여 코드를 입력하고 파일을 addreg.s로 저장합니다.

2. 명령 프롬프트에 armasm -g addreg.s를 입력하여 소스 파일을 어셈블합니다.

3. armlink addreg.o -o addreg를 입력하여 파일을 링크합니다.

4. RealView Debugger 등의 호환되는 디버거를 적절한 디버그 타겟과 함께 사용하여 이미지를 실행합니다. 프로그램 명령어를 한 번에 하나씩 단계별로 실행하면 프로세서가 Thumb 상태로 전환되는 것을 확인할 수 있습니다. 상태 변경이 나타나는 방식을 확인하려면 사용하고 있는 디버거의 사용 설명서를 참조하십시오.

4.2.4 ARM 아키텍처 v5T 이상과 인터워킹

ARMv5T 이상의 경우

• 다음과 같은 추가 인터워킹 명령어를 사용할 수 있습니다.

BLX address

프로세서에서 링크를 사용하여 address로 PC 기준 분기를 수행하고 상태를 변경합니다. address는 ARM 코드에서 PC의 32MB 이내, Thumb 코드에서 PC의 4MB 이내에 있어야 합니다.

BLX register

프로세서에서 지정된 레지스터에 포함된 주소에 대한 링크를 사용하여 분기를 수행합니다. 비트[0] 값은 새 프로세서 상태를 결정합니다.

두 경우 모두 lr의 비트[0]은 CPSR에 있는 Thumb 비트의 현재 값으로 설정됩니다. 즉, 복귀 명령어는 올바른 프로세서 상태로 자동으로 복귀할 수 있습니다.

• LDR, LDM 또는 POP가 PC로 로드될 경우 CPSR의 Thumb 비트는 PC에 로드된 값의 비트[0]으로 설정됩니다. 이 값을 사용하여 명령어 세트를 변경할 수 있습니다. 이는 하위 루틴에서 복귀하는 데 특히 유용합니다. 동일한 복귀 명령어로 ARM 호출자나 Thumb 호출자로 복귀할 수 있습니다.

자세한 내용은 어셈블러 설명서 및 ARM 아키텍처 참조 문서를 참조하십시오.

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 4-11

Page 76: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

ARM과 Thumb의 인터워킹

4.2.5 Thumb 코드의 레이블

링커에서는 다음을 참조하는 각 레이블을 구별합니다.

• ARM 명령어

• Thumb 명령어

• 데이터

링커에서는 Thumb 명령어를 참조하는 레이블의 값을 재배치할 때 재배치된 값의 최하위 비트를 설정합니다. 따라서 레이블에 대한 분기에서 적절한 명령어 세트를 자동으로 선택할 수 있습니다. 이는 다음에 나오는 명령어가 분기에 사용되는 경우에 유용합니다.

• ARMv4T의 BX

• ARMv5T 이상의 BX, BLX 또는 LDR

4-12 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 77: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

ARM과 Thumb의 인터워킹

4.3 C/C++ 인터워킹 및 비니어

ARM 및 Thumb용으로 컴파일된 C 코드와 C++ 코드를 함께 사용할 수 있지만 ARMv4T에서는 ARM 코드와 Thumb 코드 사이에서 상태 변경을 수행하는 비니어가 필요합니다. ARM 링커에서는 인터워킹 호출이 발견될 때 이러한 인터워킹 비니어를 생성합니다. 비니어에 대한 자세한 내용은 4-5페이지의 링커에서 생성된 비니어를 참조하십시오.

4.3.1 인터워킹을 위한 코드 컴파일

--apcs /interwork 컴파일러 옵션을 사용하면 ARM 컴파일러에서는 다른 프로세서 상태용으로 컴파일된 루틴에서 호출할 수 있는 루틴이 포함된 C 및 C++ 모듈을 컴파일할 수 있습니다.

armcc --c90 --thumb --apcs /interworkarmcc --c90 --arm --apcs /interworkarmcc --cpp --thumb --apcs /interworkarmcc --cpp --arm --apcs /interwork

참고

--arm이 기본 옵션입니다. --c90은 확장명이 .c인 파일에 대한 기본 옵션이고, --cpp는 확장명이 .cpp인 파일에 대한 기본 옵션입니다.

ARMv4T에서 인터워킹을 위해 컴파일된 모듈은 조금 더 큰 코드를 생성합니다. ARMv5의 경우에는 차이가 없습니다.

본문에 함수 호출이 없는 함수인 리프 함수의 경우, 컴파일러에 의해 생성된 코드에서 MOV pc,lr이 BX lr로 대체된다는 점을 제외하고는 변경 사항이 없습니다. MOV 명령어는 필요한 상태 변경을 수행하지 않습니다.

Thumb 모드에서 ARMv4T용으로 빌드된 리프가 아닌 함수의 경우, 컴파일러에서는 다음과 같이 단일 명령어를 대체해야 합니다.

POP {r4,r5,pc}

이 단일 명령어를 다음 시퀀스로 대체해야 합니다.

POP {r4,r5} POP {r3} BX r3

이렇게 하면 성능에 약간의 영향이 미칩니다. 따라서 인터워킹과 함께 사용할 가능성이 조금이라도 있는 경우에는 모든 소스 모듈을 인터워킹용으로 컴파일하는 것이 좋습니다.

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 4-13

Page 78: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

ARM과 Thumb의 인터워킹

--apcs /interwork 옵션은 모듈이 컴파일되는 코드 영역의 인터워킹 특성도 설정합니다. 링커에서는 이 특성을 감지하고 적절한 비니어를 삽입합니다.

참고

ARMv4T 이전 프로세서에서는 BX 명령어를 구현하지 않으므로 인터워킹용으로 컴파일된 ARM 코드는 ARMv4T 이상에서만 사용할 수 있습니다.

비니어가 차지하는 공간의 크기를 확인하려면 링커 옵션 --info veneers를 사용하십시오.

C 인터워킹 예제

예제 4-3에서는 인터워킹을 통해 ARM 하위 루틴을 호출하는 Thumb 루틴을 보여 줍니다. ARM 하위 루틴 호출에서는 인터워킹을 통해 Thumb 라이브러리의 printf()가 호출됩니다. 이러한 두 개의 모듈은 주 예제 디렉토리의 ...\interwork에 thumbmain.c 및 armsub.c로 제공되어 있습니다.

예제 4-3

/********************* * thumbmain.c * **********************/ #include <stdio.h> extern void arm_function(void); int main(void) { printf("Hello from Thumb\n"); arm_function(); printf("And goodbye from Thumb\n"); return (0); }

/********************* * armsub.c * **********************/ #include <stdio.h> void arm_function(void) { printf("Hello and Goodbye from ARM\n"); }

4-14 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 79: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

ARM과 Thumb의 인터워킹

이러한 모듈을 컴파일 및 링크하려면

1. Thumb 코드를 인터워킹용으로 컴파일하려면 다음을 입력합니다.

armcc --thumb -c -g -O1 --apcs /interwork -o thumbmain.o thumbmain.c

2. ARM 코드를 인터워킹용으로 컴파일하려면 다음을 입력합니다.

armcc -c -g -O1 --apcs /interwork -o armsub.o armsub.c

3. 개체 파일을 링크하려면 다음을 입력합니다.

armlink thumbmain.o armsub.o -o thumbtoarm.axf

또는 예제 4-4에 표시된 것과 같이 인터워킹 비니어의 크기를 보려면 다음을 입력합니다.

armlink armsub.o thumbmain.o -o thumbtoarm.axf --info veneers

예제 4-4

Adding TA veneer (4 bytes, Inline) for call to 'arm_function' from thumbmain.o(.text).Adding AT veneer (8 bytes, Inline) for call to '__0printf' from armsub.o(.text).Adding AT veneer (8 bytes, Inline) for call to '__rt_lib_init' from kernel.o(.text).Adding AT veneer (12 bytes, Long) for call to '__rt_lib_shutdown' from kernel.o(.text).Adding TA veneer (4 bytes, Inline) for call to '__aeabi_memclr4' from stdio.o(.text).Adding TA veneer (4 bytes, Inline) for call to '_mutex_initialize' from stdio.o(.text).Adding TA veneer (4 bytes, Inline) for call to '__rt_raise' from stdio.o(.text).Adding AT veneer (8 bytes, Inline) for call to '__raise' from rt_raise.o(.text).Adding TA veneer (4 bytes, Inline) for call to '__heap_extend' from malloc.o(.text).Adding TA veneer (4 bytes, Inline) for call to '__user_perproc_libspace' from malloc.o(.text).Adding TA veneer (8 bytes, Short) for call to '__rt_exit' from exit.o(.text).Adding TA veneer (4 bytes, Inline) for call to '_fp_init' from lib_init.o(.text).Adding TA veneer (4 bytes, Inline) for call to '__ARM_argv_veneer' from lib_init.o(.text). Adding TA veneer (4 bytes, Inline) for call to '_sys_exit' from abort.o(.text).

14 Veneer(s) (total 80bytes) added to the image.

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 4-15

Page 80: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

ARM과 Thumb의 인터워킹

4.3.2 C 및 C++ 인터워킹의 기본 규칙

응용 프로그램 내에서의 인터워킹에는 다음 규칙이 적용됩니다.

• 다른 명령어 세트로 복귀할 수 있는 함수가 포함된 C 또는 C++ 모듈을 컴파일하려면 --apcs /interwork 명령 행 옵션을 사용해야 합니다.

• 다른 명령어 세트의 함수가 될 수 있는 간접 또는 가상 함수 호출이 포함된 C 또는 C++ 모듈을 컴파일하려면 --apcs /interwork 명령 행 옵션을 사용해야 합니다.

• 비 인터워킹 코드에 대해서는 다른 상태의 코드에서 함수 포인터를 사용한 호출과 같은 간접 호출을 수행하지 마십시오.

• 입력 개체에 Thumb 코드가 들어 있으면 링커에서는 Thumb 런타임 라이브러리를 선택합니다. 이러한 라이브러리는 인터워킹용으로 빌드되었습니다.

링커 명령 행에서 사용자의 라이브러리 중 하나를 명시적으로 지정할 경우에는 해당 라이브러리가 적절한 인터워킹 라이브러리인지 확인해야 합니다.

참고

C 또는 C++ 모듈에 #pragma arm 또는 #pragma thumb으로 표시된 함수가 들어 있으면 해당 모듈은 --apcs /interwork로 컴파일해야 합니다. 이렇게 하면 해당 함수를 다른 상태(ARM 또는 Thumb)에서 올바르게 호출할 수 있습니다.

4.3.3 Thumb 상태의 함수에 대한 포인터

Thumb 코드로 구성되고 Thumb 상태에서 실행되는 함수인 Thumb 함수가 있는 경우, 해당 함수에 대한 포인터에 최하위 비트가 설정되어 있어야 인터워킹이 제대로 작동합니다.

링커에서는 Thumb 명령어를 참조하는 레이블의 값을 재배치할 때 재배치된 값의 최하위 비트를 자동으로 설정합니다. Thumb 함수에 대한 절대 주소를 사용할 경우에는 링커에서 이 작업이 자동으로 수행되지 않습니다.

따라서 코드에서 Thumb 함수에 대한 절대 주소를 사용해야 하는 경우에는 주소에 1을 더해야 합니다. 예를 들어 4-17페이지의 예제 4-5에 표시된 것과 같이 Thumb 함수에 대한 포인터 테이블이 있을 수 있습니다.

자세한 내용은 4-7페이지의 어셈블리 언어 인터워킹을 참조하십시오.

4-16 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 81: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

ARM과 Thumb의 인터워킹

예제 4-5 Thumb 함수에 대한 절대 주소

typedef int (*FN)();

myfunc() { FN fnptrs[] = { (FN)(0x8084 + 1), // Valid Thumb address (FN)(0x8074) // Invalid Thumb address }; FN* myfunctions = fnptrs;

myfunctions[0](); // Call OK myfunctions[1](); // Call Fails}

4.3.4 동일한 함수의 두 가지 버전 사용

각각 ARM과 Thumb용으로 컴파일된 같은 이름의 함수가 두 개 있을 수 있습니다.

ARM/Thumb 동의어

링커에서는 이미지에 한 심볼에 대한 여러 개의 정의가 함께 있는 것을 허용합니다. 단, 각 정의가 서로 다른 프로세서 상태와 관련되어 있어야 합니다. 링커에서는 ARM/Thumb 동의어가 있는 심볼을 참조할 때 다음 규칙이 적용됩니다.

• ARM 상태의 심볼에 대한 B, BL 또는 BLX 명령어는 ARM 정의로 확인됩니다.

• Thumb 상태의 심볼에 대한 B, BL 또는 BLX 명령어는 Thumb 정의로 확인됩니다.

해당 심볼에 대한 다른 참조는 링커에서 발견하는 첫 번째 정의로 확인됩니다. 또한 링커에서 선택한 심볼을 명시하는 경고가 생성됩니다.

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 4-17

Page 82: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

ARM과 Thumb의 인터워킹

4.4 비니어를 사용한 어셈블리 언어 인터워킹

4-7페이지의 어셈블리 언어 인터워킹에 설명된 어셈블리 언어 ARM/Thumb 인터워킹 방법은 필요한 중간 처리를 모두 수행합니다. 링커에서 인터워킹 비니어를 삽입하는 데 필요한 요구 사항은 없습니다.

비니어에 대한 자세한 내용은 4-5페이지의 링커에서 생성된 비니어를 참조하십시오.

4.4.1 비니어를 사용한 어셈블리 전용 인터워킹

어셈블리 언어 ARM/Thumb 인터워킹 코드를 작성하여 링커에서 생성된 인터워킹 비니어를 사용할 수 있습니다. 이렇게 하려면 다음 항목을 작성합니다.

• BL 명령어를 사용하여 호출을 수행하는 비 인터워킹 루틴과 같은 호출자 루틴. 호출자 루틴은 --apcs /interwork나 --apcs /nointerwork를 사용하여 어셈블할 수 있습니다.

참고

BL 명령어의 범위는 ARM 상태의 경우 32MB이고 Thumb 상태의 경우 4MB입니다. 개발 과정에서 이 범위를 벗어나는 타겟에 대한 호출이나 다른 상태의 함수에 대한 호출이 응용 프로그램에 포함되는 경우가 있습니다. 이 경우 링커에서 비니어가 자동으로 삽입됩니다. 비니어는 원래 BL의 중간 타겟이 되며 비니어 코드는 PC를 필요한 대상 주소로 설정합니다.

• BX 명령어를 사용하여 복귀하는 호출 수신자 루틴. 호출 수신자 루틴은 --apcs /interwork를 사용하여 어셈블되어 있어야 합니다. 또한 EXPORT ThumbSub와 같이 루틴의 함수 레이블을 내보내야 할 수도 있습니다(4-19페이지의 예제 4-6 참조). 해당되는 경우 어셈블러 코드는 AAPCS를 준수해야 합니다.

이 작업은 일반적으로 ARMv4T에서, 또는 호출자와 호출 수신자가 멀리 떨어져 있거나 서로 다른 영역에 있는 경우에만 필요합니다. ARMv5T 이상에서는 호출자와 호출 수신자가 충분히 가까이 있을 경우 비니어가 필요하지 않습니다.

4-18 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 83: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

ARM과 Thumb의 인터워킹

비니어를 사용한 어셈블리 언어 인터워킹의 예제

예제 4-6에서는 레지스터 r0 ~ r2를 각각 값 1, 2 및 3으로 설정하는 코드를 보여 줍니다. 레지스터 r0과 r2는 ARM 코드에서 설정되고 r1은 Thumb 코드에서 설정됩니다. 다음을 확인하십시오.

• 코드는 --apcs /interwork 옵션을 사용하여 어셈블되어 있어야 합니다.

• BX lr 명령어는 일반적인 MOV pc,lr 대신 하위 루틴에서 복귀하는 데 사용됩니다.

예제 4-6

; ***** ; arm.s ; *****

PRESERVE8

AREA Arm,CODE,READONLY ; Name this block of code. IMPORT ThumbProg ENTRY ; Mark 1st instruction to call.ARMProg MOV r0,#1 ; Set r0 to show in ARM code. BL ThumbProg ; Call Thumb subroutine. MOV r2,#3 ; Set r2 to show returned to ARM. ; Terminate execution. MOV r0, #0x18 ; angel_SWIreason_ReportException LDR r1, =0x20026 ; ADP_Stopped_ApplicationExit SVC 0x123456 ; ARM semihosting (formerly SWI) END

; ******* ; thumb.s ; ******* AREA Thumb,CODE,READONLY ; Name this block of code. THUMB ; Subsequent instructions are Thumb. EXPORT ThumbProgThumbProg MOVS r1, #2 ; Set r1 to show reached Thumb code. BX lr ; Return to ARM subroutine. END ; Mark end of this file.

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 4-19

Page 84: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

ARM과 Thumb의 인터워킹

다음 단계에 따라 모듈을 빌드 및 링크하고 인터워킹 비니어를 확인할 수 있습니다.

1. armasm -g arm.s를 입력하여 ARM 코드를 어셈블합니다.

2. armasm --thumb -g --apcs /interwork thumb.s를 입력하여 Thumb 코드를 어셈블합니다.

3. armlink arm.o thumb.o -o count를 입력하여 두 개체 파일을 링크합니다.

4. 호환되는 디버거를 적절한 디버그 타겟과 함께 사용하여 이미지를 실행합니다.

예제 4-7의 디스어셈블된 코드에서는 링커에서 삽입된 인터워킹 비니어를 보여 줍니다. 비니어는 다음 워드 경계에 삽입되고 주소 0x0000801C에서 시작됩니다.

예제 4-7

ARMProg: 00008000 E3A00001 MOV r0,#1 00008004 EB000004 BL 0x801c 00008008 E3A02003 MOV r2,#3 0000800C E3A00018 MOV r0,#0x18 00008010 E59F1000 LDR r1,0x8018 00008014 EF123456 SVC 0x123456 00008018 00020026 <Data> '&' 0x00 0x02 0x00 0000801C E28FC001 ADR r12,{pc}+9 ; #0x8025 00008020 E12FFF1C BX r12 ThumbProg: 00008024 2102 MOV r1,#2 00008026 4770 BX r14

4-20 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 85: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

ARM과 Thumb의 인터워킹

4.4.2 비니어를 사용한 C, C++ 및 어셈블리 언어 인터워킹

특정 상태에서 실행되도록 컴파일된 C 및 C++ 코드가 다른 상태에서 실행되도록 설계된 어셈블리 언어 코드를 호출할 수 있으며 그 반대의 경우도 가능합니다. 이렇게 하려면 호출자 루틴을 비 인터워킹 루틴으로 작성합니다. 또한 어셈블리 언어에서 호출할 경우에는 BL 명령어를 사용하여 호출합니다(4-21페이지의 예제 4-8 참조). 그런 후 다음을 수행합니다.

• 호출 수신자 루틴이 C로 작성되어 있으면 --apcs /interwork를 사용하여 이 루틴을 컴파일합니다.

• 호출 수신자 루틴이 어셈블리 언어로 작성되어 있으면 --apcs /interwork 옵션을 사용하여 이 루틴을 어셈블하고 BX lr을 사용하여 복귀합니다.

참고

이 방식으로 사용되는 어셈블리 언어 코드나 사용자 라이브러리 코드는 해당되는 경우 AAPCS를 준수해야 합니다.

예제 4-8

/********************** * thumb.c * **********************/ #include <stdio.h> extern int arm_function(int); int main(void) { int i = 1; printf("i = %d\n", i); printf("And now i = %d\n", arm_function(i)); return (0); }

; ***** ; arm.s ; ***** PRESERVE8 AREA Arm,CODE,READONLY ; Name this block of code. EXPORT arm_functionarm_function ADD r0,r0,#4 ; Add 4 to first parameter. BX lr ; Return END

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 4-21

Page 86: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

ARM과 Thumb의 인터워킹

다음 단계에 따라 모듈을 빌드하고 링크합니다.

1. armcc --thumb -g -c --apcs /interwork thumb.c를 입력하여 Thumb 코드를 컴파일합니다.

2. armasm -g --apcs /interwork arm.s를 입력하여 ARM 코드를 어셈블합니다.

3. armlink arm.o thumb.o -o add --info veneers를 입력하여 두 개체 파일을 링크하고 인터워킹 비니어의 크기를 확인합니다.

4. 호환되는 디버거를 적절한 디버그 타겟과 함께 사용하여 이미지를 실행합니다.

4-22 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 87: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

5장 C, C++ 및 어셈블리 언어 조합

이 장에서는 C, C++ 및 ARM® 어셈블리 언어가 조합된 코드를 작성하는 방법을 설명합니다. 또한 C와 C++에서 ARM 인라인 및 임베디드 어셈블러를 사용하는 방법에 대해서도 설명합니다. 여기에는 다음 단원이 포함되어 있습니다.

• 5-2페이지의 인라인 및 임베디드 어셈블러 사용

• 5-4페이지의 어셈블리 코드에서 C 전역 변수 액세스

• 5-6페이지의 C++에서 C 헤더 파일 사용

• 5-8페이지의 C, C++ 및 ARM 어셈블리 언어 간 호출

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 5-1

Page 88: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

C, C++ 및 어셈블리 언어 조합

5.1 인라인 및 임베디드 어셈블러 사용

ARM 컴파일러에 기본적으로 제공된 인라인 및 임베디드 어셈블러를 통해 C 또는 C++에서 직접 액세스할 수 없는 타겟 프로세서의 기능을 사용할 수 있습니다. 예를 들면 다음과 같습니다.

• 포화 산술(어셈블러 설명서의 4-106페이지의 포화 명령어 참조)

• 사용자 지정 보조 프로세서

• PSR(프로그램 상태 레지스터)

자세한 내용은 컴파일러 사용 설명서에서 6장 인라인 및 임베디드 어셈블러 사용을 참조하십시오.

5.1.1 인라인 어셈블러의 기능

인라인 어셈블러는 C 및 C++와의 매우 융통성 있는 인터워킹을 지원합니다. 레지스터 피연산자는 임의의 C 또는 C++ 식일 수 있습니다. 또한 인라인 어셈블러는 복잡한 명령어를 확장하고 어셈블리 언어 코드를 최적화합니다.

참고

인라인 어셈블리 언어는 컴파일러에서 수행하는 최적화의 영향을 받습니다. 결과 개체 코드는 어셈블리 코드에 정확히 대응되지 않을 수도 있습니다.

ARM 코드의 인라인 어셈블러는 일반 보조 프로세서 명령어, 하프워드 명령어, long 곱하기를 비롯하여 대부분의 ARM 명령어 세트를 구현합니다.

5.1.2 임베디드 어셈블러의 기능

임베디드 어셈블러를 사용하면 낮은 수준의 무제한 권한으로 타겟 프로세서에 액세스하고, C 및 C++ 사전 처리기 지시문을 사용하고, 구조체 구성원 오프셋에 쉽게 액세스할 수 있습니다.

임베디드 어셈블러에서는 어셈블러 지시문을 비롯하여 전체 ARM 어셈블러 명령어 세트를 사용할 수 있습니다. 임베디드 어셈블리 코드는 C 및 C++ 코드와는 별도로 어셈블됩니다. 컴파일된 개체는 생성 후 C 및 C++ 소스의 컴파일을 통해 생성된 개체와 결합됩니다.

임베디드 어셈블러는 ARM 코드와 Thumb® 코드 모두에서 지원됩니다. ARM/Thumb 명령어 세트에 대한 자세한 내용은 어셈블러 설명서를 참조하십시오.

5-2 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 89: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

C, C++ 및 어셈블리 언어 조합

5.1.3 인라인 어셈블리 코드와 임베디드 어셈블리 코드의 차이점

표 5-1에서는 인라인 어셈블러와 임베디드 어셈블러의 주요 차이점을 간단히 설명합니다.

참고

임베디드 어셈블러와 C/ C++의 차이점 목록은 컴파일러 사용 설명서의 6장 인라인 및 임베디드 어셈블러 사용에 나와 있습니다.

표 5-1 인라인 어셈블러와 임베디드 어셈블러의 차이점

기능 임베디드 어셈블러 인라인 어셈블러

명령어 세트 ARM 및 Thumb ARM만

ARM 어셈블러 지시문 모두 지원 지원 안 됨

C/C++ 식 상수 식만 모든 C/C++ 식

어셈블리 코드의 최적화 최적화 안 함 모두 최적화

인라인 올바른 크기와 링커 인라인이 활성화되어 있으면 링커에서 인라인될 수 있음

가능

레지스터 액세스 지정된 물리 레지스터 사용. PC, LR 및 SP도 사용할 수 있음.

가상 레지스터 사용

sp(r13), lr (r14) 및 pc(r15) 사용 시 오류 발생

명령어 반환 코드에 추가해야 함 자동 생성됨. BX, BXJ 및 BLX 명령어는 지원 안 됨.

BKPT 명령어 직접 지원 지원 안 됨. __breakpoint 명령어 내장 함수를 사용할 수 있음(컴파일러 참조 설명서의 4-65페이지의 __breakpoint 참조).

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 5-3

Page 90: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

C, C++ 및 어셈블리 언어 조합

5.2 어셈블리 코드에서 C 전역 변수 액세스

전역 변수는 변수의 주소를 통해 간접적으로만 액세스할 수 있습니다. 전역 변수에 액세스하려면 IMPORT 지시문을 사용하여 가져오기를 수행한 후 해당 주소를 레지스터로 로드합니다. 전역 변수의 유형에 따라 로드 및 저장 명령어를 사용하여 전역 변수에 액세스할 수 있습니다.

예를 들어 unsigned 변수의 경우 다음 명령어를 사용합니다.

• char의 경우 LDRB/STRB

• short의 경우 LDRH/STRH

• int의 경우 LDR/STR

signed 변수의 경우 LDRSB 및 LDRSH와 같이 부호 있는 해당 명령어를 사용합니다.

8워드 미만의 작은 구조체는 LDM 및 STM 명령어를 사용하여 전체적으로 액세스할 수 있습니다. 구조체의 개별 구성원은 적절한 유형의 로드 또는 저장 명령어를 통해 액세스할 수 있습니다. 구성원에 액세스하려면 구조체의 시작 부분부터 구성원까지의 오프셋을 알고 있어야 합니다.

예제 5-1에서는 정수 전역 변수 globvar의 주소를 r1으로 로드하고, 해당 주소에 포함된 값을 r0으로 로드하며, 이 값에 2를 더한 다음 새 값을 globvar에 다시 저장합니다.

예제 5-1 전역 변수 액세스

PRESERVE8

AREA globals,CODE,READONLY

EXPORT asmsubroutine IMPORT globvar

asmsubroutine LDR r1, =globvar ; read address of globvar into ; r1 from literal pool LDR r0, [r1] ADD r0, r0, #2 STR r0, [r1] BX lr END

5-4 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 91: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

C, C++ 및 어셈블리 언어 조합

ARM 또는 Thumb 코드에서 사용할 수 있는 명령어에 대한 자세한 내용은 어셈블러 설명서의 4장 ARM 및 Thumb 명령어를 참조하십시오.

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 5-5

Page 92: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

C, C++ 및 어셈블리 언어 조합

5.3 C++에서 C 헤더 파일 사용

C 헤더 파일은 C++에서 호출되기 전에 extern "C" 지시문으로 래핑되어야 합니다.

5.3.1 시스템 C 헤더 파일 포함

stdio.h와 같은 표준 시스템 C 헤더 파일을 포함하기 위해 특별한 단계를 수행하지 않아도 됩니다. 표준 C 헤더 파일에는 이미 적절한 extern "C" 지시문이 포함되어 있습니다. 예를 들면 다음과 같습니다.

#include <stdio.h>int main(){ ... // C++ code return 0;}

이 구문을 사용하여 헤더를 포함하면 모든 라이브러리 이름이 전역 네임스페이스에 배치됩니다.

C++ 표준은 C++ 관련 헤더 파일을 통해 C 헤더 파일의 기능을 사용할 수 있도록 지정합니다. 이러한 파일은 표준 C 헤더 파일과 함께 install_directory\RVCT\Data\3.0\build_num\include\platform에 설치되며, 일반적인 방법으로 참조할 수 있습니다. 예를 들면 다음과 같습니다.

#include <cstdio>

ARM C++에서 이러한 헤더는 C 헤더를 포함(#include)합니다. 이 구문을 사용하여 헤더를 포함하면 C 라이브러리 이름을 포함하여 모든 C++ 표준 라이브러리 이름이 std 네임스페이스에 정의됩니다. 따라서 다음 방법 중 하나를 사용하여 모든 라이브러리 이름을 정규화해야 합니다.

• 아래와 같이 표준 네임스페이스를 지정합니다.

std::printf("example\n");

• C++ 키워드 using을 사용하여 전역 네임스페이스로 이름을 가져옵니다.

using namespace std;printf("example\n");

• 컴파일러 옵션 --using_std를 사용합니다.

5-6 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 93: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

C, C++ 및 어셈블리 언어 조합

5.3.2 사용자 고유의 C 헤더 파일 포함

사용자 고유의 C 헤더 파일을 포함하려면 extern "C" 문에서 #include 지시문을 래핑해야 합니다. 다음 방법으로 이 작업을 수행할 수 있습니다.

• 파일이 포함(#include)되어 있는지 확인합니다(예제 5-2 참조).

• 헤더 파일에 extern "C" 문을 추가합니다(예제 5-3참조).

예제 5-2 파일을 포함하기 전의 지시문

// C++ code

extern "C" {#include "my-header1.h"#include "my-header2.h"}

int main(){ // ... return 0;}

예제 5-3 파일 헤더의 지시문

/* C header file */

#ifdef __cplusplus /* Insert start of extern C construct */extern "C" {#endif

/* Body of header file */

#ifdef __cplusplus /* Insert end of extern C construct */} /* The C header file can now be */#endif /* included in either C or C++ code. */

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 5-7

Page 94: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

C, C++ 및 어셈블리 언어 조합

5.4 C, C++ 및 ARM 어셈블리 언어 간 호출

이 단원에서는 C++에서 C 및 어셈블리 언어 코드를 호출하고 C 및 어셈블리 언어에서 C++ 코드를 호출하는 방법을 보여 주는 예제를 제공합니다. 다음을 비롯한 호출 규칙 및 데이터 유형에 대해서도 설명합니다.

AAPCS를 준수할 경우 C/C++ 및 어셈블리 언어 루틴 간의 호출을 조합할 수 있습니다. 자세한 내용은 install_directory\Documentation\Specifications\...에 있는 Procedure Call Standard for the ARM Architecture 사양(aapcs.pdf)을 참조하십시오.

참고

이 단원의 내용은 구현 방식에 따라 달라지며 이후 릴리스에서 변경될 수 있습니다.

5.4.1 언어 간 호출을 위한 일반적인 규칙

C, C++ 및 어셈블리 언어 간의 호출에는 다음과 같은 일반적인 규칙이 적용됩니다. 자세한 내용은 컴파일러 사용 설명서를 참조하십시오.

임베디드 어셈블러를 사용하고 ABI(응용 프로그램 바이너리 인터페이스) for the ARM Architecture(기본 표준)[BSABI]를 준수하면 조합 언어 프로그래밍을 보다 쉽게 구현할 수 있습니다. 이를 통해 다음 사항과 관련된 작업을 쉽게 수행할 수 있습니다.

• __cpp 키워드를 사용한 이름 변환

• 암시적 this 매개변수가 전달되는 방식

• 가상 함수가 호출되는 방식

• 참조 표현

• 기본 클래스 또는 가상 구성원 함수가 있는 C++ 클래스 유형의 레이아웃

• 기존의 일반 데이터 구조체가 아닌 클래스 개체 전달

조합 언어 프로그래밍에는 다음과 같은 일반적인 규칙이 적용됩니다.

• C 호출 규칙을 사용합니다.

• C++에서 비 구성원 함수를 extern "C"로 선언하여 C 링키지를 포함하도록 지정할 수 있습니다. 이번 릴리스의 RealView® Compilation Tools(RVCT)에서 C 링키지를 포함한다는 것은 함수를 정의하는 심볼의 이름이 변환되지 않는다는 것을 의미합니다. C 링키지를 사용하면 함수를 한 언어로 구현한 후 다른 언어에서 호출할 수 있습니다.

5-8 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 95: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

C, C++ 및 어셈블리 언어 조합

참고

extern "C"로 선언된 함수는 오버로드할 수 없습니다.

• 어셈블리 언어 모듈은 응용 프로그램에서 사용하는 메모리 모듈에 적절한 AAPCS 표준을 준수해야 합니다.

C 및 어셈블리 언어에서 C++ 함수를 호출하는 데는 다음 규칙이 적용됩니다 .

• 전역(비 구성원) C++ 함수를 호출하려면 해당 함수를 extern "C"로 선언하여 함수에 C 링키지를 지정합니다.

• 구성원 함수(정적 및 비정적 함수 모두 포함)에는 항상 변환된 이름이 있습니다. 임베디드 어셈블러의 __cpp 키워드를 사용하면 변환된 이름을 직접 찾을 필요가 없습니다.

• C++ 컴파일러에서 함수의 라인 외부 복사본을 생성할 수 없는 경우에는 C에서 C++ 인라인 함수를 호출할 수 없습니다. 예를 들어 함수의 주소를 사용하면 라인 외부 복사본이 생성됩니다.

• 비정적 구성원 함수는 int 계열이 아닌 구조체를 반환할 경우 첫 번째 인수(r0)나 두 번째 인수(r1)로 암시적 this 매개변수를 받습니다. 정적 구성원 함수는 암시적 this 매개변수를 받지 않습니다.

5.4.2 C++ 관련 정보

다음 내용은 C++에만 해당됩니다.

C++ 호출 규칙

ARM C++에서는 다음 사항을 제외하고는 ARM C와 동일한 호출 규칙을 사용합니다.

• 비정적 구성원 함수는 int 계열이 아닌 struct를 반환할 경우 첫 번째 인수나 두 번째 인수로 암시적 this 매개변수를 사용하여 호출됩니다. 이는 이후 구현에서 변경될 수 있습니다.

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 5-9

Page 96: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

C, C++ 및 어셈블리 언어 조합

C++ 데이터 유형

ARM C++에서는 다음 사항을 제외하고는 ARM C와 동일한 데이터 유형을 사용합니다.

• struct 또는 class 유형의 C++ 개체는 기본 클래스나 가상 함수가 없는 경우 ARM C에서 일반적으로 사용되는 레이아웃과 동일한 레이아웃을 사용합니다. 이러한 struct에 사용자 정의 복사본 할당 연산자나 사용자 정의 소멸자가 없으면 해당 구조체는 기존의 일반적인 데이터 구조체입니다.

• 참조는 포인터로 표시됩니다.

• C 함수에 대한 포인터와 C++ 비 구성원 함수에 대한 포인터가 구별되지 않습니다.

심볼 이름 변환

링커에서는 메시지의 심볼 이름을 변환하지 않습니다.

C++ 프로그램에서 C 이름은 extern "C"로 선언되어야 합니다. ARM ISO C 헤더의 경우에는 C 이름이 이미 이렇게 선언되어 있습니다. 자세한 내용은 5-6페이지의 C++에서 C 헤더 파일 사용을 참조하십시오.

5.4.3 언어 간 호출 예제

다음 단원에는 여러 언어 간의 호출 방법을 보여 주는 코드 예제가 포함되어 있습니다.

• 5-11페이지의 C에서 어셈블리 언어 호출

• 5-12페이지의 어셈블리 언어에서 C 호출

• 5-13페이지의 C++에서 C 호출

• 5-14페이지의 C++에서 어셈블리 언어 호출

• 5-15페이지의 C에서 C++ 호출

• 5-16페이지의 어셈블리 언어에서 C++ 호출

• 5-18페이지의 C 또는 어셈블리 언어에서 C++ 호출

• 5-17페이지의 C 및 C++ 간에 참조 전달

5-10 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 97: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

C, C++ 및 어셈블리 언어 조합

C에서 어셈블리 언어 호출

예제 5-4와 예제 5-5에서는 어셈블리 언어 하위 루틴을 호출하여 한 문자열을 다른 문자열의 맨 위에 복사하는 C 프로그램을 보여 줍니다.

예제 5-4 C에서 어셈블리 언어 호출

#include <stdio.h>extern void strcopy(char *d, const char *s);int main(){ const char *srcstr = "First string - source "; char dststr[] = "Second string - destination ";/* dststr is an array since weíre going to change it */ printf("Before copying:\n"); printf(" %s\n %s\n",srcstr,dststr); strcopy(dststr,srcstr); printf("After copying:\n"); printf(" %s\n %s\n",srcstr,dststr); return (0);}

예제 5-5 어셈블리 언어 문자열 복사 하위 루틴

PRESERVE8

AREA SCopy, CODE, READONLY EXPORT strcopystrcopy ; r0 points to destination string. ; r1 points to source string. LDRB r2, [r1],#1 ; Load byte and update address. STRB r2, [r0],#1 ; Store byte and update address. CMP r2, #0 ; Check for zero terminator. BNE strcopy ; Keep going if not. BX lr ; Return. END

예제 5-4는 주 예제 디렉토리의 ...\asm에 strtest.c 및 scopy.s라는 이름으로 포함되어 있습니다.

명령 행에서 예제를 빌드하려면 다음 단계를 수행하십시오.

1. armasm --debug scopy.s를 입력하여 어셈블리 언어 소스를 빌드합니다.

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 5-11

Page 98: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

C, C++ 및 어셈블리 언어 조합

2. armcc -c --debug strtest.c를 입력하여 C 소스를 빌드합니다.

3. armlink strtest.o scopy.o -o strtest를 입력하여 개체 파일을 링크합니다.

4. 호환되는 디버거를 적절한 디버그 타겟과 함께 사용하여 이미지를 실행합니다.

어셈블리 언어에서 C 호출

예제 5-6과 예제 5-7에서는 어셈블리 언어에서 C++를 호출하는 방법을 보여 줍니다.

예제 5-6 C에서 함수 정의

int g(int a, int b, int c, int d, int e) { return a + b + c + d + e;}

예제 5-7 어셈블리 언어 호출

; int f(int i) { return g(i, 2*i, 3*i, 4*i, 5*i); }

PRESERVE8

EXPORT f AREA f, CODE, READONLY IMPORT g ; i is in r0 STR lr, [sp, #-4]! ; preserve lr ADD r1, r0, r0 ; compute 2*i (2nd param) ADD r2, r1, r0 ; compute 3*i (3rd param) ADD r3, r1, r2 ; compute 5*i STR r3, [sp, #-4]! ; 5th param on stack ADD r3, r1, r1 ; compute 4*i (4th param) BL g ; branch to C function ADD sp, sp, #4 ; remove 5th param LDR pc, [sp], #4 ; return END

5-12 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 99: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

C, C++ 및 어셈블리 언어 조합

C++에서 C 호출

예제 5-8과 예제 5-9에서는 C++에서 C를 호출하는 방법을 보여 줍니다.

예제 5-8 C++에서 C 함수 호출

struct S { // has no base classes // or virtual functions S(int s) : i(s) { } int i;};extern "C" void cfunc(S *); // declare the C function to be called from C++int f(){ S s(2); // initialize 's' cfunc(&s); // call 'cfunc' so it can change 's' return s.i * 3;}

예제 5-9 C에서 함수 정의

struct S { int i;};void cfunc(struct S *p) {/* the definition of the C function to be called from C++ */ p->i += 5;}

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 5-13

Page 100: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

C, C++ 및 어셈블리 언어 조합

C++에서 어셈블리 언어 호출

예제 5-10과 예제 5-11에서는 C++에서 어셈블리 언어를 호출하는 방법을 보여 줍니다.

예제 5-10 C++에서 어셈블리 언어 호출

struct S { // has no base classes // or virtual functions S(int s) : i(s) { } int i;};

extern "C" void asmfunc(S *); // declare the Asm function // to be calledint f() { S s(2); // initialize 's' asmfunc(&s); // call 'asmfunc' so it // can change 's' return s.i * 3;}

예제 5-11 어셈블리 언어 함수 정의

PRESERVE8

AREA Asm, CODE EXPORT asmfuncasmfunc ; the definition of the Asm LDR r1, [r0] ; function to be called from C++ ADD r1, r1, #5 STR r1, [r0] BX lr END

5-14 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 101: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

C, C++ 및 어셈블리 언어 조합

C에서 C++ 호출

예제 5-12와 예제 5-13에서는 C에서 C++를 호출하는 방법을 보여 줍니다.

예제 5-12 C++에서 호출되도록 함수 정의

struct S { // has no base classes or virtual functions S(int s) : i(s) { } int i;};

extern "C" void cppfunc(S *p) { // Definition of the C++ function to be called from C.// The function is written in C++, only the linkage is C p->i += 5; //}

예제 5-13 C에서 함수 선언 및 호출

struct S { int i;};

extern void cppfunc(struct S *p); /* Declaration of the C++ function to be called from C */

int f(void) { struct S s; s.i = 2; /* initialize 's' */ cppfunc(&s); /* call 'cppfunc' so it */ /* can change 's' */ return s.i * 3;}

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 5-15

Page 102: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

C, C++ 및 어셈블리 언어 조합

어셈블리 언어에서 C++ 호출

예제 5-14와 예제 5-15에서는 어셈블리 언어에서 C++를 호출하는 방법을 보여 줍니다.

예제 5-14 C++에서 호출되도록 함수 정의

struct S { // has no base classes or virtual functions S(int s) : i(s) { } int i;};extern "C" void cppfunc(S * p) {// Definition of the C++ function to be called from ASM.// The body is C++, only the linkage is C p->i += 5;}

ARM 어셈블리 언어에서는 C++ 함수의 이름을 가져오고 BL(링크 포함 분기) 명령어를 사용하여 해당 함수를 호출합니다.

예제 5-15 어셈블리 언어 함수 정의

AREA Asm, CODE IMPORT cppfunc ; import the name of the C++ ; function to be called from Asm

EXPORT ff STMFD sp!,{lr} MOV r0,#2 STR r0,[sp,#-4]! ; initialize struct MOV r0,sp ; argument is pointer to struct BL cppfunc ; call 'cppfunc' so it can change ; the struct LDR r0, [sp], #4 ADD r0, r0, r0,LSL #1 LDMFD sp!,{pc} END

5-16 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 103: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

C, C++ 및 어셈블리 언어 조합

C 및 C++ 간에 참조 전달

예제 5-16과 예제 5-17에서는 C 및 C++ 간에 참조를 전달하는 방법을 보여 줍니다.

예제 5-16 C++ 함수 정의

extern "C" int cfunc(const int&); // Declaration of the C function to be called from C++

extern "C" int cppfunc(const int& r) {// Definition of the C++ to be called from C. return 7 * r;}

int f() { int i = 3; return cfunc(i); // passes a pointer to 'i'}

예제 5-17 C 함수 정의

extern int cppfunc(const int*); /* declaration of the C++ to be called from C */

int cfunc(const int *p) { /* definition of the C function to be called from C++ */ int k = *p + 4; return cppfunc(&k);}

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 5-17

Page 104: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

C, C++ 및 어셈블리 언어 조합

C 또는 어셈블리 언어에서 C++ 호출

예제 5-18, 예제 5-19와 5-19페이지의 예제 5-20에 나오는 코드에서는 C 또는 어셈블리 언어에서 비정적이며 가상이 아닌 구성원 함수를 호출하는 방법을 보여 줍니다. 함수의 변환된 이름을 찾으려면 컴파일러에서 어셈블러 출력을 사용합니다.

예제 5-18 C++ 구성원 함수 호출

struct T { T(int i) : t(i) { } int t; int f(int i);};

int T::f(int i) { return i + t; } // Definition of the C++ function to be called from C.

extern "C" int cfunc(T*); // declaration of the C function to be called from C++

int f() { T t(5); // create an object of type T return cfunc(&t);}

예제 5-19 C 함수 정의

struct T;

extern int _ZN1T1fEi(struct T*, int); /* the mangled name of the C++ */ /* function to be called */

int cfunc(struct T* t) { /* Definition of the C function to be called from C++. */ return 3 * _ZN1T1fEi(t, 2); /* like '3 * t->f(2)' */}

5-18 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 105: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

C, C++ 및 어셈블리 언어 조합

예제 5-20 어셈블리 언어에서 함수 구현

EXPORT cfunc AREA foo, CODE IMPORT _ZN1T1fEi

cfunc STMFD sp!,{lr} ; r0 already contains the object pointer MOV r1, #2 BL _ZN1T1fEi ADD r0, r0, r0, LSL #1 ; multiply by 3 LDMFD sp!,{pc} END

또는 예제 5-21에서 보여 주는 대로 임베디드 어셈블리를 사용하여 5-18페이지의 예제 5-18과 예제 5-20을 구현할 수 있습니다. 이 예제에서 __cpp 키워드는 함수를 참조하는 데 사용됩니다. 따라서 함수의 변환된 이름을 몰라도 됩니다.

예제 5-21 임베디드 어셈블리에서 함수 구현

struct T { T(int i) : t(i) { } int t; int f(int i);};int T::f(int i) { return i + t; }

// Definition of asm function called from C++__asm int asm_func(T*) { STMFD sp!, {lr} MOV r1, #2; BL __cpp(T::f); ADD r0, r0, r0, LSL #1 ; multiply by 3 LDMFD sp!, {pc}}

int f() { T t(5); // create an object of type T return asm_func(&t);}

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 5-19

Page 106: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

C, C++ 및 어셈블리 언어 조합

5-20 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 107: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

6장 프로세서 예외 처리

이 장에서는 ARMv6 및 이전 아키텍처와 v7-A 및 v7-R 프로파일에서 지원하는 여러 가지 유형의 예외를 처리하는 방법을 설명합니다.

Cortex-M3와 같은 ARMv7-M 프로세서는 다른 예외 처리 모델을 사용합니다. 자세한 내용은 7장 Cortex-M3 프로세서 예외 처리를 참조하십시오.

이 장에는 다음 단원이 포함되어 있습니다.

• 6-2페이지의 프로세서 예외 개요• 6-6페이지의 프로세서 상태 확인• 6-8페이지의 예외 발생 및 종료• 6-13페이지의 예외 처리• 6-14페이지의 예외 처리기 설치• 6-19페이지의 SVC 처리기• 6-29페이지의 인터럽트 처리기• 6-40페이지의 리셋 처리기• 6-41페이지의 정의되지 않은 명령어 처리기• 6-42페이지의 프리페치 어보트 처리기• 6-43페이지의 데이터 어보트 처리기• 6-44페이지의 시스템 모드

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 6-1

Page 108: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

프로세서 예외 처리

6.1 프로세서 예외 개요

프로그램을 통한 일반적인 실행 흐름 동안에는 주소 공간을 통해 PC(프로그램 카운터)가 순차적으로 늘어나면서 인접 레이블로 분기되거나 하위 루틴으로 분기 및 링크됩니다.

이러한 일반적인 실행 흐름에 변화가 생기면 프로세서 예외가 발생하여, 프로세서에서 내부 또는 외부 원인으로 인해 생성된 이벤트를 처리할 수 있도록 합니다. 이러한 이벤트의 예는 다음과 같습니다.

• 외부에서 인터럽트가 생성되는 경우

• 프로세서에서 정의되지 않은 명령어를 실행하려고 시도하는 경우

• 권한이 필요한 운영 체제 기능에 액세스하려는 경우

이러한 예외를 처리할 때는 적절한 예외 루틴이 완료된 후 예외 발생 시점에서 실행하고 있던 프로그램의 실행을 다시 시작할 수 있도록 이전 프로세서 상태를 유지해야 합니다.

6-2 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 109: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

프로세서 예외 처리

6.1.1 예외 유형

표 6-1에서는 ARM 프로세서에서 인식하는 다양한 예외 유형을 보여 줍니다.

잘못된 주소

잘못된 가상 주소는 현재 실제 메모리의 주소에 해당하지 않거나 메모리 관리 하위 시스템에서 현재 모드의 프로세서가 액세스할 수 없는 것으로 확인된 주소입니다.

표 6-1 예외 유형

예외 설명

리셋 프로세서 리셋 핀이 어설션될 때 발생합니다. 이 예외는 전원 켜짐 신호가 전달되거나 프로세서가 전원이 켜졌을 때와 같은 상태로 재설정되는 경우에만 발생합니다. 소프트 리셋은 리셋 벡터(0x0000 또는 0xFFFF0000)로 분기하여 수행될 수 있습니다.

정의되지 않은 명령어 프로세서 및 연결된 보조 프로세서 모두에서 현재 실행 중인 명령어를 인식할 수 없는 경우에 발생합니다.

SVC(관리자 호출) SVC는 사용자 정의 동기 인터럽트 명령어입니다. 이 명령어는 사용자 모드에서 실행되는 프로그램이 RTOS 함수와 같이 관리자 모드에서 실행되며 권한이 필요한 작업을 요청할 수 있도록 합니다.

프리페치 어보트 프로세서에서 잘못된 주소로 인해 가져오지 못한 명령어를 실행하려고 할 때 발생합니다(잘못된 주소 참조).

데이터 어보트 데이터 전송 명령어가 잘못된 주소에서 데이터를 로드하거나 저장하려고 할 때 발생합니다(잘못된 주소 참조).

IRQ 프로세서 외부 인터럽트 요청 핀이 어설션(LOW)되고 CPSR의 I 비트가 지워진 경우에 발생합니다.

FIQ 프로세서 외부 고속 인터럽트 요청 핀이 어설션(LOW)되고 CPSR의 F 비트가 지워진 경우에 발생합니다.

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 6-3

Page 110: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

프로세서 예외 처리

6.1.2 벡터 테이블

벡터 테이블은 프로세서 예외 처리를 제어합니다. 벡터 테이블은 32바이트 크기의 예약된 영역으로, 대개 메모리 맵의 맨 아래에 있습니다. 벡터 테이블에는 각 예외 유형에 할당된 공간의 워드 하나와 현재 예약된 워드가 하나 있습니다.

벡터 테이블에는 처리기의 전체 코드를 포함할 만큼 충분한 공간이 없으므로 각 예외 유형의 벡터 엔트리에는 대개 적절한 처리기로 실행을 계속하기 위한 분기 명령어나 PC 로드 명령어가 포함되어 있습니다.

6.1.3 예외별 모드 및 레지스터 사용

일반적으로 응용 프로그램은 사용자 모드에서 실행되지만 예외를 처리하려면 권한 모드가 필요합니다. 예외가 발생하면 프로세서 모드가 변경되므로 각 예외 처리기에서 다음과 같은 뱅크 레지스터의 특정 하위 세트에 액세스할 수 있게 됩니다.

• 해당하는 r13 또는 스택 포인터(sp_mode)

• 해당하는 r14 또는 링크 레지스터(lr_mode)

• 해당하는 저장된 프로그램 상태 레지스터(spsr_ mode)

FIQ의 경우 각 예외 처리기에서는 다섯 개의 추가 범용 레지스터(r8_FIQ ~ r12_FIQ)에 액세스할 수 있습니다.

각 예외 처리기가 종료되면 다른 레지스터는 원래 내용으로 복원되어야 합니다. 이렇게 하려면 처리기에서 사용해야 하는 레지스터의 내용을 해당 스택에 저장하고 복귀 전에 이 레지스터를 복원합니다. RealView ARMulator® ISS를 사용하는 경우에는 필요한 스택이 자동으로 설정됩니다. 그 밖의 경우에는 사용자가 직접 필요한 스택을 설정해야 합니다.

참고

어셈블러는 register_mode 형식의 심볼 레지스터 이름이 미리 선언되지 않은 상태로 제공됩니다. 따라서 이 형식을 사용하려면 RN 어셈블러 지시문으로 적절한 심볼 이름을 직접 선언해야 합니다. 예를 들어 lr_FIQ RN r14는 r14의 심볼 레지스터 이름 lr_FIQ를 선언합니다. RN 지시문에 대한 자세한 내용은 어셈블러 설명서에서 지시문 장을 참조하십시오.

6-4 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 111: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

프로세서 예외 처리

6.1.4 예외 우선순위

여러 개의 예외가 동시에 발생하면 고정된 우선순위에 따라 예외가 처리됩니다. 각 예외가 차례대로 처리된 후에 사용자 프로그램의 실행이 계속됩니다. 모든 예외가 동시에 발생할 수는 없습니다. 예를 들어 정의되지 않은 명령어 예외와 SVC 예외는 모두 명령어를 실행함으로써 트리거되므로 동시에 발생할 수 없습니다.

표 6-2에서는 예외, 해당 프로세서 모드 및 처리 우선순위를 보여 줍니다.

데이터 어보트 예외는 FIQ 예외보다 우선순위가 높으므로 데이터 어보트는 실제로 FIQ가 처리되기 전에 등록됩니다. 그러나 데이터 어보트 처리기가 시작된 후에는 제어권이 FIQ 처리기에 즉시 전달됩니다. FIQ가 처리되면 제어권은 데이터 어보트 처리기에 반환됩니다. 따라서 FIQ가 먼저 처리될 때와 마찬가지로 데이터 전송 오류가 감지될 수 있습니다.

표 6-2 예외 우선순위

벡터 주소 예외 유형 예외 모드 우선순위(1=높음, 6=낮음)

0x0 리셋 관리자(SVC) 1

0x4 정의되지 않은 명령어 정의되지 않음 6

0x8 SVC(관리자 호출) 관리자(SVC) 6

0xC 프리페치 어보트 어보트 5

0x10 데이터 어보트 어보트 2

0x14 예약되어 있음 해당 없음 해당 없음

0x18 인터럽트(IRQ) 인터럽트(IRQ) 4

0x1C 고속 인터럽트(FIQ) 고속 인터럽트(FIQ)

3

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 6-5

Page 112: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

프로세서 예외 처리

6.2 프로세서 상태 확인

예외 처리기에서는 예외가 발생할 때 프로세서가 ARM 상태에 있었는지 아니면 Thumb® 상태에 있었는지를 확인해야 할 수 있습니다.

특히 SVC 처리기에서는 프로세서 상태를 읽어야 합니다. 이렇게 하려면 SPSR T 비트를 검사합니다. 이 비트는 Thumb 상태일 때 설정되고 ARM 상태일 때 지워집니다.

ARM 및 Thumb 명령어 세트에는 SVC 명령어가 있습니다. Thumb 상태에서 SVC를 호출할 경우에는 다음 사항을 고려해야 합니다.

• 명령어 주소는 lr-4가 아니라 lr-2입니다.

• 명령어 자체는 16비트이므로 하프워드 로드가 필요합니다(그림 6-1 참조).

• SVC 번호는 ARM 상태에서 24비트가 아니라 8비트 형식으로 저장됩니다.

그림 6-1 Thumb SVC 명령어

6-7페이지의 예제 6-1에서는 두 가지 원인으로 인해 발생한 SVC를 모두 처리하는 ARM 코드를 보여 줍니다.

다음 사항을 고려하십시오.

• 각 do_svc_x 루틴은 필요한 경우 Thumb 상태로 전환했다가 다시 이전 상태로 전환함으로써 코드 밀도를 높일 수 있습니다.

• 점프 테이블을 switch() 문이 들어 있는 C 함수에 대한 호출로 대체하여 SVC를 구현할 수 있습니다.

• SVC 번호는 해당 SVC가 호출된 상태에 따라 다르게 처리될 수 있습니다.

• 6-19페이지의 SVC 처리기에 설명된 대로 SVC를 동적으로 호출하면 Thumb 상태에서 액세스할 수 있는 SVC 번호의 범위를 늘릴 수 있습니다.

�� �� �� �� �� �� � �

�� ���������

������ ������� � �� � ���

6-6 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 113: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

프로세서 예외 처리

예제 6-1 SVC 처리기

T_bit EQU 0x20 ; Thumb bit of CPSR/SPSR, that is, ; bit 5. : :SVCHandler STMFD sp!, {r0-r3,r12,lr} ; Store registers. MRS r0, spsr ; Move SPSR into ; general purpose register. TST r0, #T_bit ; Occurred in Thumb state? LDRNEH r0,[lr,#-2] ; Yes: load halfword and... BICNE r0,r0,#0xFF00 ; ...extract comment field. LDREQ r0,[lr,#-4] ; No: load word and... BICEQ r0,r0,#0xFF000000 ; ...extract comment field.

; r0 now contains SVC number

CMP r0, #MaxSVC ; Rangecheck LDRLS pc, [pc, r0, LSL#2] ; Jump to the appropriate routine. B SVCOutOfRangesvctable DCD do_svc_1 DCD do_svc_2 : :do_svc_1 ; Handle the SVC. LDMFD sp!, {r0-r3,r12,pc}^ ; Restore the registers and return.do_svc_2 :

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 6-7

Page 114: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

프로세서 예외 처리

6.3 예외 발생 및 종료

이 단원에서는 예외에 대한 프로세서 응답과 예외가 처리된 후 예외가 발생한 지점으로 복귀되는 방식을 설명합니다. 복귀 방법은 예외 유형에 따라 달라집니다. 자세한 내용은 6-3페이지의 예외 유형을 참조하십시오.

Thumb 상태를 지원하는 프로세서와 Thumb 상태를 지원하지 않는 프로세서는 동일한 기본 예외 처리 메커니즘을 사용합니다. 예외가 발생하면 적절한 벡터 테이블 엔트리에서 다음 명령어를 가져옵니다.

Thumb 상태와 ARM 상태에서 예외에 사용되는 벡터 테이블은 동일합니다. 단, Thumb 상태에서는 예외에 대한 프로세서 응답에 설명된 것과 같이 ARM 상태로 전환하기 위한 초기 단계가 예외 처리 프로시저에 추가됩니다.

다음 설명에서는 Thumb 상태를 지원하는 프로세서에서 사용하기에 적합한 예외 처리기를 작성할 때 고려해야 할 추가 사항이 있으면 해당 사항에 대해서도 설명합니다.

6.3.1 예외에 대한 프로세서 응답

예외가 발생하면 프로세서에서는 다음과 같은 작업을 수행합니다.

1. CPSR(현재 프로그램 상태 레지스터)을 예외를 처리할 모드의 SPSR(저장된 프로그램 상태 레지스터)에 복사합니다. 이렇게 하면 현재 모드, 인터럽트 마스크 및 조건 플래그가 저장됩니다.

2. 현재 명령어 세트 상태가 예외 벡터 테이블에서 사용되는 명령어 세트 상태와 일치하지 않으면 명령어 세트를 자동으로 전환할 수 있습니다. ARM 아키텍처 v6T2 이전의 ARM 아키텍처에는 예외 백터 테이블에 항상 ARM 명령어가 포함되어 있습니다. ARM 아키텍처 v6T2 이상에서는 예외 벡터 테이블에 ARM 명령어나 Thumb 명령어가 포함될 수 있습니다.

3. 적절한 CPSR 모드 비트를 변경하여 다음 작업을 수행합니다.

• 적절한 모드로 변경하고 해당 모드의 적절한 뱅크 레지스터에 매핑합니다.

• 인터럽트를 비활성화합니다. IRQ는 예외가 발생할 때 비활성화되고, FIQ는 FIQ가 발생할 때와 프로세서가 재설정될 때 비활성화됩니다.

4. 6-10페이지의 복귀 주소 및 복귀 명령어에 정의된 대로 lr_mode를 복귀할 주소로 설정합니다.

5. PC를 예외의 벡터 주소로 설정합니다.

6-8 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 115: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

프로세서 예외 처리

6.3.2 예외 처리기에서 복귀

예외에서 복귀하는 데 사용되는 방법은 예외 처리기에서 스택 작업을 사용하는지 여부에 따라 달라집니다. 두 경우 모두 예외가 발생했던 위치로 실행 권한을 되돌리려면 예외 처리기에서 다음을 수행해야 합니다.

• spsr_mode에서 CPSR을 복원합니다.

• lr_mode에 저장된 복귀 주소를 사용하여 PC를 복원합니다.

스택에서 대상 모드 레지스터를 복원하지 않아도 되는 간단한 복귀의 경우 예외 처리기에서는 다음 조건을 만족하는 데이터 처리 명령어를 실행하여 이러한 작업을 수행합니다.

• S 플래그가 설정되어 있습니다.

• PC를 대상 레지스터로 사용합니다.

필요한 복귀 명령어는 예외 유형에 따라 달라집니다. 각 예외 유형에서 복귀되는 방식에 대한 자세한 내용은 6-10페이지의 복귀 주소 및 복귀 명령어를 참조하십시오.

참고

리셋 처리기는 주 코드를 직접 실행하므로 리셋 처리기에서는 복귀할 필요가 없습니다.

예외 처리기 진입 코드가 예외를 처리하는 동안 유지해야 하는 레지스터를 스택에 저장하는 경우 다중 로드 명령어와 ^ 한정자를 함께 사용하여 예외 처리기에서 복귀할 수 있습니다. 예를 들어 예외 처리기는 다음을 사용하는 단일 명령어에서 복귀할 수 있습니다.

LDMFD sp!,{r0-r12,pc}^

이렇게 하려면 예외 처리기에서 스택에 다음을 저장해야 합니다.

• 처리기가 호출될 때 사용하고 있던 모든 작업 레지스터

• 6-10페이지의 복귀 주소 및 복귀 명령어에 설명된 데이터 처리 명령어와 동일한 결과를 생성하도록 수정된 링크 레지스터

^ 한정자는 CPSR이 SPSR에서 복원되도록 지정합니다. 이 한정자는 권한 모드에서만 사용해야 합니다. 스택 작업에 대한 자세한 내용은 어셈블러 설명서에서 LDM 및 STM을 사용한 스택 구현 방법에 대한 설명을 참조하십시오.

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 6-9

Page 116: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

프로세서 예외 처리

6.3.3 복귀 주소 및 복귀 명령어

예외가 보고될 때 PC가 가리키는 실제 위치는 예외 유형에 따라 달라집니다. 즉, 복귀 주소는 PC가 가리키는 다음 명령어가 아닐 수도 있습니다.

ARM 상태에서 예외가 발생하면 프로세서에서는 lr_ mode에 PC- 4를 저장합니다. 그러나 Thumb 상태에서 발생한 예외의 경우 프로세서에서는 각 예외 유형에 대해 서로 다른 값을 자동으로 저장합니다. ARM 명령어가 32비트를 차지하는 것과 달리 Thumb 또는 Thumb-2 명령어는 크기가 다를 수 있기 때문에 이 조정 작업이 필요합니다.

이 조정 작업을 수행하면 프로세서에서는 예외 발생 시점에서의 명령어 세트 상태에 관계없이 올바르게 복귀하는 단일 복귀 명령어가 처리기에 포함되도록 합니다.

다음 단원에서는 각 예외 유형의 처리 코드에서 올바르게 복귀하는 명령어에 대해 자세히 설명합니다.

SVC 및 정의되지 않은 명령어 처리기에서 복귀

SVC 및 정의되지 않은 명령어 예외는 명령어 자체에서 생성되므로 예외가 보고될 때 PC가 업데이트되지 않습니다. 프로세서에서는 lr_ mode에 PC-4를 저장합니다. 이렇게 하면 lr_mode는 다음에 실행할 명령어를 가리키게 됩니다. 다음 명령어로 링크 레지스터에서 PC를 복원할 수 있습니다.

MOVS pc, lr

이 경우 처리기에서 제어권이 반환됩니다.

복귀 주소를 스택에 푸시하고 복귀 시 이를 팝하는 처리기 진입 및 종료 코드는 다음과 같습니다.

STMFD sp!,{reglist,lr} ;... LDMFD sp!,{reglist,pc}^

Thumb 상태에서 발생하는 예외의 경우 처리기 복귀 명령어(MOVS pc,lr)는 PC를 다음에 실행할 명령어의 주소로 변경합니다. 이 주소는 PC-2이므로 프로세서가 lr_mode에 저장한 값은 PC-2입니다.

6-10 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 117: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

프로세서 예외 처리

FIQ 및 IRQ 처리기에서 복귀

각 명령어를 실행한 후 프로세서에서는 인터럽트 핀이 LOW 상태인지 여부와 CPSR의 인터럽트 비활성화 비트가 지워졌는지 여부를 확인합니다. 따라서 IRQ 또는 FIQ 예외는 PC가 업데이트된 이후에만 발생합니다. 프로세서에서는 lr_ mode에 PC-4를 저장합니다. 이렇게 하면 lr_mode는 예외가 발생한 명령어 다음에 나오는 명령어 하나를 가리키게 됩니다. 처리기가 완료되면 lr_mode가 가리키는 명령어의 앞에 있는 명령어에서 실행이 계속되어야 합니다. 실행을 계속할 주소는 lr_mode의 주소보다 1워드가 작으므로 복귀 명령어는 다음과 같습니다.

SUBS pc, lr, #4

복귀 주소를 스택에 푸시하고 복귀 시 이를 팝하는 처리기 진입 및 종료 코드는 다음과 같습니다.

SUB lr,lr,#4 STMFD sp!,{reglist,lr} ;... LDMFD sp!,{reglist,pc}^

Thumb 상태에서 발생하는 예외의 경우 처리기 복귀 명령어(SUBS pc,lr,#4)는 PC를 다음에 실행할 명령어의 주소로 변경합니다. PC는 예외가 보고되기 전에 업데이트되므로 다음 명령어는 PC-4에 있습니다. 따라서 프로세서가 lr_mode에 저장한 값은 PC입니다.

프리페치 어보트 처리기에서 복귀

프로세서가 잘못된 주소에서 명령어를 가져오려고 할 경우 해당 명령어는 잘못된 것으로 플래그가 지정됩니다. 파이프라인에 이미 있는 명령어는 프리페치 어보트가 발생한 지점의 잘못된 명령어에 도달할 때까지 계속 실행됩니다.

예외 처리기에서는 매핑되지 않은 명령어를 실제 메모리에 로드하고 MMU가 있는 경우 이를 사용하여 가상 메모리 위치를 실제 메모리에 매핑합니다. 그런 다음 처리기가 복귀하여 예외를 발생시킨 명령어를 다시 시도해야 합니다. 그러면 명령어가 로드 및 실행됩니다.

프리페치 어보트가 발생할 때 PC는 업데이트되지 않으므로 lr_ABT는 예외를 발생시킨 명령어 다음의 명령어를 가리킵니다. 처리기는 다음 명령어를 통해 lr_ABT-4로 복귀해야 합니다.

SUBS pc,lr, #4

복귀 주소를 스택에 푸시하고 복귀 시 이를 팝하는 처리기 진입 및 종료 코드는 다음과 같습니다.

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 6-11

Page 118: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

프로세서 예외 처리

SUB lr,lr,#4 STMFD sp!,{reglist,lr} ;... LDMFD sp!,{reglist,pc}^

Thumb 상태에서 발생하는 예외의 경우 처리기 복귀 명령어(SUBS pc,lr,#4)는 PC를 중단된 명령어의 주소로 변경합니다. PC는 예외가 보고되기 전에 업데이트되지 않으므로 중단된 명령어는 (PC-4)에 있습니다. 따라서 프로세서가 lr_mode에 저장한 값은 PC입니다.

데이터 어보트 처리기에서 복귀

로드 또는 저장 명령어가 메모리에 액세스하려고 할 때는 먼저 PC가 업데이트됩니다. 따라서 lr_ABT에 저장된 값 PC-4는 예외가 발생한 주소 다음의 두 번째 명령어를 가리킵니다. MMU(있는 경우)에서 실제 메모리의 적절한 주소를 매핑한 경우 처리기는 중단된 원래 명령어를 다시 시도할 수 있도록 이 명령어로 복귀해야 합니다. 따라서 복귀 주소는 lr_ABT의 주소보다 2워드가 작으며 복귀 명령어는 다음과 같이 됩니다.

SUBS pc, lr, #8

복귀 주소를 스택에 푸시하고 복귀 시 이를 팝하는 처리기 진입 및 종료 코드는 다음과 같습니다.

SUB lr,lr,#8 STMFD sp!,{reglist,lr} ;... LDMFD sp!,{reglist,pc}^

Thumb 상태에서 발생하는 예외의 경우 처리기 복귀 명령어(SUBS pc,lr,#8)는 PC를 중단된 명령어의 주소로 변경합니다. PC는 예외가 보고되기 전에 업데이트되므로 중단된 명령어는 PC-6에 있습니다. 따라서 프로세서가 lr_mode에 저장한 값은 PC+2입니다.

6-12 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 119: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

프로세서 예외 처리

6.4 예외 처리

최상위 수준 비니어 루틴에서는 프로세서 상태와 필요한 레지스터를 스택에 저장해야 합니다. 그런 후 다음과 같은 방법으로 예외 처리기를 작성할 수 있습니다.

• 전체 예외 처리기를 ARM 코드에 작성합니다.

• 프로세서에서 Thumb-2 명령어를 지원하는 경우 Thumb-2 코드로 전체 예외 처리기를 작성합니다.

• ARM 코드 최상위 수준 처리기에서 예외를 처리하는 Thumb 코드 루틴으로의 분기 및 전환(BX)을 수행합니다. Thumb-1 명령어 세트에는 SPSR에서 CPSR을 복원하는 데 필요한 명령어가 없으므로 예외에서 복귀하려면 이 루틴에서는 ARM 또는 Thumb-2 코드를 사용해야 합니다.

그림 6-2에서는 이 전략을 구현하는 방법을 보여 줍니다.

그림 6-2 ARM 또는 Thumb 상태에서의 예외 처리

이 방법으로 ARM 코드와 Thumb 코드를 함께 사용하는 방법에 대한 자세한 내용은 4장 ARM과 Thumb의 인터워킹을 참조하십시오.

��������� �������

�������������

�������������������������

����������� ����

�������������� ���������������

����������� ����

�������������� ����

������������������

���������������� ���� ����

�� ��������������� ���� ����

���� �!�����

�����������

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 6-13

Page 120: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

프로세서 예외 처리

6.5 예외 처리기 설치

새 예외 처리기는 벡터 테이블에 설치해야 합니다. 설치가 완료되면 새 처리기는 해당 예외가 발생할 때마다 실행됩니다.

6.5.1 예외 처리기 설치 방법

예외 처리기는 다음과 같은 방법으로 설치할 수 있습니다.

분기 명령어

예외 처리기에 도달하는 가장 간단한 방법은 분기 명령어를 사용하는 것입니다. 벡터 테이블의 각 엔트리에는 필요한 처리기 루틴으로의 분기가 포함되어 있습니다. 그러나 이 방법에는 제한이 있습니다. 분기 명령어의 주소 범위는 PC를 기준으로 32MB 이내이므로 일부 메모리 구성에서는 분기를 통해 처리기에 도달할 수 없습니다.

PC 로드 명령어

이 방법을 사용할 경우 다음과 같은 방법으로 PC가 처리기 주소로 직접 강제 조정됩니다.

1. 적합한 메모리 위치(벡터 주소의 4KB 이내)에 처리기의 절대 주소를 저장합니다.

2. PC와 선택한 메모리 위치의 내용을 함께 로드하는 명령어를 벡터에 배치합니다.

6.5.2 리셋 시 처리기 설치

응용 프로그램에서 디버거나 디버그 모니터를 사용하지 않고 프로그램 실행을 시작할 수 있는 경우 어셈블리 언어 리셋 또는 시작 코드에서 직접 벡터 테이블을 로드할 수 있습니다.

ROM이 메모리의 0x0 위치에 있으면 코드의 시작 부분에 각 벡터에 대한 분기 문을 배치할 수 있습니다. ROM이 0x1C에서 직접 실행되고 있으면 이때 FIQ 처리기도 포함할 수 있습니다. 자세한 내용은 6-29페이지의 인터럽트 처리기를 참조하십시오.

예제 6-2에서는 벡터가 주소 0의 ROM에 있는 경우 벡터를 설정하는 코드를 보여 줍니다. 로드 대신 분기 문을 사용해도 됩니다.

6-14 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 121: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

프로세서 예외 처리

예제 6-2

Vector_Init_Block LDR pc, Reset_Addr LDR pc, Undefined_Addr LDR pc, SVC_Addr LDR pc, Prefetch_Addr LDR pc, Abort_Addr NOP ;Reserved vector LDR pc, IRQ_Addr LDR pc, FIQ_Addr

Reset_Addr DCD Start_BootUndefined_Addr DCD Undefined_HandlerSVC_Addr DCD SVC_HandlerPrefetch_Addr DCD Prefetch_HandlerAbort_Addr DCD Abort_Handler DCD 0 ;Reserved vectorIRQ_Addr DCD IRQ_HandlerFIQ_Addr DCD FIQ_Handler

리셋 시 ROM은 0x0 위치에 있어야 합니다. 리셋 코드에서 RAM을 0x0 위치에 다시 매핑할 수 있습니다. 이렇게 하려면 먼저 ROM 영역의 벡터와 FIQ 처리기(필요한 경우)를 RAM에 복사해야 합니다.

이 경우 LDR pc 명령어를 사용하여 리셋 처리기를 처리해야 리셋 벡터 코드가 위치 독립적으로 실행될 수 있습니다.

예제 6-3에서는 6-15페이지의 예제 6-2에 지정된 벡터를 RAM의 벡터 테이블에 복사합니다.

예제 6-3

MOV r8, #0 ADR r9, Vector_Init_Block LDMIA r9!,{r0-r7} ;Copy the vectors (8 words) STMIA r8!,{r0-r7} LDMIA r9!,{r0-r7} ;Copy the DCD'ed addresses STMIA r8!,{r0-r7} ;(8 words again)

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 6-15

Page 122: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

프로세서 예외 처리

또는 스캐터 로딩 메커니즘을 사용하여 벡터 테이블의 로드 및 실행 주소를 정의할 수 있습니다. 이 경우 C 라이브러리에서 자동으로 벡터 테이블을 복사합니다. 자세한 내용은 2장 임베디드 소프트웨어 개발을 참조하십시오.

6.5.3 C에서 처리기 설치

개발 작업 중 때로는 주 응용 프로그램에서 직접 예외 처리기를 벡터에 설치해야 하는 경우가 있습니다. 따라서 필요한 명령어 인코딩이 적절한 벡터 주소에 작성되어 있어야 합니다. 처리기에 도달하기 위한 분기 및 PC 로드 방법 모두에 대해 이를 수행할 수 있습니다.

분기 방법

필요한 명령어는 다음과 같이 생성할 수 있습니다.

1. 예외 처리기의 주소를 가져옵니다.

2. 해당 벡터의 주소를 뺍니다.

3. 0x8을 빼서 프리페치용으로 제공합니다.

4. 결과를 오른쪽으로 2만큼 시프트하여 바이트 오프셋이 아닌 워드 오프셋을 제공합니다.

5. 시프트 결과 값의 상위 8비트가 지워졌는지 테스트하여 결과가 24비트 길이인지 확인합니다.

6. 결과 값과 0xEA000000(분기 명령어의 op 코드)에 대해 논리 OR 연산을 수행하여 벡터에 배치할 값을 생성합니다.

6-17페이지의 예제 6-4에서는 이 알고리즘을 구현하는 C 함수를 보여 줍니다.

여기서는 다음 인수를 사용합니다.

• 처리기의 주소

• 처리기가 설치되는 벡터 주소

함수는 처리기를 설치하고 벡터의 원래 내용을 반환할 수 있습니다. 이 결과는 특정 예외에 대한 처리기 체인을 만드는 데 사용할 수 있습니다.

다음 코드에서는 이 함수를 호출하여 IRQ 처리기를 설치합니다.

unsigned *irqvec = (unsigned *)0x18;Install_Handler ((unsigned)IRQHandler, irqvec);

6-16 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 123: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

프로세서 예외 처리

이 경우 반환된 IRQ 벡터의 원래 내용은 폐기됩니다.

예제 6-4 분기 메서드 구현

unsigned Install_Handler (unsigned routine, unsigned *vector)/* Updates contents of 'vector' to contain branch instruction *//* to reach íroutineí from ívectorí. Function return value is *//* original contents of 'vector'.*//* NB: íRoutineí must be within range of 32MB from ívectorí.*/

{ unsigned vec, oldvec; vec = ((routine - (unsigned)vector - 0x8)>>2); if ((vec & 0xFF000000)) { /* diagnose the fault */ printf ("Installation of Handler failed"); exit (1); } vec = 0xEA000000 | vec; oldvec = *vector; *vector = vec; return (oldvec);}

PC 로드 방법

필요한 명령어는 다음과 같이 생성할 수 있습니다.

1. 예외 처리기의 주소가 들어 있는 워드의 주소를 가져옵니다.

2. 해당 벡터의 주소를 뺍니다.

3. 0x8을 빼서 프리페치용으로 제공합니다.

4. 결과를 12비트로 나타낼 수 있는지 확인합니다.

5. 결과 값과 0xe59FF000(LDR pc, [pc,#offset]의 op 코드)에 대해 논리 OR 연산을 수행하여 벡터에 배치할 값을 생성합니다.

6. 처리기의 주소를 스토리지 위치에 저장합니다.

6-18페이지의 예제 6-5에서는 이 방법을 구현하는 C 루틴을 보여 줍니다.

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 6-17

Page 124: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

프로세서 예외 처리

이 예제에서도 반환된 IRQ 벡터의 원래 내용은 폐기되지만 이 내용을 사용하여 처리기 체인을 만들 수 있습니다.

예제 6-5 PC 로드 방법 구현

unsigned Install_Handler (unsigned location, unsigned *vector)

/* Updates contents of 'vector' to contain LDR pc, [pc, #offset] *//* instruction to cause long branch to address in 'location'. *//* Function return value is original contents of 'vector'. */

{ unsigned vec, oldvec; vec = ((unsigned)location - (unsigned)vector - 0x8) | 0xe59ff000; oldvec = *vector; *vector = vec; return (oldvec);}

다음 코드에서는 이 함수를 호출하여 IRQ 처리기를 설치합니다.

unsigned *irqvec = (unsigned *)0x18;static unsigned pIRQ_Handler = (unsigned)IRQ_handlerInstall_Handler (&pIRQHandler, irqvec);

참고

별도의 명령어와 데이터 캐시가 있는 프로세서를 사용하는 경우에는 캐시 일관성 문제로 인해 벡터의 새 내용을 사용할 수 없는 경우가 없도록 해야 합니다.

새 벡터 내용을 주 메모리에 쓸 수 있도록 하려면 데이터 캐시나 적어도 수정된 벡터가 포함된 엔트리를 지워야 합니다. 그런 다음 새 벡터 내용을 주 메모리에서 읽을 수 있도록 명령어 캐시를 플러시해야 합니다.

캐시 지우기 및 플러시 작업에 대한 자세한 내용은 타겟 프로세서의 기술 참조 문서를 참조하십시오.

6-18 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 125: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

프로세서 예외 처리

6.6 SVC 처리기

이 단원에서는 SVC 처리기에 대해 설명합니다.

6.6.1 호출할 SVC 결정

SVC 처리기는 시작 시 호출할 SVC를 설정해야 합니다. 이 정보는 그림 6-3에서 보여 주는 대로 명령어 자체의 0-23 비트에 저장되거나 대개 r0-r3 중 하나인 정수 레지스터에 전달됩니다.

그림 6-3 ARM SVC 명령어

최상위 수준 SVC 처리기에서는 링크 레지스터를 기준으로 SVC 명령어를 로드할 수 있습니다. 이 작업은 어셈블리 언어, C/C++ 인라인 또는 임베디드 어셈블러에서 수행합니다.

처리기에서는 먼저 예외를 발생시킨 SVC 명령어를 레지스터에 로드해야 합니다. 이때 lr_SVC에는 SVC 명령어 다음에 나오는 명령어의 주소가 들어 있으므로 다음을 사용하여 SVC를 레지스터(이 경우 r0)에 로드할 수 있습니다.

LDR r0, [lr,#-4]

그런 다음 처리기에서는 주석 필드 필드를 검사하여 필요한 작업을 결정할 수 있습니다. op 코드의 상위 8비트를 지우면 SVC 번호가 추출됩니다.

BIC r0, r0, #0xFF000000

예제 6-6에서는 이러한 명령어를 함께 배치하여 최상위 수준 SVC 처리기를 구성하는 방법을 보여 줍니다.

ARM 상태와 Thumb 상태 모두의 SVC 명령어를 처리하는 처리기의 예제를 보려면 6-6페이지의 프로세서 상태 확인을 참조하십시오.

예제 6-6 최상위 수준 SVC 처리기

PRESERVE8

AREA TopLevelSVC, CODE, READONLY ; Name this block of code.

�� � � �� �� �� �� �

���� �������� ������� � � �

�� ���������

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 6-19

Page 126: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

프로세서 예외 처리

EXPORT SVC_HandlerSVC_Handler STMFD sp!,{r0-r12,lr} ; Store registers. LDR r0,[lr,#-4] ; Calculate address of SVC instruction

; and load it into r0. BIC r0,r0,#0xff000000 ; Mask off top 8 bits of instruction

; to give SVC number. ; ; Use value in r0 to determine which SVC routine to execute. ; LDMFD sp!, {r0-r12,pc}^ ; Restore registers and return. END ; Mark end of this file.

6.6.2 어셈블리 언어의 SVC 처리기

요청된 SVC 번호에 대한 처리기를 호출하는 가장 간단한 방법은 점프 테이블을 사용하는 것입니다. r0에 SVC 번호가 들어 있으면 예제 6-7의 코드를 6-19페이지의 예제 6-6에 제공된 최상위 수준 처리기의 BIC 명령어 다음에 삽입할 수 있습니다.

예제 6-7 SVC 점프 테이블

CMP r0,#MaxSVC ; Range check LDRLS pc, [pc,r0,LSL #2] B SVCOutOfRangeSVCJumpTable DCD SVCnum0 DCD SVCnum1 ; DCD for each of other SVC routinesSVCnum0 ; SVC number 0 code B EndofSVCSVCnum1 ; SVC number 1 code B EndofSVC ; Rest of SVC handling code ;EndofSVC ; Return execution to top level ; SVC handler so as to restore ; registers and return to program.

6-20 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 127: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

프로세서 예외 처리

6.6.3 C 및 어셈블리 언어의 SVC 처리기

최상위 수준 처리기는 항상 ARM 어셈블리 언어로 작성해야 하지만 각 SVC를 처리하는 루틴은 어셈블리 언어나 C로 작성할 수 있습니다. 제한 사항에 대한 자세한 내용은 6-22페이지의 관리자 모드에서 SVC 사용을 참조하십시오.

최상위 수준 처리기에서는 링크 포함 분기(BL) 명령어를 사용하여 적절한 C 함수로 점프합니다. SVC 번호는 어셈블리 루틴에 의해 r0으로 로드되므로 SVC 번호가 C 함수에 첫 번째 매개변수로 전달됩니다. C 함수는 이 값을 switch() 문 등에 사용할 수 있습니다.

6-19페이지의 예제 6-6의 SVC_Handler 루틴에 다음 행을 추가할 수 있습니다.

BL C_SVC_Handler ; Call C routine to handle the SVC

예제 6-8에서는 C 함수를 구현하는 방법을 보여 줍니다.

예제 6-8

void C_SVC_handler (unsigned number){ switch (number) { case 0 : /* SVC number 0 code */ break; case 1 : /* SVC number 1 code */ break; ... default : /* Unknown SVC - report error */ }}

많은 양의 스택 공간이 필요한 함수를 사용할 수 없도록 관리자 스택 공간을 제한할 수 있습니다.

MOV r1, sp ; Second parameter to C routine... ; ...is pointer to register values. BL C_SVC_Handler ; Call C routine to handle the SVC

최상위 수준 처리기에서 스택 포인터 값을 C 함수에 두 번째 매개변수(r1)로 전달하는 경우 C로 작성된 SVC 처리기로 또는 이 SVC 처리기에서 값을 전달할 수 있으며 C 함수가 이 처리기에 액세스할 수 있도록 업데이트됩니다.

void C_SVC_handler(unsigned number, unsigned *reg)

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 6-21

Page 128: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

프로세서 예외 처리

그러면 C 함수는 주 응용 프로그램 코드에서 SVC 명령어가 발생할 때 레지스터에 들어 있던 값에 액세스할 수 있습니다(6-22페이지의 그림 6-4 참조). C 함수는 이 값에서 다음 내용을 읽습니다.

value_in_reg_0 = reg [0]; value_in_reg_1 = reg [1]; value_in_reg_2 = reg [2]; value_in_reg_3 = reg [3];

또한 해당 값에 다음 내용을 다시 씁니다.

reg [0] = updated_value_0; reg [1] = updated_value_1; reg [2] = updated_value_2; reg [3] = updated_value_3;

이렇게 하면 최상위 수준 처리기에서는 업데이트된 값을 적절한 스택 위치에 썼다가 나중에 레지스터로 복원합니다.

그림 6-4 관리자 스택 액세스

6.6.4 관리자 모드에서 SVC 사용

SVC 명령어가 실행되면 다음이 수행됩니다.

1. 프로세서가 관리자 모드로 전환됩니다.

2. CPSR이 spsr_SVC에 저장됩니다.

3. 복귀 주소가 lr_SVC에 저장됩니다(6-8페이지의 예외에 대한 프로세서 응답 참조).

프로세서가 이미 관리자 모드에 있으면 lr_SVC 및 spsr_SVC가 손상됩니다.

��"�!�

��

�#

�$

�%

������ � �"�!�

�"�!�������

������

6-22 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 129: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

프로세서 예외 처리

관리자 모드에서 SVC를 호출할 경우에는 링크 레지스터와 SPSR의 원래 값이 손실되지 않도록 lr_SVC 및 spsr_SVC를 저장해야 합니다. 예를 들어 특정 SVC 번호에 대한 처리기 루틴에서 다른 SVC를 호출할 경우 처리기 루틴에서 lr_SVC와 spsr_SVC 모두를 스택에 저장하도록 해야 합니다. 이렇게 하면 처리기를 호출할 때마다 처리기를 호출한 SVC 다음의 명령어로 복귀하는 데 필요한 정보가 저장됩니다. 6-23페이지의 예제 6-9에서 이를 수행하는 방법을 보여 줍니다.

예제 6-9 SVC 처리기

AREA SVC_Area, CODE, READONLY

PRESERVE8

EXPORT SVC_Handler IMPORT C_SVC_Handler

T_bit EQU 0x20

SVC_Handler

STMFD sp!,{r0-r3,r12,lr} ; Store registers. MOV r1, sp ; Set pointer to parameters. MRS r0, spsr ; Get spsr. STMFD sp!, {r0, r3} ; Store spsr onto stack and another register to maintain ; 8-byte-aligned stack. Only really needed in case of nested SVCs.

TST r0, #T_bit ; Occurred in Thumb state?LDRNEH r0,[lr,#-2] ; Yes: load halfword and...BICNE r0,r0,#0xFF00 ; ...extract comment field.LDREQ r0,[lr,#-4] ; No: load word and...BICEQ r0,r0,#0xFF000000 ; ...extract comment field.

; r0 now contains SVC number ; r1 now contains pointer to stacked registers

BL C_SVC_Handler ; Call C routine to handle the SVC. LDMFD sp!, {r0, r3} ; Get spsr from stack. MSR spsr_cf, r0 ; Restore spsr. LDMFD sp!, {r0-r3,r12,pc}^ ; Restore registers and return.

END

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 6-23

Page 130: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

프로세서 예외 처리

C 및 C++의 중첩된 SVC

C 또는 C++에서 중첩된 SVC를 작성할 수 있습니다. ARM 컴파일러에서 생성된 코드는 필요할 경우 lr_SVC를 저장하고 다시 로드합니다.

6.6.5 응용 프로그램에서 SVC 호출

어셈블리 언어 또는 C/C++에서 SVC를 호출할 수 있습니다.

어셈블리 언어에서 필요한 레지스터 값을 설정하고 관련 SVC를 실행합니다. 예를 들면 다음과 같습니다.

MOV r0, #65 ; load r0 with the value 65 SVC 0x0 ; Call SVC 0x0 with parameter value in r0

SVC 명령어는 거의 모든 ARM 명령어와 마찬가지로 조건부로 실행할 수 있습니다.

C/C++에서 SVC를 __SVC 함수로 선언하고 호출합니다. 예를 들면 다음과 같습니다.

__svc(0) void my_svc(int); . . . my_svc(65);

이렇게 하면 다음과 같은 경우 추가 호출 오버헤드 없이 SVC를 인라인으로 컴파일할 수 있습니다.

• 모든 인수가 r0-r3에만 전달되는 경우

• 결과가 r0-r3에만 반환되는 경우

매개변수는 SVC가 실제 함수 호출인 것처럼 SVC에 전달됩니다. 그러나 두 개에서 네 개 사이의 반환 값이 있으면 반환 값이 구조체에 반환되고 __value_in_regs 지시문을 사용한다는 것을 컴파일러에 알려야 합니다. struct 값 함수는 대개 결과 구조체를 배치할 주소를 첫 번째 인수로 사용하는 void 함수와 같은 방식으로 처리되기 때문입니다.

예제 6-10 및 6-25페이지의 예제 6-11에서는 SVC 번호 0x0, 0x1, 0x2 및 0x3을 제공하는 SVC 처리기를 보여 줍니다. SVC 0x0 및 0x1은 각각 두 개의 정수 매개변수를 받고 단일 결과를 반환합니다. SVC 0x2는 네 개의 매개변수를 받고 단일 결과를 반환합니다. SVC 0x3은 네 개의 매개변수를 받고 네 개의 결과를 반환합니다. 이 예제는 주 예제 디렉토리의 ...\svc\main.c와 ...\svc\svc.h에 있습니다.

6-24 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 131: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

프로세서 예외 처리

예제 6-10 main.c

#include <stdio.h>#include "svc.h"

unsigned *svc_vec = (unsigned *)0x08;extern void SVC_Handler(void);

int main( void ){ int result1, result2; struct four_results res_3; Install_Handler( (unsigned) SVC_Handler, svc_vec ); printf("result1 = multiply_two(2,4) = %d\n", result1 = multiply_two(2,4)); printf("result2 = multiply_two(3,6) = %d\n", result2 = multiply_two(3,6)); printf("add_two( result1, result2 ) = %d\n", add_two( result1, result2 )); printf("add_multiply_two(2,4,3,6) = %d\n", add_multiply_two(2,4,3,6)); res_3 = many_operations( 12, 4, 3, 1 ); printf("res_3.a = %d\n", res_3.a ); printf("res_3.b = %d\n", res_3.b ); printf("res_3.c = %d\n", res_3.c ); printf("res_3.d = %d\n", res_3.d ); return 0;}

예제 6-11 svc.h

__svc(0) int multiply_two(int, int);__svc(1) int add_two(int, int);__svc(2) int add_multiply_two(int, int, int, int);

struct four_results{ int a; int b; int c; int d;};

__svc(3) __value_in_regs struct four_results many_operations(int, int, int, int);

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 6-25

Page 132: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

프로세서 예외 처리

6.6.6 응용 프로그램에서 동적으로 SVC 호출

경우에 따라 런타임까지 번호를 알 수 없는 SVC를 호출해야 할 수 있습니다. 예를 들어 한 오브젝트에 대해 수행할 수 있는 관련 연산이 여러 개이고 각 연산에 고유한 SVC가 있을 때 이러한 경우가 발생할 수 있습니다. 이 경우 이전 단원에서 설명한 방법은 적합하지 않습니다.

이를 처리하는 데는 다음과 같은 몇 가지 방법을 사용할 수 있습니다.

• SVC 번호에서 SVC 명령어를 생성하여 적절한 위치에 저장한 다음 실행합니다.

• 인수에 대해 수행할 실제 연산의 코드를 추가 인수로 사용하는 일반 SVC를 사용합니다. 일반 SVC에서는 연산을 디코딩하여 수행합니다.

두 번째 메커니즘은 레지스터에 필요한 연산 번호(대개 r0 또는 r12)를 전달하여 어셈블리 언어로 구현할 수 있습니다. 그런 다음 적절한 레지스터의 값에 대해 작동하도록 SVC 처리기를 다시 작성할 수 있습니다.

일부 값은 SVC의 주석 필드에 전달해야 하므로 이 두 가지 방법을 함께 사용할 수도 있습니다.

예를 들어 운영 체제에서 단일 SVC 명령어를 사용하고, 레지스터를 사용하여 필요한 연산의 번호를 전달할 수 있습니다. 이렇게 하면 응용 프로그램 관련 SVC에 사용할 수 있는 SVC 공간의 나머지 부분만 남게 됩니다. 특정 응용 프로그램에서 명령어의 연산 번호를 추출할 때의 오버헤드가 너무 큰 경우 이 방법을 사용할 수 있습니다. ARM 및 Thumb의 세미호스팅된 명령어는 이러한 방식으로 구현됩니다.

예제 6-12에서는 __svc를 사용하여 세미호스팅 호출에 C 함수 호출을 매핑하는 방법을 보여 줍니다. 이 예제는 주 예제 디렉토리의 ...\emb_sw_dev\source\retarget.c에 있는 retarget.c를 기반으로 합니다.

예제 6-12 세미호스팅 호출에 C 함수 매핑

#ifdef __thumb/* Thumb Semihosting */#define SemiSVC 0xAB#else/* ARM Semihosting */#define SemiSVC 0x123456#endif

6-26 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 133: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

프로세서 예외 처리

/* Semihosting call to write a character */ __svc(SemiSVC) void Semihosting(unsigned op, char *c);#define WriteC(c) Semihosting (0x3,c)

void write_a_character(int ch){ char tempch = ch; WriteC( &tempch );}

컴파일러에는 r12를 사용하여 필요한 연산의 값을 전달할 수 있는 메커니즘이 포함되어 있습니다. AAPCS에서 r12는 ip 레지스터로, 함수를 호출하는 동안에만 전용 역할이 있습니다. 평소에는 이를 스크래치 레지스터로 사용할 수 있습니다. 앞부분에서 설명한 대로 일반 SVC의 인수는 레지스터 r0-r3에 전달되고 값은 r0-r3

에 선택적으로 반환됩니다(6-24페이지의 응용 프로그램에서 SVC 호출 참조). r12에 전달되는 연산 번호는 일반 SVC에서 호출할 SVC의 번호일 수 있습니다. 그러나 이 번호는 필요하지 않습니다.

6-27페이지의 예제 6-13에서는 일반 또는 간접 SVC를 사용하는 C 코드 조각을 보여 줍니다.

예제 6-13

__svc_indirect(0x80) unsigned SVC_ManipulateObject(unsigned operationNumber, unsigned object,unsigned parameter);

unsigned DoSelectedManipulation(unsigned object, unsigned parameter, unsigned operation){ return SVC_ManipulateObject(operation, object, parameter);}

이 예제에서는 다음 코드를 생성합니다.

DoSelectedManipulation PROC STMFD sp!,{r3,lr} MOV r12,r2 SVC 0x80 LDMFD sp!,{r3,pc} ENDP

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 6-27

Page 134: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

프로세서 예외 처리

C에서 __svc 메커니즘을 사용하여 r0에 SVC 번호를 전달할 수도 있습니다. 예를 들어 SVC 0x0이 일반 SVC로 사용되고 연산 0이 문자 읽기이며 연산 1은 문자 쓰기인 경우 다음과 같이 설정할 수 있습니다.

__svc (0) char __ReadCharacter (unsigned op);__svc (0) void __WriteCharacter (unsigned op, char c);

다음과 같이 정의하면 이러한 코드를 보다 읽기 쉬운 방식으로 사용할 수 있습니다.

#define ReadCharacter () __ReadCharacter (0);#define WriteCharacter (c) __WriteCharacter (1, c);

그러나 이 방식으로 r0을 사용하면 SVC에 매개변수를 전달하는 데 세 개의 레지스터만 사용할 수 있습니다. 일반적으로 r0-r3 외에도 더 많은 매개변수를 하위 루틴에 전달해야 하는 경우에는 스택을 사용하여 이를 수행할 수 있습니다. 그러나 스택 매개변수는 대개 SVC 처리기에서 사용하는 관리자 스택이 아니라 사용자 모드 스택에 있으므로 SVC 처리기에 쉽게 액세스할 수 없습니다.

또는 레지스터 중 하나(대개 r1)를 사용하여 다른 매개변수를 저장하는 메모리 블록을 가리킬 수 있습니다.

6-28 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 135: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

프로세서 예외 처리

6.7 인터럽트 처리기

이 단원에서는 인터럽트 처리기를 작성하여 외부 인터럽트 FIQ 및 IRQ를 처리하는 방법을 설명합니다.

6.7.1 외부 인터럽트 수준

ARM 프로세서에는 FIQ와 IRQ라는 두 가지 외부 인터럽트 수준이 있으며 이 두 인터럽트 수준은 모두 코어로 보내지는 수준 인식 활성 LOW 신호입니다. 인터럽트를 받으려면 CPSR의 해당 비활성 비트가 지워져 있어야 합니다.

FIQ는 IRQ보다 우선순위가 높으므로 다음과 같은 방식으로 처리됩니다.

• 여러 개의 인터럽트가 발생할 경우 FIQ가 먼저 처리됩니다.

• FIQ를 처리할 때 IRQ는 비활성화되므로 FIQ 처리기에서 IRQ를 다시 활성화할 때까지는 IRQ가 처리되지 않습니다. 대개 처리기의 끝에 있는 SPSR에서 CPSR을 복원하면 IRQ가 다시 활성화됩니다.

FIQ 벡터는 벡터 테이블의 주소 0x1C에 있는 마지막 엔트리이므로 이 벡터 위치에 직접 FIQ 처리기를 배치하고 해당 주소에서부터 순차적으로 실행할 수 있습니다. 이렇게 하면 분기 및 관련 지연에 대한 요구 사항이 제거되며, 시스템에 캐시가 있는 경우 벡터 테이블 및 FIQ 처리기가 모두 캐시 내의 한 블록에 잠깁니다. FIQ는 인터럽트를 가능한 한 빠르게 처리하도록 설계되었기 때문에 이 작업은 중요합니다. 다섯 개의 추가 FIQ 모드 뱅크 레지스터를 사용하면 상태를 호출과 처리기 사이에 저장하고 실행 속도를 높일 수 있습니다.

참고

인터럽트 처리기에는 인터럽트의 원인을 제거하는 코드가 포함되어 있어야 합니다.

6.7.2 C의 간단한 인터럽트 처리기

__irq 함수 선언 키워드를 사용하여 간단한 C 인터럽트 처리기를 작성할 수 있습니다. __irq 키워드는 간단한 단일 수준 인터럽트 처리기와 하위 루틴을 호출하는 인터럽트 처리기 모두에 사용할 수 있습니다. 그러나 재진입 인터럽트 처리기는 SPSR을 저장하거나 복원하지 않으므로 이 인터럽트 처리기에는 __irq 키워드를 사용할 수 없습니다. 여기서 재진입이란 처리기에서 인터럽트를 다시 활성화하는 것을 의미하며 재진입 자체도 인터럽트될 수 있습니다. 자세한 내용은 6-31페이지의 재진입 인터럽트 처리기를 참조하십시오.

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 6-29

Page 136: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

프로세서 예외 처리

__irq 키워드는 다음과 같은 역할을 합니다.

• 손상될 수 있는 모든 AAPCS 레지스터를 보관합니다.

• 함수에 사용되는 다른 모든 레지스터(NEON/VFP 확장 레지스터 제외)를 보관합니다.

• PC를 lr-4로 설정하고 CPSR을 원래 값으로 복원하여 함수를 종료합니다.

함수가 하위 루틴을 호출하면 __irq는 인터럽트 모드의 링크 레지스터를 보관할 뿐 아니라 손상될 수 있는 다른 레지스터도 보관합니다. 자세한 내용은 인터럽트 처리기에서 하위 루틴 호출을 참조하십시오.

참고

Thumb-1 코드를 컴파일할 때는 C 인터럽트 처리기를 이와 같은 방식으로 생성할 수 없습니다. Thumb용으로 컴파일할 경우 __irq로 지정된 함수는 ARM용으로 컴파일됩니다.

그러나 인터워킹이 설정된 경우 __irq 함수에서 호출하는 하위 루틴은 Thumb-1용으로 컴파일할 수 있습니다. 인터워킹에 대한 자세한 내용은 4장 ARM과 Thumb의 인터워킹을 참조하십시오.

이 제한은 Thumb-2를 지원하는 프로세서에는 적용되지 않습니다.

인터럽트 처리기에서 하위 루틴 호출

최상위 수준 인터럽트 처리기에서 하위 루틴을 호출할 경우 __irq 키워드는 스택에서 lr_IRQ의 값을 복원하므로 SUBS 명령어에서 이 키워드를 사용하면 인터럽트가 처리된 후 올바른 주소로 복귀할 수 있습니다.

예제 6-14에서는 이 작업을 수행하는 방법을 보여 줍니다. 최상위 수준 인터럽트 처리기에서는 메모리에 매핑된 인터럽트 컨트롤러 기본 주소(0x80000000)의 값을 읽습니다. 주소 값이 1이면 최상위 수준 처리기가 C로 작성된 처리기로 분기됩니다.

예제 6-14

__irq void IRQHandler (void){ volatile unsigned int *base = (unsigned int *) 0x80000000;

if (*base == 1) // which interrupt was it? { C_int_handler(); // process the interrupt

6-30 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 137: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

프로세서 예외 처리

} *(base+1) = 0; // clear the interrupt}

armcc로 컴파일된 예제 6-14에서는 다음 코드를 생성합니다.

IRQHandler PROC STMFD sp!,{r0-r4,r12,lr} MOV r4,#0x80000000 LDR r0,[r4,#0] SUB sp,sp,#4 CMP r0,#1 BLEQ C_int_handler MOV r0,#0 STR r0,[r4,#4] ADD sp,sp,#4 LDMFD sp!,{r0-r4,r12,lr} SUBS pc,lr,#4 ENDP

이 코드를 __irq 키워드를 사용하지 않을 때의 결과와 비교해 보십시오.

IRQHandler PROC STMFD sp!,{r4,lr} MOV r4,#0x80000000 LDR r0,[r4,#0] CMP r0,#1 BLEQ C_int_handler MOV r0,#0 STR r0,[r4,#4] LDMFD sp!,{r4,pc} ENDP

6.7.3 재진입 인터럽트 처리기

인터럽트 처리기에서 인터럽트를 다시 활성화하고 하위 루틴을 호출한 후 다른 인터럽트가 발생하면 두 번째 IRQ가 보고될 때 lr_IRQ에 저장된 하위 루틴의 복귀 주소가 손상됩니다. C에서 __irq 키워드를 사용하면 재진입 인터럽트 처리기에서 필요로 하는 SPSR이 저장 및 복원되지 않으므로 어셈블리 언어로 최상위 수준 인터럽트 처리기를 작성해야 합니다.

재진입 인터럽트 처리기에서는 IRQ 상태를 저장하고, 프로세서 모드를 전환하며, 중첩된 하위 루틴이나 C 함수로 분기하기 전에 새 프로세서 모드의 상태를 저장해야 합니다. 또한 LDRD 또는 STRD 명령어나 8바이트로 정렬된 스택 할당 데이터를 사용할 수 있는 AAPCS와 호환되는 컴파일된 C 코드를 호출하기 전에 스택이 새 프로세서 모드에 대해 8바이트로 정렬되었는지 확인해야 합니다. 스택 정렬 문제

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 6-31

Page 138: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

프로세서 예외 처리

에 대한 자세한 내용은ARM 웹 사이트의 ABI for the ARM Architecture Advisory Note - SP는 AAPCS 준수 함수에 진입 시 8바이트로 정렬되어야 합니다.(ARM GENC-007024)를 참조하십시오.

ARMv4 이상에서는 시스템 모드로 전환할 수 있습니다. 시스템 모드에서는 사용자 모드 레지스터를 사용하고 예외 처리기에서 필요로 할 수 있는 권한 액세스를 활성화합니다. 자세한 내용은 6-44페이지의 시스템 모드를 참조하십시오. ARMv4 이전의 ARM 아키텍처에서는 대신 관리자 모드로 전환해야 합니다.

참고

이 방법은 IRQ 및 FIQ 인터럽트 모두에 사용할 수 있습니다. 그러나 FIQ 인터럽트는 가능한 한 빠르게 처리되어야 하기 때문에 일반적으로 인터럽트 원인이 하나만 있을 수 있으며 따라서 재진입을 위해 FIQ 인터럽트를 제공할 필요는 없습니다.

IRQ 처리기에서 인터럽트를 안전하게 다시 활성화하는 데 필요한 단계는 다음과 같습니다.

1. 복귀 주소를 생성하여 IRQ 스택에 저장합니다.

2. 작업 레지스터, 수신자가 저장하지 않는 레지스터 및 spsr_IRQ를 저장합니다.

3. 인터럽트의 원인을 제거합니다.

4. 시스템 모드로 전환하고 IRQ를 비활성화합니다.

5. 스택이 8바이트로 정렬되어 있는지 확인하고 필요한 경우 조정합니다.

6. SP_usr에서 사용되는 사용자 모드 링크 레지스터와 조정(아키텍처 v4 또는 v5TE의 경우 0 또는 4)을 저장합니다.

7. 인터럽트를 다시 활성화하고 C 인터럽트 처리기 함수를 호출합니다.

8. C 인터럽트 처리기 함수가 복귀할 때 인터럽트를 비활성화합니다.

9. 사용자 모드 링크 레지스터와 스택 조정 값을 복원합니다.

10. 필요한 경우 스택을 다시 조정합니다.

11. IRQ 모드로 전환합니다.

12. 다른 레지스터와 spsr_IRQ를 복원합니다.

6-32 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 139: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

프로세서 예외 처리

13. IRQ에서 복귀합니다.

예제 6-15에서는 ARMv4/v5TE 프로세서의 경우 시스템 모드에서 이 작업을 수행하는 방법을 보여 줍니다. 6-33페이지의 예제 6-16은 ARMv6 프로세서에 대한 예제입니다.

예제 6-15

PRESERVE8 AREA INTERRUPT, CODE, READONLY IMPORT C_irq_handler

IRQ SUB lr, lr, #4 ; construct the return address STR lr, [sp, #-4]! ; and push the adjusted lr_IRQ MRS r14, SPSR ; copy spsr_IRQ to r14 STMFD sp!, {r0-r4,r12, r14} ; save AAPCS regs and spsr_IRQ

BL identify_and_clear_sourceMSR CPSR_c, #0x9f ; switch to SYS mode, IRQ is

; still disabled. USR mode ; registers are now current. AND r1, sp, #4 ; test alignment of the stack SUB sp, sp, r1 ; remove any misalignment (0 or 4) STMFD sp!, {r1, lr} ; store the adjustment and lr_USR MSR CPSR_c, #0x1f ; enable IRQ BL C_irq_handler ; branch to C IRQ handler MSR CPSR_c, #0x9f ; disable IRQ, remain in SYS mode LDMFD sp!, {r1,lr} ; restore stack adjustment and lr_USR ADD sp, sp, r1 ; add the stack adjustment (0 or 4) MSR CPSR_c, #0x92 ; switch to IRQ mode and keep IRQ ; disabled. FIQ is still enabled. LDMFD sp!, {r0-r4, r12, r14} ; restore registers and MSR SPSR_csxf, r14 ; spsr_IRQ LDMFD sp!, {pc}^ ; return from IRQ. END

예제 6-16 중첩된 인터럽트(ARMv6, 비벡터 인터럽트)

IRQ_HandlerSUB lr, lr, #4SRSFD #0x1f! ; Save LR_irq and SPSR_irq to System mode stackCPS #0x1f ; Switch to System modeSTMFD sp!, {r0-r3,r12} ; Store other AAPCS registersAND r1, sp, #4SUB sp, sp, r1

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 6-33

Page 140: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

프로세서 예외 처리

STMFD sp!, {r1, lr}BL identify_and_clear_sourceCPSIE i ; Enable IRQBL C_irq_handlerCPSID i ; Disable IRQLDMFD sp!, {r1,lr}ADD sp, sp, r1LDMFD sp!, {r0-r3, r12} ; Restore registersRFEFD sp! ; Return using RFE from System mode stack

이러한 예제에서는 FIQ가 영구적으로 활성화 상태인 것으로 가정합니다.

6.7.4 어셈블리 언어의 예제 인터럽트 처리기

인터럽트 처리기는 빠르게 실행될 수 있도록 어셈블리 언어로 작성되는 경우도 있습니다. 다음 단원에는 몇 가지 예제가 있습니다.

• 단일 채널 DMA 전송

• 6-35페이지의 이중 채널 DMA 전송

• 6-36페이지의 인터럽트 우선순위

• 6-38페이지의 컨텍스트 전환

단일 채널 DMA 전송

예제 6-17에서는 메모리 전송(소프트 DMA)에 대해 인터럽트 구동 I/O를 수행하는 인터럽트 처리기를 보여 줍니다. 이 코드는 FIQ 처리기로, 뱅크 FIQ 레지스터를 사용하여 인터럽트 간의 상태를 유지합니다. 이 코드는 0x1C 위치에 배치하는 것이 가장 좋습니다.

예제 코드에 사용되는 요소는 다음과 같습니다.

r8 읽을 데이터가 있는 I/O 장치의 기본 주소를 가리킵니다.

IOData 기본 주소부터 읽으려는 32비트 데이터 레지스터까지의 오프셋입니다. 이 레지스터를 읽으면 인터럽트가 지워집니다.

r9 해당 데이터가 전송될 메모리 위치를 가리킵니다.

r10 전송할 마지막 주소를 가리킵니다.

일반적인 전송을 처리하기 위한 전체 시퀀스에서는 네 개의 명령어를 사용합니다. 조건부 복귀 다음에 배치되는 코드는 전송이 완료되었다는 신호를 보내는 데 사용됩니다.

6-34 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 141: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

프로세서 예외 처리

예제 6-17 FIQ 처리기

LDR r11, [r8, #IOData] ; Load port data from the IO device. STR r11, [r9], #4 ; Store it to memory: update the pointer. CMP r9, r10 ; Reached the end ? SUBLSS pc, lr, #4 ; No, so return. ; Insert transfer complete ; code here.

로드 명령어를 로드 바이트 명령어로 대체하면 바이트 전송을 수행할 수 있습니다. 로드 명령어와 저장 명령어의 주소 모드를 서로 바꾸면 메모리에서 I/O 장치로의 전송을 수행할 수 있습니다.

이중 채널 DMA 전송

예제 6-18은 처리되는 채널이 두 개라는 점만 제외하고 6-35페이지의 예제 6-17과 비슷합니다. 이 코드는 FIQ 처리기로, 뱅크 FIQ 레지스터를 사용하여 인터럽트 간의 상태를 유지합니다. 이 코드는 0x1c 위치에 배치하는 것이 가장 좋습니다.

예제 코드에 사용되는 요소는 다음과 같습니다.

r8 읽을 데이터가 있는 I/O 장치의 기본 주소를 가리킵니다.

IOStat 기본 주소부터 두 포트 중 인터럽트를 발생시킨 포트를 나타내는 레지스터까지의 오프셋입니다.

IOPort1Active 첫 번째 포트에서 인터럽트가 발생했는지 여부를 나타내는 비트 마스크입니다. 그렇지 않으면 두 번째 포트에서 인터럽트가 발생했다고 가정합니다.

IOPort1, IOPort2 읽으려는 두 개의 데이터 레지스터에 대한 오프셋입니다. 데이터 레지스터를 읽으면 해당 포트의 인터럽트가 지워집니다.

r9 첫 번째 포트에서 데이터를 전송할 대상 메모리 위치를 가리킵니다.

r10 두 번째 포트에서 데이터를 전송할 대상 메모리 위치를 가리킵니다.

r11, r12 전송할 마지막 주소를 가리킵니다. 이 주소는 첫 번째 포트의 경우 r11이고 두 번째 포트의 경우 r12입니다.

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 6-35

Page 142: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

프로세서 예외 처리

일반적인 전송을 처리하는 전체 시퀀스에서는 아홉 개의 명령어를 사용합니다. 조건부 복귀 다음에 배치되는 코드는 전송이 완료되었다는 신호를 보내는 데 사용됩니다.

예제 6-18 FIQ 처리기

LDR r13, [r8, #IOStat] ; Load status register to find which port ; caused the interrupt. TST r13, #IOPort1Active LDREQ r13, [r8, #IOPort1] ; Load port 1 data. LDRNE r13, [r8, #IOPort2] ; Load port 2 data. STREQ r13, [r9], #4 ; Store to buffer 1. STRNE r13, [r10], #4 ; Store to buffer 2. CMP r9, r11 ; Reached the end? CMPLE r10, r12 ; On either channel? SUBNES pc, lr, #4 ; Return ; Insert transfer complete code here.

로드 명령어를 로드 바이트 명령어로 대체하면 바이트 전송을 수행할 수 있습니다. 조건부 로드 명령어와 조건부 저장 명령어의 주소 모드를 서로 바꾸면 메모리에서 I/O 장치로의 전송을 수행할 수 있습니다.

인터럽트 우선순위

예제 6-19에서는 최대 32가지의 인터럽트 원인을 적절한 처리기 루틴으로 디스패치합니다. 이 예제는 일반적인 인터럽트 벡터(IRQ)와 함께 사용할 수 있도록 설계되었으므로 0x18 위치에서 분기됩니다.

외부 하드웨어는 인터럽트의 우선순위를 지정하고 I/O 레지스터에서 우선순위가 높은 활성 인터럽트를 나타내는 데 사용됩니다.

예제 코드에 사용되는 요소는 다음과 같습니다.

IntBase 인터럽트 컨트롤러의 기본 주소를 저장합니다.

IntLevel 우선순위가 가장 높은 활성 인터럽트가 들어 있는 레지스터의 오프셋을 저장합니다.

r13 작은 전체 내림차순 스택을 가리키는 것으로 가정합니다.

인터럽트는 이 코드로의 분기를 포함하여 모두 10개의 명령어 다음에 활성화됩니다.

6-36 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 143: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

프로세서 예외 처리

각 인터럽트의 특정 처리기는 모든 레지스터가 스택에 저장된 상태에서 두 명령어를 더 실행한 후에 시작됩니다.

또한 각 처리기의 마지막 세 개 명령어는 인터럽트가 다시 해제된 상태에서 실행되므로 스택에서 SPSR을 안전하게 복구할 수 있습니다.

참고

Application Note 30: Software Prioritization of Interrupts에서는 이 설명서에서처럼 하드웨어를 사용하는 것이 아니라 소프트웨어를 사용하여 여러 원인으로 인한 인터럽트의 우선순위를 결정하는 방법에 대해 설명합니다.

예제 6-19

; first save the critical state SUB lr, lr, #4 ; Adjust the return address ; before we save it. STMFD sp!, {lr} ; Stack return address MRS r14, SPSR ; get the SPSR ... STMFD sp!, {r12, r14} ; ... and stack that plus a ; working register too. ; Now get the priority level of the ; highest priority active interrupt. MOV r12, #IntBase ; Get the interrupt controller's ; base address. LDR r12, [r12, #IntLevel] ; Get the interrupt level (0 to 31).

; Now read-modify-write the CPSR to enable interrupts.

MRS r14, CPSR ; Read the status register. BIC r14, r14, #0x80 ; Clear the I bit ; (use 0x40 for the F bit). MSR CPSR_c, r14 ; Write it back to re-enable ; interrupts and LDR pc, [pc, r12, LSL #2] ; jump to the correct handler. ; PC base address points to this ; instruction + 8 NOP ; pad so the PC indexes this table.

; Table of handler start addresses DCD Priority0Handler DCD Priority1Handler DCD Priority2Handler; ... Priority0Handler STMFD sp!, {r0 - r11} ; Save other working registers.

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 6-37

Page 144: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

프로세서 예외 처리

; Insert handler code here.; ... LDMFD sp!, {r0 - r11} ; Restore working registers (not r12).

; Now read-modify-write the CPSR to disable interrupts. MRS r12, CPSR ; Read the status register. ORR r12, r12, #0x80 ; Set the I bit ; (use 0x40 for the F bit). MSR CPSR_c, r12 ; Write it back to disable interrupts.

; Now that interrupt disabled, can safely restore SPSR then return. LDMFD sp!, {r12, r14} ; Restore r12 and get SPSR. MSR SPSR_csxf, r14 ; Restore status register from r14. LDMFD sp!, {pc}^ ; Return from handler.Priority1Handler; ...

컨텍스트 전환

6-39페이지의 예제 6-20에서는 사용자 모드 프로세스에서 컨텍스트 전환을 수행합니다. 이 코드는 실행할 수 있는 프로세스의 PCB(프로세스 제어 블록)에 대한 포인터 목록을 기반으로 합니다.

그림 6-5에서는 이 예제에 필요한 PCB의 레이아웃을 보여 줍니다.

그림 6-5 PCB 레이아웃

������������������

� �

����������

�����������

� ������������ ���

6-38 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 145: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

프로세서 예외 처리

r12는 실행할 다음 프로세스의 PCB에 대한 포인터를 가리키며 목록의 끝에는 0 포인터가 있습니다. 레지스터 r13은 PCB에 대한 포인터로, 일정 시간마다 저장되므로 진입 시점에서는 현재 실행하고 있는 프로세스의 PCB를 가리킵니다.

예제 6-20

STMIA r13, {r0 - r14}^ ; Dump user registers above r13. MRS r0, SPSR ; Pick up the user status STMDB r13, {r0, lr} ; and dump with return address below. LDR r13, [r12], #4 ; Load next process info pointer. CMP r13, #0 ; If it is zero, it is invalid LDMNEDB r13, {r0, lr} ; Pick up status and return address. MSRNE SPSR_cxsf, r0 ; Restore the status. LDMNEIA r13, {r0 - r14}^ ; Get the rest of the registers NOP SUBNES pc, lr, #4 ; and return and restore CPSR. ; Insert "no next process code" here.

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 6-39

Page 146: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

프로세서 예외 처리

6.8 리셋 처리기

리셋 처리기에서 수행하는 작업은 소프트웨어를 개발할 때 의도한 시스템에 따라 달라집니다. 예를 들면 다음과 같은 작업을 수행합니다.

• 예외 벡터를 설정합니다. 자세한 내용은 6-14페이지의 예외 처리기 설치를 참조하십시오.

• 스택과 레지스터를 초기화합니다.

• MMU를 사용하는 경우 메모리 시스템을 초기화합니다.

• 중요한 I/O 장치를 초기화합니다.

• 인터럽트를 활성화합니다.

• 프로세서 모드 및/또는 상태를 변경합니다.

• C에 필요한 변수를 초기화하고 주 응용 프로그램을 호출합니다.

자세한 내용은 2장 임베디드 소프트웨어 개발을 참조하십시오.

6-40 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 147: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

프로세서 예외 처리

6.9 정의되지 않은 명령어 처리기

다음과 같은 경우에 정의되지 않은 명령어 예외가 생성됩니다.

• 프로세서에서 명령어를 인식하지 못하는 경우

• 프로세서에서 명령어를 보조 프로세서 명령어로 인식하지만 보조 프로세서에서 해당 명령어를 인식하지 못하는 경우

명령어가 보조 프로세서용이지만 VFP와 같은 관련 보조 프로세서가 시스템에 연결되어 있지 않거나 비활성화된 경우에 이러한 예외가 발생할 수 있습니다. 그러나 이러한 보조 프로세서에 대한 소프트웨어 에뮬레이터는 사용할 수 있습니다.

이러한 에뮬레이터에서는 다음을 수행해야 합니다.

1. 정의되지 않은 명령어 벡터에 연결하고 이전 내용을 저장합니다.

2. 정의되지 않은 명령어를 검사하여 명령어를 에뮬레이션해야 하는지 여부를 확인합니다. 이는 SVC 처리기에서 SVC의 번호를 추출하는 방식과 비슷하지만 에뮬레이터에서는 맨 아래 24비트를 추출하는 것이 아니라 비트 [27:24]를 추출해야 합니다.

이러한 비트는 다음과 같은 방식으로 명령어가 보조 프로세서 작업인지 여부를 확인합니다.

• 비트 [27:24]가 b1110 또는 b110x이면 해당 명령어는 보조 프로세서 명령어입니다.

• 비트 [8:11]이 이 보조 프로세서 에뮬레이터에서 명령어를 처리해야 함을 나타내면 에뮬레이터에서는 명령어를 처리한 후 사용자 프로그램으로 복귀해야 합니다.

3. 그렇지 않으면 에뮬레이터에서는 에뮬레이터가 설치될 때 저장된 벡터를 사용하여 원래 처리기 또는 체인의 다음 에뮬레이터에 예외를 전달해야 합니다.

에뮬레이터의 체인이 모두 소모되면 정의되지 않은 명령어 처리기가 오류를 보고하고 종료되어야 합니다.

참고

ARMv6T2 이전의 Thumb 명령어 세트에는 보조 프로세서 명령어가 없으므로 정의되지 않은 명령어 처리기에서 이러한 명령어를 에뮬레이션하기 위한 요구 사항은 없습니다.

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 6-41

Page 148: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

프로세서 예외 처리

6.10 프리페치 어보트 처리기

시스템에 MMU가 없으면 프리페치 어보트 처리기가 오류를 보고하거나 종료될 수 있습니다. 그렇지 않으면 어보트를 발생시킨 주소가 실제 메모리에 복원되어야 합니다. lr_ABT는 어보트를 발생시킨 주소 다음의 주소에 있는 명령어를 가리키므로 복원할 주소는 lr_ABT-4입니다. 해당 주소의 가상 메모리 오류는 처리 가능하며 명령어 가져오기가 다시 시도됩니다. 따라서 처리기는 다음 명령어가 아니라 동일한 명령어로 복귀합니다. 예를 들면 다음과 같습니다.

SUBS pc,lr,#4

6-42 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 149: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

프로세서 예외 처리

6.11 데이터 어보트 처리기

MMU가 없으면 데이터 어보트 처리기는 오류를 보고하고 종료되어야 합니다. MMU가 있으면 처리기는 가상 메모리 오류를 처리해야 합니다.

lr_ABT는 어보트를 발생시킨 명령어 다음의 명령어 두 개를 가리키므로 어보트를 발생시킨 명령어는 lr_ABT-8에 있습니다.

다음 유형의 명령어는 이 어보트를 발생시킬 수 있습니다.

단일 레지스터 로드 또는 저장

응답은 프로세서 유형에 따라 달라집니다.

• ARM7TDMI®를 비롯한 ARM7 프로세서에서 어보트가 발생할 경우 주소 레지스터가 업데이트되고 변경 내용이 취소되어야 합니다.

• ARM9, ARM10, StrongARM 이상 프로세서에서 어보트가 발생할 경우 프로세서에서는 주소를 명령어가 시작되기 이전의 값으로 복원합니다. 변경 내용을 취소하는 데 필요한 코드는 없습니다.

Swap(SWP) 이 명령어와 관련된 주소 레지스터 업데이트는 없습니다.

다중 로드 또는 다중 저장

응답은 프로세서 유형에 따라 달라집니다.

• ARM7 프로세서에서 어보트가 발생하고 쓰기 되돌림이 활성화되어 있으면 전체 전송이 발생할 때와 같은 방식으로 기준 레지스터가 업데이트됩니다.

기준 레지스터가 레지스터 목록에 있는 LDM의 경우 프로세서에서는 덮어쓰여진 값을 수정된 기준 값으로 대체하여 복구가 가능하도록 합니다. 그러면 관련된 레지스터의 수를 사용하여 원래 기준 주소를 다시 계산할 수 있습니다.

• ARM9, ARM10, StrongARM 이상 프로세서에서 어보트가 발생하고 쓰기 되돌림이 활성화되어 있으면 기준 레지스터는 명령어가 시작되기 이전의 값으로 복원됩니다.

이러한 각각의 경우에서 MMU는 필요한 가상 메모리를 실제 메모리로 로드할 수 있습니다. MMU FAR(Fault Address Register)에는 어보트를 발생시킨 주소가 들어 있습니다. 이 작업이 수행될 때 처리기는 복귀하여 해당 명령어의 실행을 다시 시도할 수 있습니다.

예제 데이터 어보트 처리기 코드는 주 예제 디렉토리의 ...\databort에 있습니다.

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 6-43

Page 150: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

프로세서 예외 처리

6.12 시스템 모드

ARM 아키텍처에는 범용 레지스터 15개, PC 및 CPSR이 있는 사용자 모드가 정의되어 있습니다. 이 모드 외에도 권한이 필요한 다른 프로세서 모드가 있으며 각 모드에는 SPSR과 15개의 범용 사용자 모드 레지스터 중 일부를 대체하는 여러 레지스터가 있습니다.

프로세서 예외가 발생하면 현재 PC가 예외 모드의 링크 레지스터에 복사되고 CPSR이 예외 모드의 SPSR에 복사됩니다. 그런 다음 CPSR은 예외에 종속적인 방식으로 변경되고 PC는 예외 처리기를 시작하는 예외 정의 주소로 설정됩니다.

ARM 하위 루틴 호출 명령어(BL)는 PC를 변경하기 전에 복귀 주소를 r14에 복사하므로 하위 루틴 복귀 명령어는 r14를 PC(MOV pc,lr)로 이동합니다.

또한 이때 예외를 처리하는 ARM 모드에서는 하위 루틴을 호출할 경우 동일한 유형의 다른 예외가 발생하지 않도록 해야 합니다. 하위 루틴 복귀 주소가 예외 복귀 주소로 덮어쓰여지기 때문입니다.

이전 버전의 ARM 아키텍처에서는 꼭 필요한 경우가 아니면 예외 코드에서 하위 루틴을 호출하지 못하도록 하거나 권한 모드에서 사용자 모드로 변경하는 방법으로 이 문제를 해결했습니다. 첫 번째 방법을 사용하면 지나치게 제한적인 경우가 많고 두 번째 방법을 사용하면 작업을 올바르게 실행하는 데 필요한 권한으로 액세스하지 못할 수 있습니다.

ARMv4 이상에서는 시스템 모드라는 프로세서 모드를 제공하여 이 문제를 해결합니다. 시스템 모드는 사용자 모드 레지스터를 공유하는 권한이 있는 프로세서 모드입니다. 권한 모드 작업을 이 모드에서 실행할 수 있으며 예외가 더 이상 링크 레지스터를 덮어쓰지 않습니다.

참고

시스템 모드는 예외가 발생할 때 전환되지 않습니다. 예외 처리기에서 CPSR을 수정하여 시스템 모드로 전환합니다. 예제를 보려면 6-31페이지의 재진입 인터럽트 처리기를 참조하십시오.

6-44 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 151: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

7장 Cortex-M3 프로세서 예외 처리

이 장에서는 Cortex-M3 프로세서에서 지원하는 여러 가지 유형의 예외를 처리하는 방법을 설명합니다.

이 장에는 다음 단원이 포함되어 있습니다.

• 7-2페이지의 Cortex-M3 프로세서 예외

• 7-11페이지의 예외 테이블 기록

• 7-13페이지의 예외 처리기 기록

• 7-14페이지의 예외 테이블 배치

• 7-15페이지의 시스템 제어 공간 레지스터 구성

• 7-17페이지의 개별 IRQ 구성

• 7-18페이지의 관리자 호출

• 7-20페이지의 시스템 타이머

• 7-22페이지의 다른 ARM 프로세서용으로 작성된 예외 처리 코드 이식

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 7-1

Page 152: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

Cortex-M3 프로세서 예외 처리

7.1 Cortex-M3 프로세서 예외

프로그램을 통한 일반적인 실행 흐름 동안에는 주소 공간을 통해 PC(프로그램 카운터)가 순차적으로 늘어나면서 인접 레이블로 분기되거나 하위 루틴으로 분기 및 링크됩니다.

이러한 일반적인 실행 흐름에 변화가 생기면 프로세서 예외가 발생하여, 프로세서에서 내부 또는 외부 원인으로 인해 생성된 이벤트를 처리할 수 있도록 합니다. 이러한 이벤트의 예는 다음과 같습니다.

• 외부에서 인터럽트가 생성되는 경우

• 프로세서에서 정의되지 않은 명령어를 실행하려고 시도하는 경우

• 권한이 필요한 운영 체제 기능에 액세스하려는 경우

예외가 발생하면 예외가 벡터 테이블의 주소로 분기됩니다. 발생하는 특정 예외에 따라 벡터 테이블에서 사용되는 주소의 위치가 결정됩니다. 자세한 내용은 7-5페이지의 예외 번호 및 7-6페이지의 벡터 테이블을 참조하십시오.

참고

대부분의 ARM 프로세서와 달리 Cortex-M3 프로세서의 벡터 테이블에는 명령어가 아니라 주소가 포함되어 있습니다.

이러한 예외를 처리할 때는 적절한 예외 루틴이 완료된 후 예외 발생 시점에서 실행하고 있던 프로그램의 실행을 다시 시작할 수 있도록 이전 프로세서 상태를 유지해야 합니다.

저장 프로세스의 일부는 Cortex-M3 프로세서의 하드웨어에서 자동으로 수행됩니다. 손상될 수 있는 CPSR 및 AAPCS 레지스터가 자동으로 저장되기 때문에 대부분의 예외 처리기가 C 또는 C++로 작성될 수 있으며 어셈블리 언어로 작성된 저수준 처리기가 대개 필요하지 않습니다.

Cortex-M3 프로세서는 ARM v7-M 아키텍처를 기반으로 합니다. Cortex-M3 프로세서는 Thumb-2 명령어만 실행하며 ARM 명령어 세트를 지원하지 않습니다. 따라서 예외 처리 코드는 Thumb 상태에서 실행됩니다.

7-2 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 153: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

Cortex-M3 프로세서 예외 처리

7.1.1 작업 및 실행 모드

Cortex-M3 프로세서는 다음을 지원합니다.

• 두 가지 작업 모드(스레드 모드 및 처리기 모드)

• 두 가지 실행 모드(권한 모드 및 사용자 모드)

스레드 모드는 재설정할 때와 주로 예외에서 복귀할 때 시작됩니다. 스레드 모드에서 코드는 권한 모드나 사용자 모드로 실행될 수 있습니다.

처리기 모드는 예외의 결과로 시작됩니다. 모든 코드는 권한 모드로 실행됩니다. 예외가 발생하면 코어가 권한 모드로 자동 전환됩니다.

권한 모드에는 모든 액세스 권한이 있습니다.

사용자 모드에는 제한된 액세스 권한이 있습니다. 제한 사항은 다음과 같습니다.

• MSR 명령어에서 사용할 수 있는 필드와 같은 명령어 사용에 대한 제한

• 특정 보조 프로세서 레지스터의 사용에 대한 제한

• 시스템 설계에 따라 메모리 및 주변 기기에 액세스하는 데 대한 제한

• MPU 구성에 따라 설정되는 메모리 및 주변 기기에 액세스하는 데 대한 제한

링크 레지스터(R14)에서 EXC_RETURN 값을 수정하여 예외에서 복귀할 때 권한 스레드 모드에서 사용자 스레드 모드로 변경할 수 있습니다. MSR 명령어를 사용하여 CONTROL[0]을 지우는 방법으로 권한 스레드 모드를 사용자 스레드 모드로 변경할 수도 있습니다. 그러나 SVC와 같은 예외를 거치지 않고 권한 없는 모드에서 권한 있는 모드로 직접 변경할 수는 없습니다. 자세한 내용은 7-18페이지의 관리자 호출을 참조하십시오.

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 7-3

Page 154: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

Cortex-M3 프로세서 예외 처리

7.1.2 주 스택과 프로세스 스택

Cortex-M3 프로세서에서는 주 스택과 프로세스 스택이라는 두 가지 스택을 지원합니다. Cortex-M3 프로세서에는 SP(스택 포인터)가 스택마다 하나씩 있습니다. 사용 중인 스택에 따라 한 번에 스택 포인터 하나만 표시됩니다.

주 스택은 재설정할 때와 예외 처리기를 시작할 때 사용됩니다. 프로세스 스택을 사용하려면 프로세스 스택을 선택해야 합니다. 이렇게 하려면 다음 중 하나를 수행하십시오.

• 처리기 모드에서 종료할 때 EXC_RETURN 값 사용

• 스레드 모드일 때 MSR 명령어를 사용하여 CONTROL[1]에 기록

참고

초기화 또는 컨텍스트 전환 코드에서 프로세스 스택 포인터를 초기화해야 합니다.

7-4 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 155: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

Cortex-M3 프로세서 예외 처리

7.1.3 예외 번호

표 7-1에서는 Cortex-M3 프로세서에서 인식하는 다양한 예외 유형이 나와 있습니다. 각 예외 유형을 발생시키는 이벤트에 대한 자세한 내용은 7-8페이지의 이벤트를 참조하십시오.

표 7-1 예외 번호

예외 번호 예외 우선순위 비활성화 설명

1 리셋 -3 아니요

2 NMI -2 아니요 마스크할 수 없는 인터럽트

3 HardFault -1 아니요 다른 예외로 처리되지 않는 모든 오류

4 MemManage 구성 가능 가능 메모리 보호 오류(명령어 또는 데이터)

5 BusFault 구성 가능 가능 기타 메모리 오류

6 UsageFault 구성 가능 가능 메모리 오류 이외의 명령어 실행 오류

7-10 예약되어 있음 - -

11 SVCall 구성 가능 아니요 SVC 명령어 실행으로 인해 발생하는 동기 관리자 호출

12 디버그 모니터 구성 가능 가능 동기 디버그 이벤트

13 예약되어 있음 - -

14 PendSV 구성 가능 아니요 비동기 관리자 호출

15 SysTick 구성 가능 아니요 시스템 타이머 틱

16 외부 인터럽트(0)

구성 가능 가능 외부 인터럽트

... ... ... ...

16 + n 외부 인터럽트(n)

구성 가능 가능 외부 인터럽트

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 7-5

Page 156: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

Cortex-M3 프로세서 예외 처리

7.1.4 벡터 테이블

리셋 시 벡터 테이블은 주소 0x00000000에 있습니다.

코드가 권한 모드로 실행되는 경우 다음을 수행할 수 있습니다.

• VTOR(벡터 테이블 오프셋 레지스터)에서 벡터 테이블의 현재 위치(vectorbaseaddress)를 읽을 수 있습니다.

• VTOR에 기록하여 벡터 테이블을 다른 주소로 재배치할 수 있습니다.

VTOR에 대한 자세한 내용은 7-7페이지의 벡터 테이블 오프셋 레지스터를 참조하고, 권한에 대한 자세한 내용은 7-3페이지의 작업 및 실행 모드를 참조하십시오.

벡터 테이블에는 각 예외 유형에 대한 처리기의 주소가 포함되어 있습니다. 예외 번호 n의 처리기는 (vectorbaseaddress + 4 * n)에 저장됩니다. 각 예외의 n 값은 7-5페이지의 예외 번호를 참조하십시오.

참고

이 벡터 테이블은 다른 ARM 프로세서의 벡터 테이블과 다릅니다. 다른 ARM 프로세서의 벡터 테이블에는 주소가 아니라 명령어가 들어 있습니다.

ARMv7-M 프로세서에서는 Thumb 코드만 실행할 수 있기 때문에 처리기의 주소는 모두 비트[0]이 1로 설정되어야 합니다.

vectorbaseaddress의 워드에는 주 스택 포인터의 리셋 값이 들어 있습니다.

7-6 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 157: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

Cortex-M3 프로세서 예외 처리

벡터 테이블 오프셋 레지스터

이 레지스터는 주소 0xE000ED08에서 매핑되는 메모리입니다. 리셋 시 이 레지스터에는 0x00000000이 포함됩니다.

VTOR의 비트[31:30]과 비트[7:0]은 예약되어 있으며 모두 0입니다. 비트[29]가 0이면 벡터 테이블이 메모리의 코드 영역에 있고, 0이 아니면 메모리의 RAM 영역에 있습니다.

벡터 테이블 주소는 항상 32워드로 정렬되어야 합니다. 16개가 넘는 외부 인터럽트가 사용되는 경우 주소 정렬은 32비트를 초과해야 합니다. 표 7-2에서는 다양한 개수의 외부 인터럽트에 대한 정렬을 보여 줍니다. ARMv7-M에서는 240개가 넘는 외부 인터럽트를 지원하지 않습니다.

표 7-2

외부 인터럽트 수 vectorbaseaddress의 정렬

0-16 32워드

17-48 64워드

49-112 128워드

113-240 256워드

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 7-7

Page 158: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

Cortex-M3 프로세서 예외 처리

7.1.5 이벤트

각 예외 유형의 가능한 원인은 다음과 같습니다.

리셋 리셋은 리셋 신호가 어설션될 때 복구할 수 없는 방법으로 실행을 종료하는 특수 예외입니다. 리셋에는 두 가지 수준이 있습니다.

• POR(전원 켜기 리셋)은 코어, 시스템 제어 공간 및 디버그 논리를 재설정합니다.

• 논리 리셋은 코어와 대부분의 시스템 제어 공간을 재설정합니다. 시스템 제어 공간의 일부 디버그 관련 리소스와 디버그 논리는 재설정되지 않습니다.

리셋 신호가 디어설션되면 실행이 고정된 지점에서 다시 시작합니다.

NMI 마스크할 수 없는 인터럽트

HardFault 다른 예외 메커니즘으로 처리할 수 없는 모든 오류에 대한 일반 오류입니다. 일반적으로 복구할 수 없는 오류에 사용됩니다.

HardFault는 오류 에스컬레이션에 사용됩니다.

MemManage

MPU(Memory Protection Unit)의 신호를 받는 메모리 보호 오류는 데이터 액세스와 명령어 액세스에 대한 MemManage 예외를 발생시킵니다. 이 오류가 비활성화되면 메모리 보호 오류가 HardFault로 에스컬레이션됩니다.

BusFault MemManage로 처리되는 오류 이외의 메모리 관련 오류는 BusFault 예외를 발생시킵니다. 이러한 오류는 대개 시스템 버스에서 감지되는 오류이며 동기 또는 비동기일 수 있습니다. 이 오류가 비활성화되면 해당 오류가 HardFault로 에스컬레이션됩니다.

UsageFault 메모리 오류 이외의 명령어 실행 오류입니다. 여기에 해당하는 경우는 다음과 같습니다.

• 정의되지 않은 명령어를 실행하려는 시도

• 잘못된 상태로 전환되는 명령어의 실행

• 예외 복귀 시의 오류

• 사용할 수 없거나 비활성화된 보조 프로세서를 사용하려는 시도

• 0으로 나누기(UsageFault를 발생시키도록 구성된 경우)

• 정렬되지 않은 주소(UsageFault를 발생시키도록 구성된 경우)

7-8 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 159: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

Cortex-M3 프로세서 예외 처리

SVCall SVC 명령어 실행으로 인해 발생하는 동기 관리자 호출. 응용 프로그램 코드에서는 SVC 명령어를 사용하여 시스템에 대한 권한 액세스가 필요한 서비스를 요청합니다.

디버그 모니터

동기 디버그 이벤트. 이 이벤트는 브레이크포인트(BKPT) 명령어를 실행하는 것일 수 있습니다.

PendSV 비동기 관리자 호출

SysTick 시스템 타이머 이벤트

외부 인터럽트(n)

중첩된 벡터 인터럽트 컨트롤러의 신호. 자세한 내용은 7-10페이지의 중첩된 벡터 인터럽트 컨트롤러를 참조하십시오.

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 7-9

Page 160: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

Cortex-M3 프로세서 예외 처리

7.1.6 예외 우선순위와 발생 순서

우선순위 번호가 작은 예외가 우선순위 번호가 큰 예외보다 우선적으로 발생할 수 있습니다. 즉, 프로세서가 처리기 모드에 있는 경우 현재 처리 중인 예외보다 우선순위 번호가 작은 예외가 발생합니다. 우선순위 번호가 같거나 큰 모든 예외는 보류됩니다.

다음과 같은 경우에 예외 처리기가 종료됩니다.

• 보류 중인 예외가 없으며 프로세서가 스레드 모드로 복귀하고 실행이 응용 프로그램으로 복귀하는 경우

• 보류 중인 예외가 있고 실행이 우선순위 번호가 가장 작은 보류 중인 예외의 처리기로 전달되는 경우. 우선순위 번호가 동일하게 가장 작은 보류 중인 예외가 두 개인 경우 예외 번호가 가장 작은 예외가 먼저 처리됩니다.

리셋, 마스크할 수 없는 인터럽트 및 HardFault의 우선순위는 -3, -2 및 -1입니다. 다른 모든 예외의 우선순위는 구성 가능하며 0보다 큽니다.

7.1.7 중첩된 벡터 인터럽트 컨트롤러

구현에 따라 NVIC(중첩된 벡터 인터럽트 컨트롤러)는 동적으로 우선순위를 다시 지정할 수 있는 최대 256개의 우선순위 수준을 사용하여 최대 240개의 외부 인터럽트를 지원할 수 있습니다. NVIC는 수준 및 펄스 인터럽트 원인을 모두 지원합니다. 프로세서 상태는 인터럽트 시작 시 하드웨어에 자동으로 저장되고 인터럽트 종료 시 복원됩니다. NVIC는 인터럽트의 테일 체이닝(tail-chaining)도 지원합니다.

Cortex-M3에서 NVIC를 사용하는 것은 Cortex-M3의 벡터 테이블이 이전 ARM 코어와 매우 다르다는 것을 의미합니다. Cortex-M3 벡터 테이블에는 대부분의 다른 ARM 코어의 경우처럼 명령어가 포함되어 있지 않고 ISR과 예외 처리기의 주소가 포함되어 있습니다. 초기 스택 포인터와 리셋 처리기의 주소는 각각 0x0 및 0x4에 있어야 합니다. 이러한 주소는 리셋 시 적절한 CPU 레지스터로 로드됩니다.

7-10 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 161: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

Cortex-M3 프로세서 예외 처리

7.2 예외 테이블 기록

벡터 테이블을 채우는 가장 쉬운 방법은 스캐터 파일을 사용하여 함수 포인터의 C 배열을 메모리 주소 0x0에 배치하는 것입니다. C 배열을 사용하여 초기 스택 포인터, 이미지 엔트리 포인트 및 예외 처리기의 주소를 구성할 수 있습니다.

예제 7-1 예외 처리기의 C 구조체 예제

/* Filename: exceptions.c */typedef void(* const ExecFuncPtr)(void);/* Place table in separate section */#pragma arm section rodata="exceptions_area" ExecFuncPtr exception_table[] = { (ExecFuncPtr)&Image$$ARM_LIB_STACKHEAP$$ZI$$Limit,

/* Initial Stack Pointer, from linker-generated symbol */ (ExecFuncPtr)&__main, /* Initial PC, set to entry point */ &NMIException, &HardFaultException, &MemManageException, &BusFaultException, &UsageFaultException, 0, 0, 0, 0, /* Reserved */ &SVCHandler, &DebugMonitor, 0, /* Reserved */ &PendSVC, (ExecFuncPtr)&SysTickHandler, /* Configurable interrupts start here...*/ &InterruptHandler, &InterruptHandler, &InterruptHandler /* : */};#pragma arm section

이 구조체의 처음 두 항목은 초기 스택 포인터와 이미지 엔트리 포인트입니다. 예제 7-1에서는 C 라이브러리 엔트리 포인트(__main)를 이미지의 엔트리 포인트로 사용합니다.

예외 테이블에는 전용 섹션도 있습니다. 이를 위해 다음과 같은 지시문을 사용합니다.

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 7-11

Page 162: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

Cortex-M3 프로세서 예외 처리

#pragma arm section rodata="exceptions_area"

이 지시문은

#pragma arm section rodata="exceptions_area"

#pragma arm section

사이에 있는 모든 RO 데이터를 exceptions_area라는 전용 섹션에 배치하도록 컴파일러에 지시합니다. 이렇게 하면 스캐터 파일에서 이를 참조하여 메모리 맵의 올바른 위치(주소 0x0)에 예외 테이블을 배치할 수 있습니다.

7-12 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 163: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

Cortex-M3 프로세서 예외 처리

7.3 예외 처리기 기록

코어에서는 예외가 발생할 때 시스템 상태를 저장하고 복귀 시 복원합니다. 예외 처리기에서는 시스템 상태를 저장하거나 복원할 필요가 없으며 일반적인 ABI 호환 C 함수로 기록될 수 있습니다.

ABI(응용 프로그램 바이너리 인터페이스) for the ARM Architecture에서 스택은 여러 소스 파일의 함수 간 호출과 같은 모든 외부 인터페이스에서 8바이트로 정렬되어야 합니다. 그러나 코드에서는 리프 함수 등에서 8바이트 스택 정렬을 내부적으로 유지할 필요가 없습니다.

즉, IRQ가 발생할 때 스택이 올바르게 8바이트로 정렬되지 않을 수도 있습니다. 버전 1 및 이후의 Cortex-M3 프로세서에서는 예외가 발생할 때 스택 포인터를 자동으로 정렬할 수 있습니다. 주소 0xE000ED14의 구성 제어 레지스터에서 STKALIGN(비트 9)을 설정하여 이 동작을 활성화할 수 있습니다.

Cortex-M3 버전 0 프로세서를 사용하는 경우에는 이러한 조정이 하드웨어에서 수행되지 않습니다. 컴파일러는 스택을 올바르게 정렬하는 IRQ 처리기에서 코드를 생성할 수 있습니다. 이를 위해서는 IRQ 처리기 앞에 __irq를 추가하고 --cpu=Cortex-M3가 아니라 --cpu=Cortex-M3-rev0 컴파일러 스위치를 사용해야 합니다.

예제 7-2 간단한 C 예외 처리기

__irq void SysTickHandler(void){

printf("----- SysTick Interrupt -----");}

참고

인터럽트 서비스 루틴에서는 인터럽트 원인의 제거를 처리해야 합니다.

Cortex-M3 프로세서에서는 효율적인 처리를 위해 예외 우선순위 지정, 예외 중첩 및 손상될 수 있는 레지스터 저장이 코어에서 모두 처리됩니다. 즉, 예외 처리기가 시작될 때마다 코어에서 인터럽트를 활성화 상태로 유지합니다.

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 7-13

Page 164: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

Cortex-M3 프로세서 예외 처리

7.4 예외 테이블 배치

예외 테이블은 개체의 전용 섹션에 배치되었기 때문에 스캐터 파일을 사용하여 0x0에 쉽게 배치될 수 있습니다.

예제 7-3 스캐터 파일에 예외 테이블 배치

LOAD_REGION 0x00000000 0x00200000{

;; Maximum of 256 exceptions (256*4 bytes == 0x400)VECTORS 0x0 0x400{

exceptions.o (exceptions_area, +FIRST)}

}

참고

+FIRST는 exceptions_area가 영역의 시작 부분에 배치되도록 하고 링커의 사용하지 않는 섹션 제거 메커니즘을 통해 벡터 테이블이 제거되는 것을 방지합니다.

7-14 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 165: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

Cortex-M3 프로세서 예외 처리

7.5 시스템 제어 공간 레지스터 구성

SCS(시스템 제어 공간) 레지스터는 0xE000E000에 있습니다. 매우 많은 개별 레지스터가 있으므로 구조체를 사용하여 SCS 레지스터를 나타내는 것이 가장 좋습니다. 예외 테이블과 유사한 방법을 사용하여 스캐터 파일에 구조체를 추가함으로써 올바른 메모리 위치에 SCS 레지스터를 배치할 수 있습니다. 예제 7-4에서는 SCS 레지스터의 구조체 예제를 보여 줍니다.

예제 7-4 SCS 레지스터 구조체

typedef volatile struct {int MasterCtrl;int IntCtrlType;int zReserved008_00c[2]; /* Reserved space */struct {

int Ctrl;int Reload;int Value;int Calibration;

} SysTick;int zReserved020_0fc[(0x100-0x20)/4]; /* Reserved space *//* Offset 0x0100 */struct {

int Enable[32];int Disable[32];int Set[32];int Clear[32];int Active[64];int Priority[64];

} NVIC;int zReserved0x500_0xcfc[(0xd00-0x500)/4]; /* Reserved space *//* Offset 0x0d00 */int CPUID;int IRQcontrolState;int ExceptionTableOffset;int AIRC;int SysCtrl;int ConfigCtrl;int SystemPriority[3];int SystemHandlerCtrlAndState;int ConfigurableFaultStatus;int HardFaultStatus;int DebugFaultStatus;int MemManageAddress;int BusFaultAddress;int AuxFaultStatus;

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 7-15

Page 166: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

Cortex-M3 프로세서 예외 처리

int zReserved0xd40_0xd90[(0xd90-0xd40)/4]; /* Reserved space *//* Offset 0x0d90 */struct {

int Type;int Ctrl;int RegionNumber;int RegionBaseAddr;int RegionAttrSize;

} MPU;} SCS_t;

참고

여기에는 장치의 모든 SCS 레지스터가 포함되지 않았을 수도 있습니다. 장치의 실리콘 제조업체가 제공하는 참조 문서를 참조하십시오.

7-16 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 167: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

Cortex-M3 프로세서 예외 처리

7.6 개별 IRQ 구성

각 IRQ는 NVIC 레지스터의 일부인 인터럽트 설정 활성화 레지스터에서 개별 활성화 비트를 갖고 있습니다. 인터럽트를 활성화하려면 인터럽트 설정 활성화 레지스터에서 해당 비트를 1로 설정합니다. 인터럽트 설정 활성화 레지스터에 대한 자세한 내용은 사용 중인 장치의 참조 문서를 참조하십시오.

예제 7-5에서는 7-15페이지의 예제 7-4에 나와 있는 SCS 구조체의 인터럽트 활성화 코드 예제를 보여 줍니다.

예제 7-5 IRQ 활성화 함수

void NVIC_enableISR(unsigned isr){

/* The isr argument is the number of the interrupt to enable. */SCS.NVIC.Enable[ (isr/32) ] = 1<<(isr % 32);

}

참고

NVIC 영역의 일부 레지스터는 권한 모드에서만 액세스할 수 있습니다.

인터럽트 제거 활성화 레지스터에서 해당 비트를 0으로 지워서 개별 IRQ를 비활성화할 수 있습니다.

7.6.1 인터럽트 우선순위

인터럽트 우선순위 레지스터를 사용하여 각각의 개별 인터럽트에 우선순위 수준을 할당할 수 있습니다. 구현에 따라 최대 256개의 우선순위 수준을 각각의 개별 인터럽트에 할당할 수 있습니다. 우선순위 수준은 최대 8비트를 사용하여 표현됩니다. 인터럽트 우선순위 네 개의 그룹이 메모리의 워드에 저장됩니다.

0은 우선순위가 가장 높고 255는 우선순위가 가장 낮습니다.

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 7-17

Page 168: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

Cortex-M3 프로세서 예외 처리

7.7 관리자 호출

SVC 명령어(이전의 SWI)는 관리자 호출(이전의 소프트웨어 인터럽트)을 생성합니다. 관리자 호출은 권한이 필요한 작업을 요청하거나 운영 체제에서 시스템 리소스에 액세스하는 데 주로 사용됩니다.

SVC 명령어에는 대개 SVC 번호라고 하는 번호가 포함되어 있습니다. 대부분의 ARM 프로세서에서 이 번호는 요청 중인 서비스를 나타내는 데 사용될 수 있습니다. 그러나 Cortex-M3 프로세서에서는 초기 예외 진입 시 스택에 인수 레지스터를 저장합니다.

SVC 처리기의 첫 번째 명령어가 실행되기 전에 늦게 도착한 예외가 발생하면 R0-R3에 아직 저장되어 있는 인수의 복사본이 손상될 수 있습니다. 따라서 인수의 스택 복사본은 SVC 처리기에서 사용되어야 합니다. 또한 스택 레지스터 값을 수정하여 반환 값이 호출자에게 다시 전달되어야 합니다. 이렇게 하려면 SVC 처리기의 시작으로 작은 어셈블리 코드를 구현해야 합니다. 이 코드에서는 레지스터가 저장된 스택을 식별하고, 명령어에서 SVC 번호를 추출하고, 번호와 인수 포인터를 C로 작성된 처리기의 본문에 전달합니다.

예제 7-6에서는 SVC 처리기의 예제를 보여 줍니다. 이 코드에서는 프로세서에서 설정한 EXC_RETURN 값을 테스트하여 SVC가 호출되었을 때 사용 중이던 스택 포인터를 확인합니다. 대부분의 시스템에서 이러한 작업은 필요하지 않습니다. 일반적으로 설계된 시스템에서는 관리자 호출이 프로세스 스택을 사용하는 사용자 코드에서만 수행되기 때문입니다. 이 경우 어셈블리 코드는 단일 MSR 명령어와 처리기 C 본문으로의 마무리 호출 분기(B 명령어)로 구성될 수 있습니다.

예제 7-6 SVC 처리기 예제

__asm void SVCHandler(void){

IMPORT SVCHandler_mainTST lr, #4MRSEQ r0, MSPMRSNE r0, PSPB SVCHandler_main

}void SVCHandler_main(unsigned int * svc_args){

unsigned int svc_number;/** Stack contains:* r0, r1, r2, r3, r12, r14, the return address and xPSR* First argument (r0) is svc_args[0]

7-18 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 169: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

Cortex-M3 프로세서 예외 처리

*/svc_number = ((char *)svc_args[6])[-2];switch(svc_number){

case SVC_00:/* Handle SVC 00 */break;

case SVC_01:/* Handle SVC 01 */break;

default:/* Unknown SVC */break;

}}

예제 7-7에서는 많은 SVC에 대한 서로 다른 선언을 만드는 방법을 보여 줍니다. __svc는 함수 호출을 지정된 번호가 포함된 SVC 명령어로 대체하는 컴파일러 키워드입니다.

예제 7-7 C 코드에서 SVC를 호출하는 예제

#define SVC_00 0x00#define SVC_01 0x01void __svc(SVC_00) svc_zero(const char *string);void __svc(SVC_01) svc_one(const char *string);

int call_system_func(void){

svc_zero("String to pass to SVC handler zero");svc_one("String to pass to a different OS function");

}

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 7-19

Page 170: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

Cortex-M3 프로세서 예외 처리

7.8 시스템 타이머

SCS에는 다른 플랫폼에서 더욱 쉽게 이식하기 위해 운영 체제에서 사용할 수 있는 시스템 타이머 SysTick이 포함되어 있습니다. 소프트웨어에서 SysTick을 폴링할 수 있으며 인터럽트를 생성하도록 SysTick을 구성할 수 있습니다. SysTick 인터럽트는 벡터 테이블에 자체 엔트리가 있으므로 전용 처리기를 사용할 수 있습니다.

표 7-3에서는 SysTick을 구성하는 데 사용하는 네 가지 레지스터에 대해 설명합니다.

7.8.1 SysTick 구성

SysTick을 구성하려면 SysTick 이벤트 간에 필요한 간격을 SysTick 다시 로드 값 레지스터에 로드합니다. 타이머 인터럽트(SysTick 제어 및 상태 레지스터의 COUNTFLAG 비트)는 1에서 0으로 전환될 때 활성화되므로 n+1 클럭 틱마다 활성화됩니다. 기간 100이 필요한 경우 99를 SysTick 다시 로드 값 레지스터에 기록합니다. SysTick 다시 로드 값 레지스터는 1에서 0x00FFFFFF 사이의 값을 지원합니다.

SysTick을 사용하여 지정된 간격(예: 1ms)에 이벤트를 생성하려면 SysTick 조정 값 레지스터를 사용하여 다시 로드 레지스터의 값을 조정할 수 있습니다. SysTick 조정 값 레지스터는 TENMS 필드, 비트[23:0]에 10ms 동안의 펄스 수가 포함된 읽기 전용 레지스터입니다.

이 레지스터에는 SKEW 비트도 있습니다. 비트[30] == 1은 TENMS 섹션의 10ms에 대한 조정이 클럭 주파수 때문에 정확히 10ms가 아님을 나타냅니다. 비트[31] == 1은 참조 클럭이 제공됨을 나타냅니다.

제어 및 상태 레지스터는 COUNTFLAG, 비트[16]을 읽거나 인터럽트를 생성하는 SysTick에 의해 타이머를 폴링할 수 있습니다.

표 7-3

이름 주소 설명

SysTick 제어 및 상태 0xE000E010 SysTick의 기본 제어: 활성화, 클럭 소스, 인터럽트 또는 폴링

SysTick 다시 로드 값 0xE000E014 0이 되었을 때 현재 값 레지스터를 로드할 값

SysTick 현재 값 0xE000E018 카운트다운의 현재 값

SysTick 조정 값 0xE000E01C 10ms 간격 및 기타 정보를 생성할 틱 수가 포함되어 있습니다.

7-20 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 171: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

Cortex-M3 프로세서 예외 처리

기본적으로 SysTick은 폴링 모드에 대해 구성됩니다. 이 모드에서 사용자 코드는 COUNTFLAG를 폴링하여 SysTick 이벤트가 발생했는지 확인합니다. SysTick 이벤트가 발생하면 COUNTFLAG가 설정됩니다. 제어 및 상태 레지스터를 읽으면 COUNTFLAG가 지워집니다. 인터럽트를 생성하도록 SysTick을 구성하려면 SysTick 제어 및 상태 레지스터의 TICKINT, 비트[1]을 1로 설정합니다. 또한 NVIC에서 해당 인터럽트를 활성화하고 CLKSOURCE, 비트[2]를 사용하여 클럭 소스를 선택해야 합니다. CLKSOURCE, 비트[2]를 1로 설정하면 코어 클럭이 선택되고 0으로 설정하면 외부 참조 클럭이 선택됩니다.

SysTick 상태 및 제어 레지스터의 비트[0]을 1로 설정하여 타이머를 활성화합니다.

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 7-21

Page 172: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

Cortex-M3 프로세서 예외 처리

7.9 다른 ARM 프로세서용으로 작성된 예외 처리 코드 이식

예외 처리기는 Cortex-M3에 맞게 조정되어야 합니다.

재진입이 코어에서 처리되기 때문에 어셈블리 언어로 된 하위 수준 처리기는 대개 필요하지 않습니다. 하위 수준 처리기에서 추가 작업을 수행하는 경우 새 처리기에서 호출할 수 있는 여러 함수에 추가 작업을 분할해야 할 수도 있습니다. 명확성을 위해 __irq 키워드를 사용하여 IRQ 처리기를 표시하고 컴파일러에서 Cortex-M3 버전 0 하드웨어의 스택 조정을 유지할 수 있도록 해야 합니다.

Cortex-M3에는 FIQ 입력이 없으므로 ARM7TDMI 프로젝트에서 FIQ 신호를 보내는 주변 기기가 우선순위가 높은 벡터 인터럽트로 이동해야 합니다. Cortex-M3 프로세서에 뱅크 레지스터가 없으므로 이러한 유형의 인터럽트에 대한 처리기에서 뱅크 FIQ 레지스터를 사용하지 않는지 확인해야 할 수 있으며, 다른 일반 IRQ 처리기의 경우 R8-R12를 스택에 저장해야 합니다.

마지막으로, 새로운 초기화 함수를 작성하여 인터럽트 우선순위를 비롯하여 NVIC를 구성해야 합니다. 이렇게 하면 주 응용 프로그램 코드에 진입하기 전에 인터럽트를 활성화할 수 있습니다.

7.9.1 중요한 섹션과 예외 동작

Cortex-M3 프로세서에서는 예외 우선순위 지정, 예외 중첩 및 손상될 수 있는 레지스터 저장이 코어에서 모두 처리되므로 처리 효율성이 매우 높고 인터럽트 지연이 최소화됩니다. 즉, 예외 처리기가 시작될 때마다 코어에서 인터럽트를 활성화 상태로 유지합니다. 또한 인터럽트가 예외에서 복귀할 때 비활성화되면 프로세서에서 자동으로 다시 활성화되지 않습니다. 인터럽트의 원자적 활성화를 수행하고 예외에서 복귀하는 것은 가능하지 않습니다. 처리기에서 인터럽트를 일시적으로 비활성화하는 경우 복귀하는 데 사용되는 명령어를 실행하기 전에 별도의 명령어로 인터럽트를 다시 활성화해야 합니다. 따라서 예외가 복귀하기 전에 다른 예외가 즉시 발생할 수 있습니다.

예외 모델의 이러한 기능은 시스템 설계에 따라 코드의 중요한 섹션에 영향을 미칠 수도 있습니다. 중요한 섹션에서는 운영 체제의 컨텍스트 전환 코드와 같이 인터럽트가 인터럽트 불가능한 블록으로 실행되도록 실행 중에 비활성화되어야 합니다. 특정 레거시 코드에서는 인터럽트가 예외 처리기 시작 시 비활성화되고 중요한 섹션이 완료된 후 코드에서 명시적으로만 활성화된다고 가정할 수도 있습니다. 이러한 가정은 Cortex-M3의 새로운 예외 모델에서는 성립되지 않으며 해당 코드는 이를 고려하여 다시 작성되어야 할 수도 있습니다.

7-22 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 173: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

8장 디버그 통신 채널

이 장에서는 DCC(디버그 통신 채널)를 사용하는 방법을 설명합니다. 여기에는 다음 단원이 포함되어 있습니다.

• 8-2페이지의 디버그 통신 채널 개요

• 8-3페이지의 타겟에서의 데이터 전송

• 8-4페이지의 폴링 방식 디버그 통신

• 8-8페이지의 인터럽트 구동 디버그 통신

• 8-9페이지의 Thumb 상태에서 액세스

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 8-1

Page 174: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

디버그 통신 채널

8.1 디버그 통신 채널 개요

ARM® 코어의 EmbeddedICE® 논리에는 디버그 통신 채널이 포함되어 있습니다. 디버그 통신 채널은 프로그램 흐름을 중지하거나 디버그 상태로 전환하지 않고도 프로토콜 변환기와 JTAG 포트를 사용하여 타겟과 호스트 디버거 간에 데이터를 전달할 수 있게 해 줍니다. 이 장에서는 타겟에서 실행되는 프로그램과 호스트 디버거에서 DCC에 액세스하는 방법을 설명합니다.

8-2 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 175: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

디버그 통신 채널

8.2 타겟에서의 데이터 전송

타겟에서는 ARM 명령어 MCR 및 MRC를 사용하여 코어의 보조 프로세서 14를 통해 DCC에 액세스합니다.

데이터를 전송하기 위해 두 가지 레지스터가 제공됩니다.

통신 데이터 읽기 레지스터

디버거로부터 데이터를 받는 데 사용하는 32비트 레지스터입니다. 다음 명령어는 Rd의 읽기 레지스터 값을 반환합니다.

MRC p14, 0, Rd, c1, c0

통신 데이터 쓰기 레지스터

디버거로 데이터를 보내는 데 사용하는 32비트 레지스터입니다. 다음 명령어는 Rn의 값을 쓰기 레지스터에 씁니다.

MCR p14, 0, Rn, c1, c0

참고

ARM10 및 ARM11 코어의 DCC 레지스터에 액세스하는 데 대한 자세한 내용은 해당 기술 참조 문서를 참조하십시오. 사용되는 명령어, 상태 비트의 위치 및 상태 비트의 해석은 ARM9 프로세서와 그 이후 버전의 프로세서에서 각기 다릅니다.

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 8-3

Page 176: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

디버그 통신 채널

8.3 폴링 방식 디버그 통신

DCC에서는 통신 데이터 읽기 및 쓰기 레지스터 외에 통신 데이터 제어 레지스터도 제공합니다.

8.3.1 통신 데이터 제어 레지스터

다음 명령어는 Rd의 제어 레지스터 값을 반환합니다.

MRC p14, 0, Rd, c0, c0

이 제어 레지스터에서 두 개의 비트는 타겟과 호스트 디버거 간에 동기화된 핸드셰이크를 제공합니다.

비트 1(W 비트) 타겟 관점에서 통신 데이터 쓰기 레지스터를 사용할 수 있는지 여부를 나타냅니다.

W = 0 타겟 응용 프로그램에서 새 데이터를 쓸 수 있습니다.

W = 1 호스트 디버거에서 쓰기 레지스터의 새 데이터를 스캔할 수 있습니다.

비트 0(R 비트) 타겟 관점에서 통신 데이터 읽기 레지스터에 새 데이터가 있는지 여부를 나타냅니다.

R = 1 타겟 응용 프로그램에서 새 데이터를 읽을 수 있습니다.

R = 0 호스트 디버거에서 쓰기 레지스터로 새 데이터를 스캔할 수 있습니다.

참고

디버거에서는 보조 프로세서 14가 아무런 의미가 없으므로 보조 프로세서 14를 사용하여 디버그 통신 채널에 직접 액세스할 수 없습니다. 대신 디버거에서 스캔 체인을 사용하여 DCC 레지스트리에 대한 데이터 읽기 및 쓰기를 수행할 수 있습니다. DCC 데이터 및 제어 레지스트리는 EmbeddedICE 논리의 주소에 매핑됩니다. EmbeddedICE 논리 레지스터를 보려면 디버거 및 디버그 타겟의 설명서를 참조하십시오.

8-4 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 177: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

디버그 통신 채널

8.3.2 타겟에서 디버거로의 통신

ARM 코어에서 실행되는 응용 프로그램이 호스트에서 실행되는 디버거와 통신하는 과정에서는 다음과 같은 일련의 작업이 수행됩니다.

1. 타겟 응용 프로그램에서 DCC 쓰기 레지스터를 사용할 수 있는지를 확인합니다. 이를 위해 MRC 명령어를 사용하여 디버그 통신 채널 제어 레지스터를 읽고 W 비트가 지워져 있는지 확인합니다.

2. W 비트가 지워져 있으면 통신 데이터 쓰기 레지스터가 지워져 있는 것이며 응용 프로그램에서는 MCR 명령어를 사용하여 보조 프로세서 14에 워드를 씁니다. 레지스터에 쓰는 작업을 수행하면 자동으로 W 비트가 설정됩니다. W 비트가 설정되어 있으면 디버거에서 통신 데이터 쓰기 레지스터를 비우지 않은 것입니다. 응용 프로그램에서 다른 워드를 보낸 경우에는 이 워드가 지워질 때까지 W 비트를 폴링해야 합니다.

3. 디버거에서는 스캔 체인 2를 통해 통신 데이터 제어 레지스터를 폴링합니다. 디버거에서 W 비트가 설정되어 있음을 알게 되면 DCC 데이터 레지스터를 읽어 응용 프로그램에서 보낸 메시지를 확인할 수 있습니다. 데이터를 읽는 작업을 수행하면 통신 데이터 제어 레지스터의 W 비트가 자동으로 지워집니다.

예제 8-1에서는 이 작업을 수행하는 방법을 보여 줍니다. 이 예제 코드는 주 예제 디렉토리의 ...\dcc\outchan.s에 있습니다.

예제 8-1

AREA OutChannel, CODE, READONLY ENTRY MOV r1,#3 ; Number of words to send ADR r2, outdata ; Address of data to sendpollout MRC p14,0,r0,c0,c0 ; Read control register TST r0, #2 BNE pollout ; if W set, register still fullwrite LDR r3,[r2],#4 ; Read word from outdata ; into r3 and update the pointer MCR p14,0,r3,c1,c0 ; Write word from r3 SUBS r1,r1,#1 ; Update counter BNE pollout ; Loop if more words to be written MOV r0, #0x18 ; Angel_SWIreason_ReportException LDR r1, =0x20026 ; ADP_Stopped_ApplicationExit SVC 0x123456 ; ARM semihosting (formerly SWI)

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 8-5

Page 178: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

디버그 통신 채널

outdata DCB "Hello there!" END

예제를 실행하려면

1. outchan.s를 어셈블합니다.

armasm --debug outchan.s

2. 출력 개체를 링크합니다.

armlink outchan.o -o outchan.axf

링크 단계에서 실행 가능 파일 outchan.axf가 만들어집니다.

3. 이미지를 로드하고 실행합니다. 자세한 내용은 디버거 설명서를 참조하십시오.

8.3.3 디버거에서 타겟으로의 통신

호스트에서 실행되는 디버거가 코어에서 실행되는 응용 프로그램으로 메시지를 전송하는 과정에서는 다음과 같은 일련의 작업이 수행됩니다.

1. 디버거에서 통신 데이터 제어 레지스터 R 비트를 폴링합니다. R 비트가 지워지면 통신 데이터 읽기 레지스터가 지워지며 타겟 응용 프로그램에서 읽을 수 있도록 데이터가 기록될 수 있습니다.

2. 디버거에서 스캔 체인 2를 통해 통신 데이터 읽기 레지스터로 데이터를 스캔합니다. 이때 통신 데이터 제어 레지스터의 R 비트가 자동으로 설정됩니다.

3. 타겟 응용 프로그램에서 통신 데이터 제어 레지스터의 R 비트를 폴링합니다. R 비트가 설정되어 있으면 통신 데이터 읽기 레지스터에 데이터가 있는 것이며 응용 프로그램에서는 MRC 명령어를 사용하여 보조 프로세서 14에서 이러한 데이터를 읽을 수 있습니다. R 비트는 읽기 명령어를 실행할 때 자동으로 지워집니다.

8-7페이지의 예제 8-2에 있는 타겟 응용 프로그램 코드에서는 이 작업을 보여 줍니다. 이 예제 코드는 주 예제 디렉토리의 ...\dcc\inchan.s에 있습니다.

예제를 실행하려면

1. 호스트에 And goodbye!와 같은 텍스트가 들어 있는 입력 파일을 만듭니다.

2. inchan.s를 어셈블합니다.

8-6 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 179: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

디버그 통신 채널

armasm --debug inchan.s

3. 출력 개체를 링크합니다.

armlink inchan.o -o inchan.axf

링크 단계에서 실행 가능 파일 inchan.axf가 만들어집니다.

4. 이미지를 로드하고 실행합니다. 자세한 내용은 디버거 설명서를 참조하십시오.

예제 8-2

AREA InChannel, CODE, READONLY ENTRY MOV r1,#3 ; Number of words to read LDR r2, =indata ; Address to store data readpollin MRC p14,0,r0,c0,c0 ; Read control register TST r0, #1 BEQ pollin ; If R bit clear then loopread MRC p14,0,r3,c1,c0 ; read word into r3 STR r3,[r2],#4 ; Store to memory and ; update pointer SUBS r1,r1,#1 ; Update counter BNE pollin ; Loop if more words to read MOV r0, #0x18 ; Angel_SWIreason_ReportException LDR r1, =0x20026 ; ADP_Stopped_ApplicationExit SVC 0x123456 ; ARM semihosting (formerly SWI)

AREA Storage, DATA, READWRITEindata DCB "Duffmessage#" END

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 8-7

Page 180: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

디버그 통신 채널

8.4 인터럽트 구동 디버그 통신

8-4페이지의 폴링 방식 디버그 통신에 있는 예제에서는 DCC 폴링 방식을 보여 줍니다. Embedded ICE 논리의 COMMRX 및 COMMTX 신호를 인터럽트 컨트롤러에 연결하여 이러한 예제를 인터럽트 구동 예제로 변환할 수 있습니다.

그런 다음 8-5페이지의 예제 8-1과 8-7페이지의 예제 8-2에 있는 읽기 및 쓰기 코드를 인터럽트 처리기로 이동할 수 있습니다.

인터럽트 처리기 작성에 대한 자세한 내용은 6-29페이지의 인터럽트 처리기를 참조하십시오.

8-8 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 181: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

디버그 통신 채널

8.5 Thumb 상태에서 액세스

ARMv6T2 이전의 프로세서에는 보조 프로세서 명령어가 없으므로 코어가 Thumb 상태에 있는 동안 디버그 통신 채널을 사용할 수 없습니다.

다음 세 가지 방법으로 이 문제를 해결할 수 있습니다.

• SVC 처리기에 각 폴링 루틴을 작성하고 ARM 상태나 Thumb 상태에 있는 동안 해당 루틴을 실행할 수 있습니다. SVC 처리기가 시작되면 코어는 보조 프로세서 명령어를 사용할 수 있는 ARM 상태로 즉시 전환됩니다. SVC에 대한 자세한 내용은 6장 프로세서 예외 처리를 참조하십시오.

• Thumb 코드에서 인터워킹을 통해 폴링을 구현하는 ARM 하위 루틴을 호출할 수 있습니다. ARM 코드와 Thumb 코드를 함께 사용하는 데 대한 자세한 내용은 4장 ARM과 Thumb의 인터워킹을 참조하십시오.

• 폴링 방식 통신 대신 인터럽트 구동 통신을 사용합니다. 인터럽트 처리기는 ARM 명령어 세트 상태에서 실행되므로 보조 프로세서 명령어에 직접 액세스할 수 있습니다.

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. 8-9

Page 182: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

디버그 통신 채널

8-10 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 183: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

부록 A 세미호스팅

이 장에서는 세미호스팅 메커니즘에 대해 설명합니다. 여기에는 다음 단원이 포함되어 있습니다.

• A-2페이지의 세미호스팅 개요

• A-6페이지의 세미호스팅 구현

• A-8페이지의 세미호스팅 작업

• A-24페이지의 디버그 에이전트 상호작용 SVC

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. A-1

Page 184: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

세미호스팅

A.1 세미호스팅 개요

세미호스팅을 사용하면 ARM® 타겟에서 실행되는 코드에서 RealView® 디버거를 실행하는 호스트 컴퓨터의 I/O 기능을 사용할 수 있습니다. 이러한 기능의 예로는 키보드 입력, 화면 출력, 디스크 I/O 등이 포함됩니다.

A.1.1 세미호스팅이란?

세미호스팅은 ARM 타겟과 디버거를 실행 중인 호스트 컴퓨터 간에 응용 프로그램 코드의 I/O 요청을 전달하는 메커니즘입니다. 예를 들어 이 메커니즘을 사용하면 printf() 및 scanf()와 같은 C 라이브러리의 함수를 활성화하여 타겟 시스템에 화면과 키보드를 갖추는 대신 호스트의 화면과 키보드를 사용할 수 있습니다.

이는 개발 하드웨어가 최종 시스템의 입력 및 출력 기능을 빠짐없이 갖추지 못한 경우가 많으므로 유용합니다. 세미호스팅을 통해 호스트 컴퓨터가 이러한 기능을 제공할 수 있습니다.

세미호스팅은 프로그램 제어에서 예외를 생성하는 정의된 소프트웨어 명령어 세트(예: SVC)로 구현됩니다. 응용 프로그램이 적절한 세미호스팅 호출을 호출하면 디버그 에이전트가 예외를 처리합니다. 디버그 에이전트는 호스트와의 사이에 필요한 통신을 제공합니다.

세미호스팅 인터페이스는 ARM Limited에서 제공하는 모든 디버그 에이전트에서 공통입니다. 세미호스팅된 작업은 이식에 대한 아무 요구조건 없이 RealView ARMulator® ISS(RVISS), ISSM(명령어 세트 시스템 모델), RealView ICE 또는 RealMonitor를 사용할 경우 작동됩니다(A-3페이지의 그림 A-1 참조).

많은 경우, 세미호스팅은 라이브러리 함수 내부의 코드에서 호출됩니다. 응용 프로그램에서도 세미호스팅 작업을 직접 호출할 수 있습니다. ARM C 라이브러리의 세미호스팅 지원에 대한 자세한 내용은 라이브러리 설명서에서 2장 C 및 C++ 라이브러리를 참조하십시오.

A-2 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 185: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

세미호스팅

그림 A-1 세미호스팅 개요

참고

ARMv7 이전의 ARM 프로세서는 이전에 SWI 명령어라고 하던 SVC 명령어를 사용하여 세미호스팅 호출을 수행합니다. 그러나 Cortex-M1 또는 Cortex-M3과 같은 v6-M 또는 v7-M 프로세서용으로 컴파일할 경우 세미호스팅은 BKPT 명령어를 사용하여 구현됩니다.

A.1.2 세미호스팅 인터페이스

ARM 및 Thumb® SVC 명령어에는 응용 프로그램 코드에서 사용되는 SVC 번호가 인코딩되어 있는 필드가 있습니다. 시스템 SVC 처리기가 이 번호를 디코딩할 수 있습니다.

참고

Cortex-M1 또는 Cortex-M3과 같은 v6-M 또는 v7-M 프로세서용으로 컴파일할 경우 Thumb BKPT 명령어가 Thumb SVC 명령어 대신 사용됩니다. BKPT와 SVC는 모두 8비트 즉치값을 가져옵니다. 다른 모든 측면에서 세미호스팅은 지원되는 모든 ARM 프로세서에 대해 동일합니다.

��� ������������

���

����������������

����� � !�����

����"��������!���#$��$���

�����

�� #���������%��"���#$$� � #����$���"�&�

'�(����&���!�����"�&��&� ���

���#$$�

'� $��

)�&�

��� ��

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. A-3

Page 186: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

세미호스팅

세미호스팅 작업은 단일 SVC 번호를 통해 요청되므로 응용 프로그램 또는 운영 체제가 기타 번호를 사용할 수 있게 됩니다. 세미호스팅에 사용되는 SVC 번호는 타겟 아키텍처나 프로세서에 따라 다릅니다.

SVC 0x123456 ARM 상태인 경우(모든 아키텍처 해당)

SVC 0xAB Thumb 상태(ARMv7-M 제외) 및 ARM 상태인 경우. 이 동작은 ARM 또는 타사의 일부 디버그 타겟에서는 보장되지 않습니다.

BKPT 0xAB ARMv7-M용(Thumb 상태만 해당)

A-5페이지의 세미호스팅 작업 번호 변경도 참조하십시오.

SVC 번호는 디버그 에이전트에 SVC 명령어가 세미호스팅 요청임을 표시합니다. 작업 간 구분을 위해 작업 유형이 r0으로 전달됩니다. 다른 모든 매개변수는 r1이 가리키는 블록으로 전달됩니다.

결과는 명시적 반환 값 또는 데이터 블록에 대한 포인터로 r0에 반환됩니다. 결과가 반환되지 않더라도 r0이 손상되었다고 가정합니다.

r0으로 전달되는 사용 가능한 세미호스팅 작업 번호는 다음과 같이 할당됩니다.

0x00-0x31 ARM이 사용합니다.

0x32-0xFF ARM의 향후 사용을 위해 예약됩니다.

0x100-0x1FF 사용자 응용 프로그램을 위해 예약됩니다. ARM은 이러한 번호를 사용하지 않습니다.

그러나 자체 SVC 작업을 작성하는 중이라면 세미호스팅된 SVC 번호와 이들 작업 유형 번호를 사용하기보다 다른 SVC 번호를 사용하는 것이 좋습니다.

0x200-0xFFFFFFFF

정의되지 않았으며 현재 사용되지 않습니다. 이 번호는 사용하지 않는 것이 좋습니다.

다음 단원에서 작업 이름 뒤의 괄호 안 번호는 r0으로 배치되는 값입니다(예: SYS_OPEN(0x01)).

어셈블리 언어 코드에서 SVC를 호출하는 경우, ARM은 semihost.h에 정의된 작업 이름을 사용하는 것이 좋습니다. 이 파일은 RealView ARMulator Extension Kit의 일부로 설치됩니다. EQU 지시문으로 작업 이름을 정의할 수 있습니다. 예를 들면 다음과 같습니다.

A-4 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 187: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

세미호스팅

SYS_OPEN EQU 0x01SYS_CLOSE EQU 0x02

세미호스팅 작업 번호 변경

세미호스팅 작업 번호를 변경하지 않는 것이 좋습니다. 변경하는 경우에는 반드시 다음과 같이 해야 합니다.

• 새 번호를 사용하도록 라이브러리 코드를 포함한 모든 시스템 코드 변경

• 새 번호를 사용하도록 디버거 재구성

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. A-5

Page 188: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

세미호스팅

A.2 세미호스팅 구현

세미호스팅이 제공하는 기능은 일반적으로 모든 디버그 에이전트에서 동일합니다. 그러나 세미호스팅의 구현은 호스트별로 다릅니다.

이 단원에서는 다양한 디버그 에이전트별 세미호스팅 구현에 대해 설명합니다.

A.2.1 RealView ARMulator ISS

세미호스팅 요청이 나타나면 RVISS가 SVC를 직접 트래핑하고 벡터 테이블의 SVC 엔트리에 있는 명령어는 실행되지 않습니다.

RVISS에서 세미호스팅 지원을 해제하려면 default.ami 파일의 Default_Semihost를 No_Semihost로 변경합니다.

자세한 내용은 RealView ARMulator ISS 사용 설명서를 참조하십시오.

A.2.2 RealView ICE

RealView ICE DLL을 사용하는 경우 세미호스팅은 실제 SVC 예외 처리기로 처리되거나, 브레이크포인트를 사용하여 처리기를 에뮬레이션하여 처리됩니다. RealView ICE를 사용하는 세미호스팅에 대한 자세한 내용은 RealView ICE 및 RealView 트레이스 사용 설명서를 참조하십시오.

A.2.3 명령어 세트 시스템 모델

세미호스팅 요청이 나타나면 ISSM에서 요청을 직접 트래핑하고 벡터 테이블의 SVC 엔트리에 있는 명령어는 실행되지 않습니다. ISSM을 사용하는 세미호스팅에 대한 자세한 내용은 디버거 설명서를 참조하십시오.

ISSM에서 세미호스팅 지원을 해제하려면 디버거에서 타겟을 구성하거나 default.smc 파일의 해당 엔트리를 변경하십시오.

...Name="semihosting-enable" Type="Bool">1</param>

A-6 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 189: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

세미호스팅

A.2.4 RealMonitor

RealMonitor는 시스템과 함께 통합되어야만 세미호스팅을 지원할 수 있는 SVC 처리기를 구현합니다.

타겟이 세미호스팅된 SVC 명령어를 실행하면 RealMonitor SVC 처리기가 호스트와의 사이에 필요한 통신을 수행합니다.

자세한 내용은 RealMonitor와 함께 제공되는 설명서를 참조하십시오.

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. A-7

Page 190: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

세미호스팅

A.3 세미호스팅 작업

이 단원에서는 호스트 컴퓨터와 ARM 타겟 간의 디버그 I/O 기능을 사용할 수 있도록 하는 세미호스팅 작업에 대해 설명합니다.

A.3.1 angel_SWIreason_EnterSVC (0x17)

프로세서를 관리자 모드로 설정하고 새 CPSR의 두 인터럽트 마스크 비트를 모두 설정하여 모든 인터럽트를 비활성화합니다. RealView ICE 또는 RealMonitor를 사용하면 사용자 스택 포인터(r13_USR)가 관리자 스택 포인터(r13_SVC)로 복사되고, 현재 CPSR의 I 및 F 비트가 설정되어 일반 및 고속 인터럽트를 비활성화합니다.

참고

RVISS를 사용하는 디버깅의 경우

• r0이 0으로 설정되어, 사용자 모드로 복귀하기 위해 사용할 수 있는 함수가 없음을 나타냅니다.

• 사용자 모드 스택 포인터는 관리자 스택 포인터로 복사되지 않습니다.

시작

레지스터 r1은 사용되지 않습니다. CPSR이 사용자 또는 관리자 모드를 지정할 수 있습니다.

반환

종료 시 r0은 사용자 모드로 복귀하기 위해 호출할 함수의 주소를 포함합니다. 함수의 프로토타입은 다음과 같습니다.

void ReturnToUSR(void)

EnterSVC가 사용자 모드에서 호출되면 이 루틴이 호출자를 사용자 모드로 반환하고 인터럽트 플래그를 복원합니다. 그렇지 않으면 이 루틴의 작업이 정의되지 않은 것입니다.

사용자 모드에서 입력하면 사용자 스택 포인터를 복사한 결과 관리자 스택이 손실됩니다. 사용자 루틴으로 복귀하면 r13_SVC가 관리자 모드 스택 값으로 복원되지만 이 스택은 응용 프로그램에서 사용하면 안 됩니다.

SVC를 실행한 후 현재 링크 레지스터는 r14_USR이 아니라 r14_SVC입니다. 호출 후 r14_USR의 값이 필요하면 호출 전에 스택으로 푸시되고, 호출 후에는 팝되어야 합니다(BL 함수 호출에 관련된 경우).

A-8 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 191: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

세미호스팅

A.3.2 angel_SWIreason_ReportException (0x18)

이 SVC는 응용 프로그램에서 호출되어 디버거에 예외를 직접 보고할 수 있습니다. 가장 일반적인 용도는 ADP_Stopped_ApplicationExit를 사용하여 실행이 완료되었음을 보고하는 것입니다.

시작

시작 시 r1은 표 A-1 및 A-9페이지의 표 A-2에 나열된 값 중 하나로 설정됩니다. 이러한 값은 angel_reasons.h에 정의되어 있습니다.

하드웨어 예외는 디버거 변수 vector_catch가 예외 유형을 캐치하도록 설정되고 디버그 에이전트가 해당 예외 유형을 보고할 수 있을 경우에 생성됩니다.

예외 처리기는 기본 작업으로 처리기 체인 끝에서 이러한 SVC를 사용하여 예외가 처리되지 않았음을 나타낼 수 있습니다.

표 A-1 하드웨어 벡터 이유 코드

이름 16진수 값

ADP_Stopped_BranchThroughZero 0x20000

ADP_Stopped_UndefinedInstr 0x20001

ADP_Stopped_SoftwareInterrupt 0x20002

ADP_Stopped_PrefetchAbort 0x20003

ADP_Stopped_DataAbort 0x20004

ADP_Stopped_AddressException 0x20005

ADP_Stopped_IRQ 0x20006

ADP_Stopped_FIQ 0x20007

표 A-2 소프트웨어 이유 코드

이름 16진수 값

ADP_Stopped_BreakPoint 0x20020

ADP_Stopped_WatchPoint 0x20021

ADP_Stopped_StepComplete 0x20022

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. A-9

Page 192: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

세미호스팅

표 A-2에서 값 옆에 * 기호가 있으면 ARM 디버거에서 지원하지 않는 값이라는 뜻입니다. 디버거는 이러한 값에 대해 Unhandled ADP_Stopped exception을 보고합니다.

반환

이러한 호출에서는 아무런 반환이 예상되지 않습니다. 그러나 디버거가 RDI_Execute 요청이나 이에 상당하는 작업을 수행하여 응용 프로그램이 계속되도록 요청할 수 있습니다. 이 경우 레지스터가 SVC 시작 시에 있었거나 이후 디버거에 의해 수정되므로 레지스터 실행이 계속됩니다.

ADP_Stopped_RunTimeErrorUnknown *0x20023

ADP_Stopped_InternalError *0x20024

ADP_Stopped_UserInterruption 0x20025

ADP_Stopped_ApplicationExit 0x20026

ADP_Stopped_StackOverflow *0x20027

ADP_Stopped_DivisionByZero *0x20028

ADP_Stopped_OSSpecific *0x20029

표 A-2 소프트웨어 이유 코드 (계속)

이름 16진수 값

A-10 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 193: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

세미호스팅

A.3.3 SYS_CLOSE (0x02)

호스트 시스템에서 파일을 닫습니다. 핸들은 SYS_OPEN으로 열린 파일을 참조해야 합니다.

시작

시작 시 r1은 1워드 인수 블록에 대한 포인터를 포함합니다.

워드 1 열린 파일에 대한 핸들을 포함합니다.

반환

종료 시 r0에는 다음이 포함됩니다.

• 호출이 성공한 경우 0

• 호출이 성공하지 못한 경우 -1

A.3.4 SYS_CLOCK (0x10)

실행 시작 이후 경과된 100분의 1초 수를 반환합니다.

이 SVC가 반환한 값은 통신 오버헤드나 다른 에이전트 관련 요소 때문에 일부 벤치마킹 목적에 대해 사용이 제한될 수 있습니다. 예를 들어 RealView ICE를 사용하면 실행을 위해 요청이 호스트로 다시 전달됩니다. 따라서 전송 및 프로세스 일정에 예상치 않은 지연이 발생할 수 있습니다.

이 함수는 시간이 지정된 코드 순서가 있는 경우와 없는 경우에 대해 각각의 간격 간 차이를 계산하여 시간 간격을 계산하는 데 사용합니다.

일부 시스템에서는 보다 정확한 타이밍을 제공할 수 있습니다(A-12페이지의 SYS_ELAPSED (0x30) 및 A-20페이지의 SYS_TICKFREQ (0x31) 참조).

시작

레지스터 r1은 0을 포함해야 합니다. 다른 매개변수는 없습니다.

반환

종료 시 r0에는 다음이 포함됩니다.

• 호출이 성공한 경우 특정한 임의 시작점 이후 경과한 100분의 1초 수

• 통신 오류 등으로 인해 호출이 성공하지 못한 경우 -1

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. A-11

Page 194: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

세미호스팅

A.3.5 SYS_ELAPSED (0x30)

실행 시작 이후 경과된 타겟 틱 수를 반환합니다. 틱 주기를 결정하려면 SYS_TICKFREQ를 사용하십시오.

시작

시작 시 r1은 경과된 틱 수 반환에 사용되는 2워드 데이터 블록을 가리킵니다.

워드 1 더블워드 값에서 최하위 워드

워드 2 최상위 워드

반환

종료 시:

• r1이 경과된 틱 수를 포함하는 더블워드를 가리킬 경우 r0은 -1을 포함합니다. RealView ICE는 이 SVC를 지원하지 않고 항상 r0에 -1을 반환합니다.

• r1은 경과된 틱 수를 포함하는 더블워드(하위 워드가 먼저)를 가리킵니다.

A.3.6 SYS_ERRNO (0x13)

세미호스팅 SVC의 호스트 구현과 관련된 C 라이브러리 errno 변수의 값을 반환합니다. errno 변수는 다음을 포함하는 여러 C 라이브러리 세미호스팅된 함수에 의해 설정될 수 있습니다.

• SYS_REMOVE

• SYS_OPEN

• SYS_CLOSE

• SYS_READ

• SYS_WRITE

• SYS_SEEK.

errno가 설정되었는지 여부와 어떤 값으로 설정되었는지 여부는 ISO C 표준이 동작을 정의하는 경우를 제외하고 전적으로 호스트에 따라 다릅니다.

시작

매개변수가 없습니다. 레지스터r1은 0이어야 합니다.

A-12 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 195: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

세미호스팅

반환

종료 시 r0은 C 라이브러리 errno 변수의 값을 포함합니다.

A.3.7 SYS_FLEN (0x0C)

지정된 파일의 길이를 반환합니다.

시작

시작 시 r1은 1워드 인수 블록에 대한 포인터를 포함합니다.

워드 1 이전에 열린 검색 가능한 파일 개체에 대한 핸들

반환

종료 시 r0에는 다음이 포함됩니다.

• 호출이 성공한 경우 파일 개체의 현재 길이

• 오류가 발생한 경우 -1

A.3.8 SYS_GET_CMDLINE (0x15)

실행 가능 파일 호출에 사용되는 명령 행(즉 argc 및 argv)을 반환합니다.

시작

시작 시 r1은 명령 문자열 및 해당 문자열의 길이 반환에 사용되는 2워드 데이터 블록을 가리킵니다.

워드 1 워드 2에 지정된 크기 이상의 버퍼에 대한 포인터

워드 2 버퍼의 길이(바이트)

반환

종료 시:

• 레지스터 r1은 2워드 데이터 블록을 가리킵니다.

워드 1 명령 행의 Null로 끝나는 문자열에 대한 포인터

워드 2 문자열의 길이

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. A-13

Page 196: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

세미호스팅

디버그 에이전트가 전송 가능한 문자열의 최대 길이에 제한을 둘 수 있습니다. 그러나 에이전트는 최소한 80바이트의 명령 행을 전송할 수 있어야 합니다.

• 레지스터 r0은 다음 오류 코드를 포함합니다.

— 호출이 성공한 경우 0

— 통신 오류 등으로 인해 호출이 성공하지 못한 경우 -1

A.3.9 SYS_HEAPINFO (0x16)

시스템 스택 및 힙 매개변수를 반환합니다. 반환된 값은 일반적으로 초기화 중에 C 라이브러리가 사용하는 값입니다. RVISS의 경우 반환되는 값은 peripherals.ami에 제공된 값입니다. RealView ICE의 경우에 반환되는 값은 이미지 위치 및 메모리의 최상위입니다.

C 라이브러리는 이러한 값을 무시할 수 있습니다. C 라이브러리의 메모리 관리에 대한 자세한 내용은 라이브러리 설명서에서 2-90페이지의 스토리지 관리 조정을 참조하십시오.

호스트 디버거는 top_of_memory 디버거 변수를 사용하여 반환할 실제 값을 결정합니다.

시작

시작 시 r1은 4워드 데이터 블록에 대한 포인터의 주소를 포함합니다. 데이터 블록의 내용은 함수가 채웁니다. 데이터 블록의 구조와 반환 값에 대해서는 예제 A-1을 참조하십시오.

예제 A-1

struct block { int heap_base; int heap_limit; int stack_base; int stack_limit;};struct block *mem_block, info;mem_block = &info;AngelSWI(SYS_HEAPINFO, (unsigned) &mem_block);

A-14 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 197: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

세미호스팅

참고

데이터 블록의 워드 1 값이 0이면 C 라이브러리가 0을 Image$$ZI$$Limit로 바꿉니다. 이 값은 메모리 맵에 있는 데이터 영역의 최상위에 해당합니다.

반환

종료 시 r1은 구조체에 대한 포인터의 주소를 포함합니다.

구조체의 값 중 하나가 0인 경우 시스템이 실제 값을 계산하지 못한 것입니다.

A.3.10 SYS_ISERROR (0x08)

다른 세미호스팅 호출에서의 반환 코드가 오류 상태인지 여부를 결정합니다. 이 호출은 검사할 오류 코드를 포함하는 매개변수 블록에 전달됩니다.

시작

시작 시 r1은 1워드 데이터 블록에 대한 포인터를 포함합니다.

워드 1 확인할 필수 상태 워드입니다.

반환

종료 시 r0에는 다음이 포함됩니다.

• 상태 워드가 오류를 나타내지 않을 경우 0

• 상태 워드가 오류를 나타낼 경우 0이 아닌 값

A.3.11 SYS_ISTTY (0x09)

파일이 대화형 장치에 연결되었는지 확인합니다.

시작

시작 시 r1은 1워드 인수 블록에 대한 포인터를 포함합니다.

워드 1 이전에 열린 파일 개체에 대한 핸들

반환

종료 시 r0에는 다음이 포함됩니다.

• 핸들이 대화형 장치를 식별할 경우 1

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. A-15

Page 198: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

세미호스팅

• 핸들이 파일을 식별할 경우 0

• 오류가 발생한 경우 1이나 0이 아닌 값

A.3.12 SYS_OPEN (0x01)

호스트 시스템에서 파일을 엽니다. 파일 경로는 호스트 프로세스의 현재 디렉토리에 대한 상대 경로 또는 호스트 운영 체제의 경로 규칙을 사용하는 절대 경로로 지정됩니다.

ARM 타겟이 특수 경로 이름 :tt를 콘솔 입력 스트림(열기- 읽기용) 또는 콘솔 출력 스트림(열기- 쓰기용)으로 해석합니다. 이러한 스트림 열기는 C stdio 스트림을 참조하는 해당 응용 프로그램의 표준 시작 코드의 일부로 수행됩니다.

시작

시작 시 r1은 3워드 인수 블록에 대한 포인터를 포함합니다:

워드 1 파일 또는 장치 이름을 포함하는 Null로 끝나는 문자열에 대한 포인터

워드 2 파일 열기 모드를 지정하는 정수. 표 A-3에서는 정수 및 해당 ISO C fopen() 모드에 대한 유효한 값을 제공합니다.

워드 3 워드 1이 가리키는 문자열의 길이를 나타내는 정수

길이에는 반드시 있어야 하는 마지막 Null 문자는 포함되지 않습니다.

반환

종료 시 r0에는 다음이 포함됩니다.

• 호출이 성공한 경우 0이 아닌 핸들

• 호출이 성공하지 못한 경우 -1

표 A-3 모드 값

모드 0 1 2 3 4 5 6 7 8 9 10 11

ISO C fopen 모드a r rb r+ r+b w wb w+ w+b a ab a+ a+b

a. 비ANSI 옵션 t는 지원되지 않습니다.

A-16 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 199: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

세미호스팅

A.3.13 SYS_READ (0x06)

버퍼로 파일 내용을 읽습니다. 파일 위치는 다음 중 한 가지 방식으로 지정됩니다.

• SYS_SEEK 사용(명시적)

• 이전 SYS_READ 또는 SYS_WRITE 요청의 1바이트 위(암시적)

파일 위치는 파일이 열릴 때는 파일의 시작에 있고 파일이 닫힐 때는 손실됩니다. 가능하면 항상 파일 작업을 단일 작업으로 수행하십시오. 예를 들어 대안이 없는 경우가 아닌 한 16KB 읽기를 4개의 4KB 청크로 분할하지 마십시오.

시작

시작 시 r1은 4워드 데이터 블록에 대한 포인터를 포함합니다.

워드 1 이전에 SYS_OPEN으로 열린 파일에 대한 핸들을 포함합니다.

워드 2 버퍼를 가리킵니다.

워드 3 파일에서 버퍼로 읽을 바이트 수를 포함합니다.

반환

종료 시:

• r0은 호출이 성공한 경우 0을 포함합니다.

• r0에 워드 3과 동일한 값이 포함된 경우 호출은 실패했고 EOF가 가정된 것입니다.

• r0에 워드 3보다 작은 값이 포함된 경우 호출이 부분적으로 성공한 것입니다. 오류는 가정되지 않으나, 버퍼가 채워지지 않았습니다.

핸들이 대화형 장치용인 경우(즉 SYS_ISTTY가 이 핸들에 대해 -1을 반환). SYS_READ에서 0이 아닌 값이 반환되면 행 읽기가 버퍼를 채우지 않았음을 나타냅니다.

A.3.14 SYS_READC (0x07)

콘솔에서 바이트를 읽습니다.

시작

레지스터 r1은 0을 포함해야 합니다. 다른 매개변수나 값은 가능하지 않습니다.

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. A-17

Page 200: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

세미호스팅

반환

종료 시 r0은 콘솔에서 읽은 바이트를 포함합니다.

A.3.15 SYS_REMOVE (0x0E)

주의

호스트 파일링 시스템의 지정된 파일을 삭제합니다.

시작

시작 시 r1은 2워드 인수 블록에 대한 포인터를 포함합니다.

워드 1 삭제할 파일의 경로 이름을 제공하는 Null로 끝나는 문자열을 가리킵니다.

워드 2 문자열의 길이

반환

종료 시 r0에는 다음이 포함됩니다.

• 성공적으로 삭제된 경우 0

• 삭제하지 못한 경우 0이 아닌 호스트별 오류 코드

A.3.16 SYS_RENAME (0x0F)

지정된 파일의 이름을 바꿉니다.

시작

시작 시 r1은 4워드 데이터 블록에 대한 포인터를 포함합니다.

워드 1 이전 파일 이름에 대한 포인터

워드 2 이전 파일 이름의 길이

워드 3 새 파일 이름에 대한 포인터

워드 4 새 파일 이름의 길이

두 문자열 모두 Null로 끝납니다.

A-18 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 201: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

세미호스팅

반환

종료 시 r0에는 다음이 포함됩니다.

• 이름을 성공적으로 바꾼 경우 0

• 이름 바꾸기가 실패한 경우 0이 아닌 호스트별 오류 코드

A.3.17 SYS_SEEK (0x0A)

파일 시작부터 지정된 오프셋을 사용하여 파일에서 지정된 위치를 검색합니다. 파일은 바이트 배열로 가정되고 오프셋은 바이트 단위로 제공됩니다.

시작

시작 시 r1은 2워드 데이터 블록에 대한 포인터를 포함합니다.

워드 1 검색 가능한 파일 개체에 대한 핸들

워드 2 검색할 절대적 바이트 위치

반환

종료 시 r0에는 다음이 포함됩니다.

• 요청이 성공한 경우 0

• 요청이 성공하지 못한 경우 음수 값. SYS_ERRNO는 오류를 설명하는 호스트 errno 변수의 값을 읽는 데 사용할 수 있습니다.

참고

현재 파일 개체 범위 밖의 검색 효과는 정의되지 않습니다.

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. A-19

Page 202: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

세미호스팅

A.3.18 SYS_SYSTEM (0x12)

명령을 호스트 명령 행 인터프리터로 전달합니다. 그러면 dir, ls 또는 pwd와 같은 시스템 명령을 실행할 수 있습니다. 터미널 I/O는 호스트에 있으며 타겟에는 보이지 않습니다.

주의

호스트로 전달된 명령이 호스트에서 실행됩니다. 전달된 명령에 의도하지 않은 결과가 없도록 유의하십시오.

시작

시작 시 r1은 2워드 인수 블록에 대한 포인터를 포함합니다.

워드 1 호스트 명령 행 인터프리터로 전달할 문자열을 가리킵니다.

워드 2 문자열의 길이

반환

종료 시 r0은 반환 상태를 포함합니다.

A.3.19 SYS_TICKFREQ (0x31)

틱 주기를 반환합니다.

시작

레지스터 r1은 이 루틴의 시작 시 0을 포함해야 합니다.

반환

종료 시 r0은 다음 중 하나를 포함합니다.

• 1초 당 틱 수

• 타겟에서 틱 하나의 값을 모를 경우 -1. RealView ICE는 이 SVC를 지원하지 않고 항상 r0에 -1을 반환합니다.

A-20 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 203: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

세미호스팅

A.3.20 SYS_TIME (0x11)

1970년 1월 1일 00:00 이후 경과한 초 수를 반환합니다. 이것은 어떤 RVISS, ISSM 또는 RealView ICE 구성과도 무관한 실제 시간입니다.

시작

매개변수가 없습니다.

반환

종료 시 r0은 초 수를 포함합니다.

A.3.21 SYS_TMPNAM (0x0D)

시스템 파일 식별자에 의해 식별된 파일의 임시 이름을 반환합니다.

시작

시작 시 r1은 3워드 인수 블록에 대한 포인터를 포함합니다.

워드 1 버퍼에 대한 포인터

워드 2 이 파일 이름의 타겟 식별자. 값은 0 ~ 255 범위의 정수여야 합니다.

워드 3 버퍼의 길이를 포함합니다. 길이는 호스트 시스템의 L_tmpnam 값 이상이어야 합니다.

반환

종료 시 r0에는 다음이 포함됩니다.

• 호출이 성공한 경우 0

• 오류가 발생한 경우 -1

r1이 가리키는 버퍼에는 적합한 디렉토리 이름을 접두사로 붙인 파일 이름이 포함됩니다.

같은 타겟 식별자를 다시 사용하면 동일한 파일 이름이 반환됩니다.

참고

반환된 문자열은 Null로 끝나야 합니다.

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. A-21

Page 204: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

세미호스팅

A.3.22 SYS_WRITE (0x05)

현재 파일 위치에서 지정된 파일에 버퍼의 내용을 씁니다. 파일 위치는 다음 중 한 가지 방식으로 지정됩니다.

• SYS_SEEK 사용(명시적)

• 이전 SYS_READ 또는 SYS_WRITE 요청의 1바이트 위(암시적)

파일 위치는 파일이 열릴 때는 파일의 시작에 있고 파일이 닫힐 때는 손실됩니다.

가능하면 항상 파일 작업을 단일 작업으로 수행하십시오. 예를 들어, 대안이 없는 경우가 아닌 한 16KB 쓰기를 4개의 4KB 청크로 분할하지 마십시오.

시작

시작 시 r1은 3워드 데이터 블록에 대한 포인터를 포함합니다.

워드 1 이전에 SYS_OPEN으로 열린 파일에 대한 핸들을 포함합니다.

워드 2 작성할 데이터를 포함하는 메모리를 가리킵니다.

워드 3 버퍼에서 파일로 쓰일 바이트 수를 포함합니다.

반환

종료 시 r0에는 다음이 포함됩니다.

• 호출이 성공한 경우 0

• 오류가 있는 경우 쓰지 못한 바이트 수

A.3.23 SYS_WRITEC (0x03)

디버그 채널에 r1이 가리키는 문자 바이트를 씁니다. ARM 디버거에서 실행되면 문자가 호스트 디버거 콘솔에 나타납니다.

시작

시작 시 r1은 문자에 대한 포인터를 포함합니다.

반환

해당 사항이 없습니다. 레지스터 r0이 손상됩니다.

A-22 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK

Page 205: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

세미호스팅

A.3.24 SYS_WRITE0 (0x04)

디버그 채널에 Null로 끝나는 문자열을 씁니다. ARM 디버거에서 실행되면 문자가 호스트 디버거 콘솔에 나타납니다.

시작

시작 시 r1은 문자열의 첫 번째 바이트에 대한 포인터를 포함합니다.

반환

해당 사항이 없습니다. 레지스터 r0이 손상됩니다.

ARM DUI 0203HK Copyright © 2002-2007 ARM Limited. All rights reserved. A-23

Page 206: RealView Compilation Tools Developer Guideinfocenter.arm.com/help/topic/com.arm.doc.dui0203hk/DUI0203HK_rvct_developer_guide.pdf7장 Cortex-M3 프로세서 예외 처리 이 장에서는

세미호스팅

A.4 디버그 에이전트 상호작용 SVC

A-8페이지의 세미호스팅 작업에서 설명하는 C 라이브러리 세미호스팅된 함수 외에도 다음 SVC가 디버그 에이전트와의 상호작용을 지원합니다.

• A-8페이지의 angel_SWIreason_EnterSVC (0x17)

• A-9페이지의 angel_SWIreason_ReportException (0x18)

A-24 Copyright © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0203HK