10.07.2015 Views

PDF version - ARM Information Center

PDF version - ARM Information Center

PDF version - ARM Information Center

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

RealViewCompilation Tools버전 4.0개발자 설명서Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved.<strong>ARM</strong> DUI 0203IK


RealView Compilation Tools개발자 설명서Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved.릴리스 정보이 설명서에서 변경된 내용은 다음과 같습니다.변경 내역날짜 발행판 기밀 상태 변경 내용2002년 8월 A 기밀 문서 아님 릴리스 1.22003년 1월 B 기밀 문서 아님 릴리스 2.02003년 9월 C 기밀 문서 아님 <strong>ARM</strong> RealView Developer Suite용 릴리스 2.0.12004년 1월 D 기밀 문서 아님 RealView Developer Suite용 릴리스 2.12004년 12월 E 기밀 문서 아님 RealView Developer Suite용 릴리스 2.22005년 5월 F 기밀 문서 아님 RealView Developer Suite용 릴리스 2.2 SP12006년 3월 G 기밀 문서 아님 RealView Development Suite용 릴리스 3.02007년 3월 H 기밀 문서 아님 RealView Development Suite용 릴리스 3.12008년 9월 I 기밀 문서 아님 RealView Development Suite용 릴리스 4.0소유권 고지 사항이 소유권 고지 사항의 아래 부분에서 달리 명시되지 않는 한 또는 표시가 있는 단어와 로고는 EU,대한민국 및 기타 국가에서 <strong>ARM</strong> Limited의 등록 상표 또는 상표입니다. 이 설명서에 언급된 기타 브랜드와 이름은 해당 소유자의 상표일 수 있습니다.이 설명서에 포함된 전체 또는 일부 정보나 설명된 제품은 해당 저작권 소유자의 사전 서면 승인 없이는 어떤 형태로도 개조되거나 복제될 수 없습니다.이 설명서에 설명된 제품은 지속적으로 개발 및 개선될 수 있습니다. 이 설명서에 포함된 모든 제품명세와 해당 사용법은 <strong>ARM</strong>의 신뢰하에 제공됩니다. 그러나 <strong>ARM</strong>에서는 상품성 또는 특정 목적에의적합성을 비롯하여 그 밖의 묵시적이거나 명시적인 모든 보증을 부인합니다.이 설명서는 제품 사용자를 지원하는 용도로만 만들어졌습니다. <strong>ARM</strong>은 이 설명서 정보의 사용, 정보의 오류나 누락 또는 제품의 잘못된 사용에 따른 어떠한 손실이나 손상도 책임지지 않습니다.<strong>ARM</strong>이라는 단어가 사용되는 경우 "<strong>ARM</strong>이나 해당하는 자회사"를 의미합니다.ii Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


기밀 상태이 설명서는 기밀 문서가 아닙니다. 이 설명서의 사용, 복사 및 공개 권한은 <strong>ARM</strong>과 설명서 사용 당사자의 동의하에 라이센스 제한을 받습니다.액세스 제한 없음은 <strong>ARM</strong>의 내부 분류입니다.제품 상태이 설명서의 정보는 개발이 완료된 제품에 대한 최종 정보입니다.웹 주소http://www.arm.com<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. iiiUnrestricted AccessNon-Confidential


iv Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


목차RealView Compilation Tools개발자 설명서서문설명서 정보 .................................................................................................. viii사용자 의견 ................................................................................................... xii1 장 소개1.1 RealView Compilation Tools 개요 ............................................................... 1-21.2 예제 사용 ..................................................................................................... 1-32 장 <strong>ARM</strong> 프로세서용 소프트웨어 개발2.1 <strong>ARM</strong> 프로젝트 개요 .................................................................................... 2-22.2 <strong>ARM</strong> 아키텍처 v4T ...................................................................................... 2-82.3 <strong>ARM</strong> 아키텍처 v5TE ................................................................................. 2-102.4 <strong>ARM</strong> 아키텍처 v6 ...................................................................................... 2-122.5 <strong>ARM</strong> 아키텍처 v6-M .................................................................................. 2-162.6 <strong>ARM</strong> 아키텍처 v7-A .................................................................................. 2-182.7 <strong>ARM</strong> 아키텍처 v7-R .................................................................................. 2-202.8 <strong>ARM</strong> 아키텍처 v7-M .................................................................................. 2-22<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. vUnrestricted AccessNon-Confidential


목차3 장 임베디드 소프트웨어 개발3.1 임베디드 소프트웨어 개발 개요 .................................................................. 3-23.2 기본 컴파일 도구 동작 ................................................................................ 3-43.3 타겟 하드웨어에 맞게 C 라이브러리 조정 .................................................. 3-93.4 타겟 하드웨어에 맞게 이미지 메모리 맵 조정 ........................................... 3-113.5 리셋 및 초기화 .......................................................................................... 3-163.6 타겟 하드웨어 및 메모리 맵 ...................................................................... 3-234 장 C, C++ 및 어셈블리 언어 조합4.1 명령어 내장 함수 , 인라인 어셈블러 및 임베디드 어셈블러 사용 ................ 4-24.2 어셈블리 코드에서 C 전역 변수 액세스 ...................................................... 4-44.3 C++ 에서 C 헤더 파일 사용 ........................................................................ 4-54.4 C, C++ 및 <strong>ARM</strong> 어셈블리 언어 간 호출 ...................................................... 4-75 장 <strong>ARM</strong> 과 Thumb 의 인터워킹5.1 인터워킹 개요 ............................................................................................. 5-25.2 어셈블리 언어 인터워킹 .............................................................................. 5-55.3 C 및 C++ 인터워킹 ..................................................................................... 5-65.4 인터워킹 예제 ............................................................................................. 5-86 장 프로세서 예외 처리6.1 프로세서 예외 개요 ..................................................................................... 6-26.2 <strong>ARM</strong>v6 이하 , <strong>ARM</strong>v7-A 및 <strong>ARM</strong>v7-R 프로필 ............................................ 6-46.3 <strong>ARM</strong>v6-M 및 <strong>ARM</strong>v7-M 프로필 ................................................................ 6-327 장 디버그 통신 채널7.1 디버그 통신 채널 개요 ................................................................................ 7-27.2 타겟 및 호스트 디버그 도구 간의 DCC 통신 ............................................... 7-37.3 Thumb 상태에서 액세스 ............................................................................. 7-68 장 세미호스팅8.1 세미호스팅 개요 ......................................................................................... 8-28.2 세미호스팅 구현 ......................................................................................... 8-68.3 세미호스팅 작업 ......................................................................................... 8-88.4 디버그 에이전트 상호작용 SVC ................................................................ 8-26vi Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


서문이 서문에서는 <strong>ARM</strong> RealView Compilation Tools 개발자 설명서에 대해 소개합니다. 이 서문은 다음 단원으로 구성되어 있습니다.• viii페이지의 설명서 정보• xii페이지의 사용자 의견<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. viiUnrestricted AccessNon-Confidential


서문설명서 정보이 설명서에는 <strong>ARM</strong> 프로세서 제품군용 코드 개발에 도움이 되는 정보가 포함되어 있습니다. 이 설명서의 각 장과 사용된 예제에서는 사용자가 최신 릴리스의<strong>ARM</strong> RealView Compilation Tools를 사용하여 코드를 개발한다고 가정합니다.대상 독자이 설명서는 RealView Compilation Tools를 사용하여 응용 프로그램을 만드는 모든 개발자를 위한 것입니다. 여기에서는 사용자가 경험 있는 소프트웨어 개발자이고 RealView Compilation Tools 핵심 설명서에 설명된 <strong>ARM</strong> 도구에 익숙하다고가정합니다.설명서 사용이 설명서는 다음 장으로 구성되어 있습니다.1장 소개이 장에서는 RealView Compilation Tools에 대해 간략히 소개합니다.2장 <strong>ARM</strong> 프로세서용 소프트웨어 개발이 장에서는 각 아키텍처 유형의 주요 기능에 대해 설명하고RealView Compilation Tools를 사용할 때 주의해야 할 몇 가지 요점에대해 살펴봅니다.3장 임베디드 소프트웨어 개발이 장에서는 RealView Compilation Tools를 사용하여 임베디드 응용프로그램을 개발하는 방법을 자세히 설명합니다. 또한 타겟 시스템이 없을 때의 기본 RealView Compilation Tools 동작과 C 라이브러리및 이미지 메모리 맵을 타겟 시스템에 맞게 조정하는 방법에 대해 설명합니다.4장 C, C++ 및 어셈블리 언어 조합이 장에서는 <strong>ARM</strong> 아키텍처용으로 C, C++ 및 <strong>ARM</strong> 어셈블리 언어코드를 조합하여 작성하는 방법을 설명합니다. 또한 C와 C++ 파일에서 <strong>ARM</strong> 명령어 내장 함수, 인라인 어셈블러 및 임베디드 어셈블러를 사용하는 방법에 대해서도 설명합니다.viii Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


서문5장 <strong>ARM</strong>과 Thumb의 인터워킹이 장에서는 Thumb 명령어 세트를 구현하는 프로세서를 위한 코드를 작성할 때 <strong>ARM</strong> 상태와 Thumb 상태 사이에서 전환하는 방법을자세히 설명합니다.6장 프로세서 예외 처리이 장에서는 <strong>ARM</strong> 프로세서에서 지원하는 다양한 유형의 예외를 처리하는 방법을 자세히 설명합니다.7장 디버그 통신 채널이 장에서는 DCC (디버그 통신 채널) 를 사용하는 방법을 자세히 설명합니다.8장 세미호스팅이 장에서는 세미호스팅 메커니즘에 대해 설명합니다. 세미호스팅을 사용하면 <strong>ARM</strong> 타겟에서 실행되는 코드에서 <strong>ARM</strong> 디버거를 실행하는 호스트 컴퓨터의 I/O 기능을 사용할 수 있습니다.이 설명서에서는 <strong>ARM</strong> 소프트웨어가 기본 위치에 설치되어 있다고 가정합니다. 예를 들어 Windows의 경우 기본 위치는 volume:\Program Files\<strong>ARM</strong>일 수 있습니다.경로 이름을 참조할 때 install_directory는 이 위치를 가리키는 것으로 가정합니다. 예를 들어 경로는 install_directory\Documentation\...과 같을 수 있습니다.<strong>ARM</strong> 소프트웨어를 다른 위치에 설치한 경우에는 이 위치를 변경해야 합니다.표기 규칙이 설명서에서는 다음과 같은 표기 규칙을 사용합니다.monospacemonospace명령, 파일 및 프로그램 이름, 소스 코드와 같이 키보드로 입력할 수있는 텍스트를 나타냅니다.명령 또는 옵션 대신 사용할 수 있는 약어를 나타냅니다. 밑줄이 그어진 텍스트는 전체 명령이나 옵션 이름 대신 입력할 수 있습니다.monospace italic명령 및 함수의 인수를 나타냅니다. 인수는 특정 값으로 대체할 수있습니다.고정 폭 굵은 글꼴외부 예제 코드가 사용될 경우 언어 키워드를 나타냅니다.<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. ixUnrestricted AccessNon-Confidential


서문기울임 글꼴 중요한 사항을 강조 표시하고, 특수 용어를 소개하며, 내부 상호 참조 및 인용 부분을 나타냅니다.굵은 글꼴메뉴 이름과 같은 인터페이스 요소를 강조 표시합니다. 적절한 경우설명 목록의 내용을 강조할 때와 <strong>ARM</strong> 프로세서 신호 이름을 표시할 때도 사용됩니다.추가 정보이 단원에는 <strong>ARM</strong> 계열 프로세서용 코드를 개발하는 데 대한 추가 정보를 제공하는 <strong>ARM</strong> Limited 및 타사 게시물 목록이 나와 있습니다.<strong>ARM</strong> Limited는 설명서의 내용을 정기적으로 업데이트하고 수정합니다.http://infocenter.arm.com/help/index.jsp에서 정오표, 추가 목록 및 <strong>ARM</strong> FAQ(질문과 대답) 를 참조하십시오.<strong>ARM</strong> 게시물이 설명서에는 <strong>ARM</strong> 계열 프로세서용 응용 프로그램 개발에 대한 일반적인 정보가 포함되어 있습니다. 이 제품군에 포함된 다른 게시물은 다음과 같습니다.• RVCT 핵심 설명서 (<strong>ARM</strong> DUI 0202)• RVCT 컴파일러 사용 설명서 (<strong>ARM</strong> DUI 0205)• RVCT 컴파일러 참조 설명서 (<strong>ARM</strong> DUI 0348)• RVCT 라이브러리 및 부동 소수점 지원 설명서 (<strong>ARM</strong> DUI 0349)• RVCT 링커 사용 설명서 (<strong>ARM</strong> DUI 0206)• RVCT 링커 참조 설명서 (<strong>ARM</strong> DUI 0381)• RVCT 유틸리티 설명서 (<strong>ARM</strong> DUI 0382)• RVCT 어셈블러 설명서 (<strong>ARM</strong> DUI 0204)<strong>ARM</strong>에서 지원하는 기본 표준, 소프트웨어 인터페이스 및 기타 표준에 대한 자세한 내용은 install_directory\Documentation\Specifications\...를 참조하십시오.또한 <strong>ARM</strong> 제품과 관련된 구체적인 내용은 다음 설명서를 참조하십시오.• <strong>ARM</strong> 아키텍처 참조 문서, <strong>ARM</strong>v7-A 및 <strong>ARM</strong>v7-R 에디션 (<strong>ARM</strong> DDI 0406)• <strong>ARM</strong>v7-M 아키텍처 참조 문서 (<strong>ARM</strong> DDI 0403)x Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


서문• <strong>ARM</strong>v6-M 아키텍처 참조 문서 (<strong>ARM</strong> DDI 0419)• <strong>ARM</strong> 아키텍처 참조 문서 (<strong>ARM</strong> DDI 0100)• 하드웨어 장치에 대한 <strong>ARM</strong> 데이터시트 또는 기술 참조 문서기타 게시물<strong>ARM</strong> 아키텍처에 대한 소개는 <strong>ARM</strong> 시스템 개발자 지침서: Designing andOptimizing System Software (Andrew N. Sloss 등 저, 씨랩시스 역, 사이텍미디어,2005년, ISBN 8955508395) 를 참조하십시오.<strong>ARM</strong> 프로세서를 사용하는 시스템온칩 (SoC) 디자이너와 <strong>ARM</strong> 아키텍처를 사용하여 작업하는 엔지니어에게 필수적인 안내서를 보려면 <strong>ARM</strong> system-on-chip 구조 (Steve Furber 저, 나종화 등 역, 홍릉과학출판사, 2005년, ISBN 8972833592) 를참조하십시오.<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. xiUnrestricted AccessNon-Confidential


서문사용자 의견RealView Compilation Tools와 해당 설명서에 대한 의견이 있으시면 <strong>ARM</strong> Limited에 알려 주시기 바랍니다.RealView Compilation Tools에 대한 사용자 의견RealView Compilation Tools와 관련된 문제가 있으시면 해당 공급업체에 문의하십시오. 문의 시 다음 사항을 함께 알려 주시면 보다 신속하고 유용한 답변을 받으실 수 있습니다.• 사용자 이름 및 회사• 제품 일련 번호• 사용 중인 릴리스 정보• 실행 중인 플랫폼의 세부 사항 (예: 하드웨어 플랫폼, 운영 체제 종류 및 버전)• 문제를 재현하는 작은 독립 실행형 코드 샘플• 의도한 결과와 실제로 발생한 결과에 대한 명확한 설명• 사용한 명령 (명령 행 옵션 포함)• 문제를 보여 주는 샘플 출력• 도구의 버전 문자열 (버전 번호 및 날짜 포함)설명서에 대한 사용자 의견이 설명서에 오류나 누락이 있으면 다음 사항을 기재하여 errata@arm.com으로 전자 메일을 보내 주시기 바랍니다.• 설명서 제목• 설명서 번호• 문의 내용에 해당하는 페이지 번호• 문제에 대한 간략한 설명추가 및 향상되었으면 하는 기능에 대한 일반적인 제안도 환영합니다.xii Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


1장소개이 장에서는 <strong>ARM</strong> RealView Compilation Tools에 대해 소개합니다.이 장에는 다음 단원이 포함되어 있습니다.• 1-2페이지의 RealView Compilation Tools 개요• 1-3페이지의 예제 사용<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 1-1Unrestricted AccessNon-Confidential


소개1.1 RealView Compilation Tools 개요RealView Compilation Tools는 응용 프로그램과 지원 설명서 및 예제로 구성된 제품군으로서, <strong>ARM</strong> 계열의 프로세서용 응용 프로그램을 작성하는 데 사용할 수 있습니다. RealView Compilation Tools를 사용하여 C, C++ 및 <strong>ARM</strong> 어셈블리 언어 프로그램을 빌드할 수 있습니다.이 설명서에는 <strong>ARM</strong> 프로세서용 코드 개발에 도움이 되는 정보가 포함되어 있습니다. 이 설명서의 각 장과 사용된 예제에서는 사용자가 최신 릴리스의 RealViewCompilation Tools를 사용하여 코드를 개발한다고 가정합니다.이전 릴리스에서 RealView Compilation Tools로 업그레이드하는 경우에는RealView Compilation Tools 핵심 설명서에서 이 릴리스의 새로운 기능과 향상된기능에 대한 정보를 읽어 보십시오.RealView Compilation Tools를 처음 사용하는 경우에는 다양한 <strong>ARM</strong> 도구의 개요및 개발 프로젝트에 이들 도구를 함께 사용하는 방법에 대해 소개하는 RealViewCompilation Tools 핵심 설명서를 참조하십시오.RealView Compilation Tools의 이전 릴리스에 대한 자세한 내용은 RealViewCompilation Tools 핵심 설명서에서 부록 A를 참조하십시오.RealView Compilation Tools 설명서 모음에서 <strong>ARM</strong> 어셈블러, <strong>ARM</strong> 컴파일러,<strong>ARM</strong> 링커 및 지원 소프트웨어에 대한 정보를 제공하는 다른 설명서의 목록을 보려면 x페이지의 <strong>ARM</strong> 게시물을 참조하십시오.1-2 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


소개1.2 예제 사용이 설명서에서는 Realview Development Suite에서 제공되는 예제를 사용합니다.이러한 예제는 예제 디렉토리인 install_directory\RVDS\Examples에 있습니다. 제공된 예제에 대한 요약 정보는 RealView Development Suite 시작 설명서를 참조하십시오.<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 1-3Unrestricted AccessNon-Confidential


소개1-4 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


2장<strong>ARM</strong> 프로세서용 소프트웨어 개발이 장에서는 각 아키텍처 버전의 주요 기능에 대해 설명하고 <strong>ARM</strong> RealViewCompilation Tools를 사용할 때 주의해야 할 몇 가지 요점에 대해 살펴봅니다.이 장에는 다음 단원이 포함되어 있습니다.• 2-2페이지의 <strong>ARM</strong> 프로젝트 개요• 2-8페이지의 <strong>ARM</strong> 아키텍처 v4T• 2-10페이지의 <strong>ARM</strong> 아키텍처 v5TE• 2-12페이지의 <strong>ARM</strong> 아키텍처 v6• 2-16페이지의 <strong>ARM</strong> 아키텍처 v6-M• 2-18페이지의 <strong>ARM</strong> 아키텍처 v7-A• 2-20페이지의 <strong>ARM</strong> 아키텍처 v7-R• 2-22페이지의 <strong>ARM</strong> 아키텍처 v7-M<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 2-1Unrestricted AccessNon-Confidential


<strong>ARM</strong> 프로세서용 소프트웨어 개발2.1 <strong>ARM</strong> 프로젝트 개요이 단원에서는 특정 프로세서용으로 코드를 개발할 때 주의해야 할 다양한 <strong>ARM</strong>아키텍처 및 관련 기능에 대해 간략히 설명합니다.<strong>ARM</strong> 아키텍처는 32비트 <strong>ARM</strong> 및 16비트 Thumb 명령어 세트 아키텍처를 지원하는 동시에 TCM (강하게 결합된 메모리) , 메모리 관리, SIMD (Single InstructionMultiple Data) 및 NEON 기술을 지원하기 위한 아키텍처 확장을 지원합니다.<strong>ARM</strong> 아키텍처는 갈수록 늘어나는 최신 응용 프로그램 개발자의 수요를 충족하기 위해 지속적으로 개선되는 동시에, 소프트웨어 개발의 기존 투자도 보호할 수있도록 역호환성도 유지합니다.자세한 내용은 해당 프로세서의 기술 참조 문서 또는 <strong>ARM</strong> 아키텍처 참조 문서를참조하십시오.표 2-1에는 <strong>ARM</strong> 프로세서의 몇 가지 주요 기능이 간략하게 설명되어 있습니다.표 2-1 주요 기능프로세서아키텍처강하게 결합된 메모리 (TightlyCoupledMemory)메모리 관리Thumb-2<strong>ARM</strong>7TDMI <strong>ARM</strong>v4T - - -<strong>ARM</strong>920T <strong>ARM</strong>v4T - MMU -<strong>ARM</strong>922T <strong>ARM</strong>v4T - MMU -<strong>ARM</strong>926EJ-S <strong>ARM</strong>v5TEJ 예 MMU -<strong>ARM</strong>946E-S <strong>ARM</strong>v5TE 예 MPU -<strong>ARM</strong>966E-S <strong>ARM</strong>v5TE 예 - -<strong>ARM</strong>11 MPCore <strong>ARM</strong>v6K - MMU -<strong>ARM</strong>1136J-S /<strong>ARM</strong>1136JF-S <strong>ARM</strong>v6K 예 MMU -<strong>ARM</strong>1156T2-S /<strong>ARM</strong>1156T2F-S<strong>ARM</strong>v6T2 예 MPU 예<strong>ARM</strong>1176JZ-S /<strong>ARM</strong>1176JZF-S <strong>ARM</strong>v6Z 예 MMU -2-2 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


<strong>ARM</strong> 프로세서용 소프트웨어 개발표 2-1 주요 기능 (계속)프로세서아키텍처강하게 결합된 메모리 (TightlyCoupledMemory)메모리 관리Thumb-2Cortex -M1 <strong>ARM</strong>v6-M 예 - -Cortex-A8 <strong>ARM</strong>v7-A - MMU 예Cortex-A9 <strong>ARM</strong>v7-A - MMU 예Cortex-R4 및 Cortex-R4F <strong>ARM</strong>v7-R 변수 MPU 예Cortex-M3 <strong>ARM</strong>v7-M - MMU (옵션) Thumb-2만 해당2.1.1 다중 처리 시스템<strong>ARM</strong> 아키텍처 v6K에는 최대 4개의 CPU 및 관련 하드웨어를 지원하는 최초의MPCore 프로세서가 도입되었습니다. 성능을 최적화하려면 응용 프로그램을 다중 처리 시스템에서 실행하도록 특수하게 설계해야 합니다. 예를 들어 특정 CPU를 단일 스레드 응용 프로그램에서 특정 작업만 수행하도록 지정하거나 다중 스레드 환경에서 병렬 처리되도록 사용할 수 있습니다. 효율성이 높은 다중 처리 시스템의 경우 전력 소비량과 발열 정도가 낮으며, CPU 가 하나뿐인 시스템에 비해반응성은 높은 반면, 복잡하므로 디버깅 작업은 더 어렵습니다.다중 처리 시스템을 설계할 때는 다음과 같은 몇 가지 항목을 고려해야 합니다.• LDREX/STREX를 통해 동기화를 수행함으로써 뮤텍스 또는 세마포를 만들어 중요 섹션 및 공유할 수 없는 리소스를 보호합니다.• 대칭 다중 처리를 위해 캐시 결합성을 적용합니다.• 별도의 스레드에서 반복 작업을 실행합니다.• 큰 작업을 여러 스레드로 분할하여 병렬로 실행합니다.• 초기 작업에 CP15 CPU ID 레지스터를 사용하여 기본 CPU를 설정합니다.• 인터럽트 우선순위를 지정합니다.• 인터럽트 발생 순서에 비트 마스킹을 사용합니다.• 타이머 또는 watchdog을 트리거하는 사이클 수를 구성합니다.<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 2-3Unrestricted AccessNon-Confidential


<strong>ARM</strong> 프로세서용 소프트웨어 개발참고이러한 작업은 보통 OS에서 처리합니다.2.1.2 강하게 결합된 메모리 (Tightly Coupled Memory)TCM은 TCM을 사용하도록 설정하는 경우 항상 유효한 연속 메모리 영역으로, 시스템 물리 메모리 맵의 일부분으로 사용됩니다. TCM을 동일한 물리 주소를 포함하는 외부 메모리 수준으로 백업할 필요는 없습니다. 이러한 이유로 인해 TCM은쓰기를 통해 캐시 가능한 것으로 표시된 메모리 영역의 캐시와는 다르게 동작합니다. 이러한 영역에서는 TCM에 포함된 메모리 위치에 쓰는 경우에도 외부 쓰기는 수행되지 않습니다.TCM은 프로세서가 예상할 수 없는 캐시 오류 발생 위험 없이 사용할 수 있는 저지연 메모리를 제공하는 데 사용됩니다. TCM을 사용하여 캐시가 반드시 정해져야 하는 실시간 작업 또는 인터럽트 처리 루틴 등의 중요 루틴을 보관할 수 있습니다. 또한 스크래치 패드 데이터, 해당 지역 속성이 캐시에 적합하지 않은 데이터 형식 및 인터럽트 스택과 같은 중요 데이터 구조체를 보관할 때도 TCM을 사용할 수 있습니다.TCM의 전체 아키텍처에 대한 설명을 보려면 <strong>ARM</strong> 아키텍처 참조 문서 및 해당프로세서의 기술 참조 문서를 참조하십시오.2.1.3 메모리 관리<strong>ARM</strong> 메모리 관리 옵션은 다음과 같습니다.MMUMPUMMU (Memory Management Unit) 를 사용하면 메모리 시스템을 세밀하게 제어할 수 있습니다. 대부분의 상세 제어 기능은 메모리에보관되어 있는 변환 테이블을 통해 제공됩니다. 이러한 테이블 항목은 다음과 같은 여러 메모리 영역의 속성을 정의합니다.• 가상 대 실제 주소 매핑• 메모리 액세스 권한• 메모리 형식MPU (Memory Protection Unit) 는 MMU에 비해 훨씬 간단하게 사용할 수 있습니다. 즉, MMU의 모든 기능을 필요로 하지 않는 시스템에서 하드웨어와 소프트웨어를 모두 간편하게 관리할 수 있습니다.2-4 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


<strong>ARM</strong> 프로세서용 소프트웨어 개발MPU를 사용하면 외부 메모리를 크기와 속성이 서로 다른 여러 연속 영역으로 분할할 수 있습니다. 또한 여러 메모리 영역의 액세스권한 및 메모리 특성도 제어할 수 있습니다.MPU는 변환 테이블에 대해 외부 메모리를 필요로 하지 않으며, 캐시를 사용하도록 설정하려면 MPU를 먼저 사용하도록 설정해야 합니다.MMU 또는 MPU의 전체 아키텍처에 대한 설명을 보려면 <strong>ARM</strong> 아키텍처 참조 문서 및 해당 프로세서의 기술 참조 문서를 참조하십시오.2.1.4 Thumb-2Thumb-2 기술은 <strong>ARM</strong>v6T2 이상 아키텍처에서 사용할 수 있으며, 16비트 Thumb명령어 세트가 대폭 향상된 것입니다. Thumb-2에서 제공하는 32비트 명령어를프로그램에서 16비트 명령어와 원하는 대로 조합할 수 있습니다. Thumb-2는 추가로 제공되는 32비트 명령어를 통해 <strong>ARM</strong> 명령어 세트의 해당하는 기능을 제공할 수 있습니다. 뿐만 아니라 이전 Thumb 버전 수준의 코드 밀도 및 <strong>ARM</strong> 명령어세트와 동일한 성능을 제공할 수 있습니다.Thumb-2 명령어 세트와 <strong>ARM</strong> 명령어 세트의 가장 중요한 차이점은, 대부분의 32비트 Thumb 명령어가 무조건 명령어인 반면 대부분의 <strong>ARM</strong> 명령어는 조건 명령어일 수 있다는 것입니다. Thumb-2에는 조건부 실행 명령어 IT가 도입되었습니다. 이 명령어는 후속 명령어에 적용하여 해당 명령어를 조건 명령으로 지정할 수있는 논리적 if-then-else 연산입니다.명령어 세트에 대한 자세한 내용은 <strong>ARM</strong> 아키텍처 참조 문서 또는 해당 프로세서의 기술 참조 문서를 참조하십시오.2.1.5 부동 소수점 빌드 옵션다음 지침은 응용 프로그램에 사용할 가장 적합한 부동 소수점 빌드 옵션을 선택하도록 지원하는 데 사용할 수 있습니다.<strong>ARM</strong> 및 Thumb 부동 소수점 (<strong>ARM</strong>v6 이하)<strong>ARM</strong> 상태 코드와 Thumb 상태 코드에서 부동 소수점 연산을 수행하는 코드를 컴파일하는 데 사용할 수 있는 옵션에는 여러 가지가 있습니다.<strong>ARM</strong>만 해당--fpu vfpv2 옵션을 선택하여 컴파일러에서 부동 소수점 연산이 포함된 함수에 대해서만 <strong>ARM</strong> 코드를 생성하게 합니다.<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 2-5Unrestricted AccessNon-Confidential


<strong>ARM</strong> 프로세서용 소프트웨어 개발혼합 <strong>ARM</strong>/Thumb--fpu vfpv2 옵션을 선택하면 컴파일 대상이 <strong>ARM</strong>인지 아니면Thumb인지 여부와 관계없이 부동 소수점 연산이 포함된 모든 함수에 대해 <strong>ARM</strong> 코드가 생성됩니다.Thumb 코드는 VFP 명령어를 포함할 수 없거나 VFP 레지스터에 액세스할 수 없기 때문에 부동 소수점 연산을 포함하고 Thumb에 대해컴파일된 함수는 <strong>ARM</strong> 코드로 컴파일됩니다. 이 작업에는 하드웨어VFP 연결이 사용됩니다.<strong>ARM</strong>에 대해서만 컴파일할 때는 --fpu=softvfp+vfp가 아닌 --fpu=vfp를 사용합니다. 소프트웨어를 연결하면 VFP와 <strong>ARM</strong> 간의 전송 값에오버헤드가 추가되어 전송 속도가 느려지며 추가 명령어가 필요합니다.--fpu softvfp+vfpv2 옵션을 선택하여 컴파일러에서 혼합된<strong>ARM</strong>/Thumb 코드를 생성하게 합니다.--fpu softvfp+vfpv2 옵션을 선택하면 모든 함수는 소프트웨어 부동소수점 연결을 사용하여 컴파일됩니다. 즉, 부동 소수점 인수는 정수 레지스터에서 함수로 전달되며 함수에서 반환됩니다.Thumb 명령어 세트는 VFP 명령어를 포함하지 않으므로 VFP 레지스터에 액세스할 수 없습니다. 따라서 Thumb 코드에 대해--fpu=softvfp+vfpv2를 사용하는 경우 컴파일러에서 VFP 연산을 수행하기 위해 라이브러리 함수에 대한 호출을 생성합니다. Thumb 코드는 하드웨어 연결을 사용하는 데 필요한 VFP 레지스터에 액세스할 수 없으므로, 이러한 라이브러리 함수는 소프트웨어 연결을 사용해야 합니다.RVCT 라이브러리는 <strong>ARM</strong>에 대해 컴파일되는 소프트웨어 부동 소수점 함수의 버전을 포함하며, --fpu=softvfp+vfpv2에 사용되는 VFP명령어를 사용합니다. 이러한 라이브러리 함수를 사용하는 경우 전체 소프트웨어 부동 소수점 함수에 비해 성능이 향상되며 코드 크기가 작아집니다.최상의 코드 크기 또는 성능을 제공하는 옵션은 컴파일되는 코드에 따라 다릅니다. <strong>ARM</strong>에 대해 컴파일할 때 --fpu softvfp+vfpv2 및 --fpu vfpv2 옵션 중 어느 것이 필요한 코드 크기와 성능 속성을 제공하는지 결정하는 것이 좋습니다.<strong>ARM</strong>과 Thumb을 혼합하여 사용하는 경우에는 --fpu 옵션을 사용하여 시험적으로 컴파일을 수행하면 최상의 결과를 얻을 수 있습니다.2-6 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


<strong>ARM</strong> 프로세서용 소프트웨어 개발<strong>ARM</strong>과 Thumb-2 부동 소수점 (<strong>ARM</strong>v7, RealView Development Suite 버전3.0 이상)혼합 <strong>ARM</strong>/Thumb-2<strong>ARM</strong>만 해당Thumb-2만 해당--fpu softvfp+vfpv3 옵션을 선택하여 컴파일러에서 혼합된<strong>ARM</strong>/Thumb 코드를 생성하게 합니다.--fpu softvfp+vfpv3 옵션을 선택하면 모든 함수는 소프트웨어 부동소수점 연결을 사용하여 컴파일됩니다. 부동 소수점 인수는 <strong>ARM</strong>정수 레지스터에서 함수로 전달되거나 함수에서 반환되었다는 것을 의미합니다.소프트웨어 부동 소수점 링키지를 사용하여 소프트웨어 부동 소수점 링키지로 자체 구축된 레거시 코드와 일반 라이브러리에 링크할수 있습니다.--arm --fpu vfpv3 옵션을 선택하여 컴파일러에서 <strong>ARM</strong> 코드만 생성하게 합니다. 이 작업에는 하드웨어 VFP 연결이 사용됩니다.--thumb --fpu vfpv3 옵션을 선택하여 컴파일러에서 전체 프로그램에 대해서만 Thumb-2 코드를 생성하게 합니다. Thumb-2에서는 VFP명령어를 지원하므로 VFP 연산을 수행하기 위해 <strong>ARM</strong> 상태로 전환할 필요가 없습니다. 이 작업에는 하드웨어 VFP 연결이 사용됩니다.참고이 옵션은 Cortex-A8과 같이 VFPv3이 있는 <strong>ARM</strong>v7 프로세서에만 사용할 수 있습니다. 여기서 VFP는 <strong>ARM</strong> 및 Thumb-2 명령어 세트를통해 직접 액세스할 수 있습니다.<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 2-7Unrestricted AccessNon-Confidential


<strong>ARM</strong> 프로세서용 소프트웨어 개발2.2 <strong>ARM</strong> 아키텍처 v4T이 단원에서는 <strong>ARM</strong>v4T에 대한 RealView 도구 지원에 대해 간략히 설명합니다.이 <strong>ARM</strong> 아키텍처 변형은 32비트 <strong>ARM</strong> 명령어 세트의 하위 세트인 16비트 Thumb명령어를 제공하며, <strong>ARM</strong> 및 Thumb 명령어 세트를 모두 지원합니다.표 2-2 유용한 명령 행 옵션명령 행 옵션--cpu=4T--cpu=name--apcs=qualifier설명Thumb이 있는 <strong>ARM</strong>v4여기서 name은 특정 <strong>ARM</strong> 프로세서입니다. 예를 들면 <strong>ARM</strong>7TDMI와 같습니다.qualifier는 인터워킹 및 위치 독립성을 위한 하나 이상의 한정자를 나타냅니다.예를 들어 --apcs=/interwork와 같습니다.2.2.1 주요 기능<strong>ARM</strong>v4T용 코드를 컴파일할 때 컴파일러는 보다 높은 코드 밀도를 위해 Thumb명령어를 추가로 지원하지만, 이 경우 다음과 같은 제한이 적용됩니다.• 일반적으로 Thumb 코드는 지정된 작업에 대해 더 많은 명령어를 사용하므로, 시간이 중요한 코드의 성능을 최대화하는 데는 <strong>ARM</strong> 코드가 가장 적합합니다.• 예외 처리에는 <strong>ARM</strong> 상태 및 관련 <strong>ARM</strong> 명령어가 필요합니다.2.2.2 정렬 지원모든 로드 및 저장 명령어는 기본 정렬 경계에 정렬된 주소를 지정해야 합니다.예를 들면 다음과 같습니다.• LDR 및 STR 주소는 단어 경계에 정렬되어야 합니다.• LDRH 및 STRH 주소는 하프워드 경계에 정렬되어야 합니다.• LDRB 및 STRB 주소는 모든 경계에 정렬할 수 있습니다.기본 정렬 경계에 있지 않은 주소에 액세스하면 예기치 않은 결과를 발생시킵니다. 이러한 동작을 제어하려면 정렬되지 않은 주소에 액세스할 때 컴파일러가 안전한 코드를 생성하도록 __packed 를 사용하여 컴파일러에 알려야 합니다. 자세한 내용은 컴파일러 참조 설명서에서 4-11페이지의 __packed를 참조하십시오.2-8 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


<strong>ARM</strong> 프로세서용 소프트웨어 개발참고허용되는 경우 정렬되지 않은 액세스는 회전된 정렬 액세스로 취급됩니다.2.2.3 엔디안 지원컴파일러 명령 행 옵션 --littleend 및 --bigend를 각각 사용하여 리틀엔디안 코드또는 빅엔디안 코드를 생성할 수 있습니다.<strong>ARM</strong>v4T에서는 다음과 같은 엔디안 모드를 지원합니다.LE 리틀엔디안 형식BE-32 레거시 빅엔디안 형식<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 2-9Unrestricted AccessNon-Confidential


<strong>ARM</strong> 프로세서용 소프트웨어 개발2.3 <strong>ARM</strong> 아키텍처 v5TE이 단원에서는 <strong>ARM</strong>v5TE에 대한 RealView 도구 지원에 대해 간략히 설명합니다.이 <strong>ARM</strong> 아키텍처 변형은 DSP (디지털 신호 처리) 알고리즘에 대한 향상된 산술지원을 제공하며, <strong>ARM</strong> 및 Thumb 명령어 세트를 모두 지원합니다.표 2-3 유용한 명령 행 옵션명령 행 옵션--cpu=5TE--cpu=5TEJ--cpu=name설명Thumb, 인터워킹, DSP 곱하기 및 더블워드 명령어가 있는 <strong>ARM</strong>v5Thumb, 인터워킹, DSP 곱하기, 더블워드 명령어 및 Jazelle 확장 a 이 있는 <strong>ARM</strong>v5여기서 name은 특정 <strong>ARM</strong> 프로세서입니다. 예를 들면 다음과 같습니다.• Thumb, Jazelle 확장, 물리적으로 매핑된 캐시 및 MMU가 있는 <strong>ARM</strong>v5용<strong>ARM</strong>926EJ-Sa. <strong>ARM</strong> 컴파일러에서는 Jazelle 바이트코드를 생성하지 않습니다.2.3.1 주요 기능<strong>ARM</strong>v5TE에 대한 코드를 컴파일할 때 컴파일러는 다음을 수행합니다.• <strong>ARM</strong>과 Thumb 코드 간의 향상된 인터워킹 (예: BLX) 을 지원합니다.• 지정된 프로세서에 대해 명령어 일정을 수행합니다. 인터록을 최소화하고성능을 향상시키기 위해 명령어 순서가 변경됩니다.• 16비트 데이터 항목에 적용되는 곱하기 및 곱하기 누산 명령어를사용합니다.• 명령어 내장 함수를 사용하여 부호 있는 포화 산술을 수행하는 더하기 및 빼기 명령어를 생성합니다. 포화 산술을 수행하면 계산이 일반 정수 범위에서오버플로되는 경우 결과를 래핑하는 대신 최대 양수 또는 음수 값을 생성합니다.• 두 단어로 된 데이터에 적용되는 로드 (LDRD) 및 저장 (STRD) 명령어를 사용합니다.• 사전 로드 데이터 명령어 PLD를 사용합니다.2-10 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


<strong>ARM</strong> 프로세서용 소프트웨어 개발2.3.2 정렬 지원모든 로드 및 저장 명령어는 기본 정렬 경계에 정렬된 주소를 지정해야 합니다.예를 들면 다음과 같습니다.• LDR 및 STR 주소는 단어 경계에 정렬되어야 합니다.• LDRH 및 STRH 주소는 하프워드 경계에 정렬되어야 합니다.• LDRD 및 STRD 주소는 더블워드 경계에 정렬되어야 합니다.• LDRB 및 STRB 주소는 모든 경계에 정렬할 수 있습니다.기본 정렬 경계에 있지 않은 주소에 액세스하면 예기치 않은 결과가 발생합니다. 이러한 동작을 제어하려면 정렬되지 않은 주소에 액세스할 때 컴파일러가 안전한코드를 생성하도록 __packed를 사용하여 컴파일러에 알려야 합니다. 자세한 내용은 컴파일러 참조 설명서에서 4-11페이지의 __packed를 참조하십시오.LDR 및 STR 명령어 (LDRD 및 STRD 제외) 는 단어로 정렬된 주소를 지정해야 하며, 그렇지 않으면 명령어가 중단됩니다.참고허용되는 경우 정렬되지 않은 액세스는 회전된 정렬 액세스로 취급됩니다.추가 참고• 해당 프로세서의 기술 참조 문서• 컴파일러 사용 설명서의 5-26페이지의 데이터 정렬• 컴파일러 참조 설명서의 2-122페이지의 --[no_]unaligned_access2.3.3 엔디안 지원컴파일러 명령 행 옵션 --littleend 및 --bigend를 각각 사용하여 리틀엔디안 코드또는 빅엔디안 코드를 생성할 수 있습니다.<strong>ARM</strong>v5TE에서는 다음과 같은 엔디안 모드를 지원합니다.LE 리틀엔디안 형식BE-32 레거시 빅엔디안 형식<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 2-11Unrestricted AccessNon-Confidential


<strong>ARM</strong> 프로세서용 소프트웨어 개발2.4 <strong>ARM</strong> 아키텍처 v6이 단원에서는 <strong>ARM</strong>v6에 대한 RealView 도구 지원에 대해 간략히 설명합니다. 이<strong>ARM</strong> 아키텍처 변형은 원래 <strong>ARM</strong> 명령어 세트를 확장하여 다중 처리를 지원하고메모리 모델 기능을 추가로 제공하며, <strong>ARM</strong> 및 Thumb 명령어 세트를 모두 지원합니다.표 2-4 유용한 명령 행 옵션옵션--cpu=6--cpu=6Z--cpu=6T2--cpu=name설명Thumb, 인터워킹, DSP 곱하기, 더블워드 명령어, 정렬되지 않은 혼합엔디안 지원, Jazelle및 미디어 확장이 있는 <strong>ARM</strong>v6보안 확장이 있는 <strong>ARM</strong>v6Thumb-2가 있는 <strong>ARM</strong>v6여기서 name은 특정 <strong>ARM</strong> 프로세서입니다. 예를 들면 다음과 같습니다.• 소프트웨어 VFP 지원이 포함된 <strong>ARM</strong>1136J-S용 코드를 생성하는 <strong>ARM</strong>1136J-S• 하드웨어 VFP가 포함된 <strong>ARM</strong>1136J-S용 코드를 생성하는 <strong>ARM</strong>1136JF-S2.4.1 주요 기능<strong>ARM</strong>v6에 대한 코드를 컴파일할 때 컴파일러는 다음을 수행합니다.• 지정된 프로세서에 대해 명령어 일정을 수행합니다. 인터록을 최소화하고성능을 향상시키기 위해 명령어 순서가 변경됩니다.• 적절한 경우 명시적인 SXTB, SXTH, UXTB, UXTH 바이트 또는 하프워드 확장 명령어를 생성합니다.• C 식이 엔디안 반전을 수행한다는 것을 추론할 수 있는 경우 엔디안 반전 명령어 REV, REV16 및 REVSH를 생성합니다.• <strong>ARM</strong>v6에서 사용할 수 있는 CPS, CPY, REV, REV16, REVSH, SETEND, SXTB, SXTH, UXTB,UXTH와 같은 Thumb 명령어를 추가로 생성합니다.• <strong>ARM</strong>v6용으로 특수하게 최적화된 일부 함수 (예: memcpy () ) 를 사용합니다.C 식에 제대로 매핑되지 않으므로 컴파일러는 SIMD 명령어를 생성할 수 없습니다. SIMD 코드를 생성하려면 어셈블리 언어 또는 내장 함수를 사용해야 합니다.2-12 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


<strong>ARM</strong> 프로세서용 소프트웨어 개발예외 처리를 개선하기 위한 몇 가지 향상된 명령어를 사용할 수 있습니다.• LR (링크 레지스터) 및 SPSR (저장된 프로그램 상태 레지스터) 을 저장 및복원하기 위한 SRS 및 RFE 명령어• CPSR (현재 프로그램 상태 레지스터) 의 I 및 F 비트 수정과 상태 변경 작업을 단순화하는 CPS• 벡터 인터럽트 컨트롤러를 사용하는 벡터 인터럽트에 대한 아키텍처 지원• 저지연 인터럽트 모드• Thumb-2 코드를 사용하여 Thumb 상태에서 예외를 입력할 수 있는<strong>ARM</strong>1156T2-S2.4.2 정렬 지원기본적으로 컴파일러는 LDR 및 STR 명령어가 기본 워드 경계에 정렬되지 않은 워드에서 로드하거나 그 워드에 저장하게 하여 패킹된 구조체에 대한 액세스 속도를 빠르게 하기 위해 정렬되지 않은 <strong>ARM</strong>v6 액세스 지원을 사용합니다. 구조체는__packed를 통해 명시적으로 한정하는 경우가 아니면 패킹되지 않습니다. 표 2-5에서는 <strong>ARM</strong>v6 및 이전 아키텍처에 대해 컴파일할 때 1바이트 정렬의 효과를 보여 줍니다.__packed struct{int i;char ch;short sh;} foo;표 2-5 1바이트 정렬<strong>ARM</strong>v6 이전 아키텍처용으로 컴파일:MOV R4,R0BL __aeabi_uread4LDRB R1, [R4,#4]LDRSB R2,[R4,#5]LDRB R12,[R4,#6]ORR R2,R12,R2 LSL#8<strong>ARM</strong>v6 이상 아키텍처용으로 컴파일:LDR R0, [R4,#0]LDRB R1,[R4,#4]LDRSH R2,[R4,#5]프로세서에서 정렬되지 않은 데이터 액세스 지원을 사용하도록 설정하는 경우에만 <strong>ARM</strong>v6 용으로 컴파일된 코드가 올바르게 실행됩니다. CP15 레지스터 c1의 U및 A 비트를 사용하거나, 프로세서에 대한 UBITINIT 입력을 HIGH로 입력하여 정렬을 제어할 수 있습니다.<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 2-13Unrestricted AccessNon-Confidential


<strong>ARM</strong> 프로세서용 소프트웨어 개발<strong>ARM</strong>v6 이전의 정렬되지 않은 데이터 액세스 동작을 사용하는 코드는 컴파일러옵션 --no_unaligned_access를 사용하여 생성할 수 있습니다.참고BE-32 엔디안 모드에서는 정렬되지 않은 데이터 액세스를 사용할 수 없습니다.LDRD 및 STRD는 워드로 정렬할 수 있습니다.추가 참고• 해당 프로세서의 기술 참조 문서• 컴파일러 사용 설명서의 5-26페이지의 데이터 정렬• 컴파일러 참조 설명서의 2-122페이지의 --[no_]unaligned_access2.4.3 엔디안 지원컴파일러 명령 행 옵션 --littleend 및 --bigend를 각각 사용하여 리틀엔디안 코드또는 빅엔디안 코드를 생성할 수 있습니다.<strong>ARM</strong>v6에서는 다음과 같은 엔디안 모드를 지원합니다.LE 리틀엔디안 형식BE8 빅엔디안 형식BE-32 레거시 빅엔디안 형식SETEND 및 REV 명령어를 사용하여 혼합된 엔디안 시스템을 구성할 수도 있습니다.<strong>ARM</strong>v6 엔디안 모드 BE8용으로 컴파일기본적으로 컴파일러는 <strong>ARM</strong>v6 및 빅엔디안용으로 컴파일할 때 BE8 빅엔디안코드를 생성합니다. 컴파일러는 코드를 BE8로 레이블을 지정하는 플래그를 코드에 설정합니다. 따라서 <strong>ARM</strong> 프로세서에서 BE8 지원을 사용하도록 설정하려면일반적으로 CPSR에서 E 비트를 설정해야 합니다.<strong>ARM</strong>v6 기반 프로세서에서 실행하도록 레거시 코드를 <strong>ARM</strong>v6 코드에 링크할 수있습니다. 그러나 이 경우 링커는 레거시 코드의 바이트 순서를 BE8 모드로 전환합니다. 그 결과로 생성되는 이미지는 BE8 모드 상태입니다.2-14 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


<strong>ARM</strong> 프로세서용 소프트웨어 개발<strong>ARM</strong>v6 레거시 엔디안 모드 BE32용으로 컴파일<strong>ARM</strong>v6 이전 또는 레거시 BE32 모드를 사용하려면 BIGENDINIT 입력을 프로세서HIGH에 연결하거나 CP 15 레지스터 c1의 B 비트를 설정해야 합니다.참고링커 옵션 --be32를 사용하여 BE32 호환 코드를 링크해야 합니다. 그렇지 않으면<strong>ARM</strong>v6 속성에 의해 BE8 이미지가 생성됩니다.자세한 내용은 다음 항목을 참조하십시오.• 2-13페이지의 정렬 지원• 컴파일러 참조 설명서의 2-17페이지의 --bigend• 컴파일러 참조 설명서의 2-81페이지의 --littleend• 컴파일러 참조 설명서의 2-122페이지의 --[no_]unaligned_access• 링커 참조 설명서의 2-5페이지의 --be8• 링커 참조 설명서의 2-5페이지의 --be32<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 2-15Unrestricted AccessNon-Confidential


<strong>ARM</strong> 프로세서용 소프트웨어 개발2.5 <strong>ARM</strong> 아키텍처 v6-M이 단원에서는 <strong>ARM</strong>v6-M에 대한 RealView 도구 지원에 대해 간략히 설명합니다.마이크로컨트롤러 프로필은 고속 인터럽트 처리용으로 설계된 프로그래머 모델을 구현합니다. 이 모델은 레지스터의 하드웨어 스택과 상위 언어를 사용한 인터럽트 처리기 작성 지원을 포함합니다. 이 모델은 FPGA에 통합된 소형 프로세서를 필요로 하는 고수준 임베디드 응용 프로그램에 사용할 수 있으며, Thumb 명령어 세트 및 소수의 32비트 Thumb-2 명령어를 지원합니다.표 2-6 유용한 명령 행 옵션명령 행 옵션--cpu=6-M--cpu=6S-M--cpu=name설명프로세서 상태 명령어를 포함하며 Thumb만 있는 <strong>ARM</strong>v6 마이크로컨트롤러 프로필프로세서 상태 명령어 및 OS 확장을 포함하며 Thumb만 있는 <strong>ARM</strong>v6 마이크로컨트롤러 프로필여기서 name은 특정 <strong>ARM</strong> 프로세서입니다. 예를 들면 다음과 같습니다.• 프로세서 상태 명령어, OS 확장 및 BE8/LE 데이터 엔디안 지원을 포함하며Thumb만 있는 <strong>ARM</strong>v6용 Cortex-M12.5.1 주요 기능<strong>ARM</strong>v6-M용 주요 기능:• 컴파일러는 Thumb-2 기술을 사용한 Thumb 명령어 세트 확장을 지원합니다.예들 들면 BL, DMB, DSB, ISB, MRS, MSR 등입니다.2.5.2 정렬 지원기본적으로 컴파일러는 LDR 및 STR 명령어가 기본 워드 경계에 정렬되지 않은 워드에서 로드하거나 그 워드에 저장하게 하여 패킹된 구조체에 대한 액세스 속도를 빠르게 하기 위해 정렬되지 않은 <strong>ARM</strong>v6 액세스 지원을 사용합니다.정렬되지 않은 데이터 액세스는 해당 크기와 정렬에 따라 두 개 또는 세 개의 정렬된 액세스로 변환됩니다. 그러면 정렬되지 않은 액세스가 완료될 때까지 후속액세스는 중단됩니다. DCode 및 System 버스 인터페이스를 사용하여 정렬을 제어할 수 있습니다.추가 참고• Cortex-M1 아키텍처 참조 문서2-16 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


<strong>ARM</strong> 프로세서용 소프트웨어 개발• 컴파일러 사용 설명서의 5-26페이지의 데이터 정렬• 컴파일러 참조 설명서의 2-122페이지의 --[no_]unaligned_access2.5.3 엔디안 지원컴파일러 명령 행 옵션 --littleend 및 --bigend를 각각 사용하여 리틀엔디안 코드또는 빅엔디안 코드를 생성할 수 있습니다.<strong>ARM</strong>v6-M에서는 다음과 같은 엔디안 모드를 지원합니다.LE 리틀엔디안 형식BE8 빅엔디안 형식<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 2-17Unrestricted AccessNon-Confidential


<strong>ARM</strong> 프로세서용 소프트웨어 개발2.6 <strong>ARM</strong> 아키텍처 v7-A이 단원에서는 <strong>ARM</strong>v7-A에 대한 RealView 도구 지원에 대해 간략히 설명합니다.응용 프로그램 프로필은 여러 모드가 포함된 일반 <strong>ARM</strong> 아키텍처를 구현하며MMU를 기반으로 하는 가상 메모리 시스템 아키텍처를 지원합니다. 또한 이들프로필은 <strong>ARM</strong> 및 Thumb 명령어 세트를 모두 지원합니다.표 2-7 유용한 명령 행 옵션명령 행 옵션--cpu=7--cpu=7-A--cpu=name설명Thumb-2만 있고 하드웨어 나누기 a 가 없는 <strong>ARM</strong>v7<strong>ARM</strong>, Thumb 및 Thumb-2와 Thumb-2EE 명령어 세트가 있고 NEON 및 32비트 SIMD를 지원하는 가상 MMU 기반 메모리 시스템 지원 <strong>ARM</strong>v7 응용 프로그램 프로필여기서 name은 특정 <strong>ARM</strong> 프로세서입니다. 예를 들면 다음과 같습니다.• <strong>ARM</strong>, Thumb, Thumb-2, 하드웨어 VFP가 있고 NEON 및 32비트 SIMD를 지원하는 <strong>ARM</strong>v7용 Cortex-A8a. <strong>ARM</strong> v7은 인식되는 <strong>ARM</strong> 아키텍처가 아니라 <strong>ARM</strong>v7-A, <strong>ARM</strong>v7-R 및 <strong>ARM</strong>v7-M 아키텍처에 공통적으로 적용되는기능을 나타냅니다.2.6.1 주요 기능<strong>ARM</strong>v7-A용 주요 기능:• Advanced SIMD Extension 지원• Thumb-2EE (Thumb Execution Environment) 지원2.6.2 정렬 지원<strong>ARM</strong> 아키텍처에서 지원하는 데이터 정렬 동작은 <strong>ARM</strong>v4와 <strong>ARM</strong>v7 간에 크게다릅니다. <strong>ARM</strong>v7 구현에서는 정렬되지 않은 데이터 액세스를 지원해야 합니다.CP15 레지스터 c1의 A 비트를 사용하여 로드 및 저장 명령어의 정렬 요구 사항을제어할 수 있습니다.참고<strong>ARM</strong>v7 아키텍처에서는 <strong>ARM</strong>v6 이전의 정렬을 지원하지 않습니다.추가 참고• 해당 프로세서의 기술 참조 문서2-18 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


<strong>ARM</strong> 프로세서용 소프트웨어 개발• 컴파일러 사용 설명서의 5-26페이지의 데이터 정렬• 컴파일러 참조 설명서의 2-122페이지의 --[no_]unaligned_access2.6.3 엔디안 지원컴파일러 명령 행 옵션 --littleend 및 --bigend를 각각 사용하여 리틀엔디안 코드또는 빅엔디안 코드를 생성할 수 있습니다.<strong>ARM</strong>v7-A에서는 다음과 같은 엔디안 모드를 지원합니다.LE 리틀엔디안 형식BE8 <strong>ARM</strong>v6 및 <strong>ARM</strong>v7에서 사용하는 빅엔디안 형식<strong>ARM</strong>v7에서는 레거시 BE-32 모드를 지원하지 않습니다. 빅엔디안 바이트 순서가 적용된 명령어를 포함하는 <strong>ARM</strong>v7 프로세서용 레거시 코드가 있는 경우에는바이트 순서 반전을 수행해야 합니다. <strong>ARM</strong> 아키텍처 참조 문서를 참조하십시오.<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 2-19Unrestricted AccessNon-Confidential


<strong>ARM</strong> 프로세서용 소프트웨어 개발2.7 <strong>ARM</strong> 아키텍처 v7-R이 단원에서는 <strong>ARM</strong>v7-R에 대한 RealView 도구 지원에 대해 간략히 설명합니다. 실시간 프로필은 여러 모드가 포함된 일반 <strong>ARM</strong> 아키텍처를 구현하며 MPU를기반으로 하는 보호된 메모리 시스템 아키텍처를 지원합니다. <strong>ARM</strong>v7-R 아키텍처에서는 <strong>ARM</strong> 및 Thumb 명령어 세트를 모두 지원합니다.표 2-8 유용한 명령 행 옵션명령 행 옵션--cpu=7--cpu=7-R--cpu=name설명Thumb-2만 있고 하드웨어 나누기 a 가 없는 <strong>ARM</strong>v7<strong>ARM</strong>, Thumb 및 Thumb-2 (옵션) , VFP 및 하드웨어 나누기가 있고 32비트 SIMD를 지원하는 <strong>ARM</strong>v7 실시간 프로필여기서 name은 특정 <strong>ARM</strong> 프로세서입니다. 예를 들면 다음과 같습니다.• <strong>ARM</strong>, Thumb, Thumb-2, 하드웨어 VFP, 하드웨어 나누기가 있고 SIMD를 지원하는 <strong>ARM</strong>v7용 Cortex-R4Fa. <strong>ARM</strong> v7은 인식되는 <strong>ARM</strong> 아키텍처가 아니라 <strong>ARM</strong>v7-A, <strong>ARM</strong>v7-R 및 <strong>ARM</strong>v7-M 아키텍처에 공통적으로 적용되는기능을 나타냅니다.2.7.1 주요 기능<strong>ARM</strong>v7-R용 주요 기능:• SDIV 및 UDIV 명령어를 지원합니다2.7.2 정렬 지원<strong>ARM</strong> 아키텍처에서 지원하는 데이터 정렬 동작은 <strong>ARM</strong>v4와 <strong>ARM</strong>v7 간에 크게변경되었습니다. <strong>ARM</strong>v7 구현에서는 LDR, STR, LDRH 및 STRH를 사용하는 일부 정렬되지 않은 데이터 액세스에 대해 하드웨어 지원을 제공합니다. 기타 데이터 액세스에서는 LDM, STM, LDRD, STRD, LDC, STC, LDREX, STREX 및 SWP를 사용하는 정렬을 유지해야 합니다.CP15 레지스터 c1의 A 비트를 사용하여 로드 및 저장 명령어의 정렬 요구 사항을제어할 수 있습니다.추가 참고• 해당 프로세서의 기술 참조 문서• 컴파일러 사용 설명서의 5-26페이지의 데이터 정렬2-20 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


<strong>ARM</strong> 프로세서용 소프트웨어 개발• 컴파일러 참조 설명서의 2-122페이지의 --[no_]unaligned_access2.7.3 엔디안 지원컴파일러 명령 행 옵션 --littleend 및 --bigend를 각각 사용하여 리틀엔디안 코드또는 빅엔디안 코드를 생성할 수 있습니다.<strong>ARM</strong>v7-R에서는 다음과 같은 엔디안 모드를 지원합니다.LE 리틀엔디안 형식BE8 빅엔디안 형식<strong>ARM</strong>v7에서는 레거시 BE-32 모드를 지원하지 않습니다. 빅엔디안 바이트 순서가 적용된 명령어를 포함하는 <strong>ARM</strong>v7 프로세서용 레거시 코드가 있는 경우에는바이트 순서 반전을 수행해야 합니다.<strong>ARM</strong>v7-R에서는 리셋에서 정적 옵션으로 바이트 순서 반전 하드웨어 (옵션) 를지원합니다. <strong>ARM</strong> 아키텍처 참조 문서, <strong>ARM</strong>v7-A 및 <strong>ARM</strong>v7-R 에디션을 참조하십시오.<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 2-21Unrestricted AccessNon-Confidential


<strong>ARM</strong> 프로세서용 소프트웨어 개발2.8 <strong>ARM</strong> 아키텍처 v7-M이 단원에서는 <strong>ARM</strong>v7-M에 대한 RealView 도구 지원에 대해 간략히 설명합니다.마이크로컨트롤러 프로필은 고속 인터럽트 처리용으로 설계된 프로그래머 모델을 구현합니다. 이 모델은 레지스터의 하드웨어 스택과 상위 언어를 사용한 인터럽트 처리기 작성 지원을 포함합니다. 또한 <strong>ARM</strong>v7 보호 메모리 시스템 아키텍처의 변형을 구현하며 Thumb-2 명령어 세트만 지원합니다.표 2-9 유용한 명령 행 옵션명령 행 옵션--cpu=7--cpu=7-M--cpu=name설명Thumb-2만 있고 하드웨어 나누기 a 가 없는 <strong>ARM</strong>v7하드웨어 나누기와 Thumb-2만 있는 <strong>ARM</strong>v7 마이크로컨트롤러 프로필여기서 name은 특정 <strong>ARM</strong> 프로세서입니다. 예를 들면 다음과 같습니다.• Thumb-2만 있고 하드웨어 나누기와 정렬되지 않은 액세스를 포함하며<strong>ARM</strong>v6 스타일 BE8 및 LE 데이터 엔디안을 지원하는 <strong>ARM</strong>v7용 Cortex-M3a. <strong>ARM</strong> v7은 인식되는 <strong>ARM</strong> 아키텍처가 아니라 <strong>ARM</strong>v7-A, <strong>ARM</strong>v7-R 및 <strong>ARM</strong>v7-M 아키텍처에 공통적으로 적용되는기능을 나타냅니다.2.8.1 주요 기능<strong>ARM</strong>v7-M용 주요 기능:• SDIV 및 UDIV 명령어를 지원합니다.• 인터럽트 내장 함수를 사용하여 현재 발생 순서 우선순위를 변경하는 CPSIE또는 CPSID 명령어를 생성합니다 (2-23페이지의 표 2-10 참조) . 예를 들어__disable_irq 내장 함수를 사용하는 경우 컴파일러는 PRIMASK를 1로 설정하는 CPSID i 명령어를 생성합니다. 그러면 실행 우선순위가 0으로 높아지며구성할 수 있는 우선순위가 지정된 예외를 입력할 수 없게 됩니다.<strong>ARM</strong>v7-M 아키텍처 참조 문서를 참조하십시오.2-22 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


<strong>ARM</strong> 프로세서용 소프트웨어 개발표 2-10 인터럽트 내장 함수내장 함수 Op 코드 PRIMASK FAULTMASK__enable_irq CPSIE i 0__disable_irq CPSID i 1__enable_fiq CPSIE f 0__disable_fiq CPSID f 12.8.2 정렬 지원<strong>ARM</strong> 아키텍처에서 지원하는 데이터 정렬 동작은 <strong>ARM</strong>v4와 <strong>ARM</strong>v7 간에 크게변경되었습니다. <strong>ARM</strong>v7 구현에서는 정렬되지 않은 데이터 액세스를 지원해야합니다. CP15 레지스터 c1의 A 비트를 사용하여 로드 및 저장 명령어의 정렬 요구사항을 제어할 수 있습니다.참고<strong>ARM</strong>v7 아키텍처에서는 <strong>ARM</strong>v6 이전의 정렬을 지원하지 않습니다.2.8.3 엔디안 지원컴파일러 명령 행 옵션 --littleend 및 --bigend를 각각 사용하여 리틀엔디안 코드또는 빅엔디안 코드를 생성할 수 있습니다.<strong>ARM</strong>v7-M에서는 다음과 같은 엔디안 모드를 지원합니다.LE 리틀엔디안 형식BE8 빅엔디안 형식<strong>ARM</strong>v7 아키텍처에서는 레거시 BE-32 모드를 지원하지 않습니다. 빅엔디안 바이트 순서가 적용된 명령어를 포함하는 <strong>ARM</strong>v7 프로세서용 레거시 코드가 있는경우에는 바이트 순서 반전을 수행해야 합니다. <strong>ARM</strong> 아키텍처 참조 문서를 참조하십시오.<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 2-23Unrestricted AccessNon-Confidential


<strong>ARM</strong> 프로세서용 소프트웨어 개발2-24 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


3장임베디드 소프트웨어 개발이 장에서는 타겟 시스템이 있는 상태나 없는 상태에서 <strong>ARM</strong> RealViewCompilation Tools를 사용하여 임베디드 응용 프로그램을 개발하는 방법을 설명합니다.이 장은 다음 단원으로 구성되어 있습니다.• 3-2페이지의 임베디드 소프트웨어 개발 개요• 3-4페이지의 기본 컴파일 도구 동작• 3-9페이지의 타겟 하드웨어에 맞게 C 라이브러리 조정• 3-11페이지의 타겟 하드웨어에 맞게 이미지 메모리 맵 조정• 3-16페이지의 리셋 및 초기화• 3-23페이지의 타겟 하드웨어 및 메모리 맵<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 3-1Non-Confidential


임베디드 소프트웨어 개발3.1 임베디드 소프트웨어 개발 개요대부분의 임베디드 응용 프로그램을 처음 개발할 때는 최종 제품에서 사용할 수있는 리소스와는 다른 리소스를 사용하는 프로토타입 환경에서 작업이 수행됩니다. 따라서 개발 또는 디버깅 환경의 기능에 의존하는 시스템으로부터 타겟 하드웨어에서 독립적으로 실행되는 시스템으로 임베디드 응용 프로그램을 이동하는것과 관련된 프로세스를 고려해야 합니다.RealView Compilation Tools를 사용하여 임베디드 소프트웨어를 개발할 때 고려해야 할 사항은 다음과 같습니다.• 기본 빌드에서 완전한 독립 실행형 응용 프로그램으로 이동하는 데 필요한단계를 올바르게 파악할 수 있도록 컴파일 도구의 기본 동작을 익힙니다.• 일부 C 라이브러리 기능은 디버그 환경 리소스를 사용하여 실행됩니다. 디버그 환경 리소스를 사용하는 경우 타겟 하드웨어를 사용하도록 이 기능을다시 구현해야 합니다.• RealView Compilation Tools에는 기본적으로 특정 타겟의 메모리 맵에 대한정보가 없습니다. 따라서 타겟 하드웨어의 메모리 레이아웃에 맞게 이미지메모리 맵을 조정해야 합니다.• 주 응용 프로그램을 실행하려면 먼저 임베디드 응용 프로그램에서 몇 가지초기화 작업을 수행해야 합니다. 전체 초기화 시퀀스에는 RealViewCompilation Tools C 라이브러리 초기화 루틴뿐 아니라 사용자가 구현하는코드도 필요합니다.3.1.1 예제 코드이 장에서 설명하는 항목을 확인하려면 예제 디렉토리(...\RVDS\Examples\...\emb_sw_dev\) 의 관련 예제 프로젝트를 참조하십시오. 각 빌드는 별도의 디렉토리에 있으며 이 장의 이후 단원에서 설명하는 기술의 예제를제공합니다. 각 빌드에 대한 자세한 내용은 readme.txt 파일을 참조하십시오.빌드 1빌드 2빌드 1은 Dhrystone 벤치마크의 기본 빌드이며 기본 RealViewCompilation Tools 동작을 따릅니다.자세한 내용은 3-4페이지의 기본 컴파일 도구 동작을 참조하십시오.이 예제에서는 클럭 타이밍 및 문자열 I/O에 대해 Versatile 보드를 사용하도록 빌드 1을 조정합니다.자세한 내용은 3-9페이지의 타겟 하드웨어에 맞게 C 라이브러리 조정을 참조하십시오.3-2 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-Confidential


임베디드 소프트웨어 개발빌드 3빌드 4빌드 5이 예제에서는 스택 및 힙 배치를 조정하기 위해 스캐터 로딩 설명파일을 구현합니다.자세한 내용은 3-11페이지의 타겟 하드웨어에 맞게 이미지 메모리맵 조정을 참조하십시오.이 예제는 Versatile 보드에서 독립 실행형으로 실행할 수 있습니다.백터 테이블 및 리셋 처리기가 구현됩니다. 자세한 내용은 3-16페이지의 리셋 및 초기화를 참조하십시오.이 예제는 빌드 4와 같지만 모든 타겟 메모리 맵 정보가 스캐터 로딩설명 파일에 있다는 점이 다릅니다.자세한 내용은 3-23페이지의 타겟 하드웨어 및 메모리 맵을 참조하십시오.Dhrystone 벤치마킹 프로그램은 예제 프로젝트에 대한 코드 베이스를 제공합니다. 이 예제는 Versatile 보드에서 실행하도록 조정됩니다. 그러나 해당 원칙은 모든 타겟 하드웨어에 적용할 수 있습니다. 보드 연결 및 설정에 대한 자세한 내용은 해당 보드의 사용 설명서에서 시작하기 단원을 참조하십시오.참고이 장에서는 Dhrystone 프로그램에 대해서만 설명하는 것이 아니라 이 프로그램이 완전한 독립 실행형 시스템에서 실행되도록 하기 위해 수행해야 하는 단계에대해서도 설명합니다. 벤치마킹 도구로서의 Dhrystone에 대한 자세한 내용은Application Note 93 - Benchmarking with <strong>ARM</strong>ulator 를 참조하십시오. <strong>ARM</strong>Application Notes는 <strong>ARM</strong> 웹 사이트 (http://www.arm.com) 의 Documentation 영역에서 다운로드할 수 있습니다.<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 3-3Non-Confidential


임베디드 소프트웨어 개발3.2 기본 컴파일 도구 동작임베디드 응용 프로그램의 소프트웨어에 대한 작업을 시작할 때는 타겟 하드웨어의 전체 기술 사양을 알지 못할 수 있습니다. 예를 들면 타겟 주변 기기나 메모리 맵, 심지어는 프로세서 자체에 대한 세부 사항을 모를 수 있습니다.이러한 세부 사항을 알 수 없는 상태에서도 소프트웨어 개발을 진행할 수 있도록컴파일 도구에는 응용 프로그램 코드를 즉시 빌드하고 디버깅할 수 있게 해주는기본 동작이 포함되어 있습니다. 이러한 기본 동작을 알고 있으면 기본 빌드에서완전한 독립 실행형 응용 프로그램으로 이동하는 데 필요한 단계를 올바르게 파악할 수 있으므로 유용합니다.<strong>ARM</strong> C 라이브러리에서 일부 ISO C 기능은 장치 드라이버 수준의 호스트 디버깅환경에서 지원됩니다. 이 기능을 제공하는 메커니즘을 세미호스팅이라고 합니다.세미호스팅이 실행되면 디버그 에이전트에서는 이를 식별하고 프로그램 실행을일시 중단합니다. 그런 다음 디버그 에이전트에서 세미호스팅 작업이 처리되고코드 실행이 다시 시작됩니다. 따라서 호스트 자체에서 수행되는 작업은 프로그램에 투명합니다.자세한 내용은 8장 세미호스팅을 참조하십시오.3.2.1 C 라이브러리 구조개념적으로 C 라이브러리는 ISO C 표준에 포함된 함수와 ISO C 표준을 지원하는함수로 나눌 수 있습니다.예를 들어 3-5페이지의 그림 3-1에서는 디버거 콘솔 창에 출력하는 방식으로printf () 함수를 구현하는 C 라이브러리를 보여 줍니다. 이 구현은 세미호스팅호출을 실행하여 타겟 주변 기기 대신 디버거를 사용하는 기본 동작을 수행하는지원 함수인 _sys_write () 를 호출하는 방식으로 제공됩니다.3-4 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-Confidential


임베디드 소프트웨어 개발ISO CFunctions called byyour application,for example, printf()C Libraryinput/outputerrorhandlingstack andheapsetupotherDevice driver level.Use semihosting,for example, _sys_write()DebugAgentSemihosting SupportImplemented bythe debuggingenvironment그림 3-1 C 라이브러리 구조3.2.2 기본 메모리 맵메모리 맵이 설명되어 있지 않은 이미지에서 링커는 3-6페이지의 그림 3-2에서처럼 기본 메모리 맵에 따라 코드와 데이터를 배치합니다.참고<strong>ARM</strong>v6-M 및 <strong>ARM</strong>v7-M 아키텍처 기반 프로세서에는 고정 메모리 맵이 있습니다. 따라서 이러한 프로세서 기반의 서로 다른 시스템 간에 소프트웨어를 더욱 쉽게 이식할 수 있습니다. 자세한 내용은 Cortex-M1 기술 참조 문서 및 Cortex-M3 기술 참조 문서를 참조하십시오.기본 메모리 맵은 다음과 같이 설명할 수 있습니다.• 이미지는 링크되어 주소 0x8000에서 로드되고 실행됩니다. 모든 RO (읽기전용) 섹션이 먼저 배치되고 그 다음에 RW (읽기- 쓰기) 섹션, ZI (0으로 초기화됨) 섹션 순으로 배치됩니다.<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 3-5Non-Confidential


임베디드 소프트웨어 개발• 힙은 ZI 섹션의 바로 위에 배치되므로 정확한 위치는 링크 타임에결정됩니다.• 스택 기준 위치는 응용 프로그램 시작 중에 세미호스팅 작업을 통해 제공됩니다. 이 세미호스팅 작업에서 반환되는 값은 디버그 환경에 따라 다릅니다.STACKFromSemihostingcallHEAPZIDecided atlink timeRWRO0x8000그림 3-2 기본 메모리 맵링커는 3-7페이지의 그림 3-3과 같은 일련의 규칙에 따라 메모리 내부 코드와 데이터를 배치할 위치를 결정합니다. 일반적으로 링커는 입력 목록에서 속성, 이름,위치순으로 입력 섹션을 정렬합니다. 자세한 내용은 링커 사용 설명서에서 3-2페이지의 이미지 구조체 지정 및 3-8페이지의 섹션 배치를 참조하십시오.3-6 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-Confidential


임베디드 소프트웨어 개발ZIsection Afrom file2.oRWRODATACODEBAsection Afrom file1.o그림 3-3 링커 배치 규칙코드 및 데이터 배치를 완전히 제어하려면 스캐터 로딩 메커니즘을 사용해야 합니다. 자세한 내용은 3-11페이지의 타겟 하드웨어에 맞게 이미지 메모리 맵 조정을 참조하십시오.3.2.3 응용 프로그램 시작대부분의 임베디드 시스템에서 초기화 시퀀스는 주 작업이 실행되기 전에 시스템을 설정하기 위해 실행됩니다. 3-8페이지의 그림 3-4에서는 기본 RealViewCompilation Tools 초기화 시퀀스를 보여 줍니다.<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 3-7Non-Confidential


임베디드 소프트웨어 개발C LibraryUser Codeentry point. ....__rt_entryset up application stackand heapinitialize library functionscall top-levelconstructors (C++)Exit from applicationImage.__maincopy codecopy/decompress RW datazero uninitialized data.main()causes the linker to link inlibrary initialization code그림 3-4 기본 초기화 시퀀스__main은 메모리를 설정하고 __rt_entry는 런타임 환경을 설정합니다.__main은 코드 및 데이터 복사, 압축 해제 및 ZI 데이터의 0 초기화를 수행합니다.그런 다음 __rt_entry를 분기하여 스택 및 힙을 설정하고, 라이브러리 함수 및 정적 데이터를 초기화하고, 모든 최상위 C++ 생성자를 호출합니다. 그런 후에__rt_entry는 응용 프로그램의 엔트리인 main () 으로 분기됩니다. 주 응용 프로그램의 실행이 완료되면 __rt_entry는 라이브러리를 종료한 다음 제어권을 디버거에 다시 넘겨줍니다.함수 레이블 main () 에는 특별한 의미가 있습니다. main () 함수가 있으면 링커가 __main 및 __rt_entry의 초기화 코드에서 링크됩니다. main () 레이블이 붙은 함수가 없으면 초기화 시퀀스가 링크되지 않으므로 일부 표준 C 라이브러리 기능이 지원되지 않습니다. __main과 다른 시작 기호를 통해 C 라이브러리를 사용하는데 대한 자세한 내용은 링커 참조 설명서의 2-61페이지의--[no_]startup=symbol을 참조하십시오.3-8 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-Confidential


임베디드 소프트웨어 개발3.3 타겟 하드웨어에 맞게 C 라이브러리 조정기본적으로 C 라이브러리는 세미호스팅을 사용하여 장치 드라이버 수준 기능을제공하므로 호스트 컴퓨터가 입력 및 출력 장치 역할을 할 수 있습니다. 이는 개발 하드웨어가 최종 시스템의 입력 및 출력 기능을 빠짐없이 갖추지 못한 경우가많으므로 유용합니다.타겟 하드웨어를 사용하며 C 라이브러리의 구현을 위해 이미지에 자동으로 링크되는 C 라이브러리 함수를 구현할 수 있습니다. 그림 3-5에서는 C 라이브러리 타겟 조정이라고 하는 이 과정을 보여 줍니다.ISO CISO CC LibraryUserCodeInput/OutputRetargetInput/OutputDebugAgentSemihostingSupportTargetHardware그림 3-5 C 라이브러리 타겟 조정예를 들어 LCD 화면과 같은 주변 I/O 장치가 있는 경우 디버거 콘솔에 출력하는fputc () 의 라이브러리 구현을 재정의하고 LCD로 출력하는 라이브러리를 구현할 수 있습니다. fputc () 의 이러한 구현은 최종 이미지에 링크되므로 printf ()계열의 함수 전체가 LCD로 출력하게 됩니다.<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 3-9Non-Confidential


임베디드 소프트웨어 개발3-10페이지의 예제 3-1에서는 fputc () 의 구현 예제를 보여 줍니다. 이 예제에서는 직렬 출력 함수 sendchar () 이 별도의 소스 파일에 구현되어 있다고 가정하고fputc () 의 입력 문자 매개변수를 이 함수로 리디렉션합니다. 이러한 방식으로fputc () 는 타겟 종속 출력과 C 라이브러리 표준 출력 함수 간의 추상 계층 역할을 합니다.예제 3-1 fputc () 의 구현extern void sendchar (char *ch) ;int fputc (int ch, FILE *f){ /* e.g. write a character to an LCD screen */char tempch = ch;sendchar (&tempch) ;return ch;}독립 실행형 응용 프로그램에서는 대개 세미호스팅 작업을 지원할 필요가 없습니다. 따라서 세미호스팅하는 함수에 대한 모든 호출을 제거하거나 이러한 함수를 세미호스팅되지 않은 함수로 다시 구현해야 합니다. 자세한 내용은 라이브러리 및 부동 소수점 지원 설명서에서 2-23페이지의 세미호스팅되지 않은 환경에대한 응용 프로그램 빌드를 참조하십시오.세미호스팅을 사용하는 C 라이브러리 함수의 전체 목록은 8장 세미호스팅을 참조하십시오.3-10 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-Confidential


임베디드 소프트웨어 개발3.4 타겟 하드웨어에 맞게 이미지 메모리 맵 조정세미호스팅 기능이 없는 최종 임베디드 시스템에서는 대개 기본 메모리 맵을 사용할 필요가 없습니다. 타겟 하드웨어에는 일반적으로 각기 다른 주소 범위에 있는 메모리 장치가 여러 개 있습니다. 이러한 장치를 최대한 사용하려면 로드 및런타임에 별도의 메모리 뷰가 있어야 합니다.스캐터 로딩을 사용하면 스캐터 로딩 설명 파일이라고 하는 텍스트 형식의 설명파일에서 코드 및 데이터의 메모리 내 로드 타임 및 런타임 위치를 설명할 수 있습니다. 이 파일은 명령 행에서 --scatter 옵션을 사용하여 링커에 전달됩니다. 예를 들면 다음과 같습니다.armlink --scatter scatter.scat file1.o file2.o스캐터 로딩은 다음 두 가지 유형의 메모리 영역을 정의합니다.• 리셋 및 로드 시에 응용 프로그램 코드 및 데이터를 포함하는 로드 영역• 응용 프로그램이 실행되는 동안 코드와 데이터를 포함하는 실행 영역. 응용프로그램이 시작될 때 각 로드 영역에서 실행 영역이 하나 이상 만들어집니다.단일 코드 또는 데이터 섹션은 단일 실행 영역에만 배치할 수 있으며 분할할 수없습니다.시작할 때 __main의 C 라이브러리 초기화 코드에서는 이미지 로드 뷰에서 실행 뷰로 이동하는 데 필요한 코드와 데이터를 복사하고 데이터를 0으로 초기화합니다.<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 3-11Non-Confidential


임베디드 소프트웨어 개발3.4.1 스캐터 로딩 설명 파일스캐터 로딩 설명 파일 구문은 스캐터 로딩 자체에서 제공되는 기능을 반영합니다. 그림 3-6에서는 이 파일 구문을 보여 줍니다.name of regionstart addressMY_REGION 0x0000 0x2000{contents of region}optional lengthparameter그림 3-6 스캐터 로딩 설명 파일 구문영역은 영역 이름 및 시작 주소와 그 밖의 여러 요소를 포함하는 헤더 태그로 정의됩니다. 필요한 경우 최대 길이와 다양한 특성을 추가할 수 있습니다.영역의 내용은 영역 유형에 따라 다릅니다.• 로드 영역에는 최소한 하나의 실행 영역이 있어야 합니다. 실제로 각 로드영역에는 대개 여러 개의 실행 영역이 있습니다.• 실행 영역은 EMPTY 속성을 사용하여 선언되지 않은 경우 최소한 하나의 코드또는 데이터 섹션이 있어야 합니다. EMPTY 속성이 설정되지 않은 영역에는일반적으로 객체 또는 라이브러리 코드가 포함되어 있습니다. 와일드카드(*) 구문을 사용하면 스캐터 로딩 설명 파일의 다른 곳에서 특정 속성이 지정되지 않은 모든 섹션을 그룹화할 수 있습니다.여러 메모리 맵에 대한 자세한 예제 및 내용은 링커 사용 설명서에서 5-5페이지의단순 메모리 맵을 가진 이미지를 참조하십시오.3-12 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-Confidential


임베디드 소프트웨어 개발형식적 구문에 대한 자세한 내용은 링커 참조 설명서에서 3장 스캐터 로딩 설명파일의 형식적 구문을 참조하십시오.3.4.2 루트 영역루트 영역은 해당 로드 주소와 동일한 실행 주소를 갖는 실행 영역입니다. 각 스캐터 로딩 설명 파일에는 루트 영역이 하나 이상 있어야 합니다.스캐터 로딩을 사용할 경우 실행 영역을 만들어야 하는 코드와 데이터를 다른 위치에 복사할 수 없다는 제한 사항이 있습니다. 따라서 루트 영역에 다음 섹션을추가해야 합니다.• 코드와 데이터를 복사하는 코드가 포함된 __main.o 및 __scatter*.o• 압축 해제를 수행하는 __dc*.o• 복사하거나 압축을 해제할 코드 및 데이터의 주소가 포함된 Region$$Table섹션이러한 섹션은 읽기 전용으로 정의되어 있기 때문에 * (+RO) 와일드카드 구문을기준으로 그룹화됩니다. 따라서 * (+RO) 가 루트가 아닌 영역에 지정된 경우InRoot$$Sections를 사용하여 루트 영역에 이러한 섹션을 명시적으로 선언해야 합니다.자세한 내용은 링커 사용 설명서에서 5-26페이지의 루트 영역에 섹션 할당을 참조하십시오.3.4.3 스택 및 힙 배치스캐터 로딩 메커니즘에서는 코드와 정적으로 할당된 데이터를 이미지에 배치하는 방식을 지정하는 방법을 제공합니다. 응용 프로그램 스택 및 힙은 C 라이브러리를 초기화하는 동안 설정됩니다. 특수하게 이름이 지정된 <strong>ARM</strong>_LIB_HEAP,<strong>ARM</strong>_LIB_STACK 또는 <strong>ARM</strong>_LIB_STACKHEAP 실행 영역을 사용하여 스택 및 힙 배치를 조정할 수 있습니다. 스캐터 로딩 설명 파일을 사용하지 않는 경우에는__user_initial_stackheap () 함수를 다시 구현할 수도 있습니다.자세한 내용은 링커 사용 설명서에서 5-3페이지의 스캐터 로딩 설명 파일을 통한스택 및 힙 지정을 참조하십시오.<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 3-13Non-Confidential


임베디드 소프트웨어 개발런타임 메모리 모델RealView Compilation Tools에서는 다음과 같은 런타임 메모리 모델을 제공합니다.단일 영역 모델응용 프로그램 스택과 힙은 같은 메모리 영역에서 서로 반대 방향으로 늘어납니다. 자세한 내용은 그림 3-7을 참조하십시오. 이 런타임메모리 모델에서는 새 힙 공간이 할당되면 (예: malloc () 가 호출되는 경우) 스택 포인터의 값을 기준으로 힙이 확인됩니다.SBSTACK0x40000HBHEAP0x20000그림 3-7 단일 영역 모델예제 3-2 단일 영역 모델 루틴LOAD_FLASH ...{...<strong>ARM</strong>_LIB_STACKHEAP 0x20000 EMPTY 0x20000 ; Heap and stack growing towards{ } ; each other in the same region...}2-영역 모델스택과 힙이 별도의 메모리 영역에 배치됩니다. 예를 들어 스택 전용으로 예약하려는 작은 고속 RAM 블록이 있을 수 있습니다. 2-영역 모델에서는 __use_two_region_memory를 가져와야 합니다.이 런타임 메모리 모델에서는 새 힙 공간이 할당되면 힙 한계를 기준으로 힙이 확인됩니다.3-14 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-Confidential


임베디드 소프트웨어 개발HL0x28080000HBSBHEAPSTACK0x280000000x40000그림 3-8 2-영역 모델예제 3-3 2-영역 모델 루틴LOAD_FLASH ...{...<strong>ARM</strong>_LIB_STACK 0x40000 EMPTY -0x20000 ; Stack region growing down{ } ;<strong>ARM</strong>_LIB_HEAP 0x28000000 EMPTY 0x80000 ; Heap region growing up{ }...}두 런타임 메모리 모델 모두에서 스택 증가는 확인되지 않습니다.자세한 내용은 라이브러리 및 부동 소수점 지원 설명서에서 2-77페이지의 런타임메모리 모델 조정을 참조하십시오.<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 3-15Non-Confidential


임베디드 소프트웨어 개발3.5 리셋 및 초기화이 장에서는 실행이 C 라이브러리 초기화 루틴에 대한 진입점인 __main에서 시작된다는 가정하에 관련 내용을 설명했습니다. 실제로 타겟 하드웨어의 모든 임베디드 응용 프로그램은 시작될 때 시스템 수준 초기화를 수행합니다. 이 단원에서는 이 작업에 대해 자세히 설명합니다.그림 3-9에서는 <strong>ARM</strong> 아키텍처 기반의 임베디드 시스템에 사용할 수 있는 초기화 시퀀스를 보여 줍니다. 스캐터 로딩 설명 파일을 사용하여 스택 및 힙 배치를조정하는 경우, 링커에서는 해당 영역 이름에 대해 링커 정의 기호를 사용하여__user_initial_stackheap () 함수를 만듭니다. 자세한 내용은 링커 사용 설명서에서 5-3페이지의 스캐터 로딩 설명 파일을 통한 스택 및 힙 지정을 참조하십시오. 구현을 직접 만들 수도 있습니다..__mainC Librarycopy codecopy/decompress RWdata. zero uninitialized data..__rt_entryinitialize library functions2call top-level constructors(C++)Exit from application1346..User Codereset handlerinitialize stack pointers. configure MMU/MPUsetup cache/enable TCM.__user_initial_stackheap()set up application stackand heap.$Sub$$main()enable caches andinterrupts.main()causes the linker to link inlibrary initialization codeImageEntry Point5그림 3-9 초기화 시퀀스리셋 처리기는 어셈블러에서 코딩된 짧은 모듈로서, 시스템이 시작되면 즉시 실행됩니다. 최소한 리셋 처리기는 응용 프로그램이 실행되는 모드의 스택 포인터를 초기화합니다. 캐시, TCM, MMU, MPU와 같은 지역 메모리 시스템이 있는 프3-16 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-Confidential


임베디드 소프트웨어 개발로세서의 경우, 초기화 프로세스의 이 단계에서 몇 가지 구성 작업이 수행되어야합니다. 실행 후 리셋 처리기는 일반적으로 __main으로 분기되어 C 라이브러리 초기화 시퀀스를 시작합니다.인터럽트 활성화와 같이 일반적으로 C 라이브러리 초기화 코드의 실행이 완료된후에 수행되는 몇 가지 시스템 초기화 구성요소가 있습니다. $Sub$$main () 레이블이 붙은 코드 블록에서는 주 응용 프로그램의 실행이 시작되기 바로 전에 이러한 작업을 수행합니다. 자세한 내용은 링커 사용 설명서에서 4-14페이지의$Super$$ 및 $Sub$$를 사용하여 기호 정의 재정의를 참조하십시오.3.5.1 벡터 테이블모든 <strong>ARM</strong> 시스템에는 벡터 테이블이 있습니다. 벡터 테이블은 초기화 시퀀스의구성요소는 아니지만 예외를 처리하는 데 필요합니다. 이 테이블은 특정 주소 (일반적으로 0x0) 에 배치해야 합니다. 이렇게 하려면 스캐터 로딩 +FIRST 지시어를사용하면 됩니다 (예제 3-4 참조) .예제 3-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}}마이크로컨트롤러 프로필의 벡터 테이블은 대부분의 <strong>ARM</strong> 아키텍처와 크게 다릅니다. 해당 프로세서의 벡터 테이블 예제는 다음을 참조하십시오.• <strong>ARM</strong>v6 이하, <strong>ARM</strong>v7-A 및 <strong>ARM</strong>v7-R 프로필의 경우 6-5페이지의 벡터 테이블• <strong>ARM</strong>v6-M 및 <strong>ARM</strong>v7-M 프로필의 경우 6-34페이지의 벡터 테이블<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 3-17Non-Confidential


임베디드 소프트웨어 개발3.5.2 ROM 및 RAM 재매핑참고이 단원은 <strong>ARM</strong>v6-M 및 <strong>ARM</strong>v7-M 프로필에는 적용되지 않습니다.시스템에서 실행할 첫 번째 명령어의 주소인 0x0에 있는 메모리 종류를 고려해야합니다.참고이 단원에서는 <strong>ARM</strong> 프로세서가 0x0에서 명령어 가져오기를 시작한다고 가정합니다. <strong>ARM</strong> 프로세서 기반의 시스템에서는 일반적으로 이 주소에서 명령어를 가져오기 시작합니다. 그러나 일부 <strong>ARM</strong> 프로세서의 경우 0xFFFF0000에서 명령어 가져오기를 시작하도록 구성할 수 있습니다.시작할 때 0x0에 올바른 명령어가 있어야 하므로 리셋 시에 0x0에 비휘발성 메모리가 있어야 합니다. 이렇게 구성하는 한 가지 방법은 ROM을 0x0에 배치하는 것입니다. 그러나 이 구성에는 몇 가지 단점이 있습니다.예제 3-5에서는 리셋 시 ROM/RAM 재매핑을 구현하는 다른 솔루션을 보여 줍니다. 이 예제에 표시된 상수는 Versatile 보드에서만 사용할 수 있는 상수이지만 유사한 방식으로 재매핑을 구현하는 모든 플랫폼에서 같은 방법을 적용할 수 있습니다. 재매핑 후에는 스캐터 로딩 설명 파일을 사용하여 메모리 맵을 설명해야 합니다.예제 3-5 ROM/RAM 재매핑; --- System memory locationsVersatile_ctl_reg EQU 0x101E0000 ; Address of control registerDEVCHIP_Remap_bit EQU 0x100 ; Bit 8 is remap bit of control registerENTRY; Code execution starts here on reset; On reset, an alias of ROM is at 0x0, so jump to 'real' ROM.LDR pc, =Instruct_2Instruct_2; Remap by setting remap bit of the control register; Clear the DEVCHIP_Remap_bit by writing 1 to bit 8 of the control registerLDR R1, =Versatile_ctl_regLDR R0, [R1]ORR R0, R0, #DEVCHIP_Remap_bitSTR R0, [R1]; RAM is now at 0x0.3-18 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-Confidential


임베디드 소프트웨어 개발; The exception vectors must be copied from ROM to RAM; The copying is done later by the C library code inside __main; Reset_Handler follows on from here3.5.3 지역 메모리 설정 고려 사항대부분의 <strong>ARM</strong> 프로세서에는 MMU 또는 MPU와 같은 칩 내부 메모리 관리 시스템이 있습니다. 이러한 장치는 일반적으로 시스템을 시작하는 동안 설정되고 활성화됩니다. 따라서 지역 메모리 시스템이 있는 프로세서의 경우 초기화 시퀀스에서 특별히 고려해야 할 사항이 있습니다.이 장에서 설명한 대로 __main의 C 라이브러리 초기화 코드는 이미지의 실행 시메모리 맵을 설정합니다. 따라서 __main으로 분기하기 전에 프로세서의 런타임 메모리 뷰를 설정해야 합니다. 즉, 모든 MMU 또는 MPU를 리셋 처리기에서 설정하고 활성화해야 합니다.또한 대개는 코드 및 데이터를 TCM으로 스캐터 로드하므로 __main으로 분기하기전에 (일반적으로 MMU/MPU를 설정하기 전에) TCM도 활성화해야 합니다.TCM이 활성화된 경우 TCM으로 마스킹된 메모리에 액세스할 필요가 없다는 점에 유의하십시오.또한 __main으로 분기하기 전에 캐시가 활성화된 경우 캐시 일관성 문제가 있을수 있습니다. __main의 코드는 해당 로드 주소의 코드 영역을 해당 실행 주소로 복사하며, 본질적으로 명령어를 데이터로 처리합니다. 그 결과 일부 명령어는 데이터 캐시에 캐시될 수 있으며 이 경우 명령어가 명령어 경로에 표시되지 않습니다.이러한 일관성 문제가 발생하지 않도록 하려면 C 라이브러리 초기화 시퀀스의 실행이 완료된 후에 캐시를 활성화합니다.3.5.4 스택 포인터 초기화리셋 처리기는 적어도 응용 프로그램에서 사용하는 모든 실행 모드의 스택 포인터에 초기값을 지정해야 합니다.3-20페이지의 예제 3-6에서 스택은 stack_base에 있습니다. 이 기호는 하드 코딩된주소일 수도 있고, 별도의 어셈블러 소스 파일에 정의되어 스캐터 로딩 설명 파일에서 찾을 수도 있습니다. 이 작업을 수행하는 방법에 대한 자세한 내용은 링커사용 설명서에서 5-3페이지의 스캐터 로딩 설명 파일을 통한 스택 및 힙 지정을참조하십시오.<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 3-19Non-Confidential


임베디드 소프트웨어 개발예제 3-6 스택 포인터 초기화; ***************************************************************; This example does not apply to <strong>ARM</strong>v6-M and <strong>ARM</strong>v7-M profiles; ***************************************************************Len_FIQ_Stack EQU 256Len_IRQ_Stack EQU 256stack_base DCD 0x18000;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_Bit ; Interrupts disabledMOV sp, R0SUB R0, R0, #Len_FIQ_StackMSR CPSR_c, #Mode_IRQ:OR:I_Bit:OR:F_Bit ; Interrupts disabledMOV sp, R0SUB R0, R0, #Len_IRQ_StackMSR CPSR_c, #Mode_SVC:OR:I_Bit:OR:F_Bit ; Interrupts disabledMOV sp, R0; Leave processor in SVC mode예제 3-6에서는 FIQ 및 IRQ (인터럽트 요청) 모드에 대해 256바이트의 스택을 할당하지만 다른 실행 모드에 대해서도 동일하게 할당할 수 있습니다. 스택 포인터를 설정하려면 인터럽트가 비활성화된 상태에서 각 모드로 전환하고 스택 포인터에 적절한 값을 할당합니다.리셋 처리기에서 설정된 스택 포인터 값은 C 라이브러리 초기화 코드에 의해__user_initial_stackheap () 에 매개변수로 자동 전달됩니다. 따라서__user_initial_stackheap () 으로 이 값을 수정하지 않아야 합니다.3.5.5 하드웨어 초기화참고이 단원은 <strong>ARM</strong>v6-M 및 <strong>ARM</strong>v7-M 프로필에는 적용되지 않습니다.일반적으로 모든 시스템 초기화 코드는 주 응용 프로그램에서 분리하는 것이 좋습니다. 그러나 캐시 및 인터럽트 활성화와 같은 몇 가지 시스템 초기화 구성요소는 C 라이브러리 초기화 코드를 실행한 후에 수행되어야 합니다.3-20 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-Confidential


임베디드 소프트웨어 개발$Sub 및 $Super 함수 래퍼 기호를 사용하면 주 응용 프로그램을 시작하기 직전에실행되는 루틴을 삽입할 수 있습니다. 이 메커니즘을 사용하면 소스 코드를 변경하지 않고도 함수를 확장할 수 있습니다.예제 3-7에서는 $Sub 및 $Super를 이러한 방식으로 사용하는 방법을 보여 줍니다.링커에서는 main () 에 대한 함수 호출을 $Sub$$main () 에 대한 호출로 바꿉니다. 이 호출을 통해 캐시를 활성화하는 루틴과 인터럽트를 활성화하는 다른 루틴을호출할 수 있습니다.코드는 $Super$$main () 을 호출하여 실제 main () 으로 분기됩니다.참고자세한 내용은 링커 사용 설명서에서 4-14페이지의 $Super$$ 및 $Sub$$를 사용하여 기호 정의 재정의를 참조하십시오.예제 3-7 $Sub 및 $Super 사용extern void $Super$$main (void) ;void $Sub$$main (void){cache_enable () ; // enables cachesint_enable () ; // enables interrupts$Super$$main () ; // calls original main ()}3.5.6 실행 모드 고려 사항참고이 단원은 <strong>ARM</strong>v6-M 및 <strong>ARM</strong>v7-M 프로필에는 적용되지 않습니다.주 응용 프로그램을 실행할 모드를 고려해야 합니다. 선택한 모드는 시스템 초기화를 구현하는 방식에 영향을 줍니다.시작할 때 리셋 처리기와 $Sub$$main 모두에서 구현할 수 있는 기능의 대부분은 칩내부 메모리 조작과 같은 권한 모드에서 실행되어 인터럽트를 활성화하는 동안에만 수행할 수 있습니다.응용 프로그램을 권한 모드에서 실행할 경우에는 이것이 문제가 되지 않습니다.리셋 처리기를 종료하기 전에 해당 모드로 변경하십시오.<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 3-21Non-Confidential


임베디드 소프트웨어 개발그러나 사용자 모드에서 응용 프로그램을 실행하려는 경우에는 권한 모드에서필요한 작업을 완료한 후에만 사용자 모드로 변경할 수 있습니다. 이 작업을 수행하기에 가장 적합한 위치는 $Sub$$main () 입니다.참고__user_initial_stackheap () 은 응용 프로그램 모드 스택을 설정해야 합니다. 따라서 사용자 모드 레지스터를 사용하는 시스템 모드에서 리셋 처리기를 종료해야 합니다. 그러면 __user_initial_stackheap () 이 시스템 모드에서 실행되며 사용자 모드로 전환될 때 응용 프로그램 스택과 힙도 설정됩니다.3-22 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-Confidential


임베디드 소프트웨어 개발3.6 타겟 하드웨어 및 메모리 맵이 장의 이전 단원에서는 스캐터 로딩 설명 파일에서의 코드 및 데이터 배치에 대해 설명했습니다. 그러나 타겟 하드웨어 주변 기기의 위치와 스택 및 힙 한계는소스 또는 헤더 파일에 하드 코딩되어 있다고 가정했습니다. 타겟의 메모리 맵과관련된 모든 정보를 설명 파일에 배치하고 소스 코드에서 절대 주소에 대한 모든참조를 제거하는 것이 좋습니다.일반적으로 주변 기기 레지스터의 주소는 프로젝트 소스 또는 헤더 파일에 하드코딩됩니다. 주변 기기 레지스터에 매핑되는 구조체를 선언하고 이러한 구조체를 스캐터 로딩 설명 파일에 배치할 수도 있습니다.예를 들어 타겟에는 두 가지 메모리 매핑 32비트 레지스터를 사용하는 타이머 주변 기기가 있을 수 있습니다. 예제 3-8에서는 이러한 레지스터에 매핑되는 C 구조체를 보여 줍니다.예제 3-8 주변 기기 레지스터에 매핑__attribute__ ( (zero_init) ) struct{volatile unsigned ctrl; /* timer control */volatile unsigned tmr; /* timer value */} timer_regs;이 구조체를 메모리 맵의 특정 주소에 배치하려면 해당 구조체를 정의하는 모듈이 포함된 실행 영역을 만들면 됩니다. 3-24페이지의 예제 3-9에서는 timer_regs구조체를 0x40000000에 배치하는 TIMER라는 실행 영역을 보여 줍니다.이러한 레지스터의 내용은 응용 프로그램을 시작할 때 0으로 초기화되지 않아야합니다. 0으로 초기화되면 시스템의 상태가 변경될 수 있기 때문입니다. 실행 영역을 UNINIT 속성으로 표시하면 해당 영역에 있는 ZI 데이터가 __main을 통해 0으로 초기화되지 않습니다.<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 3-23Non-Confidential


임베디드 소프트웨어 개발예제 3-9 매핑된 구조체 배치ROM_LOAD 0x24000000 0x04000000{; ...TIMER 0x40000000 UNINIT{timer_regs.o (+ZI)}; ...}3-24 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-Confidential


4장C, C++ 및 어셈블리 언어 조합이 장에서는 <strong>ARM</strong> 아키텍처용으로 C, C++ 및 어셈블리 언어 코드를 조합하여 작성하는 방법을 설명합니다. 또한 C와 C++ 파일에서 <strong>ARM</strong> 명령어 내장 함수, 인라인 어셈블러 및 임베디드 어셈블러를 사용하는 방법에 대해서도 설명합니다.이 장에는 다음 단원이 포함되어 있습니다.• 4-2페이지의 명령어 내장 함수, 인라인 어셈블러 및 임베디드 어셈블러 사용• 4-4페이지의 어셈블리 코드에서 C 전역 변수 액세스• 4-5페이지의 C++에서 C 헤더 파일 사용• 4-7페이지의 C, C++ 및 <strong>ARM</strong> 어셈블리 언어 간 호출<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 4-1Unrestricted AccessNon-Confidential


C, C++ 및 어셈블리 언어 조합4.1 명령어 내장 함수, 인라인 어셈블러 및 임베디드 어셈블러 사용명령어 내장 함수, 인라인 어셈블러 및 임베디드 어셈블러는 정상적인 방법으로는 C 또는 C++에서 직접 액세스할 수 없는 타겟 프로세서 기능을 사용할 수 있도록 <strong>ARM</strong> 컴파일러에서 기본적으로 제공됩니다. 예를 들면 다음과 같습니다.• 포화 산술• 사용자 지정 보조 프로세서• PSR (프로그램 상태 레지스터)명령어 내장 함수명령어 내장 함수를 사용하면 어셈블리 언어에서 복잡한 구현으로재정렬하지 않고도 C 및 C++ 소스 코드에서 타겟 프로세서 기능을손쉽게 통합할 수 있습니다. 명령어 내장 함수는 C 또는 C++의 함수호출과 비슷하지만 어셈블리 언어 명령어를 통해 컴파일되는 동안대체됩니다.참고명령어 내장 함수는 <strong>ARM</strong> 명령어 세트에 사용되므로 다른 아키텍처로 이식할 수 없습니다.인라인 어셈블러인라인 어셈블러는 C 및 C++와의 인터워킹을 지원합니다. 레지스터 피연산자는 임의의 C 또는 C++ 식일 수 있습니다. 또한 인라인 어셈블러는 복잡한 명령어를 확장하고 어셈블리 언어 코드를 최적화합니다.참고컴파일러 최적화로 인해 출력 객체 코드가 입력에 정확히 대응되지않을 수도 있습니다.임베디드 어셈블러임베디드 어셈블러에서는 어셈블러 지시어를 비롯하여 전체 <strong>ARM</strong>어셈블러 명령어 세트를 사용할 수 있습니다. 임베디드 어셈블리 코드는 C 및 C++ 코드와는 별도로 어셈블됩니다. 컴파일된 객체는 생성 후 C 및 C++ 소스의 컴파일을 통해 생성된 객체와 결합됩니다.4-2 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


C, C++ 및 어셈블리 언어 조합표 4-1에서는 명령어 내장 함수, 인라인 어셈블러 및 임베디드 어셈블러의 주요차이점을 간단히 설명합니다.기능 명령어 내장 함수 인라인 어셈블러 임베디드 어셈블러명령어 세트 <strong>ARM</strong> 및 Thumb <strong>ARM</strong>만 <strong>ARM</strong> 및 Thumb<strong>ARM</strong> 어셈블러 지시어 지원 안 됨 지원 안 됨 모두 지원C/C++ 식 모든 C/C++ 식 모든 C/C++ 식 상수 식만어셈블리 코드의 최적화 모두 최적화 모두 최적화 최적화 안 함표 4-1 차이점인라인 자동으로 인라인됨 자동으로 인라인됨 크기가 올바르며 링커 인라인이 활성화되어 있으면 링커에서 인라인될 수있음레지스터 액세스물리 레지스터 (PC, LR,SP 포함)가상 레지스터 (PC, LR,SP 제외)물리 레지스터 (PC, LR,SP 포함)명령어 반환 자동 생성됨 자동 생성됨. BX, BXJ 및BLX 명령어는 지원 안 됨코드에 추가해야 함BKPT 명령어 지원됨 지원되지 않음 지원됨자세한 내용은 다음 항목을 참조하십시오.• 컴파일러 사용 설명서의 4-2페이지의 내장 함수• 컴파일러 참조 설명서의 4-69페이지의 명령어 내장 함수• 컴파일러 사용 설명서의 7장 인라인 및 임베디드 어셈블러 사용• 어셈블러 설명서의 4-92페이지의 포화 명령어<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 4-3Unrestricted AccessNon-Confidential


C, C++ 및 어셈블리 언어 조합4.2 어셈블리 코드에서 C 전역 변수 액세스전역 변수는 변수의 주소를 통해 간접적으로만 액세스할 수 있습니다. 전역 변수에 액세스하려면 IMPORT 지시어를 사용하여 가져오기를 수행한 후 해당 주소를 레지스터로 로드합니다. 전역 변수의 유형에 따라 로드 및 저장 명령어를 사용하여전역 변수에 액세스할 수 있습니다.예를 들어 unsigned 변수의 경우 다음 명령어를 사용합니다.• char의 경우 LDRB/STRB• short의 경우 LDRH/STRH• int의 경우 LDR/STRsigned 변수의 경우 LDRSB 및 LDRSH와 같이 부호 있는 해당 명령어를 사용합니다.8워드 미만의 작은 구조체는 LDM 및 STM 명령어를 사용하여 전체적으로 액세스할수 있습니다. 구조체의 개별 구성원은 적절한 유형의 로드 또는 저장 명령어를 통해 액세스할 수 있습니다. 구성원에 액세스하려면 구조체의 시작 부분부터 구성원까지의 오프셋을 알고 있어야 합니다.예제 4-1에서는 정수 전역 변수 globvar의 주소를 R1으로 로드하고, 해당 주소에포함된 값을 R0으로 로드하며, 이 값에 2를 더한 다음 새 값을 globvar에 다시 저장합니다.예제 4-1 전역 변수 액세스PRESERVE8AREA globals,CODE,READONLYEXPORT asmsubroutineIMPORT globvarasmsubroutineLDR R1, =globvar ; read address of globvar into R1LDR R0, [R1] ; load value of globvarADD R0, R0, #2STR R0, [R1] ; store new value into globvarBX lrEND<strong>ARM</strong> 또는 Thumb 코드에서 사용할 수 있는 명령어에 대한 자세한 내용은 어셈블러 설명서에서 4장 <strong>ARM</strong> 및 Thumb 명령어를 참조하십시오.4-4 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


C, C++ 및 어셈블리 언어 조합4.3 C++에서 C 헤더 파일 사용C 헤더 파일은 C++에서 포함되기 전에 extern "C" 지시어로 래핑되어야 합니다.4.3.1 시스템 C 헤더 파일 포함표준 시스템 C 헤더 파일에는 이미 적절한 extern "C" 지시어가 포함되어 있으므로 이 파일을 포함하기 위해 특수한 단계를 수행하지 않아도 됩니다. 다른#include 구문은 사용할 네임스페이스와 보유 중인 액세스 유형을 결정합니다.예를 들면 다음과 같습니다.#include int main (){... // C++ codereturn 0;}이 구문을 사용하여 헤더를 포함하면 모든 라이브러리 이름이 전역 네임스페이스에 배치됩니다.C++ 표준은 C++ 관련 헤더 파일을 통해 C 헤더 파일의 기능을 사용할 수 있도록지정합니다. 이러한 파일은 표준 C 헤더 파일과 함께install_directory\RVCT\Data\...\include\platform에 설치되며, 일반적인 방법으로참조할 수 있습니다. 예를 들면 다음과 같습니다.#include <strong>ARM</strong> C++에서 이러한 헤더는 C 헤더를 포함 (#include) 합니다. 이 구문을 사용하여 헤더를 포함하면 C 라이브러리 이름을 포함하여 모든 C++ 표준 라이브러리이름이 std 네임스페이스에 정의됩니다. 따라서 다음 방법 중 하나를 사용하여 모든 라이브러리 이름을 정규화해야 합니다.• 아래와 같이 표준 네임스페이스를 지정합니다.std::printf ("example\n") ;• C++ 키워드 using을 사용하여 전역 네임스페이스로 이름을 가져옵니다.using namespace std;printf ("example\n") ;• 컴파일러 옵션 --using_std를 사용합니다.<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 4-5Unrestricted AccessNon-Confidential


C, C++ 및 어셈블리 언어 조합4.3.2 사용자 고유의 C 헤더 파일 포함사용자 고유의 C 헤더 파일을 포함하려면 extern "C" 문에서 #include 지시어를 래핑해야 합니다. 다음 방법으로 이 작업을 수행할 수 있습니다.• 파일이 포함 (#include) 되어 있는지 확인합니다 (예제 4-2 참조) .• 헤더 파일에 extern "C" 문을 추가합니다 (예제 4-3참조) .예제 4-2 파일을 포함하기 전의 지시어// C++ codeextern "C" {#include "my-header1.h"#include "my-header2.h"}int main (){// ...return 0;}예제 4-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. */4-6 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


C, C++ 및 어셈블리 언어 조합4.4 C, C++ 및 <strong>ARM</strong> 어셈블리 언어 간 호출이 단원에서는 C++에서 C 및 어셈블리 언어 코드를 호출하고 C 및 어셈블리 언어에서 C++ 코드를 호출하는 방법을 보여 주는 예제를 제공합니다. 다음을 비롯한 호출 규칙 및 데이터 유형에 대해서도 설명합니다.AAPCS (Procedure Call Standard for the <strong>ARM</strong> Architecture) 를 준수할 경우 C/C++및 어셈블리 언어 루틴 간의 호출을 조합할 수 있습니다. 자세한 내용은install_directory\Documentation\Specifications\...에 있는 AAPCS 사양(aapcs.pdf) 을 참조하십시오.참고이 단원의 내용은 구현 방식에 따라 달라지며 이후 릴리스에서 변경될 수 있습니다.4.4.1 언어 간 호출을 위한 일반적인 규칙C, C++ 및 어셈블리 언어 간의 호출에는 다음과 같은 일반적인 규칙이 적용됩니다. 자세한 내용은 컴파일러 사용 설명서를 참조하십시오.임베디드 어셈블러를 사용하고 BSABI (<strong>ARM</strong> 아키텍처용 기본 표준 응용 프로그램 바이너리 인터페이스) 를 준수하면 조합 언어 프로그래밍을 보다 쉽게 구현할수 있습니다. 이를 통해 다음 사항과 관련된 작업을 쉽게 수행할 수 있습니다.• __cpp 키워드를 사용한 이름 자르기• 암시적 this 매개변수가 전달되는 방식• 가상 함수가 호출되는 방식• 참조 표현• 기본 클래스 또는 가상 구성원 함수가 있는 C++ 클래스 유형의 레이아웃• PODS (기존의 일반 데이터 구조체) 가 아닌 클래스 객체 전달조합 언어 프로그래밍에는 다음과 같은 일반적인 규칙이 적용됩니다.• C 호출 규칙을 사용합니다.• C++에서 비멤버 함수를 extern "C"로 선언하여 C 연결을 포함하도록 지정할 수 있습니다. 이번 릴리스의 RealView Compilation Tools에서 C 연결을포함한다는 것은 함수를 정의하는기호가 잘리지 않는다는 것을 의미합니다. C 연결을 사용하면 함수를 한 언어로 구현한 후 다른 언어에서 호출할수 있습니다.<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 4-7Unrestricted AccessNon-Confidential


C, C++ 및 어셈블리 언어 조합참고extern "C"로 선언된 함수는 오버로드할 수 없습니다.• 어셈블리 언어 모듈은 응용 프로그램에서 사용하는 메모리 모듈에 적절한AAPCS 표준을 준수해야 합니다.C 및 어셈블리 언어에서 C++ 함수를 호출하는 데는 다음 규칙이 적용됩니다.• 전역 (비 구성원) C++ 함수를 호출하려면 해당 함수를 extern "C"로 선언하여 함수에 C 링키지를 지정합니다.• 구성원 함수 (정적 및 비정적 함수 모두 포함) 에는 항상 잘린 이름이 있습니다. 임베디드 어셈블러의 __cpp 키워드를 사용하면 변환된 이름을 직접 찾을필요가 없습니다.• C++ 컴파일러에서 함수의 라인 외부 복사본을 생성할 수 없는 경우에는 C에서 C++ 인라인 함수를 호출할 수 없습니다. 예를 들어 함수의 주소를 사용하면 라인 외부 복사본이 생성됩니다.• 비정적 구성원 함수는 int 계열이 아닌 구조체를 반환할 경우 첫 번째 인수(R0) 나 두 번째 인수 (R1) 로 암시적 this 매개변수를 받습니다. 정적 구성원함수는 암시적 this 매개변수를 받지 않습니다.4.4.2 C++ 관련 정보다음 내용은 C++에만 해당됩니다.C++ 호출 규칙<strong>ARM</strong> C++에서는 다음 사항을 제외하고는 <strong>ARM</strong> C와 동일한 호출 규칙을 사용합니다.• 비정적 구성원 함수는 int 계열이 아닌 struct를 반환할 경우 첫 번째 인수나두 번째 인수로 암시적 this 매개변수를 사용하여 호출됩니다. 이는 이후 구현에서 변경될 수 있습니다.4-8 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


C, C++ 및 어셈블리 언어 조합C++ 데이터 유형<strong>ARM</strong> C++에서는 다음 사항을 제외하고는 <strong>ARM</strong> C와 동일한 데이터 유형을 사용합니다.• struct 또는 class 유형의 C++ 객체는 기본 클래스나 가상 함수가 없는 경우<strong>ARM</strong> C에서 일반적으로 사용되는 레이아웃과 동일한 레이아웃을 사용합니다. 이러한 struct에 사용자 정의 복사본 할당 연산자나 사용자 정의 소멸자가 없으면 해당 구조체는 기존의 일반적인 데이터 구조체입니다.• 참조는 포인터로 표시됩니다.• C 함수에 대한 포인터와 C++ 비멤버 함수에 대한 포인터가 구별되지 않습니다.기호 이름 자르기링커에서는 메시지의 기호 이름을 자르지 않습니다.C++ 프로그램에서 C 이름은 extern "C"로 선언되어야 합니다. <strong>ARM</strong> ISO C 헤더의경우에는 C 이름이 이미 이렇게 선언되어 있습니다. 자세한 내용은 4-5페이지의C++에서 C 헤더 파일 사용을 참조하십시오.4.4.3 언어 간 호출 예제다음 단원에는 여러 언어 간의 호출 방법을 보여 주는 코드 예제가 포함되어 있습니다.• 4-10페이지의 C에서 어셈블리 언어 호출• 4-11페이지의 어셈블리 언어에서 C 호출• 4-12페이지의 C++에서 C 호출• 4-13페이지의 C++에서 어셈블리 언어 호출• 4-14페이지의 C에서 C++ 호출• 4-15페이지의 어셈블리 언어에서 C++ 호출• 4-17페이지의 C 또는 어셈블리 언어에서 C++ 호출• 4-16페이지의 C 및 C++ 간에 참조 전달<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 4-9Unrestricted AccessNon-Confidential


C, C++ 및 어셈블리 언어 조합C에서 어셈블리 언어 호출예제 4-4와 예제 4-5에서는 어셈블리 언어 서브루틴을 호출하여 한 문자열을 다른 문자열의 맨 위에 복사하는 C 프로그램을 보여 줍니다.예제 4-4 C에서 어셈블리 언어 호출#include 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) ;}예제 4-5 어셈블리 언어 문자열 복사 서브루틴PRESERVE8AREA SCopy, CODE, READONLYEXPORT 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 null terminator.BNE strcopy ; Keep going if not.BX lr ; Return.END예제 4-4는 예제 디렉토리의 ...\asm에 strtest.c 및 scopy.s라는 이름으로 포함되어 있습니다.명령 행에서 예제를 빌드하려면 다음 단계를 수행하십시오.1. armasm --debug scopy.s를 입력하여 어셈블리 언어 소스를 빌드합니다.2. armcc -c --debug strtest.c를 입력하여 C 소스를 빌드합니다.4-10 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


C, C++ 및 어셈블리 언어 조합3. armlink strtest.o scopy.o -o strtest를 입력하여 개체 파일을 링크합니다.4. 호환되는 디버거를 적절한 디버그 타겟과 함께 사용하여 이미지를 실행합니다.어셈블리 언어에서 C 호출예제 4-6과 예제 4-7에서는 어셈블리 언어에서 C를 호출하는 방법을 보여 줍니다.예제 4-6 C에서 함수 정의int g (int a, int b, int c, int d, int e){return a + b + c + d + e;}예제 4-7 어셈블리 언어 호출; int f (int i) { return g (i, 2*i, 3*i, 4*i, 5*i) ; }PRESERVE8EXPORT fAREA f, CODE, READONLYIMPORT g; i is in R0STR lr, [sp, #-4]! ; preserve lrADD R1, R0, R0 ; compute 2*i (2nd param)ADD R2, R1, R0 ; compute 3*i (3rd param)ADD R3, R1, R2 ; compute 5*iSTR R3, [sp, #-4]! ; 5th param on stackADD R3, R1, R1 ; compute 4*i (4th param)BL g; branch to C functionADD sp, sp, #4 ; remove 5th paramLDR pc, [sp], #4 ; returnEND<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 4-11Unrestricted AccessNon-Confidential


C, C++ 및 어셈블리 언어 조합C++에서 C 호출예제 4-8과 예제 4-9에서는 C++에서 C를 호출하는 방법을 보여 줍니다.예제 4-8 C++에서 C 함수 호출struct S {// has no base classes// or virtual functionsS (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;}예제 4-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;}4-12 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


C, C++ 및 어셈블리 언어 조합C++에서 어셈블리 언어 호출예제 4-10과 예제 4-11에서는 C++에서 어셈블리 언어를 호출하는 방법을 보여 줍니다.예제 4-10 C++에서 어셈블리 언어 호출struct S { // has no base classes// or virtual functionsS (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;}예제 4-11 어셈블리 언어 함수 정의PRESERVE8AREA Asm, CODEEXPORT asmfuncasmfuncLDR R1, [R0]ADD R1, R1, #5STR R1, [R0]BX lrEND; the definition of the Asm; function to be called from C++<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 4-13Unrestricted AccessNon-Confidential


C, C++ 및 어셈블리 언어 조합C에서 C++ 호출예제 4-12와 예제 4-13에서는 C에서 C++를 호출하는 방법을 보여 줍니다.예제 4-12 C++에서 호출되도록 함수 정의struct S { // has no base classes or virtual functionsS (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;}예제 4-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;}4-14 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


C, C++ 및 어셈블리 언어 조합어셈블리 언어에서 C++ 호출예제 4-14와 예제 4-15에서는 어셈블리 언어에서 C++를 호출하는 방법을 보여 줍니다.예제 4-14 C++에서 호출되도록 함수 정의struct S {// has no base classes or virtual functionsS (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;}<strong>ARM</strong> 어셈블리 언어에서는 C++ 함수의 이름을 가져오고 BL (링크 포함 분기) 명령어를 사용하여 해당 함수를 호출합니다.예제 4-15 어셈블리 언어 함수 정의fAREA Asm, CODEIMPORT cppfuncEXPORTf; import the name of the C++; function to be called from AsmSTMFD sp!,{lr}MOV R0,#2STR R0,[sp,#-4]! ; initialize structMOV R0,sp ; argument is pointer to structBL cppfunc ; call 'cppfunc' so it can change the structLDR R0, [sp], #4ADD R0, R0, R0,LSL #1LDMFD sp!,{pc}END<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 4-15Unrestricted AccessNon-Confidential


C, C++ 및 어셈블리 언어 조합C 및 C++ 간에 참조 전달예제 4-16과 예제 4-17에서는 C 및 C++ 간에 참조를 전달하는 방법을 보여줍니다.예제 4-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++ function to be called from C.return 7 * r;}int f () {int i = 3;return cfunc (i) ; // passes a pointer to 'i'}예제 4-17 C 함수 정의extern int cppfunc (const int*) ;/* declaration of the C++ function 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) ;}4-16 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


C, C++ 및 어셈블리 언어 조합C 또는 어셈블리 언어에서 C++ 호출예제 4-18, 예제 4-19 및 예제 4-20에 나오는 코드에서는 C 또는 어셈블리 언어에서 비정적이며 가상이 아닌 C++ 구성원 함수를 호출하는 방법을 보여 줍니다. 함수의 잘린 이름을 찾으려면 컴파일러에서 어셈블러 출력을 사용합니다.예제 4-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 Treturn cfunc (&t) ;}예제 4-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) ' */}예제 4-20 어셈블리 언어에서 함수 구현EXPORT cfuncAREA foo, CODEIMPORT _ZN1T1fEicfuncSTMFD sp!,{lr} ; R0 already contains the object pointerMOV R1, #2BL _ZN1T1fEi<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 4-17Unrestricted AccessNon-Confidential


C, C++ 및 어셈블리 언어 조합ADD R0, R0, R0, LSL #1 ; multiply by 3LDMFD sp!,{pc}END또는 예제 4-21에 나와 있는 대로 임베디드 어셈블리를 사용하여 4-17페이지의예제 4-18과 4-17페이지의 예제 4-20을 구현할 수 있습니다. 이 예제에서 __cpp 키워드는 함수를 참조하는 데 사용됩니다. 따라서 함수의 변환된 이름을 몰라도 됩니다.예제 4-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 3LDMFD sp!, {pc}}int f () {T t (5) ; // create an object of type Treturn asm_func (&t) ;}4-18 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


5장<strong>ARM</strong>과 Thumb의 인터워킹이 장에서는 <strong>ARM</strong> 및 Thumb 명령어 세트를 구현하는 프로세서를 위한 코드를 작성할 때 <strong>ARM</strong> 상태와 Thumb 상태 사이에서 전환하는 방법을 설명합니다.참고이 장의 내용은 <strong>ARM</strong>v6-M 및 <strong>ARM</strong>v7-M에는 적용되지 않습니다.이 장에는 다음 단원이 포함되어 있습니다.• 5-2페이지의 인터워킹 개요• 5-5페이지의 어셈블리 언어 인터워킹• 5-6페이지의 C 및 C++ 인터워킹• 5-8페이지의 인터워킹 예제<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 5-1Unrestricted AccessNon-Confidential


<strong>ARM</strong>과 Thumb의 인터워킹5.1 인터워킹 개요인터워킹을 통해 <strong>ARM</strong> 코드와 Thumb 코드를 함께 사용하여 다음을 수행할 수 있습니다.• <strong>ARM</strong> 루틴에서 Thumb 상태 호출자로 복귀할 수 있습니다.• Thumb 루틴에서 <strong>ARM</strong> 상태 호출자로 복귀할 수 있습니다.즉, 인터워킹용 코드를 컴파일하거나 어셈블하면 코드에서는 사용되는 명령어세트에 관계없이 다른 모듈의 루틴을 호출할 수 있습니다. <strong>ARM</strong> 컴파일러 및<strong>ARM</strong> 어셈블러에서는 모두 --apcs=/interwork 명령 행 옵션을 사용하여 인터워킹을 활성화합니다.<strong>ARM</strong> 및 Thumb용 코드를 원하는 대로 조합하여 컴파일 또는 어셈블할 수 있습니다. 단, 코드는 AAPCS를 준수해야 합니다.install_directory\Documentation\Specifications\...\<strong>PDF</strong>\aapcs.pdf에 있는 사양을참조하십시오.링커가 다음을 감지하는 경우 오류가 생성됩니다.• 호출 수신자 루틴이 인터워킹용으로 빌드되지 않은 직접 <strong>ARM</strong> 또는 Thumb인터워킹 호출• 호환되지 않는 AAPCS 옵션을 사용하는 어셈블리 언어 소스 파일인터워킹 함수를 다른 상태에서 호출하면 <strong>ARM</strong> 링커에서는 이를 감지합니다. 그러면 호출 및 반환 명령어가 변경되며 베니어라는 작은 코드 조각이 삽입되어 필요한 경우 프로세서 상태를 변경합니다. 자세한 내용은 링커 사용 설명서에서3-20페이지의 베니어를 참조하십시오.<strong>ARM</strong> 아키텍처 v5T 이상에서는 추가 명령어를 사용하지 않고도 프로세서 상태를 변경할 수 있는 방법이 제공됩니다. <strong>ARM</strong>v5T 이상 프로세서에서는 인터워킹과 관련된 비용이 거의 들지 않습니다.참고<strong>ARM</strong>v5T 이상 버전용으로 컴파일하면 자동으로 인터워킹이 사용되는 것으로 간주되어 인터워킹에 안전하게 사용할 수 있는 코드가 항상 생성됩니다. 그러나<strong>ARM</strong>v5T용으로 빌드된 어셈블리 코드에는 인터워킹이 포함되지 않으므로 어셈블리 코드를 빌드할 때 --apcs=/interwork 어셈블러 옵션을 사용해야 합니다.5-2 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


<strong>ARM</strong>과 Thumb의 인터워킹5.1.1 인터워킹을 사용하는 경우Thumb 명령어를 지원하는 <strong>ARM</strong> 프로세서를 위한 코드를 작성할 때는 보통 응용프로그램의 대부분이 Thumb 상태에서 실행되도록 빌드하게 됩니다. 이렇게 하면 코드 밀도를 최소화할 수 있습니다. 8비트 또는 16비트 메모리를 사용하면 성능을 최대화할 수도 있습니다. 그러나 다음과 같은 이유로 응용 프로그램의 일부는 <strong>ARM</strong> 상태에서 실행되도록 하려는 경우도 있습니다.속도기능예외 처리응용 프로그램의 일부 부분에서는 속도가 중요할 수 있습니다. 이러한 섹션은 Thumb 상태보다 <strong>ARM</strong> 상태에서 실행하는 것이 효율적일수 있습니다.일부 시스템에는 작은 크기의 고속 32비트 메모리가 포함되어 있습니다. <strong>ARM</strong> 코드는 8비트나 16비트 메모리에서 각 명령어를 가져오는 오버헤드 없이 이 메모리에서 실행될 수 있습니다.Thumb 명령어는 해당하는 <strong>ARM</strong> 명령어보다 융통성이 적습니다.Thumb 상태에서는 일부 작업을 수행할 수 없습니다. 다음과 같은 작업을 수행하려면 <strong>ARM</strong> 상태로 변경해야 합니다.• CPSR에 액세스하여 인터럽트를 활성화/비활성화하고 모드 변경 (어셈블러 설명서의 4-138페이지의 CPS 참조)• 보조 프로세서에 액세스• C 언어로는 수행할 수 없는 DSP (Digital Signal Processor) 수학 명령어 실행프로세서 예외가 발생하면 프로세서가 자동으로 <strong>ARM</strong> 상태로 전환됩니다. 따라서 예외 처리기의 첫 번째 부분은 <strong>ARM</strong> 명령어로 코딩해야 합니다. 이는 예외 처리기가 Thumb 상태로 다시 전환하여 예외의 주요 처리를 수행하는 경우에도 해당됩니다. 이러한 처리 과정의끝에서는 프로세서를 <strong>ARM</strong> 상태로 전환하여 처리기에서 주 응용 프로그램으로 복귀해야 합니다.독립 실행형 Thumb 프로그램Thumb 명령어를 지원하는 <strong>ARM</strong> 프로세서는 항상 <strong>ARM</strong> 상태에서시작됩니다. 간단한 Thumb 어셈블리 언어 프로그램을 실행하려면Thumb 상태로 변경한 다음 주 Thumb 루틴을 호출하는 <strong>ARM</strong> 헤더를추가합니다. 예제를 보려면 5-8페이지의 어셈블리 언어 인터워킹을참조하십시오.<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 5-3Unrestricted AccessNon-Confidential


<strong>ARM</strong>과 Thumb의 인터워킹참고Thumb-2 없이 Thumb을 지원하는 프로세서에서 발생하는 문제는 대부분 속도 또는 기능 때문에 <strong>ARM</strong> 상태를 변경하기 때문에 발생합니다. Thumb-2 명령어 세트는 <strong>ARM</strong> 명령어 세트와 거의 동일한 기능을 제공합니다.5-4 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


<strong>ARM</strong>과 Thumb의 인터워킹5.2 어셈블리 언어 인터워킹--apcs=/interwork 명령 행 옵션을 사용하면 <strong>ARM</strong> 어셈블러에서 다른 프로세서 상태로부터 호출할 수 있는 코드를 어셈블할 수 있습니다.armasm --thumb --apcs=/interworkarmasm --arm --apcs=/interwork어셈블리 언어 소스 파일에는 여러 개의 영역이 포함될 수 있습니다. 이러한 영역은 <strong>ARM</strong> ELF (Executable and Linkable Format) 섹션으로 구성됩니다. 각 영역에는<strong>ARM</strong> 명령어, Thumb 명령어 또는 둘 모두가 포함될 수 있습니다.링커를 사용하여 호출자와는 다른 명령어 세트를 사용하는 루틴에 대한 호출과이 루틴으로부터의 복귀를 지정할 수 있습니다. 이렇게 하려면 BL을 사용하여 루틴을 호출합니다 (5-9페이지의 예제 5-3 참조) .원하는 경우 명령어 세트를 명시적으로 변경하는 코드를 작성할 수 있습니다. 이렇게 하면 경우에 따라 보다 작거나 빠른 코드를 작성할 수 있습니다. BX, BLX, LDR,LDM 및 POP 명령어를 사용하여 프로세서 상태를 변경할 수 있습니다 (5-8페이지의예제 5-2 참조) . 자세한 내용은 어셈블러 설명서에서 4-114페이지의 B, BL, BX,BLX 및 BXJ를 참조하십시오.<strong>ARM</strong> 어셈블러는 Thumb 코드와 <strong>ARM</strong> 코드 모두를 어셈블할 수 있습니다. 기본적으로 <strong>ARM</strong> 어셈블러는 --thumb 옵션을 사용하여 호출되지 않은 경우 <strong>ARM</strong> 코드를 어셈블합니다.Thumb을 지원하는 모든 <strong>ARM</strong> 프로세서는 <strong>ARM</strong> 상태에서 시작되므로 Thumb 상태로 분기 및 전환하려면 BX 명령어를 사용한 후 다음 어셈블러 지시어를 사용하여 어셈블러에서 어셈블리 모드를 전환하도록 지정해야 합니다.<strong>ARM</strong> 및 THUMB 지시어는 어셈블러에서 적절한 명령어 세트의 명령어를 어셈블하도록 지정합니다 (어셈블러 설명서의 7-64페이지의 <strong>ARM</strong>, THUMB, THUMBX,CODE16 및 CODE32 참조) .<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 5-5Unrestricted AccessNon-Confidential


<strong>ARM</strong>과 Thumb의 인터워킹5.3 C 및 C++ 인터워킹--apcs=/interwork 명령 행 옵션을 사용하면 <strong>ARM</strong> 컴파일러에서 다른 프로세서 상태로부터 호출할 수 있는 C 및 C++ 코드를 컴파일할 수 있습니다.armcc --thumb --apcs=/interworkarmcc --arm --apcs=/interwork본문에 함수 호출이 없는 함수인 리프 함수의 경우, 컴파일러는 복귀 명령어 BX lr을 생성합니다.Thumb 상태에서 <strong>ARM</strong>v4T용으로 빌드된 리프가 아닌 함수의 경우, 컴파일러에서는 다음과 같이 단일 복귀 명령어를 대체해야 합니다.POP {R4-R7,pc}이 단일 명령어를 다음 시퀀스로 대체해야 합니다.POP {R4-R7}POP {R3}BX R3이렇게 하면 성능에 약간의 영향이 미칩니다.--apcs=/interwork 옵션은 모듈이 컴파일되는 코드 영역의 인터워킹 특성도 설정합니다. 링커에서는 이 속성을 감지하고 적절한 베니어를 삽입합니다. 베니어가차지하는 공간의 크기를 확인하려면 링커 명령 행 옵션 --info=veneers를 사용하면 됩니다.인터워킹과 함께 사용할 가능성이 조금이라도 있는 경우에는 모든 소스 모듈을인터워킹용으로 컴파일하는 것이 좋습니다.참고<strong>ARM</strong>v4T 이전 프로세서에서는 BX 명령어를 구현하지 않으므로 인터워킹용으로컴파일된 <strong>ARM</strong> 코드는 <strong>ARM</strong>v4T 이상에서만 사용할 수 있습니다.5.3.1 Thumb 상태의 함수에 대한 포인터Thumb 코드로 구성되고 Thumb 상태에서 실행되는 함수인 Thumb 함수가 있는 경우, 해당 함수에 대한 포인터에 최하위 비트가 설정되어 있어야 인터워킹이 제대로 작동합니다.5-6 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


<strong>ARM</strong>과 Thumb의 인터워킹링커에서는 Thumb 명령어를 참조하는 레이블의 값을 재배치할 때 재배치된 값의 최하위 비트를 자동으로 설정합니다. Thumb 함수에 대한 절대 주소를 사용할경우에는 링커에서 이 작업이 자동으로 수행되지 않습니다. 따라서 코드에서Thumb 함수에 대한 절대 주소를 사용해야 하는 경우에는 주소에 1을 더해야 합니다 (예제 5-1 참조) .예제 5-1 Thumb 함수에 대한 절대 주소typedef int (*FN) () ;myfunc () {FN fnptrs[] = {(FN) (0x8084 + 1) , // Valid Thumb address(FN) (0x8074) // Invalid Thumb address};FN* myfunctions = fnptrs;myfunctions[0] () ; // Call OKmyfunctions[1] () ; // Call fails}5.3.2 동일한 함수의 두 가지 버전 사용각각 <strong>ARM</strong>과 Thumb용으로 컴파일된 같은 이름의 함수가 두 개 있을 수 있습니다.링커에서는 이미지에 한 기호에 대한 여러 개의 정의가 함께 있는 것을 허용합니다. 단, 각 정의가 서로 다른 프로세서 상태와 관련되어 있어야 합니다. 링커에서는 <strong>ARM</strong>/Thumb 동의어가 있는 기호를 참조할 때 다음 규칙이 적용됩니다.• <strong>ARM</strong> 상태의 기호에 대한 B, BL 또는 BLX 명령어는 <strong>ARM</strong> 정의로 확인됩니다.• Thumb 상태의 기호에 대한 B, BL 또는 BLX 명령어는 Thumb 정의로 확인됩니다.해당 심볼에 대한 다른 참조는 링커에서 발견하는 첫 번째 정의로 확인됩니다. 또한 링커에서 선택한 기호를 명시하는 경고가 생성됩니다.<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 5-7Unrestricted AccessNon-Confidential


<strong>ARM</strong>과 Thumb의 인터워킹5.4 인터워킹 예제다음은 인터워킹의 예제입니다.• 예제 5-2에서는 어셈블리 언어 인터워킹을 보여 줍니다.• 5-9페이지의 예제 5-3에서는 베니어를 사용한 어셈블리 언어 인터워킹을보여 줍니다.• 5-11페이지의 예제 5-4에서는 C 및 C++ 언어 인터워킹을 보여 줍니다.• 5-12페이지의 예제 5-5에서는 베니어를 사용한 C, C++ 및 어셈블리 언어 인터워킹을 보여 줍니다.Realview Development Suite에도 몇 가지 인터워킹 예제가 제공됩니다. 자세한 내용은 install_directory\RVDS\Examples\...\interwork에 있는 readme.txt 파일을 참조하십시오.예제 5-2 어셈블리 언어 인터워킹이 예제에서는 짧은 헤더 섹션 (SECTION 1) 과 ADR 명령어를 구현하여 THUMBProg레이블의 주소를 가져오고 최하위 주소 비트를 설정합니다. BX 명령어는 상태를Thumb 상태로 변경합니다.SECTION2에서는 Thumb 코드가 ADR 명령어를 사용해 두 레지스터의 내용을 더하여<strong>ARM</strong>Prog 레이블의 주소를 가져오지만 이때 최하위 비트는 지워진 상태로 있습니다. BX 명령어는 상태를 다시 <strong>ARM</strong> 상태로 변경합니다.SECTION3에서 <strong>ARM</strong> 코드는 두 레지스터의 내용을 더하고 작업을 종료합니다.; ********; addreg.s; ********PRESERVE8AREA AddReg,CODE,READONLY ; Name this block of code.ENTRY; Mark first instruction to call.; SECTION1startADR R0, ThumbProg:OR:1 ; Generate branch target address; and set bit 0, hence arrive; at target in Thumb state.BX R0; Branch exchange to ThumbProg.; SECTION2THUMB; Subsequent instructions are Thumb code.ThumbProgMOVS R2, #2 ; Load R2 with value 2.5-8 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


<strong>ARM</strong>과 Thumb의 인터워킹MOVS R3, #3 ; Load R3 with value 3.ADDS R2, R2, R3; R2 = R2 + R3ADR R0, <strong>ARM</strong>ProgBX R0; Branch exchange to <strong>ARM</strong>Prog.; SECTION3<strong>ARM</strong>; Subsequent instructions are <strong>ARM</strong> code.<strong>ARM</strong>ProgMOV R4, #4MOV R5, #5ADD R4, R4, R5; SECTION 4stop MOV R0, #0x18; angel_SWIreason_ReportExceptionLDR R1, =0x20026; ADP_Stopped_ApplicationExitSVC 0x123456; <strong>ARM</strong> semihostingEND; Mark end of this file.다음 단계에 따라 모듈을 빌드하고 링크합니다.1. 인터워킹용으로 소스 파일을 어셈블하려면 다음을 입력합니다.armasm --debug --apcs=/interwork addreg.s2. 객체 파일을 링크하려면 다음을 입력합니다.armlink addreg.o -o addreg.axf또는 인터워킹 베니어의 크기를 보려면 다음을 입력합니다.armlink addreg.o -o addreg.axf --info=veneers3. 호환되는 디버거를 적절한 디버그 타겟과 함께 사용하여 이미지를 실행합니다.예제 5-3 베니어를 사용한 어셈블리 언어 인터워킹이 예제에서는 레지스터 R0 ~ R2를 각각 값 1, 2 및 3으로 설정하는 어셈블리 코드의 소스 코드 인터워킹을 보여 줍니다. 레지스터 R0과 R2는 <strong>ARM</strong> 코드에서 설정되고 R1은 Thumb 코드에서 설정됩니다. 링커에서 인터워킹 베니어가 자동으로 삽입됩니다. 베니어를 사용하려면 다음을 수행합니다.• --apcs=/interwork 옵션을 사용하여 코드를 어셈블해야 합니다.• MOV pc,lr이 아닌 BX lr 명령어를 사용하여 복귀해야 합니다.; *****; arm.s; *****PRESERVE8<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 5-9Unrestricted AccessNon-Confidential


<strong>ARM</strong>과 Thumb의 인터워킹AREA Arm,CODE,READONLY ; Name this block of code.IMPORT ThumbProgENTRY; Mark 1st instruction to call.<strong>ARM</strong>ProgMOV R0,#1; Set R0 to show in <strong>ARM</strong> code.BL ThumbProg ; Call Thumb subroutine.MOV R2,#3; Set R2 to show returned to <strong>ARM</strong>.; Terminate execution.MOV R0, #0x18; angel_SWIreason_ReportExceptionLDR R1, =0x20026; ADP_Stopped_ApplicationExitSVC 0x123456; <strong>ARM</strong> semihosting (formerly SWI)END; *******; thumb.s; *******AREA Thumb,CODE,READONLY ; Name this block of code.THUMB; Subsequent instructions are Thumb.EXPORT ThumbProgThumbProgMOVS R1, #2; Set R1 to show reached Thumb code.BX lr ; Return to the <strong>ARM</strong> function.END; Mark end of this file.다음 단계에 따라 모듈을 빌드하고 링크합니다.1. <strong>ARM</strong> 코드를 인터워킹용으로 어셈블하려면 다음을 입력합니다.armasm --debug --apcs=/interwork arm.s2. Thumb 코드를 인터워킹용으로 어셈블하려면 다음을 입력합니다.armasm --thumb --debug --apcs=/interwork thumb.s3. 객체 파일을 링크하려면 다음을 입력합니다.armlink arm.o thumb.o -o count.axf또는 인터워킹 베니어의 크기를 보려면 다음을 입력합니다.armlink arm.o thumb.o -o count.axf --info=veneers4. 호환되는 디버거를 적절한 디버그 타겟과 함께 사용하여 이미지를 실행합니다.5-10 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


<strong>ARM</strong>과 Thumb의 인터워킹예제 5-4 C 및 C++ 언어 인터워킹이 예제에서는 인터워킹을 통해 <strong>ARM</strong> 서브루틴을 호출하는 Thumb 루틴을 보여줍니다. <strong>ARM</strong> 서브루틴 호출에서는 인터워킹을 통해 Thumb 라이브러리의 printf() 가 호출됩니다./********************** thumbmain.c ***********************/#include 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 void arm_function (void){printf ("Hello and Goodbye from <strong>ARM</strong>\n") ;}다음 단계에 따라 모듈을 빌드하고 링크합니다.1. Thumb 코드를 인터워킹용으로 컴파일하려면 다음을 입력합니다.armcc --thumb -c --debug --apcs=/interwork thumbmain.c -o thumbmain.o2. <strong>ARM</strong> 코드를 인터워킹용으로 컴파일하려면 다음을 입력합니다.armcc -c --debug --apcs=/interwork armsub.c -o armsub.o3. 개체 파일을 링크하려면 다음을 입력합니다.armlink thumbmain.o armsub.o -o thumbtoarm.axf또는 인터워킹 베니어의 크기를 보려면 다음을 입력합니다.armlink armsub.o thumbmain.o -o thumbtoarm.axf --info=veneers<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 5-11Unrestricted AccessNon-Confidential


<strong>ARM</strong>과 Thumb의 인터워킹4. 호환되는 디버거를 적절한 디버그 타겟과 함께 사용하여 이미지를 실행합니다.예제 5-5 베니어를 사용한 C, C++ 및 어셈블리 언어 인터워킹이 예제에서는 C로 작성된 Thumb 코드와 어셈블리 언어로 작성된 <strong>ARM</strong> 코드 간의 인터워킹을 보여 줍니다./*********************** thumb.c ***********************/#include extern int arm_function (int) ;int main (void){int i = 1;printf ("i = %d\n", i) ;printf ("And i+4 = %d\n", arm_function (i) ) ;return (0) ;}; *****; arm.s; *****PRESERVE8AREA Arm,CODE,READONLY ; Name this block of code.EXPORT arm_functionarm_functionADD R0,R0,#4 ; Add 4 to first parameter.BX lr ; ReturnEND다음 단계에 따라 모듈을 빌드하고 링크합니다.1. Thumb 코드를 인터워킹용으로 컴파일하려면 다음을 입력합니다.armcc --thumb --debug -c --apcs=/interwork thumb.c2. <strong>ARM</strong> 코드를 인터워킹용으로 어셈블하려면 다음을 입력합니다.armasm --debug --apcs=/interwork arm.s3. 객체 파일을 링크하려면 다음을 입력합니다.armlink arm.o thumb.o -o add.axf5-12 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


<strong>ARM</strong>과 Thumb의 인터워킹또는 인터워킹 베니어의 크기를 보려면 다음을 입력합니다.armlink arm.o thumb.o -o add.axf --info=veneers4. 호환되는 디버거를 적절한 디버그 타겟과 함께 사용하여 이미지를 실행합니다.<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 5-13Unrestricted AccessNon-Confidential


<strong>ARM</strong>과 Thumb의 인터워킹5-14 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


6장프로세서 예외 처리이 장에서는 <strong>ARM</strong> 아키텍처에서 지원하는 여러 가지 유형의 예외를 처리하는 방법을 설명합니다.이 장에는 다음 단원이 포함되어 있습니다.• 6-2페이지의 프로세서 예외 개요• 6-4페이지의 <strong>ARM</strong>v6 이하, <strong>ARM</strong>v7-A 및 <strong>ARM</strong>v7-R 프로필• 6-32페이지의 <strong>ARM</strong>v6-M 및 <strong>ARM</strong>v7-M 프로필<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 6-1Unrestricted AccessNon-Confidential


프로세서 예외 처리6.1 프로세서 예외 개요프로그램을 통한 일반적인 실행 흐름 동안에는 주소 공간을 통해 PC (프로그램카운터) 가 순차적으로 늘어나면서 인접 레이블로 분기되거나 서브루틴으로 분기 및 링크됩니다.이러한 일반적인 실행 흐름에 변화가 생기면 프로세서 예외가 발생하여, 프로세서에서 내부 또는 외부 원인으로 인해 생성된 이벤트를 처리할 수 있도록 합니다.이러한 이벤트의 예는 다음과 같습니다.• 외부에서 인터럽트가 생성되는 경우• 프로세서에서 정의되지 않은 명령어를 실행하려고 시도하는 경우• 권한이 필요한 운영 체제 기능에 액세스하려는 경우그림 6-1에서는 예외 처리 프로세스를 보여 줍니다.ApplicationcodeVectortableSave CPU andregister stateException occursHandle theexceptionRestore CPU andregister state그림 6-1 예외 처리예외가 발생하면 제어권이 벡터 테이블이라는 메모리 영역을 통해 전달됩니다.벡터 테이블은 예약된 영역으로, 대개 메모리 맵의 맨 아래에 있습니다. 테이블내에는 하나의 단어가 여러 예외 유형에 각각 할당됩니다. 이 단어에는 분기 명령어 또는 관련 예외 처리기의 주소 (<strong>ARM</strong>v6-M 및 <strong>ARM</strong>v7-M의 경우) 가 포함되어있습니다.프로세서에서 해당하는 명령어 세트를 지원하는 경우 <strong>ARM</strong> 또는 Thumb -2 코드로 예외 처리기를 작성할 수 있습니다. <strong>ARM</strong>v7-M 및 <strong>ARM</strong>v6-M 프로필의 경우에는 프로세서가 벡터 테이블에서 지정된 예외 처리기를 시작합니다. 다른 모든<strong>ARM</strong> 프로세서의 경우에는 최상위 처리기에서 예외를 처리하는 코드로 분기해야 합니다. 상태를 변경해야 하는 경우에는 분기 및 전환 (BX) 을 사용합니다. 자세6-2 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


프로세서 예외 처리한 내용은 5장 <strong>ARM</strong>과 Thumb의 인터워킹을 참조하십시오. 예외를 처리할 때는 적절한 예외 처리 루틴이 완료된 후 프로그램을 다시 시작할 수 있도록 현재 프로세서 모드, 상태 및 레지스터를 유지해야 합니다.<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 6-3Unrestricted AccessNon-Confidential


프로세서 예외 처리6.2 <strong>ARM</strong>v6 이하, <strong>ARM</strong>v7-A 및 <strong>ARM</strong>v7-R 프로필이 단원에서는 <strong>ARM</strong> 아키텍처 버전 6 이하, <strong>ARM</strong>v7-A 및 <strong>ARM</strong>v7-R 프로필에서지원하는 여러 가지 유형의 예외를 처리하는 방법을 설명합니다.참고마이크로컨트롤러 프로필은 다른 예외 처리 모델을 사용합니다. 자세한 내용은6-32페이지의 <strong>ARM</strong>v6-M 및 <strong>ARM</strong>v7-M 프로필을 참조하십시오.6.2.1 예외 유형표 6-1에는 <strong>ARM</strong>v6 이하, <strong>ARM</strong>v7-A 및 <strong>ARM</strong>v7-R 프로필에서 인식하는 여러 가지유형의 예외가 나와 있습니다. 여러 개의 예외가 동시에 발생하면 고정된 우선순위에 따라 예외가 처리됩니다. 각 예외가 차례대로 처리된 후에 원래 프로그램으로 돌아갑니다. 모든 예외가 동시에 발생할 수는 없습니다. 예를 들어 정의되지않은 명령어 (Undef) 예외와 관리자 호출 (SVC) 예외는 모두 명령어를 실행함으로써 트리거되므로 동시에 발생할 수 없습니다.예외 상태로 전환되면 다음이 수행됩니다.• 모든 예외에 대해 IRQ (인터럽트 요청) 가 비활성화됩니다.• FIQ 및 리셋 예외에 대해 FIQ (고속 인터럽트 요청) 가 비활성화됩니다.표 6-1 우선순위순 예외 유형우선순위(1=높음,6=낮음)예외 유형 예외 모드 설명1 리셋 관리자 프로세서 리셋 핀이 어설션될 때 발생합니다. 이예외는 전원 켜짐 신호가 전달되거나 프로세서가전원이 이미 켜져 있을 때와 같은 상태로 리셋되는 경우에만 발생합니다. 소프트 리셋은 리셋 벡터로 분기함으로써 수행할 수 있습니다.2 데이터 중단 중단 데이터 전송 명령어가 잘못된 주소에서 데이터를로드하거나 저장하려고 할 때 발생합니다 a .3 FIQ FIQ 프로세서 외부 고속 인터럽트 요청 핀이 어셜션(LOW) 되고 CPSR의 F 비트가 지워진 경우에 발생합니다.6-4 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


프로세서 예외 처리표 6-1 우선순위순 예외 유형 (계속)우선순위(1=높음,6=낮음)예외 유형 예외 모드 설명4 IRQ IRQ 프로세서 외부 인터럽트 요청 핀이 어셜션 (LOW)되고 CPSR의 I 비트가 지워진 경우에 발생합니다.5 프리페치 중단 중단 프로세서에서 잘못된 주소로 인해 가져오지 못한명령어를 실행하려고 할 때 발생합니다 a .6 SVC 관리자 SVC는 사용자 정의 동기 인터럽트 명령어입니다.이 명령어는 사용자 모드에서 실행되는 프로그램이 RTOS 함수와 같이 관리자 모드에서 실행되며권한이 필요한 작업을 요청할 수 있도록 합니다.6 정의되지 않은 명령어Undef프로세서 및 연결된 보조 프로세서 모두에서 현재 실행 중인 명령어를 인식할 수 없는 경우에 발생합니다.a. 잘못된 가상 주소는 현재 실제 메모리의 주소에 해당하지 않거나 메모리 관리 하위 시스템에서 현재 모드의 프로세서가 액세스할 수 없는 것으로 확인된 주소입니다.데이터 중단 예외는 FIQ 예외보다 우선순위가 높으므로 데이터 중단은 실제로FIQ가 처리되기 전에 등록됩니다. 그러나 데이터 중단을 처리할 때도 FIQ는 활성상태로 유지되므로 데이터 중단 처리기가 시작된 후에는 제어권이 FIQ 처리기에즉시 전달됩니다. FIQ가 처리되면 제어권은 데이터 중단 처리기에 반환됩니다.따라서 FIQ가 먼저 처리될 때와 마찬가지로 데이터 전송 오류가 감지될 수 있습니다.6.2.2 벡터 테이블<strong>ARM</strong>v6 이하, <strong>ARM</strong>v7-A 및 <strong>ARM</strong>v7-R 프로필의 벡터 테이블은 관련 처리기에 대한 분기 또는 로드 PC 명령어로 구성됩니다. 필요한 경우에는 벡터 테이블이 최대한 효율적으로 처리되도록 벡터 테이블 끝에 FIQ 처리기를 포함할 수 있습니다 (6-6페이지의 예제 6-1 참조) . 리터럴 풀을 사용하는 경우 나중에 필요하면 해당 주소를 쉽게 수정할 수 있습니다.<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 6-5Unrestricted AccessNon-Confidential


프로세서 예외 처리예제 6-1 리터럴 풀을 사용하는 일반적인 벡터 테이블Vector_TableFIQ_HandlerAREA vectors, CODE, READONLYENTRYLDR pc, Reset_AddrLDR pc, Undefined_AddrLDR pc, SVC_AddrLDR pc, Prefetch_AddrLDR pc, Abort_AddrNOPLDR pc, IRQ_Addr;Reserved vector; FIQ handler code - max 4kB in sizeReset_Addr DCD Reset_HandlerUndefined_Addr DCD Undefined_HandlerSVC_Addr DCD SVC_HandlerPrefetch_Addr DCD Prefetch_HandlerAbort_Addr DCD Abort_HandlerDCD 0IRQ_Addr DCD IRQ_Handler...END;Reserved vector이 예제에서는 리셋 시 ROM이 0x0 위치에 있다고 가정합니다. 또는 스캐터 로딩메커니즘을 사용하여 벡터 테이블의 로드 및 실행 주소를 정의할 수 있습니다. 이경우 C 라이브러리에서 자동으로 벡터 테이블을 복사합니다. 스캐터 로딩에 대한 자세한 내용은 링커 사용 설명서에서 5장 스캐터 로딩 설명 파일 사용을 참조하십시오.참고<strong>ARM</strong>v6 이하 아키텍처의 벡터 테이블은 <strong>ARM</strong> 명령어만 지원합니다. <strong>ARM</strong>v6T2이상 아키텍처의 벡터 테이블은 Thumb-2 및 <strong>ARM</strong> 명령어를 모두 지원합니다.<strong>ARM</strong>v6-M 및 <strong>ARM</strong>v7-M 프로필에는 이러한 내용이 적용되지 않습니다.6.2.3 프로세서 모드 및 레지스터<strong>ARM</strong> 아키텍처는 범용 레지스터 15개, PC 및 CPSR이 있는 권한이 없는 사용자 모드를 정의합니다. 또한 각각 SPSR과 여러 개의 뱅크 아웃 레지스터를 포함하는기타 권한 모드도 있습니다.6-6 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


프로세서 예외 처리일반적으로 응용 프로그램은 사용자 모드에서 실행되지만 예외를 처리하려면 권한 모드가 필요합니다. 예외가 발생하면 프로세서 모드가 변경되므로 각 예외 처리기에서 다음과 같은 뱅크 아웃 레지스터의 특정 하위 세트에 액세스할 수 있게됩니다.• 해당하는 SP (스택 포인터)• 해당하는 LR• 해당하는 SPSR• 5개의 추가 범용 레지스터 (FIQ에만 해당)각 예외 처리기가 종료되면 다른 레지스터는 원래 내용으로 복원되어야 합니다.이렇게 하려면 처리기에서 사용해야 하는 레지스터의 내용을 해당 스택에 저장하고 복귀 전에 이 레지스터를 복원합니다.시스템 모드링크 레지스터가 손상되면 같은 유형의 예외를 여러 개 처리할 때 문제가 발생할수 있습니다. 자세한 내용은 6-11페이지의 재진입 인터럽트 처리기를 참조하십시오.<strong>ARM</strong>v4 이상 아키텍처에는 시스템 모드라는 권한 모드가 포함되어 있으므로 이문제를 해결할 수 있습니다. 시스템 모드는 사용자 모드와 동일한 레지스터를 공유하고, 권한 액세스를 필요로 하는 작업을 실행할 수 있으며, 예외는 더 이상 링크 레지스터를 덮어쓰지 않습니다.참고시스템 모드는 예외가 발생할 때 전환되지 않습니다. 예외 처리기에서 CPSR을 수정하여 시스템 모드로 전환합니다. 예제를 보려면 6-11페이지의 재진입 인터럽트처리기를 참조하십시오.6.2.4 예외 처리이 단원에서는 예외에 대한 프로세서 응답과 예외가 처리된 후 주 프로그램으로복귀되는 방식을 설명합니다. 예외 처리기에서 예외가 발생할 때 시스템 상태를저장하고 복귀 시 복원하는지 확인해야 합니다.Thumb 상태를 지원하는 프로세서와 Thumb 상태를 지원하지 않는 프로세서는 동일한 기본 예외 처리 메커니즘을 사용합니다. 예외가 발생하면 적절한 벡터 테이블 엔트리에서 다음 명령어를 가져옵니다.<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 6-7Unrestricted AccessNon-Confidential


프로세서 예외 처리예외에 대한 프로세서 응답예외가 발생하면 프로세서에서는 다음과 같은 작업을 수행합니다.1. CPSR을 해당하는 SPSR로 복사합니다. 이렇게 하면 현재 모드, 인터럽트 마스크 및 조건 플래그가 저장됩니다.2. 현재 상태가 예외 벡터 테이블에서 사용되는 명령어 세트와 일치하지 않으면 상태를 자동으로 전환합니다.3. 적절한 CPSR 모드 비트를 변경하여 다음 작업을 수행합니다.• 적절한 모드로 변경하고 해당 모드의 적절한 뱅크 아웃 레지스터에 매핑• 인터럽트 비활성화. IRQ는 예외가 발생할 때 비활성화되고, FIQ는FIQ가 발생할 때와 리셋 시 비활성화됩니다.4. 해당하는 LR을 복귀 주소로 설정합니다.5. PC를 예외의 벡터 주소로 설정합니다.예외 처리기에서 복귀예외에서 복귀하는 데 사용되는 방법은 예외 처리기에서 스택 작업을 사용하는지 여부에 따라 달라집니다. 두 경우 모두 예외가 발생했던 위치로 실행 권한을되돌리려면 예외 처리기에서 다음을 수행해야 합니다.• 해당하는 SPSR에서 CPSR 복원• 해당하는 LR에서 복귀 주소를 사용하여 PC 복원스택에서 대상 모드 레지스터를 복원하지 않아도 되는 간단한 복귀의 경우 예외처리기에서는 다음 조건을 만족하는 데이터 처리 명령어를 실행하여 이러한 작업을 수행합니다.• S 플래그가 설정되어 있습니다.• PC를 대상 레지스터로 사용합니다.필요한 복귀 명령어는 예외 유형에 따라 달라집니다.참고리셋 처리기는 주 코드를 직접 실행하므로 리셋 처리기에서는 복귀할 필요가 없습니다.6-8 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


프로세서 예외 처리예외 처리기 진입 코드가 예외를 처리하는 동안 유지해야 하는 레지스터를 스택에 저장하는 경우 다중 로드 명령어와 ^ 한정자를 함께 사용하여 예외 처리기에서 복귀할 수 있습니다. 예를 들어 예외 처리기는 다음을 사용하는 단일 명령어에서 복귀할 수 있습니다.LDMFD sp!,{R0-R12,pc}^이렇게 하려면 예외 처리기에서 스택에 다음을 저장해야 합니다.• 처리기가 호출될 때 사용하고 있던 모든 작업 레지스터• 데이터 처리 명령어와 동일한 결과를 생성하도록 수정된 링크 레지스터^ 한정자는 CPSR이 SPSR에서 복원되도록 지정합니다. 이 한정자는 권한 모드에서만 사용해야 합니다. 자세한 내용은 어셈블러 설명서에서 LDM 및 STM을 사용한스택 구현 방법에 대한 설명을 참조하십시오.참고16비트 Thumb 명령어는 CPSR을 복원할 수 없으므로 예외에서 복귀하는 데 사용할 수 없습니다.6.2.5 리셋 처리기리셋 처리기에서 수행하는 작업은 소프트웨어를 개발할 때 의도한 시스템에 따라 달라집니다.예를 들면 다음과 같은 작업을 수행합니다.• 예외 벡터를 설정합니다. 자세한 내용은 6-5페이지의 벡터 테이블을 참조하십시오.• 스택과 레지스터를 초기화합니다.• MMU를 사용하는 경우 메모리 시스템을 초기화합니다.• 중요한 I/O 장치를 초기화합니다.• 인터럽트를 활성화합니다.• 프로세서 모드 및/또는 상태를 변경합니다.• C에 필요한 변수를 초기화하고 주 응용 프로그램을 호출합니다.자세한 내용은 3장 임베디드 소프트웨어 개발을 참조하십시오.<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 6-9Unrestricted AccessNon-Confidential


프로세서 예외 처리6.2.6 데이터 중단 처리기MMU가 없으면 데이터 중단 처리기는 오류를 보고하고 종료되어야 합니다.MMU가 있으면 처리기는 가상 메모리 오류를 처리해야 합니다.lr_ABT는 중단을 발생시킨 명령어 다음의 명령어 두 개를 가리키므로 중단을 발생시킨 명령어는 lr_ABT-8에 있습니다.다음 유형의 명령어는 이 어보트를 발생시킬 수 있습니다.단일 레지스터 로드 또는 저장응답은 프로세서 유형에 따라 달라집니다.• <strong>ARM</strong>7TDMI 를 비롯한 <strong>ARM</strong>7 에서 중단이 발생할 경우 주소레지스터가 업데이트되고 변경 내용이 취소되어야 합니다.• <strong>ARM</strong>9 이상 프로세서에서 중단이 발생할 경우 프로세서에서는 주소를 명령어가 시작되기 이전의 값으로 복원합니다. 변경 내용을 취소하는 데 필요한 코드는 없습니다.Swap (SWP) 이 명령어와 관련된 주소 레지스터 업데이트는 없습니다.다중 로드 또는 다중 저장응답은 프로세서 유형에 따라 달라집니다.• <strong>ARM</strong>7 프로세서에서 중단이 발생하고 갱신이 활성화되어 있으면 전체 전송이 발생할 때와 같은 방식으로 기준 레지스터가업데이트됩니다.기준 레지스터가 레지스터 목록에 있는 LDM의 경우 프로세서에서는 덮어쓰여진 값을 수정된 기준 값으로 대체하여 복구가가능하도록 합니다. 그러면 관련된 레지스터의 수를 사용하여원래 기준 주소를 다시 계산할 수 있습니다.• <strong>ARM</strong>9 이상 프로세서에서 중단이 발생하고 갱신이 활성화되어 있으면 기준 레지스터는 명령어가 시작되기 이전의 값으로복원됩니다.이러한 각각의 경우에서 MMU는 필요한 가상 메모리를 실제 메모리로 로드할 수있습니다. MMU FAR (Fault Address Register) 에는 중단을 발생시킨 주소가 들어있습니다. 이 작업이 수행될 때 처리기는 복귀하여 해당 명령어의 실행을 다시 시도할 수 있습니다.데이터 중단 처리기 예제는 예제 디렉토리의 ...\databort에 있습니다.6-10 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


프로세서 예외 처리6.2.7 인터럽트 처리기이 단원에서는 인터럽트 처리기를 작성하는 방법을 설명합니다.외부 인터럽트 수준<strong>ARM</strong> 프로세서에는 FIQ와 IRQ라는 두 가지 외부 인터럽트 수준이 있으며 이 두인터럽트 수준은 모두 프로세서로 보내지는 수준 인식 활성 LOW 신호입니다. 인터럽트를 받으려면 CPSR의 해당 비활성 비트가 지워져 있어야 합니다.FIQ는 IRQ보다 우선순위가 높으므로 다음과 같은 방식으로 처리됩니다.• 여러 개의 인터럽트가 발생할 경우 FIQ가 먼저 처리됩니다.• FIQ를 처리할 때 IRQ 및 후속 FIQ는 비활성화되므로 FIQ 처리기에서 다시활성화할 때까지는 IRQ 및 후속 FIQ가 처리되지 않습니다. 대개 처리기의끝에 있는 SPSR에서 CPSR을 복원하면 IRQ 및 후속 FIQ가 다시 활성화됩니다.FIQ 벡터는 벡터 테이블의 마지막 엔트리이므로 이 벡터 위치에 직접 FIQ 처리기를 배치하고 해당 주소에서부터 순차적으로 실행할 수 있습니다. 이렇게 하면 분기 및 관련 지연에 대한 요구 사항이 제거되며, 시스템에 캐시가 있는 경우 벡터테이블 및 FIQ 처리기가 모두 캐시 내의 한 블록에 잠깁니다. FIQ는 인터럽트를가능한 한 빠르게 처리하도록 설계되었기 때문에 이 작업은 중요합니다. 다섯 개의 추가 FIQ 모드 뱅크 레지스터를 사용하면 상태를 처리기에 대한 호출 사이에저장하고 실행 속도를 높일 수 있습니다.참고인터럽트 처리기에는 인터럽트의 원인을 제거하는 코드가 포함되어 있어야 합니다.재진입 인터럽트 처리기인터럽트 처리기에서 인터럽트를 활성화하고 서브루틴을 호출한 후 다른 인터럽트가 발생하면 두 번째 IRQ를 받을 때 IRQ 모드 LR에 저장된 서브루틴의 복귀 주소가 손상됩니다. 프로세서는 새 인터럽트에 대해 복귀 주소를 the IRQ mode LR에 자동으로 저장하여 서브루틴 복귀 주소를 덮어쓰기 때문입니다. 그러면 원래 인터럽트의 서브루틴이 복귀하려 할 때 무한 루프가 발생합니다.<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 6-11Unrestricted AccessNon-Confidential


프로세서 예외 처리재진입 인터럽트 처리기에서는 IRQ 상태를 저장하고, 프로세서 모드를 전환하며,중첩된 서브루틴이나 C 함수로 분기하기 전에 새 프로세서 모드의 상태를 저장해야 합니다. 또한 LDRD 또는 STRD 명령어나 8바이트로 정렬된 스택 할당 데이터를사용할 수 있는 AAPCS와 호환되는 컴파일된 C 코드를 호출하기 전에 스택이 새프로세서 모드에 대해 8바이트로 정렬되었는지 확인해야 합니다. 스택 정렬 문제에 대한 자세한 내용은ABI for the <strong>ARM</strong> Architecture Advisory Note 1 - SP는 AAPCS준수 함수에 진입 시 8바이트로 정렬되어야 합니다 (<strong>ARM</strong> IHI 0046A) 를 참조하십시오.C에서 __irq 키워드를 사용하면 재진입 인터럽트 처리기에서 필요로 하는 SPSR이 저장 및 복원되지 않으므로 어셈블리 언어로 최상위 수준 인터럽트 처리기를작성해야 합니다.<strong>ARM</strong>v4 이상의 경우에는 권한 액세스가 필요하면 시스템 모드로 전환할 수 있습니다. 자세한 내용은 6-7페이지의 시스템 모드를 참조하십시오.참고이 방법은 IRQ 및 FIQ 인터럽트 모두에 사용할 수 있습니다. 그러나 FIQ 인터럽트는 가능한 한 빠르게 처리되어야 하기 때문에 일반적으로 인터럽트 원인이 하나만 있을 수 있으며 따라서 재진입을 위해 FIQ 인터럽트를 제공할 필요는 없습니다.IRQ 처리기에서 인터럽트를 안전하게 활성화하는 데 필요한 단계는 다음과 같습니다.1. 복귀 주소를 생성하여 IRQ 스택에 저장합니다.2. 작업 레지스터, 호출 수신자가 저장하지 않는 레지스터 및 IRQ 모드 SPSR을 저장합니다.3. 인터럽트의 원인을 제거합니다.4. 시스템 모드로 전환하고 IRQ를 비활성화합니다.5. 스택이 8바이트로 정렬되어 있는지 확인하고 필요한 경우 조정합니다.6. 사용자 모드 SP에서 사용되는 사용자 모드 LR과 조정 (아키텍처 v4 또는v5TE의 경우 0 또는 4) 을 저장합니다.7. 인터럽트를 활성화하고 C 인터럽트 처리기 함수를 호출합니다.8. C 인터럽트 처리기 함수가 복귀할 때 인터럽트를 비활성화합니다.6-12 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


프로세서 예외 처리9. 사용자 모드 LR과 스택 조정 값을 복원합니다.10. 필요한 경우 스택을 다시 조정합니다.11. IRQ 모드로 전환합니다.12. 다른 레지스터와 IRQ 모드 SPSR을 복원합니다.13. IRQ에서 복귀합니다.예제 6-2 및 6-14페이지의 예제 6-3에서는 시스템 모드에서 이 작업을 수행하는방법을 보여 줍니다.예제 6-2 <strong>ARM</strong>v4/v5TE용 재진입 인터럽트 처리기PRESERVE8AREA INTERRUPT, CODE, READONLYIMPORT C_irq_handlerIMPORT identify_and_clear_sourceIRQ_HandlerSUB lr, lr, #4 ; construct the return addressPUSH {lr} ; and push the adjusted lr_IRQMRS lr, SPSR ; copy spsr_IRQ to lrPUSH {R0-R4,R12,lr} ; save AAPCS regs and spsr_IRQBL 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 stackSUB sp, sp, R1 ; remove any misalignment (0 or 4)PUSH {R1,lr} ; store the adjustment and lr_USRMSR CPSR_c, #0x1F ; enable IRQBL C_irq_handlerMSR CPSR_c, #0x9F ; disable IRQ, remain in SYS modePOP {R1,lr} ; restore stack adjustment and lr_USRADD 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.POP {R0-R4,R12,lr} ; restore registers andMSR SPSR_cxsf, lr ; spsr_IRQLDM sp!, {pc}^ ; return from IRQ.END<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 6-13Unrestricted AccessNon-Confidential


프로세서 예외 처리예제 6-3 <strong>ARM</strong>v6용 재진입 인터럽트 (비벡터 인터럽트)PRESERVE8AREA INTERRUPT, CODE, READONLYIMPORT C_irq_handlerIMPORT identify_and_clear_sourceIRQ_HandlerSUB lr, lr, #4SRSDB sp!,#31 ; Save LR_irq and SPSR_irq to System mode stackCPS #031; Switch to System modePUSH {R0-R3,R12} ; Store other AAPCS registersAND R1, sp, #4SUBsp, sp, R1PUSH {R1, lr}BLidentify_and_clear_sourceCPSIE i ; Enable IRQBLC_irq_handlerCPSID i; Disable IRQPOP {R1,lr}ADDsp, sp, R1POP {R0-R3, R12} ; Restore registersRFEIA sp! ; Return using RFE from System mode stackEND이러한 예제에서는 FIQ가 영구적으로 활성화 상태인 것으로 가정합니다.어셈블리 언어의 예제 인터럽트 처리기인터럽트 처리기는 빠르게 실행될 수 있도록 어셈블리 언어로 작성되는 경우가많습니다. 다음 단원에는 몇 가지 예제가 있습니다.• 단일 채널 DMA 전송• 6-15페이지의 이중 채널 DMA 전송• 6-17페이지의 인터럽트 우선순위• 6-18페이지의 컨텍스트 전환단일 채널 DMA 전송6-15페이지의 예제 6-4에서는 메모리 전송 (소프트 DMA) 에 대해 인터럽트 구동I/O를 수행하는 인터럽트 처리기를 보여 줍니다. 이 코드는 FIQ 처리기로, 뱅크FIQ 레지스터를 사용하여 인터럽트 간의 상태를 유지합니다. 이 코드는 0x1C 위치에 배치하는 것이 가장 좋습니다.6-14 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


프로세서 예외 처리예제 코드에 사용되는 요소는 다음과 같습니다.R8IODataR9R10읽을 데이터가 있는 I/O 장치의 기본 주소를 가리킵니다.기본 주소부터 읽으려는 32비트 데이터 레지스터까지의 오프셋입니다. 이 레지스터를 읽으면 인터럽트가 지워집니다.해당 데이터가 전송될 메모리 위치를 가리킵니다.전송할 마지막 주소를 가리킵니다.일반적인 전송을 처리하기 위한 전체 시퀀스에서는 네 개의 명령어를 사용합니다. 조건부 복귀 다음에 배치되는 코드는 전송이 완료되었다는 신호를 보내는 데사용됩니다.예제 6-4 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-16페이지의 예제 6-5는 처리되는 채널이 두 개라는 점만 제외하고 예제 6-4과비슷합니다. 이 코드는 FIQ 처리기로, 뱅크 FIQ 레지스터를 사용하여 인터럽트간의 상태를 유지합니다. 이 코드는 0x1C 위치에 배치하는 것이 가장 좋습니다.예제 코드에 사용되는 요소는 다음과 같습니다.R8IOStat읽을 데이터가 있는 I/O 장치의 기본 주소를 가리킵니다.기본 주소부터 두 포트 중 인터럽트를 발생시킨 포트를 나타내는 레지스터까지의 오프셋입니다.<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 6-15Unrestricted AccessNon-Confidential


프로세서 예외 처리IOPort1Active첫 번째 포트에서 인터럽트가 발생했는지 여부를 나타내는비트 마스크입니다. 그렇지 않으면 두 번째 포트에서 인터럽트가 발생했다고 가정합니다.IOPort1, IOPort2 읽으려는 두 개의 데이터 레지스터에 대한 오프셋입니다. 데이터 레지스터를 읽으면 해당 포트의 인터럽트가 지워집니다.R9R10첫 번째 포트에서 데이터를 전송할 대상 메모리 위치를 가리킵니다.두 번째 포트에서 데이터를 전송할 대상 메모리 위치를 가리킵니다.R11, R12 전송할 마지막 주소를 가리킵니다. 이 주소는 첫 번째 포트의경우 R11이고 두 번째 포트의 경우 R12입니다.일반적인 전송을 처리하는 전체 시퀀스에서는 아홉 개의 명령어를 사용합니다.조건부 복귀 다음에 배치되는 코드는 전송이 완료되었다는 신호를 보내는 데 사용됩니다.예제 6-5 FIQ 처리기LDR sp, [R8, #IOStat] ; Load status register to find which port; caused the interrupt.TST sp, #IOPort1ActiveLDREQ sp, [R8, #IOPort1] ; Load port 1 data.LDRNE sp, [R8, #IOPort2] ; Load port 2 data.STREQ sp, [R9], #4 ; Store to buffer 1.STRNE sp, [R10], #4 ; Store to buffer 2.CMP R9, R11 ; Reached the end?CMPLE R10, R12 ; On either channel?SUBSNE pc, lr, #4; Return; Insert transfer complete code here.로드 명령어를 로드 바이트 명령어로 대체하면 바이트 전송을 수행할 수 있습니다. 조건부 로드 명령어와 조건부 저장 명령어의 주소 모드를 서로 바꾸면 메모리에서 I/O 장치로의 전송을 수행할 수 있습니다.6-16 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


프로세서 예외 처리인터럽트 우선순위예제 6-6에서는 최대 32가지의 인터럽트 원인을 적절한 처리기로 디스패치합니다. 이 예제는 일반적인 인터럽트 벡터 (IRQ) 와 함께 사용할 수 있도록 설계되었으므로 0x18 위치에서 분기됩니다.외부 VIC (Vectored Interrupt Controller) 하드웨어는 인터럽트의 우선순위를 지정하고 I/O 레지스터에서 우선순위가 높은 활성 인터럽트를 나타내는 데 사용됩니다.예제 코드에 사용되는 요소는 다음과 같습니다.IntBaseIntLevelR13인터럽트 컨트롤러의 기본 주소를 저장합니다.우선순위가 가장 높은 활성 인터럽트가 들어 있는 레지스터의 오프셋을 저장합니다.작은 전체 내림차순 스택을 가리키는 것으로 가정합니다.인터럽트는 이 코드로의 분기를 포함하여 모두 10개의 명령어 다음에 활성화됩니다.각 인터럽트의 특정 처리기는 모든 레지스터가 스택에 저장된 상태에서 두 명령어를 더 실행한 후에 시작됩니다.또한 각 처리기의 마지막 세 개 명령어는 인터럽트가 다시 해제된 상태에서 실행되므로 스택에서 SPSR을 안전하게 복구할 수 있습니다.참고Application Note 30: Software Prioritization of Interrupts에서는 이 설명서에서처럼VIC 하드웨어를 사용하는 것이 아니라 소프트웨어를 사용하여 여러 원인으로 인한 인터럽트의 우선순위를 결정하는 방법에 대해 설명합니다.예제 6-6 처리기로 인터럽트 디스패치; first save the critical stateSUB lr, lr, #4 ; Adjust the return address; before we save it.STMDB sp!, {lr} ; Stack return addressMRS lr, SPSR ; get the SPSR ...PUSH {R12,lr} ; ... and stack that plus a; working register too.; Now get the priority level of the<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 6-17Unrestricted AccessNon-Confidential


프로세서 예외 처리; 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 lr, APSR ; Read the status register.BIC lr, lr, #0x80 ; Clear the I bit; (use 0x40 for the F bit) .MSR CPSR_c, lr ; Write it back to re-enable; interrupts andLDR pc, [pc, R12, LSL #2] ; jump to the correct handler.; PC base address points to this; instruction + 8NOP; pad so the PC indexes this table.; Table of handler start addressesDCD Priority0HandlerDCD Priority1HandlerDCD Priority2Handler; ...Priority0HandlerPUSH {R0-R11} ; Save other working registers.; Insert handler code here.; ...POP {R0-R11} ; Restore working registers (not R12) .; Now read-modify-write the CPSR; to disable interrupts.MRS R12, APSR ; 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.POP {r12,lr} ; Restore R12 and get SPSR.MSR SPSR_cxsf, lr ; Restore status register from R14.LDM sp!, {pc}^ ; Return from handler.Priority1Handler; ...컨텍스트 전환6-19페이지의 예제 6-7에서는 사용자 모드 프로세스에서 컨텍스트 전환을 수행합니다. 이 코드는 실행할 수 있는 프로세스의 PCB (프로세스 제어 블록) 에 대한포인터 목록을 기반으로 합니다.6-19페이지의 그림 6-2에서는 이 예제에 필요한 PCB의 레이아웃을 보여 줍니다.6-18 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


프로세서 예외 처리PCBpointerr14r13r12r11r10r9r8r7r6r5r4r3r2r1r0lrspsrUser moderegisters그림 6-2 PCB 레이아웃R12는 실행할 다음 프로세스의 PCB에 대한 포인터를 가리키며 목록의 끝에는 0포인터가 있습니다. 레지스터 R13은 PCB에 대한 포인터로, 일정 시간마다 저장되므로 진입 시점에서는 현재 실행하고 있는 프로세스의 PCB를 가리킵니다.예제 6-7 사용자 모드 프로세스에 대한 컨텍스트 전환STM sp,{R0-lr}^ ; Dump user registers above R13.MRS R0, SPSR ; Pick up the user statusSTMDB sp, {R0, lr} ; and dump with return address below.LDR sp, [R12], #4 ; Load next process info pointer.CMP sp, #0 ; If it is zero, it is invalidLDMDBNE sp, {R0, lr}; Pick up status and return address.MSRNE SPSR_cxsf, R0 ; Restore the status.LDMNE sp, {R0 - lr}^ ; Get the rest of the registersNOPSUBSNE pc, lr, #4; and return and restore CPSR.; Insert "no next process code" here.6.2.8 SVC 처리기예외 처리기에서는 예외가 발생할 때 프로세서가 <strong>ARM</strong> 상태에 있었는지 아니면Thumb 상태에 있었는지를 확인해야 할 수 있습니다.<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 6-19Unrestricted AccessNon-Confidential


프로세서 예외 처리특히 SVC 처리기에서는 프로세서 상태를 읽어야 합니다. 이렇게 하려면 SPSR T비트를 검사합니다. 이 비트는 Thumb 상태일 때 설정되고 <strong>ARM</strong> 상태일 때 지워집니다.<strong>ARM</strong> 및 Thumb 명령어 세트에는 SVC 명령어가 있습니다. Thumb 상태에서 SVC를호출할 경우에는 다음 사항을 고려해야 합니다.• 명령어 주소는 lr–4가 아니라 lr–2입니다.• 명령어 자체는 16비트이므로 하프워드 로드가 필요합니다 (그림 6-3 참조) .• SVC 번호는 <strong>ARM</strong> 상태에서 24비트가 아니라 8비트 형식으로 저장됩니다.15 14 13 12 11 10 9 8 7 01 1 0 1 1 1 1 1 8_bit_immediatecomment field그림 6-3 Thumb SVC 명령어예제 6-8에서는 SVC 예외를 처리하는 <strong>ARM</strong> 코드를 보여 줍니다. SVC를 동적으로 호출하면 Thumb 상태에서 액세스할 수 있는 SVC 번호의 범위를 늘릴 수 있습니다.예제 6-8 SVC 처리기PRESERVE8AREA SVC_Area, CODE, READONLYEXPORT SVC_HandlerIMPORT C_SVC_HandlerT_bit EQU 0x20 ; Thumb bit (5) of CPSR/SPSR.SVC_HandlerSTMFD sp!, {r0-r3, r12, lr} ; Store registersMOV r1, sp ; Set pointer to parametersMRS r0, spsr ; Get spsrSTMFD sp!, {r0, r3} ; Store spsr onto stack and another; register to maintain 8-byte-aligned stackTST r0, #T_bit ; Occurred in Thumb state?LDRNEH r0, [lr,#-2]; Yes: Load halfword and...BICNE r0, r0, #0xFF00 ; ...extract comment fieldLDREQ 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 registers6-20 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


프로세서 예외 처리BL C_SVC_Handler ; Call main part of handlerLDMFD sp!, {r0, r3} ; Get spsr from stackMSR SPSR_cxsf, r0 ; Restore spsrLDMFD sp!, {r0-r3, r12, pc}^ ; Restore registers and returnEND호출할 SVC 결정SVC 처리기는 시작 시 호출할 SVC를 설정해야 합니다. 이 정보는 그림 6-4에서보여 주는 대로 명령어 자체의 0-23 비트에 저장되거나 대개 R0-R3 중 하나인 정수레지스터에 전달됩니다.31 28 27 26 25 24 23 0cond 1 1 1 124_bit_immediatecomment field그림 6-4 <strong>ARM</strong> SVC 명령어최상위 수준 SVC 처리기에서는 LR을 기준으로 SVC 명령어를 로드할 수 있습니다.이 작업은 어셈블리 언어, C/C++ 인라인 또는 임베디드 어셈블러에서 수행합니다.처리기에서는 먼저 예외를 발생시킨 SVC 명령어를 레지스터에 로드해야 합니다.이때 SVC LR에는 SVC 명령어 다음에 나오는 명령어의 주소가 들어 있으므로 다음을 사용하여 SVC를 레지스터 (이 경우 R0) 에 로드할 수 있습니다.LDR R0, [lr,#-4]그런 다음 처리기에서는 주석 필드 필드를 검사하여 필요한 작업을 결정할 수 있습니다. op 코드의 상위 8비트를 지우면 SVC 번호가 추출됩니다.BIC R0, R0, #0xFF0000006-22페이지의 예제 6-9에서는 이러한 명령어를 함께 배치하여 최상위 수준 SVC처리기를 구성하는 방법을 보여 줍니다. <strong>ARM</strong> 상태와 Thumb 상태 모두의 SVC 명령어를 처리하는 처리기의 예제를 보려면 6-20페이지의 예제 6-8을 참조하십시오.<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 6-21Unrestricted AccessNon-Confidential


프로세서 예외 처리예제 6-9 최상위 수준 SVC 처리기PRESERVE8AREA TopLevelSVC, CODE, READONLY ; Name this block of code.EXPORT SVC_HandlerSVC_HandlerPUSH {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.;LDM sp!, {R0-R12,pc}^ ; Restore registers and return.END어셈블리 언어의 SVC 처리기요청된 SVC 번호에 대한 처리기를 호출하는 가장 간단한 방법은 점프 테이블을사용하는 것입니다. R0에 SVC 번호가 들어 있으면 예제 6-10의 코드를 예제 6-9에제공된 최상위 수준 처리기의 BIC 명령어 다음에 삽입할 수 있습니다.예제 6-10 SVC 분기 테이블AREA SVC_Area, CODE, READONLYPRESERVE8IMPORT SVCOutOfRangeIMPORT MaxSVCCMP R0,#MaxSVC ; Range checkLDRLS pc, [pc,R0,LSL #2]B SVCOutOfRangeSVCJumpTableDCD SVCnum0DCD SVCnum1; DCD for each of other SVC routinesSVCnum0; SVC number 0 codeB EndofSVCSVCnum1; SVC number 1 codeB EndofSVC; Rest of SVC handling codeEndofSVC; Return execution to top level6-22 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


프로세서 예외 처리END; SVC handler so as to restore; registers and return to program.C 및 어셈블리 언어의 SVC 처리기최상위 수준 처리기는 항상 <strong>ARM</strong> 어셈블리 언어로 작성해야 하지만 각 SVC를 처리하는 루틴은 어셈블리 언어나 C로 작성할 수 있습니다. 제한 사항에 대한 자세한 내용은 6-24페이지의 관리자 모드에서 SVC 사용을 참조하십시오.최상위 수준 처리기에서는 BL 명령어를 사용하여 적절한 C 함수로 분기합니다.SVC 번호는 어셈블리 루틴에 의해 R0으로 로드되므로 SVC 번호가 C 함수에 첫번째 매개변수로 전달됩니다. C 함수는 이 값을 switch () 문 등에 사용할 수 있습니다 (예제 6-11 참조) .이 C 함수를 호출하려면 6-22페이지의 예제 6-9의 SVC_Handler 루틴에 다음 행을추가할 수 있습니다.BL C_SVC_Handler ; Call C routine to handle the SVC예제 6-11 C 함수의 SVC 처리기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.<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 6-23Unrestricted AccessNon-Confidential


프로세서 예외 처리최상위 수준 처리기에서 스택 포인터 값을 C 함수에 두 번째 매개변수 (R1) 로 전달하는 경우 C로 작성된 SVC 처리기로 또는 이 SVC 처리기에서 값을 전달할 수있으며 C 함수가 이 처리기에 액세스할 수 있도록 업데이트됩니다.void C_SVC_handler (unsigned number, unsigned *reg)그러면 C 함수는 주 응용 프로그램 코드에서 SVC 명령어가 발생할 때 레지스터에들어 있던 값에 액세스할 수 있습니다 (그림 6-5 참조) . 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;이렇게 하면 최상위 수준 처리기에서는 업데이트된 값을 적절한 스택 위치에 썼다가 나중에 레지스터로 복원합니다.Previous sp_SVCsp_SVClr_SVCr12r3r2r1r0reg[3]reg[0]그림 6-5 관리자 모드 스택 액세스관리자 모드에서 SVC 사용SVC 명령어가 실행되면 다음이 수행됩니다.1. 프로세서가 관리자 모드로 전환됩니다.2. CPSR이 SVC SPSR에 저장됩니다.6-24 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


프로세서 예외 처리3. 복귀 주소가 SVC LR에 저장됩니다 (6-8페이지의 예외에 대한 프로세서 응답 참조) .프로세서가 이미 관리자 모드에 있으면 SVC LR 및 SPSR이 손상됩니다.관리자 모드에서 SVC를 호출할 경우에는 LR과 SPSR의 원래 값이 손실되지 않도록 SVC LR 및 SPSR을 저장해야 합니다. 예를 들어 특정 SVC 번호에 대한 처리기루틴에서 다른 SVC를 호출할 경우 처리기 루틴에서 SVC LR과 SPSR 모두를 스택에 저장하도록 해야 합니다. 이렇게 하면 처리기를 호출할 때마다 처리기를 호출한 SVC 다음의 명령어로 복귀하는 데 필요한 정보가 저장됩니다. 예제 6-12에서이를 수행하는 방법을 보여 줍니다.예제 6-12 SVC 처리기AREA SVC_Area, CODE, READONLYPRESERVE8EXPORT SVC_HandlerIMPORT C_SVC_HandlerT_bit EQU 0x20SVC_HandlerPUSH {R0-R3,R12,lr} ; Store registers.MOV R1, sp ; Set pointer to parameters.MRS R0, SPSR ; Get SPSR.PUSH {R0,R3} ; Store SPSR onto stack and another register to maintain; 8-byte-aligned stack. Only required for nested SVCs.TST R0,#0x20 ; Occurred in Thumb state?LDRHNE 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 registersBL C_SVC_Handler ; Call C routine to handle the SVC.POP {R0,R3} ; Get SPSR from stack.MSR SPSR_cf, R0 ; Restore SPSR.LDM sp!, {R0-R3,R12,pc}^ ; Restore registers and return.ENDC 및 C++의 중첩된 SVCC 또는 C++에서 중첩된 SVC를 작성할 수 있습니다. <strong>ARM</strong> 컴파일러에서 생성된코드는 필요할 경우 lr_SVC를 저장하고 다시 로드합니다.<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 6-25Unrestricted AccessNon-Confidential


프로세서 예외 처리응용 프로그램에서 SVC 호출어셈블리 언어 또는 C/C++에서 SVC를 호출할 수 있습니다.어셈블리 언어에서 필요한 레지스터 값을 설정하고 관련 SVC를 실행합니다. 예를 들면 다음과 같습니다.MOV R0, #65 ; load R0 with the value 65SVC 0x0 ; Call SVC 0x0 with parameter value in R0SVC 명령어는 거의 모든 <strong>ARM</strong> 명령어와 마찬가지로 조건부로 실행할 수 있습니다.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-13 및 6-27페이지의 예제 6-14에서는 SVC 번호 0x0, 0x1, 0x2 및 0x3을 제공하는 SVC 처리기를 보여 줍니다. SVC 0x0 및 SVC 0x1은 각각 두 개의 정수 매개변수를 사용하며 단일 결과를 반환합니다. SVC 0x2는 네 개의 매개변수를 사용하며단일 결과를 반환하고, SVC 0x3은 네 개의 매개변수를 사용하며 네 개의 결과를 반환합니다. 이 예제는 예제 디렉토리의 ...\svc\main.c와 ...\svc\svc.h에 있습니다.예제 6-13 main.c#include #include "svc.h"unsigned *svc_vec = (unsigned *) 0x08;extern void SVC_Handler (void) ;6-26 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


프로세서 예외 처리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-14 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_resultsmany_operations (int, int, int, int) ;응용 프로그램에서 동적으로 SVC 호출경우에 따라 런타임까지 번호를 알 수 없는 SVC를 호출해야 할 수 있습니다. 예를 들어 한 객체에 대해 수행할 수 있는 관련 연산이 여러 개이고 각 연산에 고유한 SVC가 있을 때 이러한 경우가 발생할 수 있습니다. 이 경우 이전 단원에서 설명한 방법은 적합하지 않습니다.<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 6-27Unrestricted AccessNon-Confidential


프로세서 예외 처리이를 처리하는 데는 다음과 같은 몇 가지 방법을 사용할 수 있습니다.• SVC 번호에서 SVC 명령어를 생성하여 적절한 위치에 저장한 다음 실행합니다.• 인수에 대해 수행할 실제 연산의 코드를 추가 인수로 사용하는 일반 SVC를사용합니다. 일반 SVC에서는 연산을 디코딩하여 수행합니다.두 번째 메커니즘은 레지스터에 필요한 연산 번호 (대개 R0 또는 R12) 를 전달하여어셈블리 언어로 구현할 수 있습니다. 그런 다음 적절한 레지스터의 값에 대해 작동하도록 SVC 처리기를 다시 작성할 수 있습니다.일부 값은 SVC의 주석 필드에 전달해야 하므로 이 두 가지 방법을 함께 사용할 수도 있습니다.예를 들어 운영 체제에서 단일 SVC 명령어를 사용하고, 레지스터를 사용하여 필요한 연산의 번호를 전달할 수 있습니다. 이렇게 하면 응용 프로그램 관련 SVC에 사용할 수 있는 SVC 공간의 나머지 부분만 남게 됩니다. 특정 응용 프로그램에서 명령어의 연산 번호를 추출할 때의 오버헤드가 너무 큰 경우 이 방법을 사용할 수있습니다. <strong>ARM</strong> 및 Thumb의 세미호스팅된 명령어는 이러한 방식으로 구현됩니다.예제 6-15에서는 __svc를 사용하여 세미호스팅 호출에 C 함수 호출을 매핑하는방법을 보여 줍니다. 이 예제는 예제 디렉토리의 ...\emb_sw_dev\source\retarget.c에 있는 retarget.c를 기반으로 합니다.예제 6-15 세미호스팅 호출에 C 함수 매핑#ifdef __thumb/* Thumb Semihosting */#define SemiSVC 0xAB#else/* <strong>ARM</strong> Semihosting */#define SemiSVC 0x123456#endif/* 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 ) ;}6-28 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


프로세서 예외 처리컴파일러에는 R12를 사용하여 필요한 연산의 값을 전달할 수 있는 메커니즘이 포함되어 있습니다. AAPCS에서 R12는 ip 레지스터로, 함수를 호출하는 동안에만 전용 역할이 있습니다. 평소에는 이를 스크래치 레지스터로 사용할 수 있습니다. 앞부분에서 설명한 대로 일반 SVC의 인수는 레지스터 R0-R3에 전달되고 값은 R0-R3에 선택적으로 반환됩니다 (6-26페이지의 응용 프로그램에서 SVC 호출 참조) .R12에 전달되는 연산 번호는 일반 SVC에서 호출할 SVC의 번호일 수 있습니다. 그러나 이 번호는 필요하지 않습니다.예제 6-16에서는 일반 또는 간접 SVC를 사용하는 C 코드 조각을 보여 줍니다.예제 6-16 간접 SVC 사용__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) ;}이 예제에서는 다음 코드를 생성합니다.DoSelectedManipulationPUSH {R4,lr}MOV R12,R2SVC #0x80POP {R4,pc}ENDC에서 __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) ;<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 6-29Unrestricted AccessNon-Confidential


프로세서 예외 처리그러나 이 방식으로 R0을 사용하면 SVC에 매개변수를 전달하는 데 세 개의 레지스터만 사용할 수 있습니다. 일반적으로 R0-R3 외에도 더 많은 매개변수를 서브루틴에 전달해야 하는 경우에는 스택을 사용하여 이를 수행할 수 있습니다. 그러나스택 매개변수는 대개 SVC 처리기에서 사용하는 관리자 모드 스택이 아니라 사용자 모드 스택에 있으므로 SVC 처리기에서 쉽게 액세스할 수 없습니다.또는 레지스터 중 하나 (대개 R1) 를 사용하여 다른 매개변수를 저장하는 메모리블록을 가리킬 수 있습니다.6.2.9 프리페치 중단 처리기시스템에 MMU가 없으면 프리페치 중단 처리기가 오류를 보고하거나 종료될 수있습니다. 그렇지 않으면 어보트를 발생시킨 주소가 실제 메모리에 복원되어야합니다. lr_ABT는 어보트를 발생시킨 주소 다음의 주소에 있는 명령어를 가리키므로 복원할 주소는 lr_ABT-4입니다. 해당 주소의 가상 메모리 오류는 처리 가능하며 명령어 가져오기가 다시 시도됩니다. 따라서 처리기는 다음 명령어가 아니라 동일한 명령어로 복귀합니다. 예를 들면 다음과 같습니다.SUBSpc,lr,#46.2.10 정의되지 않은 명령어 처리기다음과 같은 경우에 정의되지 않은 명령어 예외가 생성됩니다.• 프로세서에서 명령어를 인식하지 못하는 경우• 프로세서에서 명령어를 보조 프로세서 명령어로 인식하지만 보조 프로세서에서 해당 명령어를 인식하지 못하는 경우명령어가 보조 프로세서용이지만 VFP와 같은 관련 보조 프로세서가 시스템에 연결되어 있지 않거나 비활성화된 경우에 이러한 예외가 발생할 수 있습니다. 그러나 이러한 보조 프로세서에 대한 소프트웨어 에뮬레이터는 사용할 수 있습니다.이러한 에뮬레이터에서는 다음을 수행해야 합니다.1. 정의되지 않은 명령어 벡터에 연결하고 이전 내용을 저장합니다.2. 정의되지 않은 명령어를 검사하여 명령어를 에뮬레이션해야 하는지 여부를 확인합니다. 이는 SVC 처리기에서 SVC의 번호를 추출하는 방식과 비슷하지만 에뮬레이터에서는 맨 아래 24비트를 추출하는 것이 아니라 비트[27:24]를 추출해야 합니다.6-30 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


프로세서 예외 처리이러한 비트는 다음과 같은 방식으로 명령어가 보조 프로세서 작업인지 여부를 확인합니다.• 비트 [27:24]가 b1110 또는 b110x이면 해당 명령어는 보조 프로세서 명령어입니다.• 비트 [8:11]이 이 보조 프로세서 에뮬레이터에서 명령어를 처리해야함을 나타내면 에뮬레이터에서는 명령어를 처리한 후 사용자 프로그램으로 복귀해야 합니다.3. 그렇지 않으면 에뮬레이터에서는 에뮬레이터가 설치될 때 저장된 벡터를사용하여 원래 처리기 또는 체인의 다음 에뮬레이터에 예외를 전달해야 합니다.에뮬레이터의 체인이 모두 소모되면 정의되지 않은 명령어 처리기가 오류를 보고하고 종료되어야 합니다.참고<strong>ARM</strong>v6T2 이전의 Thumb 명령어 세트에는 보조 프로세서 명령어가 없으므로 정의되지 않은 명령어 처리기에서 이러한 명령어를 에뮬레이션하기 위한 요구 사항은 없습니다.<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 6-31Unrestricted AccessNon-Confidential


프로세서 예외 처리6.3 <strong>ARM</strong>v6-M 및 <strong>ARM</strong>v7-M 프로필이 단원에서는 Cortex -M1 및 Cortex-M3과 같은 마이크로컨트롤러 프로필에서지원하는 여러 가지 유형의 예외를 처리하는 방법을 설명합니다.마이크로컨트롤러 프로필은 다음을 지원합니다.• 두 가지 작업 모드 (스레드 모드 및 처리기 모드)• 두 가지 실행 모드 (권한 모드 및 사용자 모드)스레드 모드는 재설정할 때와 주로 예외에서 복귀할 때 시작됩니다. 스레드 모드에서 코드는 권한 모드나 사용자 모드로 실행될 수 있습니다.처리기 모드는 예외의 결과로 시작됩니다. 모든 코드는 권한 모드로 실행됩니다.예외가 발생하면 프로세서가 권한 모드로 자동 전환됩니다.권한 모드에는 모든 액세스 권한이 있습니다.사용자 모드에는 제한된 액세스 권한이 있습니다. 제한 사항은 다음과 같습니다.• MSR 명령어에서 사용할 수 있는 필드와 같은 명령어 사용에 대한 제한• 특정 보조 프로세서 레지스터의 사용에 대한 제한• 시스템 설계에 따라 메모리 및 주변 기기에 액세스하는 데 대한 제한• MPU 구성에 따라 설정되는 메모리 및 주변 기기에 액세스하는 데 대한 제한MSR 명령어를 사용하여 CONTROL[0]을 지우는 방법으로 권한 스레드 모드를 사용자 스레드 모드로 변경할 수 있습니다. 그러나 SVC와 같은 예외를 거치지 않고사용자 모드에서 권한 있는 모드로 직접 변경할 수는 없습니다. 자세한 내용은6-40페이지의 관리자 호출을 참조하십시오.6.3.1 주 스택과 프로세스 스택마이크로컨트롤러 프로필에서는 주 스택과 프로세스 스택이라는 두 가지 스택을지원합니다. 스택마다 하나씩 두 개의 스택 포인터가 있습니다. 사용 중인 스택에따라 한 번에 스택 포인터 하나만 표시됩니다.주 스택은 리셋할 때와 예외 처리기를 시작할 때 사용됩니다. 프로세스 스택을 사용하려면 프로세스 스택을 선택해야 합니다. 이렇게 하려면 스레드 모드일 때 MSR명령어를 사용하여 CONTROL[1]에 기록하면 됩니다.6-32 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


프로세서 예외 처리참고초기화 또는 컨텍스트 전환 코드에서 프로세스 스택 포인터를 초기화해야 합니다.6.3.2 예외 유형표 6-2에서는 마이크로컨트롤러 프로필에서 인식하는 다양한 예외 유형이 나와있습니다. 여러 개의 예외가 동시에 발생하면 고정된 우선순위에 따라 예외가 처리됩니다. 각 예외가 차례대로 처리된 후에 원래 프로그램으로 돌아갑니다.위치 예외 우선순위 비활성화 설명1 리셋 –3 아니요2 NMI –2 아니요 마스크할 수 없는 인터럽트 (NMI)3 HardFault –1 아니요 다른 예외로 처리되지 않는 모든 오류표 6-2 우선순위순 예외 유형4 MemManage 구성 가능 가능 메모리 보호 오류 (<strong>ARM</strong>v7-M에만 해당)5 BusFault 구성 가능 가능 기타 메모리 오류 (<strong>ARM</strong>v7-M에만 해당)6 UsageFault 구성 가능 가능 메모리 오류 이외의 명령어 실행 오류 (<strong>ARM</strong>v7-M에만 해당)7-10 예약되어 있음 - -11 SVCall 구성 가능 가능 SVC 명령어 실행으로 인해 발생하는 동기 SVC 호출12 디버그 모니터 구성 가능 가능 동기 디버그 이벤트 (<strong>ARM</strong>v7-M에만 해당)13 예약되어 있음 - -14 PendSV 구성 가능 가능 비동기 SVC 호출15 SysTick 구성 가능 가능 시스템 타이머 틱16 이상. 외부 인터럽트 구성 가능 가능 외부 인터럽트우선순위 번호가 작은 예외의 우선순위 상태가 더 높습니다. 예를 들어 프로세서가 처리기 모드에 있는 경우 현재 처리 중인 예외보다 우선순위 번호가 작은 예외가 발생합니다. 우선순위 번호가 같거나 큰 모든 예외는 보류됩니다.<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 6-33Unrestricted AccessNon-Confidential


프로세서 예외 처리다음과 같은 경우에 예외 처리기가 종료됩니다.• 보류 중인 예외가 없으며 프로세서가 스레드 모드로 복귀하고 실행이 응용프로그램으로 복귀하는 경우• 보류 중인 예외가 있고 실행이 우선순위 번호가 가장 작은 보류 중인 예외의 처리기로 전달되는 경우. 우선순위 번호가 동일하게 가장 작은 보류 중인 예외가 두 개인 경우 예외 번호가 가장 작은 예외가 먼저 처리됩니다.6.3.3 벡터 테이블마이크로컨트롤러 프로필의 벡터 테이블은 관련 처리기에 대한 주소로 구성됩니다. 예외 번호 n의 처리기는 (vectorbaseaddress + 4 * n) 에 저장됩니다.<strong>ARM</strong>v7-M 프로세서에서는 VTOR (벡터 테이블 오프셋 레지스터) 에서vectorbaseaddress를 지정하여 벡터 테이블을 재배치할 수 있습니다. 리셋 시 기본위치는 0x0 (CODE 공간) 입니다. <strong>ARM</strong>v6-M의 경우 벡터 테이블 기본 주소는 0x0에 고정됩니다. 각 예외의 n 값은 6-33페이지의 예외 유형을 참조하십시오.vectorbaseaddress의 워드에는 주 스택 포인터의 리셋 값이 들어 있습니다.참고중요도가 가장 낮은 비트 (벡터 테이블에 있는 각 주소의 비트[0]) 를 설정해야 하며, 그렇지 않으면 HardFault 예외가 생성됩니다. 테이블에서 Thumb 기호 이름을사용하는 경우에는 보통 RealView 도구에서 이를 자동으로 활성화합니다.벡터 테이블 오프셋 레지스터 (<strong>ARM</strong>v7-M에만 해당)벡터 테이블 오프셋 레지스터는 벡터 테이블을 CODE 또는 SRAM 공간에 배치합니다. 다른 위치를 설정하는 경우에는 테이블의 예외 수를 기준으로 오프셋을 정렬해야 합니다. 즉, 최대 16개의 인터럽트에 사용할 수 있는 최소 정렬은 32워드입니다. 인터럽트 수가 더 많은 경우에는 다음 2의 제곱으로 반올림하여 정렬을조정해야 합니다. 예를 들어 21개의 인터럽트가 필요한 경우 테이블 크기는 37워드이므로 다음 2의 제곱이 64가 됩니다. 그러므로 정렬은 64워드 경계에 있어야합니다.6-34 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


프로세서 예외 처리예외 테이블 기록벡터 테이블을 채우는 가장 쉬운 방법은 스캐터 로딩 설명 파일을 사용하여 함수포인터의 C 배열을 메모리 주소 0x0에 배치하는 것입니다. C 배열을 사용하여 초기 스택 포인터, 이미지 진입점 및 예외 처리기의 주소를 구성할 수 있습니다 (예제 6-17 참조) .참고예제 6-17에 나와 있는 일부 기능은 <strong>ARM</strong>v6-M에서 사용할 수 없습니다. 정렬을유지하려면 벡터 테이블에 0을 입력하여 공간을 예약해야 합니다.스캐터 로딩에 대한 자세한 내용은 링커 사용 설명서에서 5장 스캐터 로딩 설명파일 사용을 참조하십시오.예제 6-17 예외 처리기의 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$$<strong>ARM</strong>_LIB_STACKHEAP$$ZI$$Limit,/* Initial Stack Pointer, from linker-generated symbol */(ExecFuncPtr) &__main,/* Initial PC, set to entry point*/&NMIException,&HardFaultException,&MemManageException, /* <strong>ARM</strong>v7-M only (0 for <strong>ARM</strong>v6-M) */&BusFaultException, /* <strong>ARM</strong>v7-M only (0 for <strong>ARM</strong>v6-M) */&UsageFaultException, /* <strong>ARM</strong>v7-M only (0 for <strong>ARM</strong>v6-M) */0, 0, 0, 0, /* Reserved */&SVCHandler, /* Only available with OS extensions */&DebugMonitor, /* <strong>ARM</strong>v7-M only (0 for <strong>ARM</strong>v6-M) */0, /* Reserved */&PendSVC, /* Only available with OS extensions */(ExecFuncPtr) &SysTickHandler, /* Only available with OS extensions*//* Configurable interrupts start here...*/&InterruptHandler,&InterruptHandler,&InterruptHandler/*:<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 6-35Unrestricted AccessNon-Confidential


프로세서 예외 처리*/};#pragma arm section6.3.4 중첩된 벡터 인터럽트 컨트롤러구현에 따라 NVIC (중첩된 벡터 인터럽트 컨트롤러) 를 지원할 수 있습니다.<strong>ARM</strong>v6-M<strong>ARM</strong>v7-M1, 8, 16 또는 32개의 외부 인터럽트 (서로 다른 네 가지 우선순위 수준 포함)최대 240개의 외부 인터럽트 (동적으로 우선순위를 다시 지정할 수있는 서로 다른 256가지 우선순위 수준 포함) . NVIC는 인터럽트의테일 체이닝 (tail-chaining) 도 지원합니다.마이크로컨트롤러 프로필은 수준 및 펄스 인터럽트 원인을 모두 지원합니다. 프로세서 상태는 인터럽트 시작 시 하드웨어에 자동으로 저장되고 인터럽트 종료시 복원됩니다.마이크로컨트롤러 프로필에서 NVIC를 사용하는 것은 벡터 테이블이 명령어가아닌 주소로 구성되는 기타 <strong>ARM</strong> 프로세서와 매우 다르다는 것을 의미합니다. 초기 스택 포인터와 리셋 처리기의 주소는 각각 0x0 및 0x4에 있어야 합니다. 프로세서는 리셋 시 이러한 주소를 SP 및 PC 레지스터로 로드합니다.6.3.5 예외 처리마이크로컨트롤러 프로필에서는 예외 우선순위 지정, 예외 중첩 및 손상될 수 있는 레지스터 저장이 프로세서에서 모두 처리되므로 처리 효율성이 매우 높고 인터럽트 지연이 최소화됩니다. 인터럽터는 모든 예외 처리기에 대해 시작될 때 자동으로 활성화됩니다. 즉, 프로젝트에서 다른 프로세서용으로 작성한 최상위 재진입 코드를 모두 제거해야 합니다. 인터럽트를 비활성화해야 하는 경우에는 코드에서 해당 작업을 처리하고 예외에서 복귀 시에 활성화되었는지 확인해야 합니다.참고인터럽트 처리기는 인터럽트의 원인을 제거해야 합니다.마이크로컨트롤러 프로필에는 FIQ 입력이 없습니다. 다른 프로세서에서 프로젝트에 대해 FIQ 신호를 보내는 주변 기기는 우선순위가 높은 외부 인터럽트로 이동해야 합니다. 마이크로컨트롤러 프로필에는 뱅크 레지스터가 없으므로 이러한6-36 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


프로세서 예외 처리유형의 인터럽트에 대한 처리기에서 뱅크 FIQ 레지스터를 사용하지 않는지 확인해야 할 수 있으며, 다른 일반 IRQ 처리기의 경우 R8-R12를 스택에 저장해야 합니다.또한 마이크로컨트롤러 프로필은 우선순위가 높은 NMI (마스크할 수 없는 인터럽트) 도 제공하는데, 이 인터럽트는 비활성화할 수 없습니다.간단한 C 예외 처리기마이크로컨트롤러 프로필용 예외 처리기는 시스템 상태를 저장하거나 복원할 필요가 없으며 일반적인 ABI 호환 C 함수로 기록될 수 있습니다. 그러나 __irq 키워드를 사용하여 함수를 인터럽트 루틴으로 식별하는 것이 좋습니다 (예제 6-18 참조) .예제 6-18 간단한 C 예외 처리기__irq void SysTickHandler (void){printf ("----- SysTick Interrupt -----") ;}8바이트 스택 정렬<strong>ARM</strong> 아키텍처용 ABI (응용 프로그램 바이너리 인터페이스) 에서 스택은 여러 소스 파일의 함수 간 호출과 같은 모든 외부 인터페이스에서 8바이트로 정렬되어야합니다. 그러나 코드에서는 리프 함수 등에서 8바이트 스택 정렬을 내부적으로유지할 필요가 없습니다. 즉, IRQ가 발생할 때 스택이 올바르게 8바이트로 정렬되지 않을 수도 있습니다.<strong>ARM</strong>v7-M 프로세서에서는 예외가 발생할 때 스택 포인터를 자동으로 정렬할 수있습니다. 주소 0xE000ED14의 구성 제어 레지스터에서 STKALIGN (비트 9) 을 설정하여 이 동작을 활성화할 수 있습니다.<strong>ARM</strong>v6-M 프로세서는 이 동작을 항상 활성화합니다. 그러나 이미지가<strong>ARM</strong>v7-M 프로세서와 호환되도록 STKALIGN (비트 9) 을 수동으로 설정하는 것이 좋습니다.<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 6-37Unrestricted AccessNon-Confidential


프로세서 예외 처리참고수정 버전 0 Cortex-M3 프로세서를 사용하는 경우에는 STKALIGN이 지원되지않으므로 하드웨어에서 조정이 수행되지 않아 소프트웨어가 조정을 수행해야 합니다. 컴파일러는 스택을 올바르게 정렬하는 IRQ 처리기에서 코드를 생성할 수있습니다. 이를 위해서는 IRQ 처리기 앞에 __irq를 추가하고 --cpu=Cortex-M3가 아니라 --cpu=Cortex-M3-rev0 컴파일러 스위치를 사용해야 합니다.6.3.6 시스템 제어 공간 레지스터 구성SCS (시스템 제어 공간) 레지스터는 0xE000E000에 있습니다. 구조체를 사용하여매우 많은 개별 레지스터와 관련 오프셋을 나타낼 수 있습니다 (예제 6-19 참조) .그런 다음 벡터 테이블에 대해 비슷한 방법을 사용하여 스캐터 로딩 설명 파일을통해 올바른 메모리 위치에 구조체를 배치할 수 있습니다.Cortex-M1 및 Cortex-M3 프로세서 모두에 대해 이 코드 샘플은 예제 디렉토리의install_directory\RVDS\Examples\..\Example3에 있습니다.예제 6-19 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* Additional space allocated to ensure alignment*/struct {int Enable[32];int Disable[32];int Set[32];int Clear[32];int Active[64];6-38 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


프로세서 예외 처리int Priority[64];} NVIC;int zReserved0x500_0xcfc[ (0xd00-0x500) /4]; /* Reserved space *//* Offset 0x0d00 */int CPUID;int IRQcontrolState;int ExceptionTableOffset;int AIRC;int SysCtrl; /* <strong>ARM</strong>v7-M only */int ConfigCtrl; /* <strong>ARM</strong>v7-M only */int SystemPriority[3]; /* <strong>ARM</strong>v7-M only */int zReserved0xd40_0xd90[ (0xd90-0xd40) /4]; /* Reserved space *//* Offset 0x0d90 */struct {int Type; /* <strong>ARM</strong>v7-M only */int Ctrl; /* <strong>ARM</strong>v7-M only */int RegionNumber; /* <strong>ARM</strong>v7-M only */int RegionBaseAddr; /* <strong>ARM</strong>v7-M only */int RegionAttrSize; /* <strong>ARM</strong>v7-M only */} MPU; /* <strong>ARM</strong>v7-M only */} SCS_t;/** System Control Space (SCS) Registers* in separate section so it can be placed correctly using scatter file*/#pragma arm section zidata="scs_registers"SCS_t SCS;#pragma arm section참고SCS 레지스터의 내용은 구현에 따라 달라질 수 있습니다. 예를 들어 운영 체제 확장을 구현하지 않는 경우에는 SysTick 레지스터가 없을 수 있습니다.6.3.7 개별 IRQ 구성각 IRQ는 NVIC 레지스터의 일부인 인터럽트 설정 활성화 레지스터에서 개별 활성화 비트를 갖고 있습니다. IRQ를 활성화 또는 비활성화하려면 인터럽트 설정활성화 레지스터의 해당 비트를 각각 1 또는 0으로 설정해야 합니다. 인터럽트 설정 활성화 레지스터에 대한 자세한 내용은 사용 중인 장치의 참조 문서를 참조하십시오.<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 6-39Unrestricted AccessNon-Confidential


프로세서 예외 처리예제 6-20에서는 6-38페이지의 예제 6-19에 나와 있는 SCS 구조체에 대해 IRQ를활성화하는 일반적인 함수를 보여 줍니다.예제 6-20 IRQ 활성화 함수void NVIC_enableISR (unsigned isr){/* The isr argument is the number of the interrupt to enable. */SCS.NVIC.Enable[ (isr/32) ] = 1


프로세서 예외 처리반적인 시스템 디자인에서는 SVC가 프로세스 스택을 사용하는 사용자 코드에서만 호출되므로 대부분의 시스템에서는 불필요합니다. 이 경우 어셈블리 코드는단일 MSR 명령어와 처리기 C 본문으로의 마무리 호출 분기 (B 명령어) 로 구성될수 있습니다.예제 6-21 SVC 처리기 예제__asm void SVCHandler (void){IMPORT SVCHandler_mainTST lr, #4ITE EQMRSEQ 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]*/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;}}6-42페이지의 예제 6-22에서는 많은 SVC에 대해 서로 다른 선언을 만드는 방법을보여 줍니다. __svc는 함수 호출을 지정된 번호가 포함된 SVC 명령어로 대체하는컴파일러 키워드입니다.<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 6-41Unrestricted AccessNon-Confidential


프로세서 예외 처리예제 6-22 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") ;}6.3.9 시스템 타이머SCS에는 다른 플랫폼에서 더욱 쉽게 이식하기 위해 운영 체제에서 사용할 수 있는 시스템 타이머 SysTick이 포함되어 있습니다. 소프트웨어에서 SysTick을 폴링할 수 있으며 인터럽트를 생성하도록 SysTick을 구성할 수 있습니다. SysTick 인터럽트는 벡터 테이블에 자체 엔트리가 있으므로 전용 처리기를 사용할 수 있습니다.표 6-3에서는 SysTick을 구성하는 데 사용하는 네 가지 레지스터에 대해설명합니다.이름 주소 설명SysTick 제어 및 상태 0xE000E010 SysTick의 기본 제어: 활성화, 클럭 소스, 인터럽트 또는 폴링SysTick 다시 로드 값 0xE000E014 0이 되었을 때 현재 값 레지스터를 로드할 값SysTick 현재 값 0xE000E018 카운트다운의 현재 값SysTick 조정 값 0xE000E01C 카운트다운의 현재 값 포함표 6-3SysTick 구성SysTick을 구성하려면 SysTick 이벤트 간에 필요한 간격을 SysTick 다시 로드 값레지스터에 로드합니다. 타이머 인터럽트 (SysTick 제어 및 상태 레지스터의COUNTFLAG 비트) 는 1에서 0으로 전환될 때 활성화되므로 n+1 클럭 틱마다 활성화됩니다. 기간 100이 필요한 경우 99를 SysTick 다시 로드 값 레지스터에 기록합니다. SysTick 다시 로드 값 레지스터는 0x1에서 0x00FFFFFF 사이의 값을 지원합니다.6-42 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


프로세서 예외 처리SysTick을 사용하여 지정된 간격 (예: 1ms) 에 이벤트를 생성하려면 SysTick 조정값 레지스터를 사용하여 다시 로드 레지스터의 값을 조정할 수 있습니다. SysTick조정 값 레지스터는 TENMS 필드, 비트[23:0]에 10ms 동안의 펄스 수가 포함된 읽기 전용 레지스터입니다.이 레지스터에는 SKEW 비트도 있습니다. 비트[30] == 1은 TENMS 섹션의 10ms에 대한 조정이 클럭 주파수 때문에 정확히 10ms가 아님을 나타냅니다. 비트[31]== 1은 참조 클럭이 제공됨을 나타냅니다.참고Cortex-M1 프로세서의 경우에는 조정 값을 알 수 없으므로 TENMS 필드의 값은0입니다.제어 및 상태 레지스터는 COUNTFLAG, 비트[16]을 읽고 인터럽트를 생성하는SysTick에 의해 타이머를 폴링할 수 있습니다.기본적으로 SysTick은 폴링 모드에 대해 구성됩니다. 이 모드에서 사용자 코드는COUNTFLAG를 폴링하여 SysTick 이벤트가 발생했는지 확인합니다. SysTick 이벤트가 발생하면 COUNTFLAG가 설정됩니다. 제어 및 상태 레지스터를 읽으면COUNTFLAG가 지워집니다. 인터럽트를 생성하도록 SysTick을 구성하려면SysTick 제어 및 상태 레지스터의 TICKINT, 비트[1]을 1로 설정합니다. 또한NVIC에서 해당 인터럽트를 활성화하고 CLKSOURCE, 비트[2]를 사용하여 클럭소스를 선택해야 합니다. CLKSOURCE, 비트[2]를 1로 설정하면 프로세서 클럭이 선택되고 0으로 설정하면 외부 참조 클럭이 선택됩니다.참고<strong>ARM</strong>v6-M 프로세서의 경우에는 SysTick이 항상 프로세서 클럭을 사용하므로CLKSOURCE 필드의 값은 1입니다.SysTick 상태 및 제어 레지스터의 비트[0]을 설정하여 타이머를 활성화할 수 있습니다.<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 6-43Unrestricted AccessNon-Confidential


프로세서 예외 처리6-44 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


7장디버그 통신 채널이 장에서는 DCC (디버그 통신 채널) 를 사용하는 방법을 설명합니다.이 장에는 다음 단원이 포함되어 있습니다.• 7-2페이지의 디버그 통신 채널 개요• 7-3페이지의 타겟 및 호스트 디버그 도구 간의 DCC 통신• 7-6페이지의 Thumb 상태에서 액세스<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 7-1Unrestricted AccessNon-Confidential


디버그 통신 채널7.1 디버그 통신 채널 개요<strong>ARM</strong> 프로세서의 EmbeddedICE 논리에는 디버그 통신 채널이 포함되어 있습니다. 이 채널을 통해 타겟 및 호스트 디버그 도구 간에 데이터를 전달할 수 있습니다. 이 장에서는 타겟에서 실행되는 프로그램과 호스트 디버거에서 DCC에 액세스하는 방법을 설명합니다.이 장에서 설명하는 DCC 사용법을 확인하려면 예제 디렉토리(install_directory\RVDS\Examples\...\dcc\) 의 예제 코드를 참조하십시오. 자세한내용은 readme.txt를 참조하십시오.참고최신 <strong>ARM</strong> RealView 디버거 릴리스에서는 DCC 뷰어를 지원합니다. RealView 디버거에서 실행 가능 이미지를 실행할 수 있으며 DCC 뷰어를 사용하여 타겟에서데이터를 주고 받을 수 있습니다.7-2 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


디버그 통신 채널7.2 타겟 및 호스트 디버그 도구 간의 DCC 통신타겟은 <strong>ARM</strong> 명령어 MCR 및 MRC를 사용하여 프로세서에서 보조 프로세서 14로DCC에 액세스합니다. 그림 7-1에서는 데이터를 제어하고 타겟 및 호스트 디버그도구 간에 전송하는 데 사용할 수 있는 세 가지 DCC 레지스터를 보여 줍니다.읽기 레지스터타겟이 호스트 디버그 도구에서 보낸 데이터를 읽는 데 사용됩니다.쓰기 레지스터타겟이 호스트 디버그 도구로 보내는 메시지를 쓰는 데 사용됩니다.제어 레지스터타겟 및 호스트 디버그 도구에 대해 핸드셰이크 정보를 제공하는 데사용됩니다.<strong>ARM</strong>v6 이전 프로세서의 경우:비트 1 (W 비트) 타겟이 데이터를 보낼 수 있으면 지워집니다.비트 0 (R 비트) 타겟이 읽을 데이터가 있으면 설정됩니다.<strong>ARM</strong>v6 이상 프로세서의 경우:비트 29 (W 비트) 타겟이 데이터를 보낼 수 있으면 지워집니다.비트 30 (R 비트) 타겟이 읽을 데이터가 있으면 설정됩니다.DCCHost debug toolsWrite registerTarget codeControl registerScan chain 2JTAGRealViewICERead register그림 7-1 타겟 및 호스트 디버그 도구 간의 DCC 통신<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 7-3Unrestricted AccessNon-Confidential


디버그 통신 채널참고DCC 레지스터 액세스에 대한 자세한 내용은 해당 프로세서의 기술 참조 문서를참조하십시오.7.2.1 인터럽트 구동 디버그 통신예제 7-1에는 간단한 DCC 루틴을 보여 주는 코드 조각이 나와 있습니다. 디버그도구에서 보낸 텍스트는 대소문자가 변경되어 타겟에서 다시 표시됩니다. 이 예제 (install_directory\RVDS\Examples\...\dcc\) 에서 실행 가능 이미지를 빌드한 다음 JTAG 포트를 사용하여 타겟에서 해당 이미지를 실행합니다. RealView 디버거의 통신 채널 뷰를 사용하여 타겟과 통신할 수 있습니다. 자세한 내용은 RealView디버거 사용 설명서를 참조하십시오.예제 7-1 타겟 및 호스트 디버그 도구 간의 DCC 통신AREA DCC, CODE, READONLYENTRYpollinMRC p14,0,r3,$SCReg,0 ; Read Debug Status and Control RegisterTST r3, $TestFullBEQ pollin ; If R bit clear then loopreadMRC p14,0,r0,$DReg,0 ; read word into r0char_masksMOV r4, #0x20 ; EOR mask to invert case of a char by flipping bit 6MOV r5, #0xC0 ; AND mask to clear all but top 2 bits of each charchangeCaseTST r0, r5 ; Check whether character value >0x3FEORNE r0, r0, r4 ; If character value >0x3F, flip bit 6 to invert caseMOV r5, r5, LSL #0x8 ; Shift the character mask left by 1 charMOVS r4, r4, LSL #0x8 ; Shift the case inverter pattern left by 1 charBNE changeCase ; Branch to do the next charpolloutMRC p14,0,r3,$SCReg,0 ; Read Debug Status and Control RegisterTST r3, $TestEmptyBNE pollout ; if W set, register still fullwriteMCR p14,0,r0,$DReg,0 ; Write word from r0B pollin ; Loop for more words to readEND7-4 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


디버그 통신 채널Embedded ICE 논리의 COMMRX 및 COMMTX 신호가 인터럽트 컨트롤러에 연결되는 경우 이러한 유형의 폴링 방식 예제를 인터럽트 구동 예제로 변환할 수 있습니다.그런 다음 읽기 및 쓰기 코드를 인터럽트 처리기에서 사용할 수 있습니다. 인터럽트 처리기 작성에 대한 자세한 내용은 6-11페이지의 인터럽트 처리기를 참조하십시오.<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 7-5Unrestricted AccessNon-Confidential


디버그 통신 채널7.3 Thumb 상태에서 액세스<strong>ARM</strong> 아키텍처 v6T2 이전 아키텍처가 포함된 프로세서에는 Thumb 보조 프로세서 명령어가 없으므로 프로세서가 Thumb 상태에 있는 동안 디버그 통신 채널을사용할 수 없습니다.다음 세 가지 방법으로 이 문제를 해결할 수 있습니다.• SVC 처리기에 각 폴링 루틴을 작성하고 <strong>ARM</strong> 상태나 Thumb 상태에 있는동안 해당 루틴을 실행할 수 있습니다. SVC 처리기가 시작되면 프로세서는보조 프로세서 명령어를 사용할 수 있는 <strong>ARM</strong> 상태로 즉시 전환됩니다.SVC에 대한 자세한 내용은 6장 프로세서 예외 처리를 참조하십시오.• Thumb 코드에서 인터워킹을 통해 폴링을 구현하는 <strong>ARM</strong> 하위 루틴을 호출할 수 있습니다. <strong>ARM</strong> 코드와 Thumb 코드를 함께 사용하는 데 대한 자세한내용은 5장 <strong>ARM</strong>과 Thumb의 인터워킹을 참조하십시오.• 폴링 방식 통신 대신 인터럽트 구동 통신을 사용합니다. 인터럽트 처리기는<strong>ARM</strong> 명령어 세트 상태에서 실행되므로 보조 프로세서 명령어에 직접 액세스할 수 있습니다.7-6 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


8장세미호스팅이 장에서는 세미호스팅 메커니즘에 대해 설명합니다.이 장에는 다음 단원이 포함되어 있습니다.• 8-2페이지의 세미호스팅 개요• 8-6페이지의 세미호스팅 구현• 8-8페이지의 세미호스팅 작업• 8-26페이지의 디버그 에이전트 상호작용 SVC<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 8-1Unrestricted AccessNon-Confidential


세미호스팅8.1 세미호스팅 개요세미호스팅을 사용하면 <strong>ARM</strong> 타겟에서 실행되는 코드에서 RealView 디버거를실행하는 호스트 컴퓨터의 I/O 기능을 사용할 수 있습니다. 이러한 기능의 예로는키보드 입력, 화면 출력, 디스크 I/O 등이 포함됩니다.8.1.1 세미호스팅이란?세미호스팅은 <strong>ARM</strong> 타겟과 디버거를 실행 중인 호스트 컴퓨터 간에 응용 프로그램 코드의 I/O 요청을 전달하는 메커니즘입니다. 예를 들어 이 메커니즘을 사용하면 printf () 및 scanf () 와 같은 C 라이브러리의 함수를 활성화하여 타겟 시스템에 화면과 키보드를 갖추는 대신 호스트의 화면과 키보드를 사용할 수 있습니다.이는 개발 하드웨어가 최종 시스템의 입력 및 출력 기능을 빠짐없이 갖추지 못한경우가 많으므로 유용합니다. 세미호스팅을 통해 호스트 컴퓨터가 이러한 기능을 제공할 수 있습니다.세미호스팅은 프로그램 제어에서 예외를 생성하는 정의된 소프트웨어 명령어 세트 (예: SVC) 로 구현됩니다. 응용 프로그램이 적절한 세미호스팅 호출을 호출하면 디버그 에이전트가 예외를 처리합니다. 디버그 에이전트는 호스트와의 사이에 필요한 통신을 제공합니다.세미호스팅 인터페이스는 <strong>ARM</strong> Limited에서 제공하는 모든 디버그 에이전트에서 공통입니다. 세미호스팅된 작업은 이식에 대한 아무 요구 사항 없이 RealView<strong>ARM</strong>ulator ISS, ISSM (명령어 세트 시스템 모델) , RTSM (실시간 시스템 모델) ,RealView ICE 또는 RealMonitor를 사용할 경우 작동됩니다 (8-3페이지의 그림 8-1참조) .많은 경우, 세미호스팅은 라이브러리 함수 내부의 코드에서 호출됩니다. 응용 프로그램에서도 세미호스팅 작업을 직접 호출할 수 있습니다. <strong>ARM</strong> C 라이브러리의 세미호스팅 지원에 대한 자세한 내용은 라이브러리 및 부동 소수점 지원 설명서에서 2장 C 및 C++ 라이브러리를 참조하십시오.8-2 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


세미호스팅prtf(hllo)Application CodeTargetprtf()SVCC Library CodeSVC handled bydebug agentHostdebuggerhlloCommunication withdebugger runningon hostText displayedon host screen그림 8-1 세미호스팅 개요참고<strong>ARM</strong>v7 이전의 <strong>ARM</strong> 프로세서는 이전에 SWI 명령어라고 하던 SVC 명령어를 사용하여 세미호스팅 호출을 수행합니다. 그러나 Cortex -M1 또는 Cortex-M3 프로세서와 같은 <strong>ARM</strong>v6-M 또는 <strong>ARM</strong>v7-M용으로 컴파일할 경우 세미호스팅은 BKPT 명령어를 사용하여 구현됩니다.8.1.2 세미호스팅 인터페이스<strong>ARM</strong> 및 Thumb SVC 명령어에는 응용 프로그램 코드에서 사용되는 SVC 번호가인코딩되어 있는 필드가 있습니다. 시스템 SVC 처리기가 이 번호를 디코딩할 수있습니다.참고<strong>ARM</strong>v6-M 또는 <strong>ARM</strong>v7-M용으로 컴파일할 경우 Thumb BKPT 명령어가 Thumb SVC명령어 대신 사용됩니다. BKPT와 SVC는 모두 8비트 즉치값을 가져옵니다. 다른 모든 측면에서 세미호스팅은 지원되는 모든 <strong>ARM</strong> 프로세서에 대해 동일합니다.<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 8-3Unrestricted AccessNon-Confidential


세미호스팅세미호스팅 작업은 단일 SVC 번호를 통해 요청되므로 응용 프로그램 또는 운영체제가 기타 번호를 사용할 수 있게 됩니다. 세미호스팅에 사용되는 SVC 번호는타겟 아키텍처나 프로세서에 따라 다릅니다.SVC 0x123456 모든 아키텍처에 대해 <strong>ARM</strong> 상태인 경우SVC 0xABBKPT 0xAB<strong>ARM</strong>v6-M 및 <strong>ARM</strong>v7-M을 제외한 <strong>ARM</strong> 상태 및 Thumb 상태인 경우.이 동작은 <strong>ARM</strong> 또는 타사의 모든 디버그 타겟에서 보장되지는 않습니다.<strong>ARM</strong>v6-M 및 <strong>ARM</strong>v7-M (Thumb 상태만 해당)8-5페이지의 세미호스팅 작업 번호 변경도 참조하십시오.SVC 번호는 디버그 에이전트에 SVC 명령어가 세미호스팅 요청임을 표시합니다.작업 간 구분을 위해 작업 유형이 R0으로 전달됩니다. 다른 모든 매개변수는 R1이가리키는 블록으로 전달됩니다.결과는 명시적 반환 값 또는 데이터 블록에 대한 포인터로 R0에 반환됩니다. 결과가 반환되지 않더라도 R0이 손상되었다고 가정합니다.R0으로 전달되는 사용 가능한 세미호스팅 작업 번호는 다음과 같이 할당됩니다.0x00-0x310x32-0xFF<strong>ARM</strong>이 사용합니다.<strong>ARM</strong>의 향후 사용을 위해 예약됩니다.0x100-0x1FF 사용자 응용 프로그램을 위해 예약됩니다. <strong>ARM</strong>은 이러한 번호를사용하지 않습니다.그러나 자체 SVC 작업을 작성하는 중이라면 세미호스팅된 SVC 번호와 이들 작업 유형 번호를 사용하기보다 다른 SVC 번호를 사용하는 것이 좋습니다.0x200-0xFFFFFFFF정의되지 않았으며 현재 사용되지 않습니다. 이 번호는 사용하지 않는 것이 좋습니다.다음 단원에서 작업 이름 뒤의 괄호 안 번호는 R0으로 배치되는 값입니다 (예:SYS_OPEN (0x01) ) .어셈블리 언어 코드에서 SVC를 호출하는 경우, <strong>ARM</strong>은 semihost.h에 정의된 작업이름을 사용하는 것이 좋습니다. 이 파일은 RealView <strong>ARM</strong>ulator Extension Kit의일부로 설치됩니다. EQU 지시문으로 작업 이름을 정의할 수 있습니다. 예를 들면다음과 같습니다.8-4 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


세미호스팅SYS_OPENSYS_CLOSEEQU 0x01EQU 0x02세미호스팅 작업 번호 변경세미호스팅 작업 번호를 변경하지 않는 것이 좋습니다. 변경하는 경우에는 반드시 다음과 같이 해야 합니다.• 새 번호를 사용하도록 라이브러리 코드를 포함한 모든 시스템 코드 변경• 새 번호를 사용하도록 디버거 재구성<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 8-5Unrestricted AccessNon-Confidential


세미호스팅8.2 세미호스팅 구현세미호스팅이 제공하는 기능은 일반적으로 모든 디버그 에이전트에서 동일합니다. 그러나 세미호스팅의 구현은 호스트별로 다릅니다.이 단원에서는 다양한 디버그 에이전트별 세미호스팅 구현에 대해 설명합니다.8.2.1 RealView <strong>ARM</strong>ulator ISS세미호스팅 요청이 나타나면 RealView <strong>ARM</strong>ulator ISS에서 SVC를 직접 트래핑하고 벡터 테이블의 SVC 엔트리에 있는 명령어는 실행되지 않습니다.RealView <strong>ARM</strong>ulator ISS에서 세미호스팅 지원을 해제하려면 default.ami 파일의Default_Semihost를 No_Semihost로 변경합니다.자세한 내용은 RealView <strong>ARM</strong>ulator ISS 사용 설명서를 참조하십시오.8.2.2 RealView ICERealView ICE DLL을 사용하는 경우 세미호스팅은 실제 SVC 예외 처리기로 처리되거나, 브레이크포인트를 통해 처리기를 에뮬레이션하여 처리됩니다. RealViewICE를 사용하는 세미호스팅에 대한 자세한 내용은 RealView ICE 및 RealView 트레이스 사용 설명서를 참조하십시오.8.2.3 명령어 세트 시스템 모델세미호스팅 요청이 나타나면 ISSM에서 요청을 직접 트래핑하고 벡터 테이블의SVC 엔트리에 있는 명령어는 실행되지 않습니다. ISSM을 사용하는 세미호스팅에 대한 자세한 내용은 디버거 설명서를 참조하십시오.ISSM에서 세미호스팅 지원을 해제하려면 디버거에서 타겟을 구성하거나default.smc 파일의 해당 엔트리를 변경하십시오....Name="semihosting-enable" Type="Bool">18-6 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


세미호스팅8.2.4 RealMonitorRealMonitor는 시스템과 함께 통합되어야만 세미호스팅을 지원할 수 있는 SVC처리기를 구현합니다.타겟이 세미호스팅된 SVC 명령어를 실행하면 RealMonitor SVC 처리기가 호스트와의 사이에 필요한 통신을 수행합니다.자세한 내용은 RealMonitor와 함께 제공되는 설명서를 참조하십시오.<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 8-7Unrestricted AccessNon-Confidential


세미호스팅8.3 세미호스팅 작업이 단원에서는 호스트 컴퓨터와 <strong>ARM</strong> 타겟 간의 디버그 I/O 기능을 사용할 수 있도록 하는 세미호스팅 작업에 대해 설명합니다.8.3.1 angel_SWIreason_EnterSVC (0x17)프로세서를 관리자 모드로 설정하고 새 CPSR의 두 인터럽트 마스크 비트를 모두설정하여 모든 인터럽트를 비활성화합니다. RealView ICE 또는 RealMonitor를 사용하면 사용자 스택 포인터 (R13_USR) 가 관리자 모드 스택 포인터 (R13_SVC) 로 복사되고, 현재 CPSR의 I 및 F 비트가 설정되어 일반 및 고속 인터럽트를 비활성화합니다.참고RealView <strong>ARM</strong>ulator ISS를 사용하여 디버그하는 경우에는 다음 사항이 적용됩니다.• R0이 0으로 설정되어, 사용자 모드로 복귀하기 위해 사용할 수 있는 함수가없음을 나타냅니다.• 사용자 모드 스택 포인터는 관리자 모드 스택 포인터로 복사되지 않습니다.시작레지스터 R1은 사용되지 않습니다. CPSR이 사용자 또는 관리자 모드를 지정할 수있습니다.반환종료 시 R0은 사용자 모드로 복귀하기 위해 호출할 함수의 주소를 포함합니다. 함수의 프로토타입은 다음과 같습니다.void ReturnToUSR (void)EnterSVC가 사용자 모드에서 호출되면 이 루틴이 호출자를 사용자 모드로 반환하고 인터럽트 플래그를 복원합니다. 그렇지 않으면 이 루틴의 작업이 정의되지 않은 것입니다.사용자 모드에서 입력하면 사용자 스택 포인터를 복사한 결과로 인해 관리자 모드 스택이 손실됩니다. 사용자 루틴으로 복귀하면 R13_SVC가 관리자 모드 스택 값으로 복원되지만 이 스택은 응용 프로그램에서 사용하면 안 됩니다.8-8 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


세미호스팅SVC를 실행한 후 현재 링크 레지스터는 R14_USR이 아니라 R14_SVC입니다. 호출 후R14_USR의 값이 필요하면 호출 전에 스택으로 푸시되고, 호출 후에는 팝되어야 합니다 (BL 함수 호출에 관련된 경우) .<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 8-9Unrestricted AccessNon-Confidential


세미호스팅8.3.2 angel_SWIreason_ReportException (0x18)이 SVC는 응용 프로그램에서 호출되어 디버거에 예외를 직접 보고할 수 있습니다. 가장 일반적인 용도는 ADP_Stopped_ApplicationExit를 사용하여 실행이 완료되었음을 보고하는 것입니다.시작시작 시 R1은 표 8-1 및 표 8-2에 나열된 값 중 하나로 설정됩니다. 이러한 값은angel_reasons.h에 정의되어 있습니다.하드웨어 예외는 디버거 변수 vector_catch가 예외 유형을 캐치하도록 설정되고디버그 에이전트가 해당 예외 유형을 보고할 수 있을 경우에 생성됩니다.표 8-1 하드웨어 벡터 이유 코드이름ADP_Stopped_BranchThroughZeroADP_Stopped_UndefinedInstrADP_Stopped_SoftwareInterruptADP_Stopped_PrefetchAbortADP_Stopped_DataAbortADP_Stopped_AddressExceptionADP_Stopped_IRQADP_Stopped_FIQ16진수 값0x200000x200010x200020x200030x200040x200050x200060x20007예외 처리기는 기본 작업으로 처리기 체인 끝에서 이러한 SVC를 사용하여 예외가 처리되지 않았음을 나타낼 수 있습니다.표 8-2 소프트웨어 이유 코드이름ADP_Stopped_BreakPointADP_Stopped_WatchPointADP_Stopped_StepComplete16진수 값0x200200x200210x200228-10 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


세미호스팅표 8-2 소프트웨어 이유 코드 (계속)이름16진수 값ADP_Stopped_RunTimeErrorUnknown *0x20023ADP_Stopped_InternalError *0x20024ADP_Stopped_UserInterruptionADP_Stopped_ApplicationExit0x200250x20026ADP_Stopped_StackOverflow *0x20027ADP_Stopped_DivisionByZero *0x20028ADP_Stopped_OSSpecific *0x200298-10페이지의 표 8-2에서 값 옆에 * 기호가 있으면 <strong>ARM</strong> 디버거에서 지원하지 않는 값이라는 뜻입니다. 디버거는 이러한 값에 대해 Unhandled ADP_Stoppedexception을 보고합니다.반환이러한 호출에서는 아무런 반환이 예상되지 않습니다. 그러나 디버거가RDI_Execute 요청이나 이에 상당하는 작업을 수행하여 응용 프로그램이 계속되도록 요청할 수 있습니다. 이 경우 레지스터가 SVC 시작 시에 있었거나 이후 디버거에 의해 수정되므로 레지스터 실행이 계속됩니다.<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 8-11Unrestricted AccessNon-Confidential


세미호스팅8.3.3 SYS_CLOSE (0x02)호스트 시스템에서 파일을 닫습니다. 핸들은 SYS_OPEN으로 열린 파일을 참조해야합니다.시작시작 시 R1은 1워드 인수 블록에 대한 포인터를 포함합니다.워드 1열린 파일에 대한 핸들을 포함합니다.반환종료 시 R0에는 다음이 포함됩니다.• 호출이 성공한 경우 0• 호출이 성공하지 못한 경우 -18.3.4 SYS_CLOCK (0x10)실행 시작 이후 경과된 100분의 1초 수를 반환합니다.이 SVC가 반환한 값은 통신 오버헤드나 다른 에이전트 관련 요소 때문에 일부 벤치마킹 목적에 대해 사용이 제한될 수 있습니다. 예를 들어 RealView ICE를 사용하면 실행을 위해 요청이 호스트로 다시 전달됩니다. 따라서 전송 및 프로세스 일정에 예상치 않은 지연이 발생할 수 있습니다.이 함수는 시간이 지정된 코드 순서가 있는 경우와 없는 경우에 대해 각각의 간격간 차이를 계산하여 시간 간격을 계산하는 데 사용합니다.일부 시스템에서는 보다 정확한 타이밍을 제공할 수 있습니다 (8-13페이지의SYS_ELAPSED (0x30) 및 8-22페이지의 SYS_TICKFREQ (0x31) 참조) .시작레지스터 R1은 0을 포함해야 합니다. 다른 매개변수는 없습니다.반환종료 시 R0에는 다음이 포함됩니다.• 호출이 성공한 경우 특정한 임의 시작점 이후 경과한 100분의 1초 수• 통신 오류 등으로 인해 호출이 성공하지 못한 경우 -18-12 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


세미호스팅8.3.5 SYS_ELAPSED (0x30)실행 시작 이후 경과된 타겟 틱 수를 반환합니다. 틱 주기를 결정하려면SYS_TICKFREQ를 사용하십시오.시작시작 시 r1은 경과된 틱 수 반환에 사용되는 2워드 데이터 블록을 가리킵니다.워드 1워드 2더블워드 값에서 최하위 워드최상위 워드반환종료 시:• R1이 경과된 틱 수를 포함하는 더블워드를 가리킬 경우 R0은 –1을 포함합니다. RealView ICE는 이 SVC를 지원하지 않고 항상 R0에 –1을 반환합니다.• R1은 경과된 틱 수를 포함하는 더블워드 (하위 워드가 먼저) 를 가리킵니다.8.3.6 SYS_ERRNO (0x13)세미호스팅 SVC의 호스트 구현과 관련된 C 라이브러리 errno 변수의 값을 반환합니다. errno 변수는 다음을 포함하는 여러 C 라이브러리 세미호스팅된 함수에의해 설정될 수 있습니다.• SYS_REMOVE• SYS_OPEN• SYS_CLOSE• SYS_READ• SYS_WRITE• SYS_SEEKerrno가 설정되었는지 여부와 어떤 값으로 설정되었는지 여부는 ISO C 표준이 동작을 정의하는 경우를 제외하고 전적으로 호스트에 따라 다릅니다.시작매개변수가 없습니다. 레지스터R1은 0이어야 합니다.<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 8-13Unrestricted AccessNon-Confidential


세미호스팅반환종료 시 R0은 C 라이브러리 errno 변수의 값을 포함합니다.8.3.7 SYS_FLEN (0x0C)지정된 파일의 길이를 반환합니다.시작시작 시 R1은 1워드 인수 블록에 대한 포인터를 포함합니다.워드 1이전에 열린 검색 가능한 파일 개체에 대한 핸들반환종료 시 R0에는 다음이 포함됩니다.• 호출이 성공한 경우 파일 개체의 현재 길이• 오류가 발생한 경우 -18.3.8 SYS_GET_CMDLINE (0x15)실행 가능 파일 호출에 사용되는 명령 행 (즉 argc 및 argv) 을 반환합니다.시작시작 시 R1은 명령 문자열 및 해당 문자열의 길이 반환에 사용되는 2워드 데이터블록을 가리킵니다.워드 1워드 2워드 2에 지정된 크기 이상의 버퍼에 대한 포인터버퍼의 길이 (바이트)반환종료 시:• 레지스터 R1은 2워드 데이터 블록을 가리킵니다.워드 1 명령 행의 Null로 끝나는 문자열에 대한 포인터워드 2 문자열의 길이8-14 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


세미호스팅디버그 에이전트가 전송 가능한 문자열의 최대 길이에 제한을 둘 수 있습니다. 그러나 에이전트는 최소한 80바이트의 명령 행을 전송할 수 있어야 합니다.• 레지스터 R0은 다음 오류 코드를 포함합니다.— 호출이 성공한 경우 0— 통신 오류 등으로 인해 호출이 성공하지 못한 경우 -18.3.9 SYS_HEAPINFO (0x16)시스템 스택 및 힙 매개변수를 반환합니다. 반환된 값은 일반적으로 초기화 중에C 라이브러리가 사용하는 값입니다. RealView <strong>ARM</strong>ulator ISS의 경우 반환되는값은 peripherals.ami에 제공된 값입니다. RealView ICE의 경우에 반환되는 값은이미지 위치 및 메모리의 최상위입니다.C 라이브러리는 이러한 값을 재정의할 수 있습니다. C 라이브러리의 메모리 관리에 대한 자세한 내용은 라이브러리 및 부동 소수점 지원 설명서에서 2-73페이지의 스토리지 관리 조정을 참조하십시오.호스트 디버거는 top_of_memory 디버거 변수를 사용하여 반환할 실제 값을 결정합니다.시작시작 시 R1은 4워드 데이터 블록에 대한 포인터의 주소를 포함합니다. 데이터 블록의 내용은 함수가 채웁니다. 데이터 블록의 구조와 반환 값에 대해서는 예제 8-1을 참조하십시오.예제 8-1struct 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) ;<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 8-15Unrestricted AccessNon-Confidential


세미호스팅참고데이터 블록의 워드 1 값이 0이면 C 라이브러리가 0을 Image$$ZI$$Limit로 바꿉니다. 이 값은 메모리 맵에 있는 데이터 영역의 최상위에 해당합니다.반환종료 시 R1은 구조체에 대한 포인터의 주소를 포함합니다.구조체의 값 중 하나가 0인 경우 시스템이 실제 값을 계산하지 못한 것입니다.8.3.10 SYS_ISERROR (0x08)다른 세미호스팅 호출에서의 반환 코드가 오류 상태인지 여부를 결정합니다. 이호출은 검사할 오류 코드를 포함하는 매개변수 블록에 전달됩니다.시작시작 시 R1은 1워드 데이터 블록에 대한 포인터를 포함합니다.워드 1확인할 필수 상태 워드입니다.반환종료 시 R0에는 다음이 포함됩니다.• 상태 워드가 오류를 나타내지 않을 경우 0• 상태 워드가 오류를 나타낼 경우 0이 아닌 값8.3.11 SYS_ISTTY (0x09)파일이 대화형 장치에 연결되었는지 확인합니다.시작시작 시 R1은 1워드 인수 블록에 대한 포인터를 포함합니다.워드 1이전에 열린 파일 개체에 대한 핸들반환종료 시 R0에는 다음이 포함됩니다.• 핸들이 대화형 장치를 식별할 경우 18-16 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


세미호스팅• 핸들이 파일을 식별할 경우 0• 오류가 발생한 경우 1이나 0이 아닌 값8.3.12 SYS_OPEN (0x01)호스트 시스템에서 파일을 엽니다. 파일 경로는 호스트 프로세스의 현재 디렉토리에 대한 상대 경로 또는 호스트 운영 체제의 경로 규칙을 사용하는 절대 경로로지정됩니다.<strong>ARM</strong> 타겟이 특수 경로 이름 :tt를 콘솔 입력 스트림 (열기- 읽기용) 또는 콘솔 출력 스트림 (열기- 쓰기용) 으로 해석합니다. 이러한 스트림 열기는 C stdio 스트림을 참조하는 해당 응용 프로그램의 표준 시작 코드의 일부로 수행됩니다.시작시작 시 R1은 3워드 인수 블록에 대한 포인터를 포함합니다:워드 1워드 2워드 3파일 또는 장치 이름을 포함하는 Null로 끝나는 문자열에 대한 포인터파일 열기 모드를 지정하는 정수. 표 8-3에서는 정수 및 해당 ISO Cfopen () 모드에 대한 유효한 값을 제공합니다.워드 1이 가리키는 문자열의 길이를 나타내는 정수.길이에는 반드시 있어야 하는 마지막 Null 문자는 포함되지 않습니다.표 8-3 모드 값모드 0 1 2 3 4 5 6 7 8 9 10 11ISO C fopen 모드 a r rb r+ r+b w wb w+ w+b a ab a+ a+ba. 비ANSI 옵션 t는 지원되지 않습니다.반환종료 시 R0에는 다음이 포함됩니다.• 호출이 성공한 경우 0이 아닌 핸들• 호출이 성공하지 못한 경우 -1<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 8-17Unrestricted AccessNon-Confidential


세미호스팅8.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이 아닌 값이 반환되면 행 읽기가 버퍼를 채우지 않았음을 나타냅니다.8-18 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


세미호스팅8.3.14 SYS_READC (0x07)콘솔에서 바이트를 읽습니다.시작레지스터 R1은 0을 포함해야 합니다. 다른 매개변수나 값은 가능하지 않습니다.반환종료 시 R0은 콘솔에서 읽은 바이트를 포함합니다.8.3.15 SYS_REMOVE (0x0E)주의호스트 파일링 시스템의 지정된 파일을 삭제합니다.시작시작 시 R1은 2워드 인수 블록에 대한 포인터를 포함합니다.워드 1워드 2삭제할 파일의 경로 이름을 제공하는 Null로 끝나는 문자열을 가리킵니다.문자열의 길이반환종료 시 R0에는 다음이 포함됩니다.• 성공적으로 삭제된 경우 0• 삭제하지 못한 경우 0이 아닌 호스트별 오류 코드<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 8-19Unrestricted AccessNon-Confidential


세미호스팅8.3.16 SYS_RENAME (0x0F)지정된 파일의 이름을 바꿉니다.시작시작 시 R1은 4워드 데이터 블록에 대한 포인터를 포함합니다.워드 1 이전 파일 이름에 대한 포인터워드 2 이전 파일 이름의 길이워드 3 새 파일 이름에 대한 포인터워드 4 새 파일 이름의 길이두 문자열 모두 Null로 끝납니다.반환종료 시 R0에는 다음이 포함됩니다.• 이름을 성공적으로 바꾼 경우 0• 이름 바꾸기가 실패한 경우 0이 아닌 호스트별 오류 코드8-20 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


세미호스팅8.3.17 SYS_SEEK (0x0A)파일 시작부터 지정된 오프셋을 사용하여 파일에서 지정된 위치를 검색합니다.파일은 바이트 배열로 가정되고 오프셋은 바이트 단위로 제공됩니다.시작시작 시 R1은 2워드 데이터 블록에 대한 포인터를 포함합니다.워드 1 검색 가능한 파일 객체에 대한 핸들워드 2 검색할 절대적 바이트 위치반환종료 시 R0에는 다음이 포함됩니다.• 요청이 성공한 경우 0• 요청이 성공하지 못한 경우 음수 값. SYS_ERRNO는 오류를 설명하는 호스트errno 변수의 값을 읽는 데 사용할 수 있습니다.참고현재 파일 개체 범위 밖의 검색 효과는 정의되지 않습니다.<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 8-21Unrestricted AccessNon-Confidential


세미호스팅8.3.18 SYS_SYSTEM (0x12)명령을 호스트 명령 행 인터프리터로 전달합니다. 그러면 dir, ls 또는 pwd와 같은시스템 명령을 실행할 수 있습니다. 터미널 I/O는 호스트에 있으며 타겟에는 보이지 않습니다.주의호스트로 전달된 명령이 호스트에서 실행됩니다. 전달된 명령에 의도하지 않은결과가 없도록 유의하십시오.시작시작 시 R1은 2워드 인수 블록에 대한 포인터를 포함합니다.워드 1 호스트 명령 행 인터프리터로 전달할 문자열을 가리킵니다.워드 2 문자열의 길이반환종료 시 R0은 반환 상태를 포함합니다.8.3.19 SYS_TICKFREQ (0x31)틱 주기를 반환합니다.시작레지스터 R1은 이 루틴의 시작 시 0을 포함해야 합니다.반환종료 시 R0은 다음 중 하나를 포함합니다.• 초당 틱 수• 타겟에서 틱 하나의 값을 모를 경우 -1. RealView ICE는 이 SVC를 지원하지않고 항상 R0에 –1을 반환합니다.8-22 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


세미호스팅8.3.20 SYS_TIME (0x11)1970년 1월 1일 00:00 이후 경과한 초 수를 반환합니다. 이것은 어떤 RealView<strong>ARM</strong>ulator ISS, ISSM, RTSM 또는 RealView ICE 구성과도 무관한 실제 시간입니다.시작매개변수가 없습니다.반환종료 시 R0은 초 수를 포함합니다.8.3.21 SYS_TMPNAM (0x0D)시스템 파일 식별자에 의해 식별된 파일의 임시 이름을 반환합니다.시작시작 시 R1은 3워드 인수 블록에 대한 포인터를 포함합니다:워드 1워드 2워드 3버퍼에 대한 포인터이 파일 이름의 타겟 식별자. 값은 0 ~ 255 범위의 정수여야 합니다.버퍼의 길이를 포함합니다. 길이는 호스트 시스템의 L_tmpnam 값 이상이어야 합니다.반환종료 시 R0에는 다음이 포함됩니다.• 호출이 성공한 경우 0• 오류가 발생한 경우 -1R1이 가리키는 버퍼에는 적합한 디렉토리 이름을 접두사로 붙인 파일 이름이 포함됩니다.같은 타겟 식별자를 다시 사용하면 동일한 파일 이름이 반환됩니다.참고반환된 문자열은 Null로 끝나야 합니다.<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 8-23Unrestricted AccessNon-Confidential


세미호스팅8.3.22 SYS_WRITE (0x05)현재 파일 위치에서 지정된 파일에 버퍼의 내용을 씁니다. 파일 위치는 다음 중한 가지 방식으로 지정됩니다.• SYS_SEEK 사용 (명시적)• 이전 SYS_READ 또는 SYS_WRITE 요청의 1바이트 위 (암시적)파일 위치는 파일이 열릴 때는 파일의 시작에 있고 파일이 닫힐 때는 손실됩니다.가능하면 항상 파일 작업을 단일 작업으로 수행하십시오. 예를 들어, 대안이 없는경우가 아닌 한 16KB 쓰기를 4개의 4KB 청크로 분할하지 마십시오.시작시작 시 R1은 3워드 데이터 블록에 대한 포인터를 포함합니다.워드 1 이전에 SYS_OPEN으로 열린 파일에 대한 핸들을 포함합니다.워드 2 작성할 데이터를 포함하는 메모리를 가리킵니다.워드 3 버퍼에서 파일로 쓰일 바이트 수를 포함합니다.반환종료 시 R0에는 다음이 포함됩니다.• 호출이 성공한 경우 0• 오류가 있는 경우 쓰지 못한 바이트 수8.3.23 SYS_WRITEC (0x03)디버그 채널에 R1이 가리키는 문자 바이트를 씁니다. <strong>ARM</strong> 디버거에서 실행되면문자가 호스트 디버거 콘솔에 나타납니다.시작시작 시 R1은 문자에 대한 포인터를 포함합니다.반환해당 사항이 없습니다. 레지스터 R0이 손상됩니다.8-24 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access


세미호스팅8.3.24 SYS_WRITE0 (0x04)디버그 채널에 Null로 끝나는 문자열을 씁니다. <strong>ARM</strong> 디버거에서 실행되면 문자가 호스트 디버거 콘솔에 나타납니다.시작시작 시 R1은 문자열의 첫 번째 바이트에 대한 포인터를 포함합니다.반환해당 사항이 없습니다. 레지스터 R0이 손상됩니다.<strong>ARM</strong> DUI 0203IK Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. 8-25Unrestricted AccessNon-Confidential


세미호스팅8.4 디버그 에이전트 상호작용 SVC8-8페이지의 세미호스팅 작업에서 설명하는 C 라이브러리 세미호스팅된 함수 외에도 다음 SVC가 디버그 에이전트와의 상호 작용을 지원합니다.• 8-8페이지의 angel_SWIreason_EnterSVC (0x17)• 8-10페이지의 angel_SWIreason_ReportException (0x18)8-26 Copyright © 2002-2008 <strong>ARM</strong> Limited. All rights reserved. <strong>ARM</strong> DUI 0203IKNon-ConfidentialUnrestricted Access

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!