Jump to content

    

FreeRTOS + ARM Cortex-M0 (BlueNRG1)

Всем привет.

Пытаюсь запустить FreeRTOS  на чипе BlueNRG-1
Это ARM Cortex-M0   от ST

Попадает в HardFault при первом же вызове xTaskCreate
Вижу что в ядре ОС какая-то белиберда  со всеми переменными.
Вижу, что не инициализируется стэк - по какой-то невероятной причине:

При первом проходе функции pvPortMalloc  не выполняется строчка  xHeapHasBeenInitialised = pdFALSE   !!!!
И программа не попадает в ветку  prvHeapInit();  (картинка)

Вопрос:  как такое вообще возможно и что с эти делать ?


Keil
ОС взята, разумеется, для M0
heap_2
Всё это запускал на других M0 , например STM32F030 
 

Заранее спасибо !

 

ОС1.jpg

Share this post


Link to post
Share on other sites

Со странным запуском ОС встречался у своего коллеги на stm32f051. Глючило всё. причём глюки были непостоянные и совершенно удивительные: вылет счётчика команд на левые адреса, испорченное содержимое озу и т.п. Причём всё это происходило в разных местах программы: то до старта шедулера, то на создании задачи. Проверили версии тактирования микроконтроллера, цепи сброса и питания. Оказалось, через пару дней поисков, что в опции отладчика стоит сброс только ядра, но не периферии. Когда поставили "сбрасывать всё", проблемы исчезли. Правда среда отладки была IAR. Но вдруг в вашем случае отладчик нечто подобное совершает? Проверьте скрипты линкера: области памяти ОЗУ и FLASH. Они правильно точно указаны? А если пошагово пройтись под отладчиком с вектора сброса, микроконтроллер выполнят код первоначальной инициализации переменных? Это, вроде. в clib делается.

Share this post


Link to post
Share on other sites
9 часов назад, MiklPolikov сказал:

При первом проходе функции pvPortMalloc  не выполняется строчка  xHeapHasBeenInitialised = pdFALSE   !!!!

Она и не должна выполняться при проходах функции. Так как там static. static-переменные инициализируются стартап-кодом ещё до старта main(). И если у Вас в ней оказывается неожиданное значение, то ищите почему:

1) этот стартап-код выполняется неверно (или вообще не выполняется);

2) или содержимое этой переменной разрушается уже после инициализации и до вызова данной функции.

Можно например поставить watchpoint на данный адрес перед вызовом стартап-кода и посмотреть кто туда пишет и что.

Share this post


Link to post
Share on other sites

Ещё можно в симуляторе посмотреть.

Но вариант с breakpoint c Read/Write конечно самый простой и быстрый.

Share this post


Link to post
Share on other sites

Спасибо.
Разобрался, всё как вы и сказали:
После RESET не выполняется никакого Startup-кода. Файл startup  ни чего не содержит. Программа сразу попадает на функцию main. Содержимое памяти и вообще всего остаётся не сброшенным.
Я ни когда не задумывался, как это происходит. Думал, при попадании на Reset_Handler процессор сам собой знает, что надо всё сбросить. А на самом деле у меня всё всегда сбрасывалось сигналом на ноге RESET.

У этого чипа невозможно использовать ногу RESET. Она отключает питание чипа, и отладчик работает, только если отключен HARDWARE RESET.
Крайне не удобная вещь. Догадываюсь, зачем так сделали, для того что бы внешний сигнал мог переводить чип в 0 потребления, иначе это достижимо только внешним ключом на питании.


Примеры от ST сыроваты:
С одной стороны полно разрозненной документации и видеоуроки на Ютубе, мол за 5 минут залил прошивку и заработало.
Просто при подаче питания на плату так и будет, а вот под отладкой пример не работает.

 

Share this post


Link to post
Share on other sites
2 часа назад, MiklPolikov сказал:

После RESET не выполняется никакого Startup-кода. Файл startup  ни чего не содержит. Программа сразу попадает на функцию main. Содержимое памяти и вообще всего остаётся не сброшенным.

Файл startup тут не при чём. Си-стартап-код формируется компилятором на базе информации об инициализированных переменных из всех файлов проекта. Не знаю какой у вас компилятор, но IAR стартап-код кладёт в функцию __iar_program_start() (Т.е.- сама функция берётся из стандартной библиотеки, а данные об инициализируемых переменных для неё - строятся компилятором динамически по мере компиляции). И где-то сразу после вектора сброса должен быть её вызов. А уже из неё управление передаётся в main(). Вот внутри этой __iar_program_start() и инициализируются все инициализируемые переменные. В других компиляторах могут быть какие-то отличия в именах, но принцип примерно тот же.

Цитата

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

При подаче питания может просто ОЗУ по месту этой переменной обнуляться. Поэтому всё и работает. А по сигналу RESET содержимое ОЗУ в МК обычно не изменяется, поэтому там оказывается мусор.

Share this post


Link to post
Share on other sites
5 hours ago, jcxz said:

Файл startup тут не при чём. Си-стартап-код формируется компилятором на базе информации об инициализированных переменных из всех файлов проекта. Не знаю какой у вас компилятор, но IAR стартап-код кладёт в функцию __iar_program_start() (Т.е.- сама функция берётся из стандартной библиотеки, а данные об инициализируемых переменных для неё - строятся компилятором динамически по мере компиляции). 

При подаче питания может просто ОЗУ по месту этой переменной обнуляться. Поэтому всё и работает. А по сигналу RESET содержимое ОЗУ в МК обычно не изменяется, поэтому там оказывается мусор.

Keil
По сигналу RESET всегда всё обнуляется, в документации на процессор для каждого регистра указано "RESET STATE= ...." 

 

Share this post


Link to post
Share on other sites

Так одно дело - регистры МК, а другое - ОЗУ. 

Share this post


Link to post
Share on other sites

В кейл инициализация происходит в функции __main (посмотрите ассемблеровский стартап-файлик), откуда в свою очередь вызывается функция main. Попробуйте запихать эту переменную в watch. А еще для более простой отладки я бы для начала выключил оптимизацию.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now