Arlleex 129 1 июня, 2019 Опубликовано 1 июня, 2019 · Жалоба Приветствую! Среда Keil uVision, версия 5.25.2.0 (не думаю, что это важно). Хочу сделать в своем GUI маленький такой раздел с ресурсными параметрами самого МК: сколько занимает прошивка во Flash, сколько выделено ОЗУ, а также разные финтиклюшки (процент загрузки CPU и т.д.). Возможно ли средствами линкера (или как еще?) разместить в две константные ячейки Flash количество занимаемых байт памяти во Flash (образ прошивки) и ОЗУ? После компиляции эти параметры известны (пишутся в build output): .text, .bss и т.д., но вот как бы их еще из run-time выцыганить... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 172 1 июня, 2019 Опубликовано 1 июня, 2019 · Жалоба 27 минут назад, Arlleex сказал: Возможно ли средствами линкера (или как еще?) разместить в две константные ячейки Flash количество занимаемых байт памяти во Flash (образ прошивки) и ОЗУ? После компиляции эти параметры известны (пишутся в build output): .text, .bss и т.д., но вот как бы их еще из run-time выцыганить... Можно конечно. В чём проблема? Забыли как слово const пишется? Вычисление размера памяти: расположить в конце и в начале региона памяти определённые секции и вычислить разницу между ними. Не знаю как в Keil, но в IAR файл .icf: define block IMAGE_HEAD with fixed order {section .intvec, section .checksum, section .codehead, section .intvecTail, section .codebegin}; place in RAM_regionB {ro, first block IMAGE_HEAD, last section .codetail, section .rodataInternal, section .textInternal, section .constFast}; define block IMAGE_HEAD_EXT with fixed order {section .codeheadExt}; place in SDRAM_regionA { first block IMAGE_HEAD_EXT, section .codeSignature, section .fnt, ... last section .codetailExt }; Файл .asm: SECTION .codeheadExt:CONST:ROOT(0) SECTION .codetailExt:CONST:ROOT(0) Файл .cpp: __noreturn int main() { #pragma section=".intvec" #pragma section=".codetail" #ifdef _CODE_SDRAM #pragma section=".codeheadExt" #pragma section=".codetailExt" #endif //_CODE_SDRAM ... LogCR0("Program image size: %u bytes", #ifdef _CODE_SDRAM (u32)__section_end(".codetailExt") - (u32)__section_begin(".codeheadExt") + #endif //_CODE_SDRAM (u32)__section_end(".codetail") - (u32)__section_begin(".intvec")); ... } Это пример для более сложного случая - когда программа разделена на 2 несмежных региона памяти. Если всё одним куском - будет ещё проще. В моём случае - отладочная сборка для выполнения в SDRAM состоит из двух регионов (как видно выше) и _CODE_SDRAM - defined. При сборке во флешь _CODE_SDRAM будет - undef. PS: Секции ".codeheadExt" и ".codetailExt" - пустые. 0-го размера. Как создать пустые секции в .cpp я не знаю, поэтому они в .asm. PPS: У IAR-а (7.80.4) есть какой-то глюк с расположением секций в начале региона (first section ...) - почему-то это не всегда срабатывает. А вот "first block" - срабатывает всегда. Поэтому в моём примере пришлось сделать отдельный блок IMAGE_HEAD_EXT только с одной секцией. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 129 1 июня, 2019 Опубликовано 1 июня, 2019 · Жалоба 18 минут назад, jcxz сказал: Можно конечно. То что нужно, похоже. Попутно накопал еще топик для размышления. Спасибо! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GeorgK 1 1 июня, 2019 Опубликовано 1 июня, 2019 · Жалоба Не скажу за все среды, но если сборка идёт с использованием командной строки LD, то можно использовать для него "скрипты" - там можно выводить в глобальные переменные константы-адреса секций и результаты операций над ними, можно добавлять новые секции и модифицировать существующие. Можно даже в два прохода компоновку делать - на первом допустим размер пользовательской секции задан нулевой, а на втором - как результат разбора файла от первого этапа с учётом получившихся размеров/адресов. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
k155la3 26 1 июня, 2019 Опубликовано 1 июня, 2019 · Жалоба 10 hours ago, Arlleex said: . . . После компиляции эти параметры известны (пишутся в build output): .text, .bss и т.д., но вот как бы их еще из run-time выцыганить... Посмотрите список макро-переменных препроцессора, возможно там есть "сегментные" Predefined macros Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 129 3 июня, 2019 Опубликовано 3 июня, 2019 · Жалоба Благодарю всех за комментарии. Выбор мой пал, все-таки, на средства линкер-скрипта. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexandrY 2 3 июня, 2019 Опубликовано 3 июня, 2019 · Жалоба 6 hours ago, Arlleex said: Благодарю всех за комментарии. Выбор мой пал, все-таки, на средства линкер-скрипта. Напрасно. Память дело такое, что легко можно забыть что в ней лежит. Я предпочитаю сканировать память и выводить инфу о чистых кусках по факту: // Проверяем заполнение памяти uint8_t *str_addr = (uint8_t *)0x00000000; uint8_t *addr; uint8_t *end_addr = (uint8_t *)0x003FFFFF; uint8_t *end = 0; uint32_t empt_bl_sz = 0; addr = str_addr; do { if (*addr != 0xFF) { if (empt_bl_sz > 256) { MPRINTF("Empty flash memory from %08X to %08X\r\n", (uint32_t)end - empt_bl_sz , (uint32_t)end); } empt_bl_sz = 0; } else { end = addr; empt_bl_sz++; } addr++; } while (addr <= end_addr); if (empt_bl_sz > 256) { MPRINTF("Empty flash memory from %08X to %08X\r\n", (uint32_t)end - empt_bl_sz , (uint32_t)end); MPRINTF("Occupied flash memory size %d\r\n", (uint32_t)end - empt_bl_sz - (uint32_t)str_addr); } else { MPRINTF("Occupied flash memory size %d\r\n", (uint32_t)end_addr - (uint32_t)str_addr); } Таким образом не пропустите опасный мусор и другие чудесные артефакты. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 129 4 июня, 2019 Опубликовано 4 июня, 2019 · Жалоба 18 часов назад, AlexandrY сказал: Я предпочитаю сканировать память и выводить инфу о чистых кусках по факту... Я думал о таком варианте, но в ней есть свои минусы: 1. Я не всегда стираю полностью все сектора при программировании. Я стираю только те, что нужны под приложение. Да, бывает и стираю полностью (но гарантии нет, что это у меня дэ-факто). 2. Время выполнения этой функции сильно зависит от объема занятой памяти. 3. С ОЗУ такой вариант уже не прокатит... Плюс, конечно, в том, что не надо заморачиваться и вспоминать, что там загрузчик еще где-то может существовать и т.д. Но, ИМХО, программист должен это учитывать при написании целевого приложения и уменьшать реальный объем доступной памяти. Например, если в устройстве предусмотрен загрузчик (и пусть занимает он 16кб), то для МК с объемом Flash 2 Мб достаточно сказать линкеру, что реальной памяти, отведенной приложению, осталось 2Мб - 16кб. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexandrY 2 4 июня, 2019 Опубликовано 4 июня, 2019 · Жалоба 2 hours ago, Arlleex said: 1. Я не всегда стираю полностью все сектора при программировании. Я стираю только те, что нужны под приложение. Да, бывает и стираю полностью (но гарантии нет, что это у меня дэ-факто). Нестертые сектора и есть довольно опасный мусор. Эт вы наверно, как и я поняли когда запустили этот код. Время на 4 Мбайтах занимает меньше секунды. Так что переживать не о чем. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
x893 32 4 июня, 2019 Опубликовано 4 июня, 2019 · Жалоба Если говорить о компиляторе ARMCC, то можно прочитать на сайте http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0474c/CHDDGJGB.html В других компиляторах тоже всё есть. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 5 июня, 2019 Опубликовано 5 июня, 2019 · Жалоба Линкер создаёт всякие символы с информацией об адресах и размерах. К ним можно обращаться из сишного исходника. http://www.keil.com/support/man/docs/armlink/armlink_pge1362065951495.htm Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 172 5 июня, 2019 Опубликовано 5 июня, 2019 · Жалоба 15 часов назад, AlexandrY сказал: Время на 4 Мбайтах занимает меньше секунды. Так что переживать не о чем. А если секунда - это недопустимо большое время для старта ПО данного устройства? не думали? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться