nRF52 시리즈 MCU를 사용할 때, RAM과 Flash 메모리의 시작 주소는 MCU가 정상적으로 동작하는 데 매우 중요한 역할을 합니다. 특히 애플리케이션에서 SoftDevice(블루투스 스택)나 부트로더를 사용하는 경우, 이 설정은 더욱 복잡해지며 상황에 따라 RAM과 Flash의 시작 주소를 적절히 조정해야 합니다.
이 글에서는 다음과 같은 경우에 맞춰 RAM 및 Flash 메모리의 크기를 조정하는 방법을 설명하겠습니다.
- SoftDevice와 MBR(Master Boot Record)을 사용하지 않는 애플리케이션
- MBR만 사용하는 애플리케이션
- SoftDevice를 사용하는 애플리케이션
1. 개요
nRF52 시리즈 MCU를 사용하는 애플리케이션에서 RAM과 Flash 메모리의 설정은 필수적입니다. MCU가 부트 로더나 SoftDevice를 사용하는지 여부에 따라 RAM과 Flash의 시작 주소를 적절히 설정해야만 정상적인 작동을 보장할 수 있습니다. SoftDevice의 버전마다 애플리케이션이 시작되는 Flash 주소와 사용 가능한 RAM 시작 주소는 달라지므로, 이를 정확하게 설정하는 방법을 이해하는 것이 중요합니다.
2. SoftDevice와 MBR(Master boot record)을 사용하지 않는 애플리케이션
애플리케이션이 SoftDevice나 MBR을 사용하지 않는 경우, Flash 메모리의 시작 주소는 0x0으로 고정됩니다. 이는 모든 펌웨어 코드가 메모리의 가장 처음 주소에서부터 시작함을 의미합니다. RAM 시작 주소는 이와 유사하게 고정되어 있으며, 기본적으로 0x20000000입니다.
이 설정은 대부분의 기본적인 MCU 프로젝트에서 사용할 수 있으며, 특별한 블루투스 통신이나 복잡한 부트로더 기능을 필요로 하지 않는 경우 적합합니다.
주요 설정
- Flash 시작 주소: 0x0
- RAM 시작 주소: 0x20000000
3. MBR만 사용하는 애플리케이션
MBR(Master Boot Record)만 사용하는 애플리케이션의 경우, Flash 메모리의 시작 주소는 0x1000으로 설정됩니다. 이 값은 MBR이 Flash 메모리의 맨 앞부분을 사용하므로, 이를 피해 애플리케이션이 0x1000부터 시작하는 것입니다. RAM 시작 주소도 다소 변경되며, 0x20000008부터 시작해야 합니다.
주요 설정
- Flash 시작 주소: 0x1000
- RAM 시작 주소: 0x20000008
MBR은 SoftDevice 없이도 부트로더와 같은 기능을 수행할 수 있는 부분으로, 애플리케이션이 시스템 시작 시 특정 절차를 따르도록 돕습니다.
4. SoftDevice를 사용하는 애플리케이션
SoftDevice를 사용하는 경우, 상황은 더 복잡해집니다. SoftDevice는 블루투스 스택을 포함하는 펌웨어로, 이를 사용하는 경우 애플리케이션이 차지할 수 있는 RAM과 Flash 크기가 제한됩니다. 각 SoftDevice 버전마다 크기가 다르므로, 사용 중인 SoftDevice 버전에 맞춰 올바른 시작 주소를 설정하는 것이 중요합니다.
RAM 및 Flash 메모리 설정
SoftDevice마다 필요한 최소 RAM 및 Flash 시작 주소가 다릅니다. 아래 표는 SoftDevice 버전에 따른 RAM과 Flash 시작 주소를 정리한 내용입니다.
SoftDevice | Version | Minimum RAM Start | FLASH start |
---|---|---|---|
S110 | 8.0.0 | 0x20002000 | 0x18000 |
S112 | 5.1.0-2.alpha | 0x20000E98 | 0x19000 |
S112 | 5.1.0 | 0x20000EB8 | 0x18000 |
S112 | 6.0.0 | 0x20000F70 | 0x19000 |
S112 | 6.1.0 | 0x20000F70 | 0x19000 |
S112 | 6.1.1 | 0x20000F70 | 0x19000 |
S112 | 7.0.0 | 0x20000EB8 | 0x19000 |
S113 | 7.0.0 | 0x20001198 | 0x1C000 |
S113 | 7.1.0 | 0x20001198 | 0x1C000 |
S113 | 7.2.0 | 0x20001198 | 0x1C000 |
S120 | 2.0.0 | 0x20002800 | 0x1D000 |
S120 | 2.1.0 | 0x20002800 | 0x1D000 |
S130 | 1.0.0 | 0x20002800 | 0x1C000 |
S130 | 2.0.0-4.alpha | 0x20001268 | 0x1C000 |
S130 | 2.0.0-7.alpha | 0x20001230 | 0x1B000 |
S130 | 2.0.0-8.alpha | 0x200012B8 | 0x1B000 |
S130 | 2.0.0 | 0x200013C8 | 0x1B000 |
S130 | 2.0.1 | 0x200013C8 | 0x1B000 |
S132 | 1.0.0-2.alpha | 0x20002800 | 0x1F000 |
S132 | 1.0.0-3.alpha | 0x20002800 | 0x1F000 |
S132 | 2.0.0-4.alpha | 0x20001268 | 0x1F000 |
S132 | 2.0.0-7.alpha | 0x20001230 | 0x1B000 |
S132 | 2.0.0-8.alpha | 0x200012B8 | 0x1C000 |
S132 | 2.0.0 | 0x200013C8 | 0x1C000 |
S132 | 2.0.1 | 0x200013C8 | 0x1C000 |
S132 | 3.0.0-1.alpha | 0x200010E0 | 0x1D000 |
S132 | 3.0.0-2.alpha | 0x20001660 | 0x1F000 |
S132 | 3.0.0 | 0x200019C0 | 0x1F000 |
S132 | 3.1.0 | 0x200019C0 | 0x1F000 |
S132 | 4.0.0-1.alpha | 0x20001470 | 0x1F000 |
S132 | 4.0.0-2.alpha | 0x20001460 | 0x1F000 |
S132 | 4.0.0 | 0x200013C0 | 0x1F000 |
S132 | 4.0.2 | 0x200013C0 | 0x1F000 |
S132 | 4.0.3 | 0x200013C0 | 0x1F000 |
S132 | 4.0.4 | 0x200013C0 | 0x1F000 |
S132 | 4.0.5 | 0x200013C0 | 0x1F000 |
S132 | 5.0.0-1.alpha | 0x200019C0 | 0x20000 |
S132 | 5.0.0-2.alpha | 0x20001478 | 0x21000 |
S132 | 5.0.0-3.alpha | 0x20001368 | 0x23000 |
S132 | 5.0.0 | 0x200014B8 | 0x23000 |
S132 | 5.0.1 | 0x20001380 | 0x23000 |
S132 | 6.0.0 | 0x20001628 | 0x26000 |
S132 | 6.1.0 | 0x20001628 | 0x26000 |
S132 | 6.1.1 | 0x20001628 | 0x26000 |
S132 | 7.0.0 | 0x20001668 | 0x26000 |
S140 | 5.0.0-1.alpha | 0x200019C0 | 0x21000 |
S140 | 5.0.0-2.alpha | 0x20001468 | 0x21400 |
S140 | 5.0.0-3.alpha | 0x200014B8 | 0x24000 |
S140 | 6.0.0-6.alpha | 0x20001530 | 0x25000 |
S140 | 6.0.0 | 0x20001628 | 0x26000 |
S140 | 6.1.0 | 0x20001628 | 0x26000 |
S140 | 6.1.1 | 0x20001628 | 0x26000 |
S140 | 7.0.0 | 0x20001678 | 0x27000 |
S140 | 7.2.0 | 0x20001678 | 0x27000 |
S212 | 4.0.2 | 0x20000A80 | 0x12000 |
S212 | 5.0.0 | 0x20000B80 | 0x12000 |
S212 | 6.1.1 | 0x20000B80 | 0x12000 |
S312 | 6.1.1 | 0x20001300 | 0x24000 |
S332 | 4.0.2 | 0x20001E30 | 0x29000 |
S332 | 5.0.0 | 0x20001F30 | 0x2D000 |
S332 | 6.1.1 | 0x20002000 | 0x30000 |
S340 | 6.1.1 | 0x20002000 | 0x31000 |
이 표는 일반적인 SoftDevice 버전에 따른 Flash와 RAM의 최소 시작 주소를 나타냅니다. SoftDevice를 사용하는 경우 RAM의 시작 주소를 가능한 낮은 값으로 설정하는 것이 좋지만, SoftDevice에서 사용하는 기능에 따라 다를 수 있습니다.
RAM 시작 주소 확인 방법
SoftDevice의 RAM 시작 주소는 응용 프로그램이 차지할 수 있는 가장 낮은 주소입니다. 만약 확실하지 않다면, SoftDevice Handler 라이브러리를 사용하여 올바른 시작 주소를 찾을 수 있습니다. 이 방법은 아래 SEGGER Embedded Studio를 사용한 RAM 시작 주소 변경에서 자세히 다룰 것입니다.
5. SEGGER Embedded Studio에서 RAM 및 Flash 시작주소 변경
프로젝트에서 RAM과 Flash 메모리의 시작 주소를 변경하려면, SEGGER Embedded Studio에서 아래 단계를 따릅니다.
- 프로젝트 왼쪽 창에서 애플리케이션 이름을 오른쪽 클릭하여 'Options'를 선택합니다.
- 'Options Window'에서 'Common'을 선택합니다.
- 왼쪽 리스트에서 'Linker'를 선택한 후, 오른쪽에서 'Section Placement Macros' 항목을 찾아 편집할 수 있습니다.
- 이 창에서 FLASH_START와 RAM_START 값을 변경하여 원하는 시작 주소로 설정할 수 있습니다.
주의사항
FLASH_SIZE는 (FLASH_PH_SIZE - FLASH_START) 보다 작아야 한다.
(RAM_SIZE + RAM_START)는 (RAM_PH_START + RAM_PH_SIZE) 보다 작아야 한다.
이 점을 고려하여 RAM과 Flash 메모리의 설정을 신중하게 조정해야 합니다.
6. RAM 시작주소 디버깅 방법
프로젝트에서 RAM 시작 주소와 관련된 문제를 해결하려면, 디버그 모드를 활용하여 RAM 시작 주소를 찾을 수 있습니다. 아래 설정을 프로젝트의 sdk_config.h 파일에 추가한 후 빌드하면, 디버그 메시지를 통해 RAM 시작 주소를 확인할 수 있습니다.
#define NRF_LOG_BACKEND_RTT_ENABLED 1
#define NRF_LOG_ENABLED 1
#define NRF_LOG_DEFAULT_LEVEL 4
#define NRF_SDH_BLE_LOG_ENABLED 1
#define NRF_SDH_BLE_LOG_LEVEL 4
#define NRF_SDH_LOG_ENABLED 1
#define NRF_SDH_LOG_LEVEL 4
RAM 시작 주소가 올바르지 않을 경우, 디버그 창에서 아래와 같은 메시지를 확인할 수 있습니다.
RAM 시작 주소가 낮게 설정된 경우
<warning> nrf\_sdh\_ble: Insufficient RAM allocated for the SoftDevice.
<warning> nrf\_sdh\_ble: Change the RAM start location from 0x20002000 to 0x200022B0.
<warning> nrf\_sdh\_ble: Maximum RAM size for application is 0xDD50.
<error> nrf\_sdh\_ble: sd\_ble\_enable() returned NRF\_ERROR\_NO\_MEM.
<error> app: Fatal error
<warning> app: System reset.
RAM 시작 주소가 높게 설정된 경우
<debug> nrf\_ddh: State request: 0x00000000
<debug> nrf\_ddh: State change: 0x00000000
<debug> nrf\_ddh: State change: 0x00000001
<debug> nrf\_ddh\_ble: RAM starts at 0x20002EE0
<debug> nrf\_ddh\_ble: RAM start location ca be adjusted to 0x200022B0.
<debug> nrf\_ddh\_ble: RAM size for application can be adjusted to 0x3DD50.
7. 디버깅으로 RAM 시작주소 찾기
더 정밀하게 RAM 시작 주소를 디버깅하려면, nrf_sdh_ble_enable() 함수에 브레이크포인트를 설정한 후 디버그 모드를 실행하여 p_app_ram_start 변수를 확인할 수 있습니다.
- 디버깅 모드에서 p_app_ram_start 변수를 Watch에 추가합니다.
- 변수의 값을 확인하여 RAM 시작 주소가 적절하게 설정되었는지 판단합니다.
이 방법을 통해 SoftDevice가 할당한 RAM 시작 주소와의 충돌을 방지할 수 있으며, 특히 프로젝트가 커지면서 발생할 수 있는 RAM 관련 문제를 쉽게 해결할 수 있습니다.
8. 결론
nRF52 시리즈 MCU에서 RAM과 Flash 시작 주소를 정확하게 설정하는 것은 안정적이고 효율적인 애플리케이션을 개발하는 데 필수적입니다. 이 글에서는 SoftDevice 및 MBR 사용 여부에 따라 달라지는 RAM과 Flash 시작 주소 설정 방법을 설명했으며, SEGGER Embedded Studio를 통해 시작 주소를 변경하는 방법을 소개했습니다.
또한 디버깅 방법을 활용하여 RAM 시작 주소를 정확히 설정하는 팁을 제공했습니다. 프로젝트가 커지거나 복잡해질수록 RAM과 Flash 메모리 설정은 중요해지며, 예상치 못한 문제를 해결할 때 이 글이 도움이 되기를 바랍니다.
'nRF52' 카테고리의 다른 글
nRF52840 PWM으로 LED 제어하기 (0) | 2024.11.05 |
---|---|
nRF ESB(무선 통신 구현) (0) | 2024.09.20 |
nRF52 Watchdog Timer: 시스템 안정성을 보장하는 방법 (0) | 2024.09.18 |
nRF52 fstorage 사용 가이드 (0) | 2024.09.17 |
nRF52 RTC(Real-Time Clock)를 활용한 캘린더 구현 (0) | 2024.09.16 |