Спасибо за развернутый топик.
Пожалуйста, прочтите это сообщение хотя бы до вопросов, оно многословное, просто потому, что поговорить не с кем.
Я в этой области не профессионал (разрабатываю ОС не за деньги), просто как-то попалась в руки книжка 1984г. издания Кейслер "Разработка ОС для малых ЭВМ", а я как раз изучал м/к Fujitsu и увидел, что параметры малых ЭВМ 70-х соответствуют одному камню, а воротили на них серьезные задачи. Ну я взял библиотеке книжки Шоу, Дейтела, скачал книжки Лябрусса, несколько исходников и написал на их основе ядро ОС, заточенное под F2MC, реализующее всего несколько функций: создание, запуск, приостановку и остановку задачи, захват и освобождение счетного семафора.
При разработке ставил следующие требования:
1. Минимальное время запрещения прерывания системными задачами.
2. Минимальное использование ОЗУ
3. Возможность освобождения семафора из-под прерывания.
4. Минимальное время вызова задачи, висящей на семафоре при возникновении события.
5. Возможность round-robin.
6. Динамические приоритеты.
Результат:
1. Макс. время запрещения прерываний - 30 тактов (<2мкс на 16 МГц)
2. Использование ОЗУ - 52 байта на задачу + стек задачи.
3. есть, прерывание может возникнуть даже во время обработки системной очереди на выполнение, освободить семафор, т.е. взять задачу из очереди на ресурс и поставить в очередь на выполнение, при макс. приоритете новая задача запустится первой.
4. Макс. время запуска ок. 5мкс.
5,6 - есть.
Требует ок. 15% проц. времени при 25 задачах.
Отдельный системный стек.
Конечно, система не идеальна (строго говоря, и не ОСРВ, впрочем, как и uCOS)
1. Ограниченное количество задач (до 29) - просто в ядре м/к имеется 32 банка РОН (все равно расчитывалась на внутр. ОЗУ, а его объем в Fuji мал: обычно 2-4 кБ).
2. Нет контроля за инверсией приоритетов и взаимной блокировкой (и вообще не ясно, как это сделать малой кровью при динамических приоритетах).
3. Нет встроенных сервисов типа таймеров, очередей и т.д. (можно реализовать семафором и спец задачей на очереди) - просто руки не дошли.
4. Очередь семафоров сделана по принципу FIFO - чтобы занимала меньше времени на обработку.
В процессе работы появились некоторые вопросы:
1. Как запускать обработчики таймеров в системе с фиксированным количеством задач? Знаю несколько решений, однако не знаю, какое наилучшее.
2. Какой набор примитивов ядра достаточен?
Поскольку эту задачу я делаю на досуге, в фоновом режиме, есть время почитать о разных методах и подходах к анализу моделей (математика кое-какая) и реализации. Попробовать разные решения - у всех свое хобби: кто-то модели самолетов делает, кто-то в машине копается, я вот про ОС статьи читаю.
Сейчас появилось много микроконтроллеров с ядром ARM7, поэтому я начал писать ОС, заточенную чисто под них.
Требования:
1. Минимальное время запрещения прерывания.
2. Минимальное использование памяти ОЗУ (должна работать с 20-ю задачами на ADuC 7020 - 8 кБ).
3. Жесткое реальное время - можно рассчитать время реакции (может быть и большИм, главное - предсказуемым).
Сразу воникли вопросы по архитектуре и реализации:
1. Основной вопрос по реализации: Как вызывать диспетчер? В Fuji я использовал для этого специальное отложенное программное прерывание с наименьшим приоритетом: т.е., например, в обработчике прерывания освобождался ресурс, задача из очереди на семафор ставилась в очередь на выполнение и выставлялся флаг отложенного прерывания. При выходе из обработчика система сразу заходила в обработчик этого отложенного прерывания т.е. диспетчер. Также флаг мог выставляться из-под прерывания 1 мс таймера с наивысшим приоритетом.
Как сделать это на ARM непонятно: использовать инстр. SWI? - она не отложенная, использовать программное выставление одной из линий прерывания - вообще ерунда какая-то.
Может сделать диспетчер не в обработчике прерываний, а задачей с макс. приоритетом? Это заметно увеличит время его запуска, что важно в обработчиках прерываний. Есть какие-либо советы на этот счет?
2. Сейчас я реализовал следующий алгоритм приоритетов, считаю идею красивой: приоритеты могут иметь значение от -8.192 до +8.192, в порядке уменьшения. Отр. приоритеты - статические, положительные приоритеты - динамические, уменьшаются до -1 и останавливаются. 0 - отдельно, мин.приоритет вообще(статический). Т.о. в системе может быть полностью с динамич. или полностью стат. приоритетами, или и теми и др. (например, одни - для драйверов, другие - для задач пользователя). Какие недостатки? Следует ли повышать динам. приоритет задачи, если она стоит в очереди к ресурсу? Как лучше организовать увеличение динам. приоритета - при каждом запуске диспетчера или по таймеру? (сейчас сделано по таймеру, типа, для deadline monotonic analisys).
3. Захват и освобождение ресурса сделаны по следующему принципу: сортировка очереди происходит при постановке ресурса в очередь, поскольку опыт показал, что возможность освобождения ресурса из-под прерывания очень удобна, поэтому там все должно быть уже отсортировано и время минимально. Для этого реализованный алгоритм сортировки подразумевает, что очередь может изменяться в момент сортировки: например, сработало прерывание и освободило этот ресурс. Или сработало прерывание, освоб. др. ресурс -> запустилась ожидающая его задача с более высоким приоритетом, и захватила рассматриваемый ресурс (или встала в сортируемую очередь к нему). Где можно почитать о подобных методах? Обычные алгоритмы сортировки подразумевают, что очередь статична.
4. Следует ли создавать для системных процессов и драйверов отдельную очередь на выполнение для уменьшения времени отклика?
5. Минимальный набор примитивов для микроядра? (в т.ч. посмотрю Java)
6. Алгоритм запуска системных обработчиков, если задачи исполняются из ПЗУ? т.е. новую задачу создавать нельзя. Пример: обработчик таймера - досчитывает в прерывании, выкидывается на выполнение, а куда? Большинство решений предполагает системный процесс с макс. приоритетом, который стоит на семафоре к очереди ф-ий обр. вызовов: как только появляется новая ф-я он ее вызывает и выполняет. Недостаток - кол-во параллельно выполняемых ф-ий равно кол-ву зарезервированных сист. процессов. Невозможно менять приоритет обработчика таймера (всегда макс.). Хотя было бы удобно, чтобы обработчик таймера наследовал приоритет запустившего процесса.
В некоторых системах, насколько я знаю в WinCE, СМХ есть HLL - hardware link layer - фактически, в ф-ии обработки прерывания разрешаются прерывания, при этом нет повторной входимости и т.п.
В PORTOS идея в том, что существует очередь т.н. приоритетных функций, наследующих приоритет, которая является чем-то вроде отдельной вытесняющей не round-robin ОС на системном обработчике (склоняюсь к этому решению). Может посоветуете что-нибудь получше?
7. В литературе обычно рассматриваются протоколы захвата/освобождения ресурсов для единственного ресурса. Какие использовать в других случаях, например, управления памятью?
8. В своих статьях специалисты ф. GreenHill пишут, что в их ОС прерывания в системных процессах не запрещаются никогда. Как это реализовано?
Цитата(merk0 @ May 6 2005, 17:45)
Мое мнение в результате опыта разработки
Хорошая ртос это
1. реализованная на C++
2. четкий и компактный HAL
3. Нечто вроде микроядра с релизацией подкачки компонент ядра и других компонент оси
4. Многозадачность вытесняющая, с динамическими приоритетами
5. Синхронная - листенеры(хуки) и асинхронная активация(события) кода
6. Разделение ресурсов методом вроде синхронизирующих механизмов java. Вообще вычислительная модель java - видится как минимальная но полная. То есть ее и надо посмотреть в первую очередь.
7. Хорошая защита системы от "лома". То есть разделение прав доступа задач и тредов к программным и физическим обьектам.
8. Проблемы устойсчивости - то есть упавшая задача не должна обрушить систему целиком. Вопросы утилизации ресурсов занятых упавшей задачей и все такое.
9. Реализация "стандартных" протоколов и драйверов, вроде компортов, тср/ip и проч
ответы по пунктам для микроконтроллеров:
1. Часто среды разработки для микроконтроллеров не поддерживают С++.
2. согласен, осталось выбрать соотв. набор функций.
3. Вещь полезная, но в случае м/к лучше организовать бутлоадер с выходом в сетевой протокол и грузить все ОС и приложения в сборе - при работе из ПЗУ все равно динамически подгружать/выгружать толком не получится.
4. Вытесняющая - совершенно верно, причем вытеснение происходит по событию, а не по таймеру, динамические приоритеты - вещь трудно прогнозируемая, они требуют значительных ресурсов на реализацию протоколов захвата/освобождения ресурсов, впрочем, см. выше.
5. Само собой.
6. Спасибо за наводку - посмотрю.
7. Механизмы контроля памяти без MMU требуют больших накладных расходов и специализированных средств разработки приложений. Вопрос важный, но я пока не знаю, как его красиво решить. Сейчас я сосредоточился на примитивах для ядра.
8. Это вытекает из предыдущего пункта.
9. важно, но не главное для архитектуры.
Цитата
Вообщем тема слишком большая...замечу что просто исследование чужих исходников - часто просто потеря времени. Вы не заметите узких мест только по тексту и "поймете" работу такого софта очень приблизительно.
А часто и нет. Мне часто достаточно идею понять.
Цитата
Вообще архитектуру ртос надо анализировать и формулировать на уровне системного анализа и математики кое какой...а как там пишут ртос отдельные авторы... все равно что изучать архитектуру зданий по конструкции избушек в деревне.
Если провести эту аналогию дальше, то я пытаюсь строить коттедж, а не аквапарк ;-)
Насчет изучения - вы, наверное, никогда не занимались архитектурой жилых помещений.
Изучение избушек полезно:
во-перых, можно изучать традиции зодчества в данном регионе - можно по теор. правилам спроектировать очень неудобное здание.
во-вторых, можно посмотреть реализацию некоторых идей, встречаются очень красивые решения.
в-третьих, называть Integrity или eCOS или PORTOS избушками некорректно.
в-четвертых, все избушки в основе имеют какой-то план.
в-пятых, если избушка была неудобна - пристройки сразу бросаются в глаза.
в-шестых, прогулки на свежем воздухе вообще полезны :-)