Haamu 0 28 февраля, 2016 Опубликовано 28 февраля, 2016 · Жалоба Контроллер STM32L151RB, CoIDE. Создаю проект, добавляю из репозитория cmsis_boot и CMSIS_core. Собирается, отладка запускается без проблем. Добавляю строку: uint8_t * ptr = malloc(4); Не собирается, ругается что не определена функция _sbrk(). Добавляю из репозитория C Library. Собирается. Запускаю отладку. Дохожу до вызова malloc(), и программа падает в Default_Handler(). Если определить все обработчики ошибок, то сваливается в HardFault. Проделываю точно такую-же последовательность действий, но уже с STM32F407. Без проблем, память выделяется. Что я делаю не так? Или может какая-то особенность есть с динамическим выделением памяти у этих STM32L151? Если все-же я что-то не так делаю, буду очень благодарен, если кто-то поделится пустой заготовкой проекта в CoIDE, чтобы нормально память выделялась. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SapegoAL 0 29 февраля, 2016 Опубликовано 29 февраля, 2016 · Жалоба Ну какая особенность при выделении памяти? Не выдумывайте ужастики. 1. Стандартная процедура выделения памяти сравнивает запрошенный объём с доступным. Если памяти в куче достаточно, то выдаёт указатель на начало, а если нет, то 0. То есть падать при этой процедуре ничего не может. Упасть может, если она выдаёт 0 (недостаточно памяти) а вы это используете как указатель. 2. Перейдите на ассемблер и выясните полную картину. 3. В опциях проекта, где-то, задаётся размер памяти, выделенный на кучу. Я CoIDE не пользуюсь, поэтому подсказать где именно не могу. Поищите. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 29 февраля, 2016 Опубликовано 29 февраля, 2016 · Жалоба Разница между Cortex-M0(+) и Cortex-M3,M4 (STM32F407) - последний умеет невыровненный доступ. И если область памяти, которую вы отдаете менеджеру памяти, не выровнена - вполне возможно падение (ибо менеджер наверняка ожидает выровненную область). Фигню написал, у 151 ядро M3, умеет невыровненный доступ. Как реализован конкретно ваш менеджер - понятия не имею. Можно туп сделать возврат из HardFault_Handler() и поставить в него точку останова. Выйдя попадете на команду, вызвавшую исключение и исходя из команды и ее аргументов можно думать дальше. У вас же есть отладчик - неужели сложно пройти по дизассемблерному коду до места падения? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Haamu 0 29 февраля, 2016 Опубликовано 29 февраля, 2016 · Жалоба Так в том то и дело, что специально для проверки создал пустой проект, в котором только одна вышеупомянутая строка. И именно на ней падает. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Aaron 1 1 марта, 2016 Опубликовано 1 марта, 2016 · Жалоба посмотрите ld-файлы для STM32F407 и для STM32L151 - может, у вас ссылки на heap в скриптах по-разному заданы? может, для 151 размер кучи = 0? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SapegoAL 0 1 марта, 2016 Опубликовано 1 марта, 2016 · Жалоба Так в том то и дело, что специально для проверки создал пустой проект, в котором только одна вышеупомянутая строка. И именно на ней падает. Вы читать умеете? Перечитайте ещё раз мой пост. Перечитайте несколько раз, если с первого не доходит. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Haamu 0 2 марта, 2016 Опубликовано 2 марта, 2016 · Жалоба посмотрите 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 5 2 марта, 2016 Опубликовано 2 марта, 2016 · Жалоба Нашел в startup файле 151го такую особенность: void Default_Reset_Handler(void) ... Удивительная штука эти кокосы... Либо этот файл не используется, либо никто никогда не пробовал с этими исходниками работать. Вопросы: этот кусок вызывается? (проще всего проверить - поставить внутрь брекпоинт). чему равны адреса _sdata, _edata, _sbss, _ebss, _sidata ? Можно посмотреть в map-файле. Заодно можно посмотреть их объявления в скрипте линкера. PS а вообще - давно пора самый минимальный пример куда-нибудь на гугл-диск выложить... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SapegoAL 0 2 марта, 2016 Опубликовано 2 марта, 2016 · Жалоба Ещё раз попробую. 1. По умолчанию размер кучи равен 0. Динамическая память не всем нужна. Вы должны настроить размер кучи в опциях проекта. 2. У вас отладчик есть? Но в принципе можно и симулятором, наверное. Пройдите по шагам и посмотрите. 3. Покажите листинг malloc. Зачем там деление? Не верю. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться