Только разрабатывая все с нуля можно ощутить весь спектр приятных ощущений от вопросов, которые ты должен решить. И этот путь позволит глубже разобраться.
Рефакторинг чужой ОС даст только ответ на вопрос "как это работает".
А между "знаю как работает" и "могу это сделать" огромная пропасть.
Не обязательно, но желательно, чтобы расставить все точки. Если есть в комментариях замечания, вопросы и т.п. Или я вижу, что меня поняли не так, как я это планировал - я лучше отвечу.
первое переключение контекста отличается от последующих, но ведь чтобы этого избежать достаточно добавить понятие инициализация контекста
Согласен, не подумал вынести это в отдельный термин. Может позже исправлю.
Но в варианте, который я принял в итоге (решение 3) это и не требуется.
В run to completion они(задержки) не нужны :). Задача вызывается только тогда, когда она нужна.
Это получается таблица событий. Это не то, что мне нужно.
Я имею ввиду, вот к примеру, пришло внешнее прерывание от АЦП и нужно тут же посчитать что-то. Понятно, что в прерывании считать не надо, иначе заблокируем все, надо передать событие задаче. Обычно так и делается, прерывание просто генерит событие, тут же вызывается планировщик и запускается нужная задача для обработки события, а как это у вас будет происходить?
Если задача 1 ждет семафор, а задача 2 выполняется, то пока квант времени задачи 2 не закончится - задача 1 не получит управление, даже если семафор установлен.
Смена контекста из прерывания еще не реализована. Но она будет.
Но с другой стороны можно взять готовую ОС например тот же Minix, и модифицируя ее понять как она работает.
Можно, но когда изучаешь что-то, разбирая уже готовое - ты можешь упустить многие нюансы, приняв мысли другого автора за чистую монету, даже не подумав "а почему именно так". А когда "переживешь" этот момент - будешь глубже это все понимать.
Кроме того вы смешиваете конкретный микроконтроллер и архитектуру ОС.
Как раз AVR не имеет ничего такого в своей архитектуре, чтобы ОС получилась исключительно для AVR. В них есть только стек и таймер, что есть во всех микроконтроллерах без исключения. А вот если писать сразу на ARM, то там и отдельный таймер для ОС есть, и аппаратные приблуды для стека, и т.д. Что и наложит свой отпечаток на ОС.
Портировать эту ОС на любую архитектуру - без проблем, а вот ОС для ARM обратно - уже будут проблемы.
Единственное влияние архитектуры, которое я здесь зацепил, это сохранение регистра "SREG" в контекст задачи. Содержимое контекста в принципе будет разным для каждой архитектуры. Банально количество регистров общего назначения будет отличаться.
А привязываться к конкретной архитетуре при изучении принципов планирования, это не очень хорошо.
Про планировщик это была скорее шутка, если привязка планировщика к архитектуре это: "не делать алгоритм планирования", то это не похоже на привязку XD
Своя ось может быть чревата серьезными последствиями. Если вы как разработчик поступательно будете осваивать все более сложные и перспективные платформы, то от своей оси придется отказаться. Но отказаться будет трудно, жалко же потраченных сил.
Я нигде не писал, что я буду использовать ее в своей работе. Это домашний проект для изучения темы. Не более.
И вот вместо изучения всего этого богатства вы пилите свою ось.
И вот вместо того, чтобы писать на пайтоне, люди пишут на Си.
Я пилю свою ось, т.к. это моя профессия, и в то же время хобби.
Да и все известные сейчас ОС начинались с таких шагов. Разве нет?
Для начала нужно определиться что такое полноценная ОС, чтобы понимать до каких требований нужно дотянуться, собственно это и есть ТЗ. Конечно, если брать FreeRTOS как полноценную, то она просто не влезет, т.к. занимает килобайты. Но там много фич, от которых можно отказаться.
и инструкций косвенного доступа не хватает
Ну так регистровые пары XYZ есть, по памяти ходить можем, мне хватает)
А вообще на AVR невозможно сделать полноценную ОС только из-за того, что нет ничего для проверки переполнения стека. Ни прерываний, ни ловушек.
на ARM было бы интереснее
Как раз таки на AVR интереснее, т.к. там ничего нет. Хотя, у каждого свои интересы...
Сделал бы ОС для ARM - вместо вопросов "а зачем тебе ОС на AVR?" были бы "а зачем тебе такая слабая ОС на ARM"?
OS – это программная прослойка, позволяющая реализовать псевдо многопоточность
Да, именно прослойка. Прослойка между аппаратным обеспечением микроконтроллера и кодом, выполняющимся в рантайме. Прослойка, которая позволяет объединить эти две части и реализовать псевдо многопоточность. Все верно. Если мое определение отличается от данного в вашем фундаментальном труде - это не значит что я не понимаю что это и как работает.
Вот простите меня пожалуйста. Вы же сами посмеиваетесь над своим поспешным подходом. Но любой человек (да и не человек тоже), который собирается писать ОС, должен сначала понимать что это такое.
Я думаю, было бы полезнее, если бы была конкретная претензия ко мне, что я сделал не так. Вместо того, чтобы цепляться за мое определение, лучше укажите на то, где я допустил ошибку в проекте, что реализовал не так. Я буду рад если будет такое замечание.
сначала понимать что это такое
Я так понимаю, мое определение повлекло за собой ошибки в реализации. Если это так - укажите какие именно. Иначе - вы подтверждаете что не повлекло, и тогда я не понимаю вашу претензию.
Если я прочту этот фундаментальный труд, и изменю слова в определении - что-то изменится?
Если два человека знают как работает что-либо, и они объясняют это своими словами - в этом нет ничего плохого.
Заодно можно узнать о существовании целого ряда готовых RTOS для MK.
Я знаю ряд готовых RTOS для МК. Это не отвернуло меня от создания своей.
Опять же "зачем делать то, что уже сделано до нас?" - затем же, зачем учиться играть на муз инструменте и писать свою музыку.
Согласен, это лучше, если бы у меня была цель сделать что-то максимально оптимальное для AVR. А здесь же была цель именно сделать настоящую вытесняющую ОС. Не важно под какую архитектуру. AVR я выбрал, т.к.:
Их, с аппаратной точки зрения, я знаю лучше других архитектур, а значит я буду сконцентрирован только на ОС, а не изучении архитектуры;
Хотел сделать максимально простую вытесняющую ОС, которая поедет даже на AVR, т.к. если делать сразу под ARM - многие моменты по поводу оптимизации могут ускользнуть, т.к. там ресурсов хоть жеппой жуй. Такой себе челендж для меня;
Опять же, я уже отвечал на другие комментарии, цель этой ОС, в первую очередь - обучение.
Первым требованием к моей ОС была возможность вызывать в задачах тупые задержки "while", т.к. делать это в кооперативных ОС нельзя, и в "run to completion", если я правильно понимаю что это, тоже нельзя.
Ожидать что-то через сервисы ОС не всегда удобно. Как опытный пользователь кооперативной RTOS - я просто уже за*бался что-то ждать без "while", если нет требований к быстродействию.
Без "while" код начинает выглядеть ненаглядно, и не далеко уходит от использования конечного автомата в "main()" без использования ОС в принципе.
Ну и конечно же сделать вытесняющую ОС общего назначения мне банально было интереснее.
Можно сказать - мечта детства, сделать свой мини-компьютер на AVR, подключить дисплей, внешнюю память и т.п. Вот для этого мне и нужна была вытесняющая ОС общего назначения. Конечно, это не эффективно, если сравнивать с Ryzen 2600 и материнкой на X570. Но это просто домашний проект, ничего важного для посторонних людей. Это просто для души)
а зачем для микронтроллера не ОСРВ вытесняющая операционка?
А я в статье не написал что она "не ОСРВ". Правда и не написал, что она "ОСРВ"...
Потому что побоялся холиваров;
Я не смог найти четкого определения ОСРВ, чтобы мог уверенно ее так назвать.
После долгих поисков информации, я пришел к выводу, что ОСРВ - это просто ОС, для которой разработчик просто указывает время реакции ОС на изменения. То есть, время переключения контекста после установки семафора, например.
Вот когда доделаю - измерю время реакции, и, наверное, назову ее ОСРВ)))
У вас получается как в Винде, пока 1мс не пройдет, никакой реакции, верно я понял?
Нет, если задача должна чего-то дождаться, она может начать ждать семафор, я их реализовал. Тогда она перестает выполняться. И потом планировщик возобновит ее если кто-то установит этот семафор.
локальные переменные обычно хранятся на стеке. и уже оттуда помещаются в регистры
Локальные переменные не хранятся в стеке просто так. Либо я не понял что имеется ввиду)
Да, они могут попасть в стек в ходе выполнения функции, например, если нужно что-то сохранить, и выполнить другие манипуляции и этими же регистрами, но это зависит от компилятора.
И это хорошее замечание, которого я не учел, спасибо!
Как будет время - я разберусь с этим и обновлю статью, т.к. это может стать причиной переполнения стека и об этом нужно знать.
Это удивительно, и может показаться не очевидным, но разбираться, делая с нуля, шаг за шагом - полезнее, и в некотором смысле проще, чем разбирать код уже готовой ОС. Т.к. там:
Много ненужных фич, которые будут отвлекать;
Много оптимизаций, которые могут запутать;
Не понятная структура для того, кто еще не делал такого ни разу. Вот и я, не делал такого ни разу, поэтому решил сделать свое, чтобы разобраться.
Я так понимаю, вы сторонник идеи "зачем делать свое, если все сделано до нас".
Вот мне как раз таки становится грустно из-за этой идеи...
Т.к. из-за этого - мало кто знает что и как работает, и способны только бездумно копировать. И конечно же плодить статьи по ардуино, из разряда:
"Подключаете библиотеку, копируете мой код - и у ваш веб-сервер и дата центр готов."
Круто, конечно, оно работает, но мне от этого грустно(
И Ваш проект звучит - мне скучно и нечем заняться
Скучно и нечем заняться - это запускать Скайрим на тесте на беременность, что, кстати, уже было.
"разобраться, как это сделать" != "нечем заняться"
А если я портирую проект на PIC24 или ARM - что-то изменится? Вашу претензию удовлетворю, т.к. там памяти больше. А что еще хорошего будет?
У моего проекта было три цели:
Разобраться, как сделать вытесняющую ОС;
Сделать вытесняющую ОС для AVR;
Определить, насколько это целесообразно, использовать вытесняющую ОС на AVR, т.к. их действительно мало, но они есть.
Так вот:
Первый пункт выполнен;
Второй пункт выполнен, хоть, она еще и не доделана;
Третий пункт выполнен, считаю, что это весьма целесообразно.
Если вы считаете, что вытесняющая ОС для AVR - абсурд, то не сталкивались с моими задачами, например, когда тебе нужно сделать типовое устройство для коммутации нагрузки и т.д. В таких проектах не требуется много памяти, а вот многопоточность - ну капец как упростит код.
И я в статье нигде не писал, что создаю конкурента FreeRTOS, ThreadX, или буду ее рекомендовать для Automotive-разработчиков или Илону Маску. А как раз таки, указал, что это ради обучения и примера. Я ни в коем случае не рекламирую свой проект, я его приложил как доказательство, что все работает, и чтобы те, кому интересно, могли поиграться, если не нашли всех ответов в статье.
А по поводу:
мой КБ (конструкторское бюро) мне выдал PIC16 для 30К $ девайса. Все было сделано на ассемблере за 2 года, плюс 1 год потрачено на новую функциональность из-за нехватки памяти.
И я не понял, у чему это было упомянуто, но, думаю, ваше КБ делает что-то не так, если приняло такое решение.
Памяти всего 1 килобайт, переключаем, вытесняем, обрабатываем... А работать когда?
Я не понял в чем суть замечания.
Работаем во время кванта времени, который длится 1 мс, если хотите - меняете период прерывания таймера, и задаёте свой квант времени, вот и работаете. До 100 мкс ядро, 1000 мкс рантайм (можете задать 10 мс, тогда рантайм будет 10 000 мкс).
Памяти всего 1 килобайт
Каждая задача требует 35 байт для стека, значит, если у нас целых четыре задачи, то:
Целых 884 байта остается!
Даже если каждый таск будет вызывать 4 вложенных функции, это еще плюс 32 байта.
Только разрабатывая все с нуля можно ощутить весь спектр приятных ощущений от вопросов, которые ты должен решить. И этот путь позволит глубже разобраться.
Рефакторинг чужой ОС даст только ответ на вопрос "как это работает".
А между "знаю как работает" и "могу это сделать" огромная пропасть.
Не обязательно, но желательно, чтобы расставить все точки. Если есть в комментариях замечания, вопросы и т.п. Или я вижу, что меня поняли не так, как я это планировал - я лучше отвечу.
Согласен, не подумал вынести это в отдельный термин. Может позже исправлю.
Но в варианте, который я принял в итоге (решение 3) это и не требуется.
Я здесь не уловил мысль...
Что значит "у вас naked не работает"?
"Ассемблер" - а как переключить контекст без ассемблера?
"а давайте первый раз выйдем из прерывания и так далее" - можно подробнее, чтобы я понял, как ответить на вопрос?
Это получается таблица событий. Это не то, что мне нужно.
Если задача 1 ждет семафор, а задача 2 выполняется, то пока квант времени задачи 2 не закончится - задача 1 не получит управление, даже если семафор установлен.
Смена контекста из прерывания еще не реализована. Но она будет.
При чем здесь пиар?
В самом начале статьи написано, для чего я ее опубликовал.
Я был бы рад увидеть такую статью, когда сам начал, но не нашел, и написал ее сам, чтобы такие как я могли ее прочитать.
Можно, но когда изучаешь что-то, разбирая уже готовое - ты можешь упустить многие нюансы, приняв мысли другого автора за чистую монету, даже не подумав "а почему именно так". А когда "переживешь" этот момент - будешь глубже это все понимать.
Как раз AVR не имеет ничего такого в своей архитектуре, чтобы ОС получилась исключительно для AVR. В них есть только стек и таймер, что есть во всех микроконтроллерах без исключения. А вот если писать сразу на ARM, то там и отдельный таймер для ОС есть, и аппаратные приблуды для стека, и т.д. Что и наложит свой отпечаток на ОС.
Портировать эту ОС на любую архитектуру - без проблем, а вот ОС для ARM обратно - уже будут проблемы.
Единственное влияние архитектуры, которое я здесь зацепил, это сохранение регистра "SREG" в контекст задачи. Содержимое контекста в принципе будет разным для каждой архитектуры. Банально количество регистров общего назначения будет отличаться.
Про планировщик это была скорее шутка, если привязка планировщика к архитектуре это: "не делать алгоритм планирования", то это не похоже на привязку XD
Я нигде не писал, что я буду использовать ее в своей работе. Это домашний проект для изучения темы. Не более.
И вот вместо того, чтобы писать на пайтоне, люди пишут на Си.
Я пилю свою ось, т.к. это моя профессия, и в то же время хобби.
Да и все известные сейчас ОС начинались с таких шагов. Разве нет?
Для начала нужно определиться что такое полноценная ОС, чтобы понимать до каких требований нужно дотянуться, собственно это и есть ТЗ. Конечно, если брать FreeRTOS как полноценную, то она просто не влезет, т.к. занимает килобайты. Но там много фич, от которых можно отказаться.
Ну так регистровые пары XYZ есть, по памяти ходить можем, мне хватает)
А вообще на AVR невозможно сделать полноценную ОС только из-за того, что нет ничего для проверки переполнения стека. Ни прерываний, ни ловушек.
Как раз таки на AVR интереснее, т.к. там ничего нет. Хотя, у каждого свои интересы...
Сделал бы ОС для ARM - вместо вопросов "а зачем тебе ОС на AVR?" были бы "а зачем тебе такая слабая ОС на ARM"?
Да, именно прослойка. Прослойка между аппаратным обеспечением микроконтроллера и кодом, выполняющимся в рантайме. Прослойка, которая позволяет объединить эти две части и реализовать псевдо многопоточность. Все верно. Если мое определение отличается от данного в вашем фундаментальном труде - это не значит что я не понимаю что это и как работает.
Я думаю, было бы полезнее, если бы была конкретная претензия ко мне, что я сделал не так. Вместо того, чтобы цепляться за мое определение, лучше укажите на то, где я допустил ошибку в проекте, что реализовал не так. Я буду рад если будет такое замечание.
Я так понимаю, мое определение повлекло за собой ошибки в реализации. Если это так - укажите какие именно. Иначе - вы подтверждаете что не повлекло, и тогда я не понимаю вашу претензию.
Если я прочту этот фундаментальный труд, и изменю слова в определении - что-то изменится?
Если два человека знают как работает что-либо, и они объясняют это своими словами - в этом нет ничего плохого.
Я знаю ряд готовых RTOS для МК. Это не отвернуло меня от создания своей.
Опять же "зачем делать то, что уже сделано до нас?" - затем же, зачем учиться играть на муз инструменте и писать свою музыку.
Согласен, это лучше, если бы у меня была цель сделать что-то максимально оптимальное для AVR. А здесь же была цель именно сделать настоящую вытесняющую ОС. Не важно под какую архитектуру. AVR я выбрал, т.к.:
Их, с аппаратной точки зрения, я знаю лучше других архитектур, а значит я буду сконцентрирован только на ОС, а не изучении архитектуры;
Хотел сделать максимально простую вытесняющую ОС, которая поедет даже на AVR, т.к. если делать сразу под ARM - многие моменты по поводу оптимизации могут ускользнуть, т.к. там ресурсов хоть жеппой жуй. Такой себе челендж для меня;
Опять же, я уже отвечал на другие комментарии, цель этой ОС, в первую очередь - обучение.
Первым требованием к моей ОС была возможность вызывать в задачах тупые задержки "while", т.к. делать это в кооперативных ОС нельзя, и в "run to completion", если я правильно понимаю что это, тоже нельзя.
Ожидать что-то через сервисы ОС не всегда удобно. Как опытный пользователь кооперативной RTOS - я просто уже за*бался что-то ждать без "while", если нет требований к быстродействию.
Без "while" код начинает выглядеть ненаглядно, и не далеко уходит от использования конечного автомата в "main()" без использования ОС в принципе.
Ну и конечно же сделать вытесняющую ОС общего назначения мне банально было интереснее.
Можно сказать - мечта детства, сделать свой мини-компьютер на AVR, подключить дисплей, внешнюю память и т.п. Вот для этого мне и нужна была вытесняющая ОС общего назначения. Конечно, это не эффективно, если сравнивать с Ryzen 2600 и материнкой на X570. Но это просто домашний проект, ничего важного для посторонних людей. Это просто для души)
А я в статье не написал что она "не ОСРВ". Правда и не написал, что она "ОСРВ"...
Потому что побоялся холиваров;
Я не смог найти четкого определения ОСРВ, чтобы мог уверенно ее так назвать.
После долгих поисков информации, я пришел к выводу, что ОСРВ - это просто ОС, для которой разработчик просто указывает время реакции ОС на изменения. То есть, время переключения контекста после установки семафора, например.
Вот когда доделаю - измерю время реакции, и, наверное, назову ее ОСРВ)))
Нет, если задача должна чего-то дождаться, она может начать ждать семафор, я их реализовал. Тогда она перестает выполняться. И потом планировщик возобновит ее если кто-то установит этот семафор.
Спасибо за фидбек, рад, что кому-то что-то смог объяснить)
Я не уловил смысл. Где поискать и зачем?
"naked" точно убирает prolog и epilog, т.к. этот атрибут именно для этого и нужен.
А вот "inline" - я не уверен что все компиляторы делают все одинаково с ним, так что его я для этих целей использовать не рекомендую.
Только что проверил в этом же проекте - компилятор мне ничего не заинлайнил. Ему вообще все пофигу. Либо моя 8-битная avr-ка недостаточно старая)
Ну очевидно, что инлайнить функции, которые вызываются несколько раз, он точно не должен. Прям вот права иметь не должен.
Разве что речь о старых AVR, в которых не было стека, но я о таких не слышал)
Локальные переменные не хранятся в стеке просто так. Либо я не понял что имеется ввиду)
Да, они могут попасть в стек в ходе выполнения функции, например, если нужно что-то сохранить, и выполнить другие манипуляции и этими же регистрами, но это зависит от компилятора.
И это хорошее замечание, которого я не учел, спасибо!
Как будет время - я разберусь с этим и обновлю статью, т.к. это может стать причиной переполнения стека и об этом нужно знать.
Чтобы разобраться!
Это удивительно, и может показаться не очевидным, но разбираться, делая с нуля, шаг за шагом - полезнее, и в некотором смысле проще, чем разбирать код уже готовой ОС. Т.к. там:
Много ненужных фич, которые будут отвлекать;
Много оптимизаций, которые могут запутать;
Не понятная структура для того, кто еще не делал такого ни разу. Вот и я, не делал такого ни разу, поэтому решил сделать свое, чтобы разобраться.
Я так понимаю, вы сторонник идеи "зачем делать свое, если все сделано до нас".
Вот мне как раз таки становится грустно из-за этой идеи...
Т.к. из-за этого - мало кто знает что и как работает, и способны только бездумно копировать. И конечно же плодить статьи по ардуино, из разряда:
"Подключаете библиотеку, копируете мой код - и у ваш веб-сервер и дата центр готов."
Круто, конечно, оно работает, но мне от этого грустно(
Скучно и нечем заняться - это запускать Скайрим на тесте на беременность, что, кстати, уже было.
"разобраться, как это сделать" != "нечем заняться"
А если я портирую проект на PIC24 или ARM - что-то изменится? Вашу претензию удовлетворю, т.к. там памяти больше. А что еще хорошего будет?
У моего проекта было три цели:
Разобраться, как сделать вытесняющую ОС;
Сделать вытесняющую ОС для AVR;
Определить, насколько это целесообразно, использовать вытесняющую ОС на AVR, т.к. их действительно мало, но они есть.
Так вот:
Первый пункт выполнен;
Второй пункт выполнен, хоть, она еще и не доделана;
Третий пункт выполнен, считаю, что это весьма целесообразно.
Если вы считаете, что вытесняющая ОС для AVR - абсурд, то не сталкивались с моими задачами, например, когда тебе нужно сделать типовое устройство для коммутации нагрузки и т.д. В таких проектах не требуется много памяти, а вот многопоточность - ну капец как упростит код.
И я в статье нигде не писал, что создаю конкурента FreeRTOS, ThreadX, или буду ее рекомендовать для Automotive-разработчиков или Илону Маску. А как раз таки, указал, что это ради обучения и примера. Я ни в коем случае не рекламирую свой проект, я его приложил как доказательство, что все работает, и чтобы те, кому интересно, могли поиграться, если не нашли всех ответов в статье.
А по поводу:
И я не понял, у чему это было упомянуто, но, думаю, ваше КБ делает что-то не так, если приняло такое решение.
Я не понял в чем суть замечания.
Работаем во время кванта времени, который длится 1 мс, если хотите - меняете период прерывания таймера, и задаёте свой квант времени, вот и работаете. До 100 мкс ядро, 1000 мкс рантайм (можете задать 10 мс, тогда рантайм будет 10 000 мкс).
Каждая задача требует 35 байт для стека, значит, если у нас целых четыре задачи, то:
Целых 884 байта остается!
Даже если каждый таск будет вызывать 4 вложенных функции, это еще плюс 32 байта.
Ну тогда будет 852 байта.
Этого недостаточно для чего?
По-моему для всего за глаза...
Целью для меня была именно статья, а не проект. Если буду выкладывать эту ОС как релиз - заведу гит.
Та я уже уставший был когда публиковал, и картинку на скорую руку сделал, тольк опотом сообразил)
Отредактировать не мог, пока статью не опубликовали. Вот, опубликовали - сейчас и исправлю)
И спойлеры подправлю, т.к. в них нет названий...
Последнюю мы вытеснили, выбираем следующую, и она становится текущей)
Все понятно)