реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
Haamu
сообщение Feb 28 2016, 19:09
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 90
Регистрация: 12-12-13
Пользователь №: 79 587



Контроллер STM32L151RB, CoIDE. Создаю проект, добавляю из репозитория cmsis_boot и CMSIS_core. Собирается, отладка запускается без проблем. Добавляю строку:
Код
uint8_t * ptr = malloc(4);

Не собирается, ругается что не определена функция _sbrk(). Добавляю из репозитория C Library. Собирается. Запускаю отладку. Дохожу до вызова malloc(), и программа падает в Default_Handler(). Если определить все обработчики ошибок, то сваливается в HardFault.
Проделываю точно такую-же последовательность действий, но уже с STM32F407. Без проблем, память выделяется.
Что я делаю не так? Или может какая-то особенность есть с динамическим выделением памяти у этих STM32L151? Если все-же я что-то не так делаю, буду очень благодарен, если кто-то поделится пустой заготовкой проекта в CoIDE, чтобы нормально память выделялась.
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Feb 29 2016, 06:38
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Ну какая особенность при выделении памяти? Не выдумывайте ужастики.
1. Стандартная процедура выделения памяти сравнивает запрошенный объём с доступным. Если памяти в куче достаточно, то выдаёт указатель на начало, а если нет, то 0. То есть падать при этой процедуре ничего не может. Упасть может, если она выдаёт 0 (недостаточно памяти) а вы это используете как указатель.
2. Перейдите на ассемблер и выясните полную картину.
3. В опциях проекта, где-то, задаётся размер памяти, выделенный на кучу. Я CoIDE не пользуюсь, поэтому подсказать где именно не могу. Поищите.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Feb 29 2016, 08:01
Сообщение #3


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



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

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

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


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Haamu
сообщение Feb 29 2016, 14:56
Сообщение #4


Частый гость
**

Группа: Участник
Сообщений: 90
Регистрация: 12-12-13
Пользователь №: 79 587



Так в том то и дело, что специально для проверки создал пустой проект, в котором только одна вышеупомянутая строка. И именно на ней падает.
Go to the top of the page
 
+Quote Post
Aaron
сообщение Mar 1 2016, 07:04
Сообщение #5


Местный
***

Группа: Свой
Сообщений: 243
Регистрация: 5-10-06
Из: Зеленоград
Пользователь №: 21 007



посмотрите ld-файлы для STM32F407 и для STM32L151 - может, у вас ссылки на heap в скриптах по-разному заданы? может, для 151 размер кучи = 0?
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Mar 1 2016, 09:23
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Цитата(Haamu @ Feb 29 2016, 17:56) *
Так в том то и дело, что специально для проверки создал пустой проект, в котором только одна вышеупомянутая строка. И именно на ней падает.

Вы читать умеете? Перечитайте ещё раз мой пост. Перечитайте несколько раз, если с первого не доходит.
Go to the top of the page
 
+Quote Post
Haamu
сообщение Mar 2 2016, 06:38
Сообщение #7


Частый гость
**

Группа: Участник
Сообщений: 90
Регистрация: 12-12-13
Пользователь №: 79 587



Цитата(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 = {};

все поля структуры инициализируются нулями. А тут почему-то в них тоже какой-то мусор находится.
Go to the top of the page
 
+Quote Post
esaulenka
сообщение Mar 2 2016, 09:49
Сообщение #8


Профессионал
*****

Группа: Свой
Сообщений: 1 032
Регистрация: 13-03-08
Из: Маськва
Пользователь №: 35 877



Цитата(Haamu @ Mar 2 2016, 09:38) *
Нашел в startup файле 151го такую особенность:
Код
void Default_Reset_Handler(void)
...

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

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


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


--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Mar 2 2016, 10:26
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Ещё раз попробую.
1. По умолчанию размер кучи равен 0. Динамическая память не всем нужна. Вы должны настроить размер кучи в опциях проекта.
2. У вас отладчик есть? Но в принципе можно и симулятором, наверное. Пройдите по шагам и посмотрите.
3. Покажите листинг malloc. Зачем там деление? Не верю.
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 26th June 2025 - 16:29
Рейтинг@Mail.ru


Страница сгенерированна за 0.0144 секунд с 7
ELECTRONIX ©2004-2016