속도 향상 위한 RAM으로의 코드 위치 변경
상태바
속도 향상 위한 RAM으로의 코드 위치 변경
  • 이현도 IAR Systems 과장
  • 승인 2019.05.16 09:00
  • 댓글 0
이 기사를 공유합니다

메모리의 접근 속도, 다시말해 메모리의 정보를 읽고 쓰는 속도는 메모리 구조상 ROM 또는 Flash영역보다 RAM의 속도가 빠르다. 하지만 RAM은 휘발성 메모리이기 때문에 전원공급이 없으면 메모리의 데이터는 삭제된다. 따라서, 일반적으로 코드 저장 용도로는 사용하지 않는다.

하지만 소스코드의 속도를 최대한 올려야하는 경우, 코드를 RAM으로 복사해 RAM에서 수행하도록 하는 방법이 있다. 우선 코드를 RAM 에 배치하는 경우는 크게 두 가지가 있다. 디버깅 중 RAM 에 모든 코드/데이터를 배치해 실행하는 방법과 ROM또는 Flash 영역에 코드/데이터를 저장해두고 MCU 초기화 과정에서 RAM으로 함수를 복사한 후 실행하는 방법이 있다.

디버깅에서 코드/데이터를 모두 RAM에 위치시키는 방법

이 방법은 별도의 특별한 코드 수정이나 옵션의 설정 변경 없이 수행할 수 있다. 링커 설정 파일(.icf)내 readonly 속성의 코드와 데이터가 배치되는 영역을 모두 RAM의 주소 영역으로 변경하면 링커가 모든 위치를 RAM의 주소로 배치된다. [그림 1]의 링커 설정 파일의 예를 참고한다.

[그림 1] 링커 설정 파일의 예

[그림 2]는 빌드 후 링커 map 파일의 내용이다. 모든 코드와 데이터가 RAM 영역에 들어가 있는 것을 확인할 수 있다.

[그림 2] 빌드 후 링커 map 파일

[그림 2] 의 방법은 매우 간단해 디버깅 중 테스트의 목적으로 활용이 가능하다. 다만 모든 코드 데이터가 RAM에 위치하게되므로 디버깅 프로브가 보드에서 분리되고 전원이 끊어지면 단독 동작을 하지 않는다.

 

ROM또는 Flash 영역에 코드/데이터를 저장 후 RAM으로 복사 방법

디버거가 연결되지 않은 단독 동작의 상태에서 코드와 데이터를 RAM으로 위치시키려면 우선 코드와 데이터 정보를 ROM/Flash 영역에 저장하고 MCU디바이스에 전원이 인가돼 초기화될때, 초기화 중 코드/데이터를 RAM으로 복사 후 동작시키는 방법이다. 코드의 종류와 작성 방법에 따라 크게 3가지 방법이 있다.

① RAM에 배치하는 함수를 개별적으로 지정하는 방법
② RAM에 배치하는 함수를 파일 단위로 지정하는 방법
③ RAM에 배치하는 함수를 전부 지정하는 방법
 
① RAM에 배치하는 함수를 개별적으로 지정하는 방법

특정 함수만 RAM에 배치하려는 경우에는 해당 함수 선언문 앞에 __ramfunc 지시어를 추가하는 방법을 사용할 수 있다. __ramfunc 지시어는 IAR Embedded Workbench에서 지원되는 확장 키워드다. [그림 3]을 참고하면 된다.

[그림 3]

링커 설정 파일의 경우 이전 디버거를 활용해 RAM에 배치한 방법과 다르게 실제 MCU의 RAM, ROM주소로 설정한다.

[그림4]

맵 파일을 보면 __ramfunc 선언한 함수 func1과 변수 x가 RAM에 배치되고 나머지 함수는 ROM 영역에 배치돼 있다.

[그림 5]

②RAM에 배치하는 함수를 파일 단위로 지정하는 방법

[그림 5]의 예제에서 RAM으로 위치를 옮긴 함수는 main함수이다. main함수는 main.c에 포함돼 있다. 그리고 main.c 파일을 컴파일 한 결과인 오브젝트 파일은 main.o이다. 파일단위로 코드를 RAM으로 옮기는 방법은 컴파일된 결과인 오브젝트 파일을 사용한다.

링커 설정 파일(.icf)에서 initialize by copy라는 명령을 사용한다. 일반적으로 초기화가 필요한 변수를 RAM으로 복사하는데 사용되지만, 오브젝트의 코드/데이터 전체를 RAM으로 복사할 수 있다. 

[그림 6]의 경우initialize by copy를 사용해 RAM으로 위치변경을 하면, 함수 func1, main과 변수 x가 RAM 영역에 배치되고 상수(변수) y가 ROM 영역에 배치된다.

[그림 6] 

링커 설정 파일에서initialize by copy를 사용해 main.o의 읽기 전용 속성의 코드를 RAM으로 복사, 초기화 한다.

[그림 7] 

[그림8]

[그림 8]에서 함수와 상수가 되는 변수 y를 RAM에 배치하려는 경우에는 ‘ro code object main.o’를 ‘ro object main.o’로 변경하면 코드와 데이터도 RAM으로 위치시킬 수 있다.

③사용자 함수를 모두 RAM에 배치하는 방법

이전까지의 방법들은 함수단위와 컴파일 완료된 오브젝트 단위로 코드와 데이터를 RAM으로 위치 시키는 방법이었다. 전체의 모든 코드를 RAM으로 한번에 위치시켜야하는 경우에는 그림9의 방법을 사용할 수 있다.

오브젝트 단위로 RAM으로 위치시키는 방법과 동일하게initialize by copy 명령을 이용한다. 다만 특정 오브젝트를 지정하는 것이 아닌 모든 코드를 RAM으로 배치하도록 명령한다.

이 방법에서 인터럽트 벡터 테이블은 ROM의 시작주소에 위치해야하므로 except를 사용해 인터럽트 벡터 영역을 initialize by copy에서 제외해야한다. 여기서 주의할 점으로 벡터 테이블을 포함한 초기화 코드는 ROM에 배치해야한다. 리셋에서 초기화 완료 되기까지 필요로하는 함수를 ROM에서 실행되도록 배치해야한다. 

맺음말 

__ramfunc 지시어를 포함한 다양한 방법으로 코드를 RAM으로 옮겨 실행 할 수 있다. ROM보다는 읽기, 쓰기 속도가 빠른 RAM을 활용해 코드를 위치시키면 최적화된 소프트웨어 수행 속도를 만들 수 있다.