MiklPolikov 0 5 мая, 2019 Опубликовано 5 мая, 2019 · Жалоба Всем привет. Пытаюсь запустить FreeRTOS на чипе BlueNRG-1 Это ARM Cortex-M0 от ST Попадает в HardFault при первом же вызове xTaskCreate Вижу что в ядре ОС какая-то белиберда со всеми переменными. Вижу, что не инициализируется стэк - по какой-то невероятной причине: При первом проходе функции pvPortMalloc не выполняется строчка xHeapHasBeenInitialised = pdFALSE !!!! И программа не попадает в ветку prvHeapInit(); (картинка) Вопрос: как такое вообще возможно и что с эти делать ? Keil ОС взята, разумеется, для M0 heap_2 Всё это запускал на других M0 , например STM32F030 Заранее спасибо ! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
haker_fox 60 5 мая, 2019 Опубликовано 5 мая, 2019 · Жалоба Со странным запуском ОС встречался у своего коллеги на stm32f051. Глючило всё. причём глюки были непостоянные и совершенно удивительные: вылет счётчика команд на левые адреса, испорченное содержимое озу и т.п. Причём всё это происходило в разных местах программы: то до старта шедулера, то на создании задачи. Проверили версии тактирования микроконтроллера, цепи сброса и питания. Оказалось, через пару дней поисков, что в опции отладчика стоит сброс только ядра, но не периферии. Когда поставили "сбрасывать всё", проблемы исчезли. Правда среда отладки была IAR. Но вдруг в вашем случае отладчик нечто подобное совершает? Проверьте скрипты линкера: области памяти ОЗУ и FLASH. Они правильно точно указаны? А если пошагово пройтись под отладчиком с вектора сброса, микроконтроллер выполнят код первоначальной инициализации переменных? Это, вроде. в clib делается. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 5 мая, 2019 Опубликовано 5 мая, 2019 · Жалоба 9 часов назад, MiklPolikov сказал: При первом проходе функции pvPortMalloc не выполняется строчка xHeapHasBeenInitialised = pdFALSE !!!! Она и не должна выполняться при проходах функции. Так как там static. static-переменные инициализируются стартап-кодом ещё до старта main(). И если у Вас в ней оказывается неожиданное значение, то ищите почему: 1) этот стартап-код выполняется неверно (или вообще не выполняется); 2) или содержимое этой переменной разрушается уже после инициализации и до вызова данной функции. Можно например поставить watchpoint на данный адрес перед вызовом стартап-кода и посмотреть кто туда пишет и что. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
x893 35 5 мая, 2019 Опубликовано 5 мая, 2019 · Жалоба Ещё можно в симуляторе посмотреть. Но вариант с breakpoint c Read/Write конечно самый простой и быстрый. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MiklPolikov 0 5 мая, 2019 Опубликовано 5 мая, 2019 · Жалоба Спасибо. Разобрался, всё как вы и сказали: После RESET не выполняется никакого Startup-кода. Файл startup ни чего не содержит. Программа сразу попадает на функцию main. Содержимое памяти и вообще всего остаётся не сброшенным. Я ни когда не задумывался, как это происходит. Думал, при попадании на Reset_Handler процессор сам собой знает, что надо всё сбросить. А на самом деле у меня всё всегда сбрасывалось сигналом на ноге RESET. У этого чипа невозможно использовать ногу RESET. Она отключает питание чипа, и отладчик работает, только если отключен HARDWARE RESET. Крайне не удобная вещь. Догадываюсь, зачем так сделали, для того что бы внешний сигнал мог переводить чип в 0 потребления, иначе это достижимо только внешним ключом на питании. Примеры от ST сыроваты: С одной стороны полно разрозненной документации и видеоуроки на Ютубе, мол за 5 минут залил прошивку и заработало. Просто при подаче питания на плату так и будет, а вот под отладкой пример не работает. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 5 мая, 2019 Опубликовано 5 мая, 2019 · Жалоба 2 часа назад, MiklPolikov сказал: После RESET не выполняется никакого Startup-кода. Файл startup ни чего не содержит. Программа сразу попадает на функцию main. Содержимое памяти и вообще всего остаётся не сброшенным. Файл startup тут не при чём. Си-стартап-код формируется компилятором на базе информации об инициализированных переменных из всех файлов проекта. Не знаю какой у вас компилятор, но IAR стартап-код кладёт в функцию __iar_program_start() (Т.е.- сама функция берётся из стандартной библиотеки, а данные об инициализируемых переменных для неё - строятся компилятором динамически по мере компиляции). И где-то сразу после вектора сброса должен быть её вызов. А уже из неё управление передаётся в main(). Вот внутри этой __iar_program_start() и инициализируются все инициализируемые переменные. В других компиляторах могут быть какие-то отличия в именах, но принцип примерно тот же. Цитата Просто при подаче питания на плату так и будет, а вот под отладкой пример не работает. При подаче питания может просто ОЗУ по месту этой переменной обнуляться. Поэтому всё и работает. А по сигналу RESET содержимое ОЗУ в МК обычно не изменяется, поэтому там оказывается мусор. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MiklPolikov 0 6 мая, 2019 Опубликовано 6 мая, 2019 · Жалоба 5 hours ago, jcxz said: Файл startup тут не при чём. Си-стартап-код формируется компилятором на базе информации об инициализированных переменных из всех файлов проекта. Не знаю какой у вас компилятор, но IAR стартап-код кладёт в функцию __iar_program_start() (Т.е.- сама функция берётся из стандартной библиотеки, а данные об инициализируемых переменных для неё - строятся компилятором динамически по мере компиляции). При подаче питания может просто ОЗУ по месту этой переменной обнуляться. Поэтому всё и работает. А по сигналу RESET содержимое ОЗУ в МК обычно не изменяется, поэтому там оказывается мусор. Keil По сигналу RESET всегда всё обнуляется, в документации на процессор для каждого регистра указано "RESET STATE= ...." Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 6 мая, 2019 Опубликовано 6 мая, 2019 · Жалоба Так одно дело - регистры МК, а другое - ОЗУ. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SMaster 0 13 мая, 2019 Опубликовано 13 мая, 2019 · Жалоба В кейл инициализация происходит в функции __main (посмотрите ассемблеровский стартап-файлик), откуда в свою очередь вызывается функция main. Попробуйте запихать эту переменную в watch. А еще для более простой отладки я бы для начала выключил оптимизацию. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться