본문 바로가기
Embedded SW/Embedded SW Introduction

mcu memory, section에 대한 상세 정리 (.text, .data, .bss, .rodata)

by 방구석 임베디드 2022. 9. 15.
반응형

안녕하세요.

오늘은 MCU 개발을 하는 과정에서

memory와 section에 대해 궁금해 하시는 분들이 많이 있으신데요.

이 부분에 대해서 한번 알아 보는 시간을 가지도록 하겠습니다.

 

먼저 section의 사전적인 뜻을 확인해 보도록 하겠습니다.

section은 아래와 같이 '부분'이라고 나와 있습니다.

메모리를 컴파일하면

section이 나누어 지게 됩니다.

예를들어서, 아래와 같은 코드가 있다고 생각해볼게요.

int Test1;
int Test2 = 2;
const int Test3 = 3; 
int main(void)
{
    int Test4 = 4;
    Test1++;
    Test2++;
    Test4++;

    return 0;
}

Test1이라는 변수는은 초기화가 되지 않은 전역변수입니다.

따라서 초기화되지 않은 전역변수는 .bss section으로 할당이 됩니다.

 

이번에는 Test2라는 초기화가 있는 변수를 생각해 보겠습니다.

Test2는 .data section으로 할당이 되게 됩니다.

Test3는 const 변수로, rodata section으로 할당되며

Test4는 지역변수로 추후 stack으로 할당이 되게 됩니다.

그리고 Test2++ 과 같은 코드 부분은 .text section으로 할당이 됩니다.

여기서 중요한 물음이 하나 있습니다.​

이렇게 section이 나누어져서 메모리를 구성하는 이유는 무엇때문일까요?

"용도가 다르기 때문입니다."

용도가 다르다는 것이 무슨 뜻을까요?

 

예를 들어 보겠습니다.

초기화가 없는 전역/정적변수는 컴파일을 할때,

Flash영역에 위치할 필요가 없습니다.

전부 0이기 때문이고

이러한 변수들은 start code 부분에서 DATA RAM 영역에

그 범위에 따라서 할당을 해주고 0의 값을 가지게 하면 되기 때문입니다.

 

하지만 초기화가 있는 전역/정적 변수는 이야기가 좀 다릅니다.

start code에서 변수할당을 하고 초기화된 값을 어디서 가지고 와야 합니다.

따라서 Flash 메모리 영역에 그 초기값이 저장이 되어야 합니다.

그리고 start code에서 flash에 저장이 되어 있는 초기값을

ram에 복사를 해오게 됩니다.

 

const는 RAM으로 값을 가져올 필요가 없습니다.

RAM은 read 및 write을 할때 필요한데

const는 단지 read만 하면 되기 때문에

flash안에만 위치에 직접접근하여 읽으면 됩니다.

따라서 start code에서 따로 data ram에 영역을 할당하지 않습니다.

text도 바로 Flash에 접근하여

Instruction을 읽어오면 되기 때문에

Flash에 위치하면 됩니다.

단, RAM에서 함수를 실행할 경우도 있는데

그 부분은 나중에 다루도록 하겠습니다.

 

정리하면

이렇게 section이 나누어져 있는것은

section별로 나누어져 있어야지

효율적이 메모리 용도 구성이 이루어질 수 있습니다.

당연히 우리가 직접 section을 만들어서,

코드 및 변수를 우리가 이름지은 section으로 할당할수 있습니다.

아래 글에서 한번 우리가 직접 section을 만들어서

변수 메모리 할당을 해보았으니 참고해 보시면 좋을 것 같습니다.

https://cafe.naver.com/binaryembedded/84

 

11. section을 직접 만들고 메모리 할당을 해보자!

직접 section을 한번 만들어 보겠습니다. 그 전에 IfxCpu_CStart0.c 파일에서 잠시 아이디어를 빌리겠습니다. #pragma protect on #pragma...

cafe.naver.com

그런데 위에서 이야기한 section 말고도 더 컴파일에 따라서

더 다양한 section이 정의되어 있습니다.

예를 들어 tasking compiler의 경우

메뉴얼을 아래에서 다운 받으실 수 있습니다.

https://resources.tasking.com/p/tasking-vx-toolset-aurix-development-studio-user-guide-non-commercial

 

TASKING VX-toolset for AURIX Development Studio User Guide (non-commercial)

 

resources.tasking.com

그리고 Tasking 컴파일러 메뉴얼을 보면

아래와  같이 정말 다양한 section type정의 되어 있는것을 확인 할 수 있습니다.

위에서 언급한 .text, .data, .bss, .rodata section은 아주 일반적인

section으로 대부분의 MCU 및 컴파일러에서 사용하는 

section입니다.

하지만 아래에 z, a라고 붙어진 section은

MCU안에서 더 효율적인(속도, 저장공간최적화) 메모리 관리를 위해

만들어진 MCU 전용 section이라고 생각하시면  될것 같습니다.

따라서 tasking compiler 메뉴얼을 잘 읽어 보시고,

1) 공간의 효율화

2) 수행시간의 효율화

3) 유지보수의 효율화

등을 고려하여

메모리를 배치하시면 됩니다.

저는 임베디드 SW를 개발하면서

정말 다양한 MCU 및 컴파일러를 사용해 보았고

다양한 SW를 개발해 보았습니다.

물론 Device Driver는 정말 많이 다루어 보았습니다.

 

그런데 Firmware SW의 핵심은

메모리 관리 및 수행시간 분석이라고 생각합니다 ㅎㅎ

메모리 section을 이해하고

Linker Script를 자유자재로 다룰수 있어야 하며

 

스택을 할당하고

메모리 section을 만들어

정해진 메모리 위치에 할당하며

메모리 공간을 최적화하여 사용하는것은 

그 누구도 쉽게 할수 없는 업무입니다.

 

따라서 위의 내용을 잘 숙지하시고

메모리를 잘 파악하시면

Embedded SW 개발 영역을 더 확장해 나가살 수 있을 것 같습니다.

이상으로 mcu memory, section에 대한 상세 정리를 마치도록 하겠습니다.

반응형

댓글