Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Запускаю scmRTOS на lpc1768 (cortex M3). Помогите.
Форум разработчиков электроники ELECTRONIX.ru > Cистемный уровень проектирования > Операционные системы > scmRTOS
Alekseeey
Здравствуйте.

Застрял на том, что система не стартует, сваливается в HardFault, нужны подсказки что и где проверить.

Среда разработки: WindowsXP + Eclipse + gcc (toolchain от klen), отладчика нет (кстати, посоветуйте, что взять для данной среды).
Запускаю так: Скачал порт для stm32 (scmRTOS.3.10.cortexm3.gcc.rar), поправил скрипт линкера, поправил таблицу прерываний в startup, откомпилировал проект 1-EventFlag (управление светодиодами сделал свое).
Запускаю - ОС делает настройку systick, PendSVC, доходит до PendSVC и затем HardFault.

Вот. Сам не понимаю, чего я не понимаю, поэтому прошу помощи. Пожалуйста.

AHTOXA
Так, телепатически, сложно сказатьsm.gif
Выложите свой проект, посмотрим.
Alekseeey
Цитата(AHTOXA @ Dec 15 2010, 09:30) *
Так, телепатически, сложно сказатьsm.gif
Выложите свой проект, посмотрим.


Проект прикреплен.

Появились конкретные вопросы:
В cortexm3 два стека - Process stack (PS) и main stack (MS). Какой стек в какой момент функционирования scmRTOS работает? Где (в каком месте программы) в системе осуществляется переключение между этими стеками?
Где (физически) в памяти PS должен располагаться, в какую сторону расти?
Прочитал user manual для lpc17xx и не понял, объясните пожалуйста, что делает и для чего вообще нужно прерывание PendSV?


Нажмите для просмотра прикрепленного файла


Там для отладки в скрипте линкера добавлена константа _ustack -- это я пытаюсь разобраться со стартом системы, с инициализацией процессов. Указатели StackPointer всех трех процессов почему-то оказывались равными _estack и указывали на стек программы и при старте все падало, поэтому я перенес _estack в середину памяти, а программный стек назвал _ustack и записал его в начало таблицы векторов прерываний. После этого система (по-моему) успешно прошла нулевую инициализацию и теперь сваливается где-то в другом месте...

AHTOXA
Похоже, что вы скачали старую версию. С тех пор кое-что поменялось в компиляторе, и, соответственно, в линкерном скрипте.
Поменяйте
Код
        __ctors_start__ = .;
        KEEP(SORT(*)(.ctors))
        __ctors_end__ = .;

на
Код
    __ctors_start__ = .;
    KEEP(SORT(*)(.init_array))  /* eabi uses .init_array for static constructor lists */
    __ctors_end__ = .;


По вопросам.
Стеки. В прерываниях используется Main stack. Это как раз тот, вершину которого мы заносим в таблицу векторов. А в задачах используется Process stack.
PendSV используется для переключения контекста. Когда выясняется, что нужно переключить контекст, задача взводит флажок прерывания PendSV. Если это происходит в прерывании, то перключение откладывается до окончания прерывания (или всех прерываний, если были вложенные). Это происходит потому, что прерывание PendSV имеет наименьший приоритет.
Ну а в прерывании происходит сохранение контекста текущей задачи (частично аппаратное), поиск задачи, на которую нужно переключиться, и восстановление контекста новой задачи.
Alekseeey
Цитата(AHTOXA @ Dec 15 2010, 15:30) *
Похоже, что вы скачали старую версию. С тех пор кое-что поменялось в компиляторе, и, соответственно, в линкерном скрипте.
Поменяйте
Код
        __ctors_start__ = .;
        KEEP(SORT(*)(.ctors))
        __ctors_end__ = .;

на
Код
    __ctors_start__ = .;
    KEEP(SORT(*)(.init_array))  /* eabi uses .init_array for static constructor lists */
    __ctors_end__ = .;


По вопросам.
Стеки. В прерываниях используется Main stack. Это как раз тот, вершину которого мы заносим в таблицу векторов. А в задачах используется Process stack.
PendSV используется для переключения контекста. Когда выясняется, что нужно переключить контекст, задача взводит флажок прерывания PendSV. Если это происходит в прерывании, то перключение откладывается до окончания прерывания (или всех прерываний, если были вложенные). Это происходит потому, что прерывание PendSV имеет наименьший приоритет.
Ну а в прерывании происходит сохранение контекста текущей задачи (частично аппаратное), поиск задачи, на которую нужно переключиться, и восстановление контекста новой задачи.



После исправления файла скрипта линкера все заработало.

Огромное спасибо вам за помощь, AHTOXA.


Пожалуй, выложу здесь рабочий проект для примера, может не я один такой страдающий.

Нажмите для просмотра прикрепленного файла (lpc1768, плата sk-mlpc1768, starterkit)

sonycman
Что-то запамятовал - на кортексе м3 при заходе в прерывание на какой стёк сохраняется контекст?
На стёк процесса или на мэйн?
AHTOXA
На текущий sm.gif
sonycman
Цитата(AHTOXA @ Jan 16 2011, 13:10) *
На текущий sm.gif

Спасибо sm.gif

Значит, предусматривать место необходимо на всех стёках программы...
AHTOXA
Да, но только на один уровень, и только на автоматически сохраняемые регистры (xPSR, PC, LR, R12, R0-R3).
Потому что при входе в прерывание происходит переключение на Main стек, и все дополнительные сохранения производятся уже на него.
(Это для обычных прерываний, в прерывании для переключения контекста весь контекст сохраняется на стеке процесса)
sonycman
То есть при переключении задач на стёк текущей задачи сохраняется 64 байта?

зы: что то я раздул мэйн стёк, при двух уровнях приоритетов прерываний, думаю, 500 байт для него хватит сполна.
AHTOXA
Да, полный контекст, 64 байта.
И да, Main стек обычно используется мало. Ну если только у вас в прерываниях нет локальных переменных на килобайты sm.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.