Комментарии 22
Не смог найти примера для Keil/ARMCC.
Плохо искал?
Плохо искал?
0
Если вы про Embox, то у нас не под Keil. Собираемся легко из консоли)
На странице проекта есть короткое описание как собирать. Для прошивки stm32 используем openocd.
На странице проекта есть короткое описание как собирать. Для прошивки stm32 используем openocd.
0
Embox собирается с помощью gcc.
Можно попробовать собрать llvm, но пока там есть нюансы:)
Можно попробовать собрать llvm, но пока там есть нюансы:)
0
Для охвата всей аудитории желательно под все три компилятора.
GCC может и не плох, но далеко не идеал.
GCC может и не плох, но далеко не идеал.
-2
Тут дело в том, что считать всей аудиторией:)
У нас cortex-m лишь маленькая, пусть и интересная часть, поддерживаемых платформ!
И на текущий момент, только gcc являтся стандартом де-факто, под все (почти) архитектуры.
Приведенные Вами среды и компиляторы, хорошо подходят для разработки под конкретный микроконтроллер! Но у Embox одной из основных идей является привнесение в мир микроконтроллеров удобства программирования, как на большим системах, благо ресурсов хватает. Немного подробнее об этом в статье.
У нас cortex-m лишь маленькая, пусть и интересная часть, поддерживаемых платформ!
И на текущий момент, только gcc являтся стандартом де-факто, под все (почти) архитектуры.
Приведенные Вами среды и компиляторы, хорошо подходят для разработки под конкретный микроконтроллер! Но у Embox одной из основных идей является привнесение в мир микроконтроллеров удобства программирования, как на большим системах, благо ресурсов хватает. Немного подробнее об этом в статье.
0
del
0
Все просто — много где есть sleep(), mutex_lock() и прочие “wait”, и за счет них потоки естественным образом и переключались.
Как мне это знакомо :) Только причина у нас была другая: мы таймер планировщика затёрли, а система до 15-25 минут могла нормально работать, пока не случался момент, когда все потоки решали подождать чего-то. Cypress FX3/ARM926E-JS/ThreadX. Такой вот гибрид кооперативной и вытесняющей многозадачности.
Кстати, косвенно про переключение контекстов в ThreadX можно посмотреть тут: https://habrahabr.ru/post/249991/. Отмечу, что под разные целевые платформы поведение может отличаться. ARM926E-JS в данном случае интересен тем, что существует два способа сохранить контекст в стек.
0
Да, с перетиранием тоже постоянно сталкивались, добавляли потом защиту стека для потоков, но не всегда помогает :) Ага, спасибо, просмотрел Вашу публикацию.
Кроме того, рассматривается случай, когда доступа к исходникам ThreadX нет и не предвидится.А если не секрет, то зачем тогда именно ThreadX использовали?
0
Нам не очень подходит вариант FreeRTOS, так как эта ОС, направлена прежде всего на микроконтроллеры, что влечет за собой некую “захардкоженность” context_switch под конкретный чип
… FreeRTOS перед первым запуском задачи инициализирует стек (в том числе разрешает прерывания) этой задачи, что кмк должно происходить в любой ОС
0
Мы тут не говорим, что во FreeRTOS что-то плохо с переключением потоков. Я уверен, что все прекрасно переключается. Дело в том, что у них context_switch делается прямо ассемблерной вставкой внутри обработчика прерывания PendSV. А хочется отдельную функцию, без всяких прерываний, которую можно вызвать явно.
… FreeRTOS перед первым запуском задачи инициализирует стекА про инициализацию в статье есть :)
Давайте изначально проинициализируем создаваемый поток так, как если бы мы выходили из прерывания — /* Simulate the stack frame as it would be created by a context switch interrupt. */И приводится код функции
pxPortInitialiseStack
. 0
Достаточно перейти в защищённый режим, и будим иметь два уникальных стека — для потоков и прерываний.
В этом случае любое прерывание сохраняет контекст в прерванный поток, а новые данные вытесняются уже в стек прерываний. Не важно какая-там получается глубина вложений прерываний, всё восстанавливается до первоначального вида.
Не требуется универсальный обработчик прерываний — это кстати костыль FreeRTOS и чибиос и ещё кучи последователей свидетелей иеговы. Не требуется запрет прерываний.
Необходимо выполнить всего одно условие: обработчик системных вызовов должен иметь нулевой приоритет, и вызываться из двух трёх прерываний максимального уровня (15) — это таймер реального времени, и таймер задачи. Пользовательские прерывания должны иметь приоритет от 1 до 15.
В качестве системного обработчика идеально подходит SVC.
Да собственно https://bitbucket.org/AVI-crak/rtos-cortex-m3-gcc/overview — моё.
В этом случае любое прерывание сохраняет контекст в прерванный поток, а новые данные вытесняются уже в стек прерываний. Не важно какая-там получается глубина вложений прерываний, всё восстанавливается до первоначального вида.
Не требуется универсальный обработчик прерываний — это кстати костыль FreeRTOS и чибиос и ещё кучи последователей свидетелей иеговы. Не требуется запрет прерываний.
Необходимо выполнить всего одно условие: обработчик системных вызовов должен иметь нулевой приоритет, и вызываться из двух трёх прерываний максимального уровня (15) — это таймер реального времени, и таймер задачи. Пользовательские прерывания должны иметь приоритет от 1 до 15.
В качестве системного обработчика идеально подходит SVC.
Да собственно https://bitbucket.org/AVI-crak/rtos-cortex-m3-gcc/overview — моё.
0
Достаточно перейти в защищённый режим, и будим иметь два уникальных стекаВы похоже про MSP и PSP? Как конкретно это решает проблему описанную в статье? Вот вы вошли в обработчик прерывания, вот у вас есть стек — окей, но пока вы из него не выйдете по стеку, новые прерывания того же типа не случаются. Именно поэтому во FreeRTOS и NuttX модифицируется стек.
Не требуется универсальный обработчик прерываний — это кстати костыль FreeRTOS и чибиосУ них есть вектор прерываний, насколько я знаю. На каждое прерывание дергается свой обработчик
0
В том весь и прикол, в защищённом режиме поток не может самостоятельно модифицировать свой стек, модификация возможна в теле прерывания.
Для того чтобы иметь 100% уверенности в том что стек прерываний полностью выбран — прерывания таймеров реального времени и таймера задачи — должны иметь 15 уровень — максимальный. Их могут все перебивать вдоль и поперёк, однако когда из них вызовется SVC — всё остальное будет ждать.
Не требуется запрет прерываний, не требуется кукла для всех прерываний сразу, нет потери прерываний.
Замена контекста у всех ос выглядит почти одинаково — переписываем стек и часть регистров. Вопрос в другом — зачем усложнять простое решение?
Для того чтобы иметь 100% уверенности в том что стек прерываний полностью выбран — прерывания таймеров реального времени и таймера задачи — должны иметь 15 уровень — максимальный. Их могут все перебивать вдоль и поперёк, однако когда из них вызовется SVC — всё остальное будет ждать.
Не требуется запрет прерываний, не требуется кукла для всех прерываний сразу, нет потери прерываний.
Замена контекста у всех ос выглядит почти одинаково — переписываем стек и часть регистров. Вопрос в другом — зачем усложнять простое решение?
0
Не требуется запрет прерыванийКонечно не требуется, обработка вложенных прерываний — обычное дело.
не требуется кукла для всех прерываний сразуПочему это плохо? Мне кажется — часто удобно.
Замена контекста у всех ос выглядит почти одинаково — переписываем стек и часть регистров. Вопрос в другом — зачем усложнять простое решение?Статья как раз была об этом. Еще раз повторюсь :)
0
dsb
ldr r12, =__SysTick_CTRL
ldr r2, [r0, #8] // читаем адрес стека
ldmia r2!, {r4-r11} // читаем сохранённое
vldmia r2!, {s16-s31} // грузим математику
ldr r3, [r0, #20] // читаем новое время Task activity timer
str r3, [r12, #4] // сохранили время #0xE014 SysTick->LOAD
mov r3, #7
str r3, [r12, #8] // перезапуск #0xE018 SysTick->VAL
strh r3, [r12]
msr psp, r2 // переписываем стек
dsb
isb
bx lr
Так это выглядит на асме в прерывании SVC, у вас должен получиться гораздо более жирный код, я в этом уверен.
Кукла для всех прерываний кроме своего прямого назначения, делает ещё и мелкую пакость — вносит неконтролируемою задержку выполнения прерываний. Ведь кукла вызывается не в момент срабатывания конкретного прерывания, а просто по таймеру. Это не слишком заметно на проектах мигания лампочкой, но если требуется обработка в реальном времени — начинается цирк.
0
Нет, регистры мы так же быстро грузить умеем, с инструкцией ldmia знакомы, уж поверьте.
Ну а вообще да, жертвуя читабельностью что угодно можно на асме наваять. Хотя может это что-то и крутое, я без цельной картины не пойму отдельно выдранный кусок
Ну а вообще да, жертвуя читабельностью что угодно можно на асме наваять. Хотя может это что-то и крутое, я без цельной картины не пойму отдельно выдранный кусок
0
Ведь кукла вызывается не в момент срабатывания конкретного прерывания, а просто по таймеруА вот тут я видимо неправильно Вас понял сначала. Подумал как раз про общий обработчик, который уже остальные дергает. И им весь вектор прерываний заполняется.
0
ответил выше
0
Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.
Как сделать context switch на STM32