Jump to content

    
Sign in to follow this  
MiklPolikov

FreeRTOS + ARM Cortex-M0 (BlueNRG1)

Recommended Posts

Всем привет.

Пытаюсь запустить 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

Спасибо.
Разобрался, всё как вы и сказали:
После 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

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

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this