Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: STM32L151 падает при выделении памяти
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Haamu
Контроллер STM32L151RB, CoIDE. Создаю проект, добавляю из репозитория cmsis_boot и CMSIS_core. Собирается, отладка запускается без проблем. Добавляю строку:
Код
uint8_t * ptr = malloc(4);

Не собирается, ругается что не определена функция _sbrk(). Добавляю из репозитория C Library. Собирается. Запускаю отладку. Дохожу до вызова malloc(), и программа падает в Default_Handler(). Если определить все обработчики ошибок, то сваливается в HardFault.
Проделываю точно такую-же последовательность действий, но уже с STM32F407. Без проблем, память выделяется.
Что я делаю не так? Или может какая-то особенность есть с динамическим выделением памяти у этих STM32L151? Если все-же я что-то не так делаю, буду очень благодарен, если кто-то поделится пустой заготовкой проекта в CoIDE, чтобы нормально память выделялась.
SasaVitebsk
Ну какая особенность при выделении памяти? Не выдумывайте ужастики.
1. Стандартная процедура выделения памяти сравнивает запрошенный объём с доступным. Если памяти в куче достаточно, то выдаёт указатель на начало, а если нет, то 0. То есть падать при этой процедуре ничего не может. Упасть может, если она выдаёт 0 (недостаточно памяти) а вы это используете как указатель.
2. Перейдите на ассемблер и выясните полную картину.
3. В опциях проекта, где-то, задаётся размер памяти, выделенный на кучу. Я CoIDE не пользуюсь, поэтому подсказать где именно не могу. Поищите.
Сергей Борщ
Разница между Cortex-M0(+) и Cortex-M3,M4 (STM32F407) - последний умеет невыровненный доступ. И если область памяти, которую вы отдаете менеджеру памяти, не выровнена - вполне возможно падение (ибо менеджер наверняка ожидает выровненную область). Фигню написал, у 151 ядро M3, умеет невыровненный доступ.

Как реализован конкретно ваш менеджер - понятия не имею. Можно туп сделать возврат из HardFault_Handler() и поставить в него точку останова. Выйдя попадете на команду, вызвавшую исключение и исходя из команды и ее аргументов можно думать дальше.

У вас же есть отладчик - неужели сложно пройти по дизассемблерному коду до места падения?
Haamu
Так в том то и дело, что специально для проверки создал пустой проект, в котором только одна вышеупомянутая строка. И именно на ней падает.
Aaron
посмотрите ld-файлы для STM32F407 и для STM32L151 - может, у вас ссылки на heap в скриптах по-разному заданы? может, для 151 размер кучи = 0?
SasaVitebsk
Цитата(Haamu @ Feb 29 2016, 17:56) *
Так в том то и дело, что специально для проверки создал пустой проект, в котором только одна вышеупомянутая строка. И именно на ней падает.

Вы читать умеете? Перечитайте ещё раз мой пост. Перечитайте несколько раз, если с первого не доходит.
Haamu
Цитата(Aaron @ Mar 1 2016, 10:04) *
посмотрите ld-файлы для STM32F407 и для STM32L151 - может, у вас ссылки на heap в скриптах по-разному заданы? может, для 151 размер кучи = 0?

Совпадают слово в слово. Разве что в 407 еще ram1 есть.

Все-таки посмотрел ассемблер и память, и стало более понятно.
Нашел в startup файле 151го такую особенность:
Код
void Default_Reset_Handler(void)
{
  /* Initialize data and bss */
//  unsigned long *pulSrc, *pulDest;

  /* Copy the data segment initializers from flash to SRAM */
//  pulSrc = &_sidata;
//
//  for(pulDest = &_sdata; pulDest < &_edata; )
//  {
//    *(pulDest++) = *(pulSrc++);
//  }
//
//  /* Zero fill the bss segment. */
//  for(pulDest = &_sbss; pulDest < &_ebss; )
//  {
//    *(pulDest++) = 0;
//  }

  /* Setup the microcontroller system. */
  SystemInit();
    
  /* Call the application's entry point.*/
  main();
}

Из-за этого в начале SRAM находился какой-то мусор и в процессе работы функции malloc в один момент происходило деление на 0.
Раскомментировал этот кусок. Мусор стал более системотизированным, но остался мусором (в сравнении с 407). Куда дальше копать?
И еще заметил особенность. Во всех других ARMах и не только, при инициализации структуры таким вот образом:
Код
static type struct_name = {};

все поля структуры инициализируются нулями. А тут почему-то в них тоже какой-то мусор находится.
esaulenka
Цитата(Haamu @ Mar 2 2016, 09:38) *
Нашел в startup файле 151го такую особенность:
Код
void Default_Reset_Handler(void)
...

Удивительная штука эти кокосы...
Либо этот файл не используется, либо никто никогда не пробовал с этими исходниками работать.

Вопросы:
этот кусок вызывается? (проще всего проверить - поставить внутрь брекпоинт).
чему равны адреса _sdata, _edata, _sbss, _ebss, _sidata ? Можно посмотреть в map-файле. Заодно можно посмотреть их объявления в скрипте линкера.


PS а вообще - давно пора самый минимальный пример куда-нибудь на гугл-диск выложить...
SasaVitebsk
Ещё раз попробую.
1. По умолчанию размер кучи равен 0. Динамическая память не всем нужна. Вы должны настроить размер кучи в опциях проекта.
2. У вас отладчик есть? Но в принципе можно и симулятором, наверное. Пройдите по шагам и посмотрите.
3. Покажите листинг malloc. Зачем там деление? Не верю.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.