Перейти к содержанию
    

STM32L151 падает при выделении памяти

Контроллер STM32L151RB, CoIDE. Создаю проект, добавляю из репозитория cmsis_boot и CMSIS_core. Собирается, отладка запускается без проблем. Добавляю строку:

uint8_t * ptr = malloc(4);

Не собирается, ругается что не определена функция _sbrk(). Добавляю из репозитория C Library. Собирается. Запускаю отладку. Дохожу до вызова malloc(), и программа падает в Default_Handler(). Если определить все обработчики ошибок, то сваливается в HardFault.

Проделываю точно такую-же последовательность действий, но уже с STM32F407. Без проблем, память выделяется.

Что я делаю не так? Или может какая-то особенность есть с динамическим выделением памяти у этих STM32L151? Если все-же я что-то не так делаю, буду очень благодарен, если кто-то поделится пустой заготовкой проекта в CoIDE, чтобы нормально память выделялась.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну какая особенность при выделении памяти? Не выдумывайте ужастики.

1. Стандартная процедура выделения памяти сравнивает запрошенный объём с доступным. Если памяти в куче достаточно, то выдаёт указатель на начало, а если нет, то 0. То есть падать при этой процедуре ничего не может. Упасть может, если она выдаёт 0 (недостаточно памяти) а вы это используете как указатель.

2. Перейдите на ассемблер и выясните полную картину.

3. В опциях проекта, где-то, задаётся размер памяти, выделенный на кучу. Я CoIDE не пользуюсь, поэтому подсказать где именно не могу. Поищите.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Разница между Cortex-M0(+) и Cortex-M3,M4 (STM32F407) - последний умеет невыровненный доступ. И если область памяти, которую вы отдаете менеджеру памяти, не выровнена - вполне возможно падение (ибо менеджер наверняка ожидает выровненную область). Фигню написал, у 151 ядро M3, умеет невыровненный доступ.

 

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

 

У вас же есть отладчик - неужели сложно пройти по дизассемблерному коду до места падения?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Так в том то и дело, что специально для проверки создал пустой проект, в котором только одна вышеупомянутая строка. И именно на ней падает.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

посмотрите ld-файлы для STM32F407 и для STM32L151 - может, у вас ссылки на heap в скриптах по-разному заданы? может, для 151 размер кучи = 0?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Так в том то и дело, что специально для проверки создал пустой проект, в котором только одна вышеупомянутая строка. И именно на ней падает.

Вы читать умеете? Перечитайте ещё раз мой пост. Перечитайте несколько раз, если с первого не доходит.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

посмотрите 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 = {};

все поля структуры инициализируются нулями. А тут почему-то в них тоже какой-то мусор находится.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Нашел в startup файле 151го такую особенность:

void Default_Reset_Handler(void)
...

Удивительная штука эти кокосы...

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

 

Вопросы:

этот кусок вызывается? (проще всего проверить - поставить внутрь брекпоинт).

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

 

 

PS а вообще - давно пора самый минимальный пример куда-нибудь на гугл-диск выложить...

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ещё раз попробую.

1. По умолчанию размер кучи равен 0. Динамическая память не всем нужна. Вы должны настроить размер кучи в опциях проекта.

2. У вас отладчик есть? Но в принципе можно и симулятором, наверное. Пройдите по шагам и посмотрите.

3. Покажите листинг malloc. Зачем там деление? Не верю.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...