[테크월드뉴스=이혜진 기자] ILINK에 대해 먼저 소개를 하면, 큰 사이즈의 재배치 가능한 멀티 모듈의 C/C++ 프로그램과 C/C++ 프로그램과 어셈블러 프로그램 혼합 링크, 또는 크기가 작은 단일 파일의 절대 주소를 가진 어셈블러 프로그램 링크등에 폭넓게 사용되는 실제 어플리케이션 개발에 적합한 강력하고 유연성 있는 링커(Linker)이다. IAR Embedded Workbench에서 선택된 타겟(Target)에 따라 표준 메모리 할당을 할 수 있는 링커 설정 파일이 자동으로 등록되지만, 더 복잡한 메모리 할당을 할 경우에는 이 링커 설정 파일(.icf파일)를 편집해야 한다. 

이 가이드는 IAR Embedded Workbench의 기본 기능 및 운영을 이해하고 링커 설정 파일에서 자유롭게 코드와 데이터를 배치하는 방법을 습득하고자하는 분들을 대상으로 하고 있다. 

대상제품은 EWARM V6.30.1 이후, EWRX V2.10 이후, EWSTM8이다. 

 

1. 링커 옵션과 링커 설정 파일

링커 설정 파일 선택

새 프로젝트를 만들 때 각 코어(Core) 및 MCU에 대한 기본 링커 설정 파일이 자동으로 선택된다. ARM Cortex 코어를 선택하면 [그림 1]과 같이 generic_cortex.icf파일이 선택된다. 여기에서 $TOOLKIT_DIR$은 Embedded Workbench가 설치되어 있는 폴더를 의미한다.  
 
[그림 1] 자동으로 선택된 링커 설정 파일

 

링커 설정 파일을 변경하고 싶을 때는 편집 결과를 저장하기 위해 다른 위치를 지정해야 한다. 프로젝트 파일(.ewp)과 같은 디렉토리에 두는 경우, Override default 항목을 체크하고 파일 경로를 $PROJ_DIR$\generic_cortex.icf와 같이 변경한 후 Edit버튼을 눌러 해당 경로에 저장을 한다. $PROJ_DIR$은 프로젝트의 파일 경로를 나타낸다. 


링커 설정 파일 편집기

 
[그림 2] ARM Cortex 디바이스 기준, 링커 설정 파일의 템플릿 첫 번째 부분

 

링커 설정 파일 편집기를 이용하면 [그림 2]의 빨간색 상자 부분을 쉽게 변경할 수 있다. 링커 설정 파일 편집기를 실행하려면 아래 그림의 편집(Edit) 버튼을 클릭한다. 편집기에는 [그림 3]과 같이 세 가지 메뉴가 있다. 벡터 테이블(Vector Table), 메모리 구성(Memory Regions), 스택/힙 크기(Stack/Heap Sizes)와 같다. 각 항목 별로 텍스트 상자에 원하는 값을 입력하면, [그림2]의 링커 설정 파일에 적용된다.  
 
[그림 3] 링커 설정 파일 편집기

 

2. 기초편

섹션(Section) 내용

링커 설정 파일에서 사용하는 섹션은 [표 1]과 같이 구분된다. 이 부분은 기초적인 내용으로 링커 설정 파일을 편집하기 위해 필수적인 이해가 필요한다. 

[표 1] 링커 설정 파일에서 사용하는 기본적인 섹션 정의

 

링커 지시문의 예

링커 설정 파일에 필요한 지시어를 설명하기전에 기본적으로 사용하는 지시문은 다음과 같다. 
-    define memory
mem이라는 이름으로 4G바이트의 메모리 공간을 정의
ex) define memory mem with size = 4G;
-    define region
mem이라는 메모리 공간에 ROM이라는 이름의 영역(region) 정의 (0~0x0003fffff)
ex) define region ROM = mem : [from 0x00000000 to 0x0003ffff];
-    define block
CSTACK이라는 이름의 256바이트의 블록을 정의 (정렬크기 = 8바이트)
ex) define block CSTACK with alignment = 8 size = 0x100 { }; 
-    initialize by copy
rw섹션을 프로그램 시작 시 자동으로 초기화
ex) initialize by copy {rw};
-    do not initialize
.noinit 섹션은 프로그램 시작 시 초기화하지 않음
ex) do not initialize {section .noinit}; 
-    place at address
읽기 전용(ro) .initvec 섹션을 메모리 공간 mem의 0번지에 위치
ex) place at address mem : 0x00 {ro section .initvec}; 
-    place in
ROM 영역에 읽기 전용 섹션을 배치
ex) place in ROM {ro}; 

 

3. 링커 설정 파일 활용

기본적인 설정

-    소스 프로그램의 예

 

[표 2] 기본적인 소스프로그램에 따른 각 변수의 섹션

 

[그림 4] 기본적인 메모리 맵


-    링커 설정 파일의 예

     
[표 3] 기본적인 링커 설정 파일에 대한 각 라인별 설명

 

초기화하지 않은 영역과 const 변수
-    소스 프로그램의 예


[표 4] 초기화하지 않은 변수와 const 변수에 대한 설명

 
[그림 5] 초기화하지 않은 변수와 const변수에 대한 메모리 맵

 

-    링커 설정 파일의 예

 

[표 5] 초기화하지 않는 변수의 링커 설정 파일에 대한 설명

 

RAM에서 실행하는 함수
-    소스 프로그램의 예
함수에 __ramfunc을 추가하면 코드가 .text 대신, .textrw 섹션에 할당됩니다. ILINK는 .textrw를 초기화가 있는 변수와 동일하게 취급하기 때문에 링커 설정 파일에 RAM에서 실행하는 함수에 대한 특별한 조치가 필요하지 않습니다.

 

[표 6] RAM에서 실행하는 함수에 대한 설명

 

[그림 6] RAM에서 실행하는 함수에 대한 메모리 맵

 

여기서 유심있게 보아야 할 것은 배열 b는 .data섹션에 배치되며, 함수 sub는 .textrw섹션에 배치된다. 링커 설정 파일에서 initialize by copy {rw};가 지정된 경우 초기화 데이터를 포함하는 섹션 .data_init과 .textrw_init 섹션이 분리된다. 이 경우, .data와 .textrw은 rw속성, .data_init과 .textrw_init은 ro속성이 된다.

 

함수/데이터 섹션 지정 및 메모리 배치

-    소스 프로그램의 예

 

[그림 7] 함수/데이터 섹션 지정에 따른 메모리 맵

 

-    링커 설정 파일의 예

 
[표 7] 함수 및 데이터를 특정 섹션에 위치시키기 위한 링커 설정 파일에 대한 설명

 

파일 단위로 배치

-    소스 프로그램의 예

main.c

 

sub1.c

 

sub2.c


[그림 8] 파일 단위로 배치시키기 위한 메모리 맵

 

-    링커 설정 파일의 예

 

   
[표 8] 파일 단위로 함수 및 데이터를 특정 섹션에 위치시키기 위한 링커 설정 파일에 대한 설명

 

RAM에서 실행하는 함수 (__ramfunc을 사용하지 않는 경우)

-    소스 프로그램의 예

 

[표 9] RAM에서 실행하는 함수(__ramfunc을 사용하지 않는 경우)에 대한 설명

 
[그림 9] RAM 실행 함수를 위한 메모리 맵

 

-    링커 설정 파일의 예

 

[표 10] RAM 실행 함수를 위한 링커 설정 파일에 대한 설명

 

4. 링커 설정 파일 활용

섹션이 중복되는 경우

섹션이 중복되는 경우는 더 작은 섹션이 우선시된다. place 지시문을 다음과 같이 지정되고 있는 경우SROM1 섹션이 RROM1 영역에 배치되지만, 다른 ro 섹션은 RROM0 영역에 배치된다. (자세한 내용은 "IAR C/C++ Development Guide – Compiling and Linking"를 참조)  
place in RROM0 {ro};
place in RROM1 {section SROM1};

 

섹션 배치 순서 지정

섹션을 고정 순서로 정렬하고 싶은 경우 define block 지시문을 통해 고정된 순서로 세그먼트를 위치시킬 수 있다. 

define block BLOCKNAME with fixed order (segment1, segment2 …) 
place in RROM0 {block BLOCKNAME};

 

외부 메모리 사용

세그먼트나 블록을 외부 메모리의 물리 영역에 맞게 배치할 수 있지만, 일반적으로 외부 메모리는 메모리의 종류를 불문하고 메모리 컨트롤러를 통한 초기 설정이 필요하다. 초기 설정 프로그램은 내부 플래시 메모리에 배치 및 시작하고 메모리 컨트롤러를 초기화를 마친 후 외부 메모리의 사용을 시작할 수 있다. 그러나C‑SPY 디버거의 매크로를 사용하여 이 역할을 대체하고, 외부 SDRAM 만을 사용하여 디버깅하는 것 등이 가능하다. (자세한 내용은 설명서 "IAR Embedded Workbench® C‑SPY® Debugging Guide" C‑SPY macro를 참조)

 

바이너리 파일 가져오기

다음은 컴파일 완료된 바이너리를 특정 섹션에 위치시키는 방법이다. 마지막 숫자는 메모리 정렬값이다. 
-‑ image_input = filename1.bin, symbol1, SECTION1, 8
-‑ image_input = filename2.bin, symbol2, SECTION2, 4

 

바이너리 파일이 두 개 이하인 경우는 Project > Options > Linker > Input > Raw binary image 옵션을 사용해도 가능하다.  

바이너리 파일은place 명령으로 위치시킬 수 있다.

place at address 0x30000000 {section SECTION1};

 

섹션 주소와 크기 읽기

외부/정적 변수의 초기화를 수동으로 수행하려는 경우, 또는 오버레이 등으로 전체 섹션의 주소와 크기를 프로그램에서 알고 싶은 경우에는 다음과 같은 섹션 연산자를 사용한다. 

void * section_begin (char const * section)      // 섹션의 시작 주소 
void * section_end (char const * section)         // 섹션의 끝 주소 
size_t * section_size (char const * section)        // 섹션의 크기 

(자세한 내용은 "IAR C/C++ Development Guide – Compiling and Linking"를 참조)

 

맺음말

개발 환경을 개발하는 업체는 개발자들의 노력과 고충을 알고 이를 해결할 수 있는 대다수의 기능을 개발해 놓고 있다. 이것을 선택하느냐 마느냐는 개발자의 몫이다. 
 

회원가입 후 이용바랍니다.
키워드
개의 댓글
0 / 400
댓글 정렬
BEST댓글
BEST 댓글 답글과 추천수를 합산하여 자동으로 노출됩니다.
댓글삭제
삭제한 댓글은 다시 복구할 수 없습니다.
그래도 삭제하시겠습니까?
댓글수정
댓글 수정은 작성 후 1분내에만 가능합니다.
/ 400
내 댓글 모음
저작권자 © 테크월드뉴스 무단전재 및 재배포 금지