В этой статье (перевод [1]) даются разъяснения, как разработчик может установить начальные адреса памяти RAM и FLASH. Демонстрируемые примеры используют SDK v15.2. Первые три раздела объясняют, какие должны использоваться адреса RAM и FLASH для разных случаев конфигурации приложения. Разделы 4, 5 и 6 демонстрируют, как можно установить адреса перед компиляцией. Раздел 7 показывает, как библиотека SoftDevice Handler может использоваться, чтобы найти точное значения начального адреса RAM, необходимое для приложения. Последний раздел показывает, как можно найти адрес начала RAM во время отладки.
Чтобы Ваше приложение нормально работало, должны быть правильно установлены начальные адреса RAM и FLASH. Для настройки этих адресов в своем проекте необходимо учитывать следующие 3 вещи.
• Приложение не использует SoftDevice или Master Boot Record (MBR). • Приложение использует только Master Boot Record (MBR). • Приложение использует SoftDevice.
Содержимое этого руководства:
1. Приложение не использует SoftDevice. 2. Приложение использует только MBR. 3. Приложение использует SoftDevice. 4. Изменение начальных адресов в Segger Embedded Studio. 5. Изменение начальных адресов в Keil 5. 6. Изменение начальных адресов в ARM GCC Compiler. 7. Изменение начальных адресов в IAR. 8. Корректировка начального адреса RAM в Segger Embedded Studio. 9. Как найти начальный адрес RAM во время отладки.
Примечание: расшифровку неизвестных терминов и сокращений см. в Словарике [3].
[1. Приложение не использует SoftDevice]
Если приложение не использует SoftDevice или or a Master Boot Record, то начальный адрес памяти FLASH всегда должен устанавливаться в 0x0, и начальный адрес RAM должен быть установлен в 0x20000000.
[2. Приложение использует только MBR]
Для устройств nRF52, если приложение использует только MBR, то начальный адрес для памяти FLASH всегда должен устанавливаться в значение 0x1000, и начальный адрес для RAM должен устанавливаться в значение 0x20000008.
[3. Приложение использует SoftDevice]
Если приложение использует SoftDevice, то начальный адрес для памяти FLASH должен быть установлен в корректное значение для соответствующего SoftDevice, иначе приложение не запустится. Причина в том, что каждая версия SoftDevice при запуске приложения ожидает найти код приложения по определенному адресу. С другой стороны, начальный адрес RAM может меняться в зависимости от количества функций, используемых в SoftDevice, но это всегда должен быть минимально допустимый адрес. Если Вы не уверены, какой это должен быть адрес начала RAM для приложения, то его значение можно определить с помощью библиотеки SoftDevice Handler (демонстрируется в разделе 7 этого руководства на примере Segger Embedded Studio).
Таблица 1 показывает различные адреса начала для RAM и FLASH для некоторых разных версий SoftDevice. Как уже упоминалось выше, начальный адрес RAM для приложения должен быть минимально возможным, потому что RAM всегда является ценным и дефицитным ресурсом. Минимальный адрес RAM может получиться не таким уж минимальным, если Ваша программа использует множество функций SoftDevice.
Таблица 1. Различные случаи для начального адреса FLASH и RAM.
SoftDevice |
Версия |
FLASH Start |
RAM Start(1) |
S110 |
8.0.0 |
0x18000 |
0x20002000 |
S112 |
5.1.0-2.alpha |
0x19000 |
0x20000E98 |
5.1.0 |
0x18000 |
0x20000EB8 |
6.0.0 |
0x19000 |
0x20000F70 |
6.1.0 |
0x19000 |
0x20000F70 |
6.1.1 |
0x19000 |
0x20000F70 |
7.0.0 |
0x19000 |
0x20000EB8 |
S113 |
7.0.0 |
0x1C000 |
0x20001198 |
7.1.0 |
0x1C000 |
0x20001198 |
7.2.0 |
0x1C000 |
0x20001198 |
S120 |
2.0.0 |
0x1D000 |
0x20002800 |
2.1.0 |
0x1D000 |
0x20002800 |
S130 |
1.0.0 |
0x1C000 |
0x20002800 |
2.0.0-4.alpha |
0x1C000 |
0x20001268 |
2.0.0-7.alpha |
0x1B000 |
0x20001230 |
2.0.0-8.alpha |
0x1B000 |
0x200012B8 |
2.0.0 |
0x1B000 |
0x200013C8 |
2.0.1 |
0x1B000 |
0x200013C8 |
S132 |
1.0.0-2.alpha |
0x1F000 |
0x20002800 |
1.0.0-3.alpha |
0x1F000 |
0x20002800 |
2.0.0-4.alpha |
0x1F000 |
0x20001268 |
2.0.0-7.alpha |
0x1B000 |
0x20001230 |
2.0.0-8.alpha |
0x1C000 |
0x200012B8 |
2.0.0 |
0x1C000 |
0x200013C8 |
2.0.1 |
0x1C000 |
0x200013C8 |
3.0.0-1.alpha |
0x1D000 |
0x200010E0 |
3.0.0-2.alpha |
0x1F000 |
0x20001660 |
3.0.0 |
0x1F000 |
0x200019C0 |
3.1.0 |
0x1F000 |
0x200019C0 |
4.0.0-1.alpha |
0x1F000 |
0x20001470 |
4.0.0-2.alpha |
0x1F000 |
0x20001460 |
4.0.0 |
0x1F000 |
0x200013C0 |
4.0.2 |
0x1F000 |
0x200013C0 |
4.0.3 |
0x1F000 |
0x200013C0 |
4.0.4 |
0x1F000 |
0x200013C0 |
4.0.5 |
0x1F000 |
0x200013C0 |
5.0.0-1.alpha |
0x20000 |
0x200019C0 |
5.0.0-2.alpha |
0x21000 |
0x20001478 |
5.0.0-3.alpha |
0x23000 |
0x20001368 |
5.0.0 |
0x23000 |
0x200014B8 |
5.0.1 |
0x23000 |
0x20001380 |
6.0.0 |
0x26000 |
0x20001268 |
6.1.0 |
0x26000 |
0x20001268 |
6.1.1 |
0x26000 |
0x20001268 |
7.0.0 |
0x26000 |
0x20001668 |
S140 |
5.0.0-1.alpha |
0x21000 |
0x200019C0 |
5.0.0-2.alpha |
0x21400 |
0x20001468 |
5.0.0-3.alpha |
0x24000 |
0x200014B8 |
6.0.0-6.alpha |
0x25000 |
0x20001530 |
6.0.0 |
0x26000 |
0x20001628 |
6.1.0 |
0x26000 |
0x20001628 |
6.1.1 |
0x26000 |
0x20001628 |
7.0.0 |
0x27000 |
0x20001678 |
7.2.0 |
0x27000 |
0x20001678 |
S212 |
4.0.2 |
0x12000 |
0x20000A80 |
5.0.0 |
0x12000 |
0x20000B80 |
6.1.1 |
0x12000 |
0x20000B80 |
S312 |
6.1.1 |
0x24000 |
0x20001300 |
S332 |
4.0.2 |
0x29000 |
0x20001E30 |
5.0.0 |
0x2D000 |
0x20001F30 |
6.1.1 |
0x30000 |
0x20002000 |
S340 |
6.1.1 |
0x31000 |
0x20002000 |
Примечание (1): в столбце RAM Start указан минимально допустимый начальный адрес RAM для приложения.
В следующих разделах показывается, как менять параметры областей памяти FLASH и RAM для приложения в различных средах разработки. Важный момент - значения начального адреса (Start) и значения размера области (Size) соответствуют абсолютным байтовым адресам, и эти значения должны нацело делиться на размер слова (4 байта).
[4. Изменение начальных адресов в Segger Embedded Studio]
Среда разработки Segger Embedded Studio использует макросы размещения секций (Section Placement Macros) для определения областей RAM и FLASH. RAM_START это макрос, используемый для определения начального адреса RAM (RAM start address). FLASH_START соответственно это макрос, используемый для определения начального адреса памяти FLASH (FLASH start address). Можно легко сконфигурировать эти значения, выполнив следующую последовательность действий:
1. Откройте свой проект в Segger Embedded Studio.
2. Выполните правый клик на папку Project, выберите Edit Options...
3. Выберите Common configuration, кликните на Linker.
4. Выполните двойной клик на Section Placement Macros, откроется окно диалога Section Placement Macros:
5. Отредактируйте значения RAM_START и FLASH_START. Имейте в виду, что значение FLASH_SIZE не должно быть больше чем (FLASH_PH_SIZE - FLASH_START), и (RAM_SIZE + RAM_START) не должно быть больше чем (RAM_PH_START + RAM_PH_SIZE).
Когда закончите редактирование, кликами на кнопку OK закройте диалоги конфигурации макросов и опций проекта.
На этом скриншоте показано, как выбрать Common configuration:
Как найти Section Placement Macros:
В таблице 2 для примера можно увидеть различные значения в Segger Embedded Studio для примера blinky в SDK 15.2 для платы nRF52840, с использованием SoftDevice и без него.
Таблица 2. Значения Section Placement Macros в Segger Embedded Studio для примера blinky из SDK.
blinky вместе с SoftDevice |
blinky без SoftDevice и MBR |
FLASH_PH_START=0x0 |
FLASH_PH_START=0x0 |
FLASH_PH_SIZE=0x100000 |
FLASH_PH_SIZE=0x100000 |
RAM_PH_START=0x20000000 |
RAM_PH_START=0x20000000 |
RAM_PH_SIZE=0x40000 |
RAM_PH_SIZE=0x40000 |
FLASH_START=0x26000 |
FLASH_START=0x0 |
FLASH_SIZE=0xda000 |
FLASH_SIZE=0x100000 |
RAM_START=0x200022B0 |
RAM_START=0x20000000 |
RAM_SIZE=0x3dd50 |
RAM_SIZE=0x40000 |
[5. Изменение начальных адресов в Keil 5]
Среда разработки Keil 5 не использует макросы для настройки адресов. Вместо этого адреса и размеры областей памяти FLASH и RAM конфигурируются в диалоге свойств проекта. Для редактирования начала и размеров областей RAM и FLASH в 5:
1. Откройте проект в Keil 5.
2. Правым кликом на папке с названием проекта откройте контекстное меню. Папка может называться, если это проект из SDK, по имени платы разработчика или используемого чипа (например nrf52840_xxaa).
3. Выберите Edit Options for Target ..., на закладке Target отредактируйте поля (начало и размер) IROM1 для FLASH, и IRAM1 для RAM.
При редактировании значения IROM1 Start и IRAM1 Start необходимо помнить, что IROM1 Size не должно быть больше, чем (доступный размер FLASH - IROM1 Start), и (IRAM1 Size + IRAM1 Start) не должно быть больше, чем размер доступного RAM.
После редактирования значений, закройте диалог свойств проекта кликом на кнопке OK.
[6. Изменение начальных адресов в ARM GCC Compiler]
Компилятор ARM GCC использует файл настроек линкера (GNU linker) для значений адресов RAM и FLASH. Чтобы отредактировать начало и размер RAM and FLASH:
1. Откройте файл настроек линкера в текстовом редактора. Этот файл обычно называется < project_name >_gcc_nrf52.ld, и он находится в корневом каталоге проекта.
2. Найдите в файле линкера следующие строки, и отредактируйте их:
FLASH (rx) : ORIGIN = начальный адрес FLASH, и LENGTH = установка размера FLASH. RAM (rwx) : ORIGIN = начальный адрес RAM, и LENGTH = установка размера RAM.
3. После редактирования сохраните файл линкера.
[7. Изменение начальных адресов в IAR]
Чтобы поменять начальные адреса в среде разработки IAR Embedded Workbench, при открытом проекте выберите в меню Project -> Options... (Alt+F7), перейдите в раздел Linker, выберите закладку Config, кликните на кнопку Edit..., и откроется окно диалога настройки областей памяти Memory Regions:
Опция ROM это настройка памяти FLASH, опция RAM это настойка памяти RAM. После ввода / редактирования значений кликните на кнопку Save, и кнопкой OK закройте диалог настройки опций проекта.
[8. Корректировка начального адреса RAM в Segger Embedded Studio]
В проекте необходимо в заголовке sdk_config.h установить следующие определения.
#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
Выполните сборку проекта, используя конфигурацию Debug, и запустите отладку кнопкой F5. Если установленное значение RAM слишком маленькое, то в терминале будет показано следующее сообщение:
Если установленное значение RAM слишком большое, то в терминале будет показано следующее сообщение:
При необходимости Вы можете подстроить значения Section Placement Macros, как это было показано выше в разделе 4, чтобы они имели корректные значения.
Если для отладки проекта используете Keil 5, те же самые отладочные сообщения можно выводить в окно J-Link RTT Viewer [2].
[9. Как найти начальный адрес RAM во время отладки]
Если приложение использует SoftDevice, то для приложения остается меньше свободной памяти, потому что SoftDevice тоже использует RAM для выполнения своих функций. Необходимый минимальный начальный адрес RAM в этом случае можно определить во время отладки. Для этого выполните следующее (можно сделать в любой среде разработки):
1. Откройте файл nrf_sdh_ble.c проекта.
2. Добавьте точку останова (breakpoint) на следующую строку в теле функции nrf_sdk_ble_enable:
ret_code_t ret_code = sd_ble_enable(p_app_ram_start);
3. Добавьте переменную p_app_ram_start в окно просмотра переменных в отладчике (Watch).
4. Запустите отладку, и дождитесь срабатывания точки останова. Значение переменной p_app_ram_start покажет минимальное значение начального адреса RAM приложение, которое может предоставить SoftDevice.
[Ссылки]
1. Adjustment of RAM and Flash memory site:devzone.nordicsemi.com. 2. J-Link RTT – Real Time Transfer. 3. Bluetooth: аббревиатуры и термины. |