Привет, я новичок в RTOS, и почти в каждом документе, который я читаю, указывается, что задачи должны быть в бесконечном цикле, но ни в одном не говорится, почему. Кто-нибудь может помочь объяснить это? Спасибо
Почему задачи RTOS должны выполняться в бесконечном цикле?
Ответы (3)
Они этого не делают, но если функция задачи выполняется до завершения, задача завершается.
Возможно, вы могли бы создать экземпляр новой задачи выполнить до завершения каждый раз, когда она необходима, но создание экземпляра задачи требует много времени и потенциально недетерминировано, поэтому не подходит для жесткого реагирования в реальном времени. Более эффективно и быстро реагировать на задачу, ожидающую некоторого блокирующего объекта, такого как событие, семафор или таймер, чтобы она могла реагировать детерминировано каждый раз, когда это требуется. С другой стороны, если у вас много разных задач не в реальном времени, которые нужно запускать только изредка, шаблон выполнение до завершения может сэкономить ресурсы.
Однако по крайней мере одна задача должна выполняться на неопределенный срок - если все просто остановится, ваша система ничего не будет делать до тех пор, пока питание не будет выключено или не будет сброшено (например, с помощью сторожевого таймера).
Реализации RTOS различаются, вам нужно будет проверить, как ваша RTOS обрабатывает функции завершения потока. Вам может понадобиться явный вызов завершения, чтобы убедиться, что ресурсы освобождены ядром.
Если у вас есть система, которая нуждается в некоторой форме контролируемого корректного завершения работы, вам не нужно кодировать задачи как бесконечные циклы, а иметь условный выход из цикла, чтобы задача могла завершаться по запросу, например;
while( (event_flags & TERMINATE) == 0 )
{
event_flags = eventWait( WAIT_FOREVER ) ;
// handle events
...
}
Я не думаю, что будет совершенно правильно сказать, что «задача RTOS должна быть бесконечным циклом». Я думаю, что более правильным утверждением будет то, что «для многих RTOS задача не должна возвращаться». Причина этого в том, что планировщик RTOS, который первоначально вызывает задачу, не предназначен для обработки возврата из задачи. Если задача вернулась, планировщик RTOS может сообщить об ошибке.
Я могу предположить несколько причин, по которым многие планировщики RTOS не обрабатывают возвраты от задач. Во-первых, бесконечный цикл — наиболее типичный тип задач, реализуемых во встраиваемых системах. Задача, которая заканчивается, встречается гораздо реже. Во-вторых, планировщик RTOS, возможно, должен быть более сложным, чтобы обрабатывать возвращаемые задачи. В-третьих, разработчик ОСРВ, возможно, не хотел предполагать, что следует делать, когда задача возвращается, и вместо этого он хочет, чтобы разработчик задачи явно вызывал соответствующую процедуру завершения задачи.
Бесконечный цикл — не единственное решение для многих ОСРВ, которые не позволяют возвращать задачи. ОСРВ может предоставлять процедуру завершения задачи, которая удаляет задачу из списка задач, чтобы она больше никогда не планировалась. Если задача вызывает процедуру завершения задачи, то задача не обязательно должна быть бесконечным циклом, и она также не вернется к вызывающей стороне. (т. е. процедура завершения задачи RTOS не возвращается, поэтому задача, вызвавшая ее, также не возвращается.) Например, во FreeRTOS есть vTaskDelete(), а в uC/OS-II есть OSTaskDel() для удаления задач, которые не являются бесконечными циклами.
Бесконечный цикл является распространенным типом задач во встроенных системах, потому что многие встроенные системы просто делают одно и то же снова и снова. Многие встроенные системы отличаются от ПК тем, что с ними не взаимодействует пользователь, запуская и завершая различные задачи или приложения.
В обычной реализации языка C, которая поставляется вместе с любой GPOS (операционной системой общего назначения), такой как Linux, Windows, Mac OSX, библиотека времени выполнения C отвечает за инициирование задачи (может быть вызвана как поток/процесс в контексте GPOS), а также как сборщик, когда задача заканчивается.
Это означает, что crt (среда выполнения C) вызовет main()
задачи, чтобы инициировать ее, и когда задача вернется с оператором return
, управление будет передано обратно crt ОС.
В RTOS, хотя вы можете программировать, используя язык C, нет конкретной реализации crt как таковой. Функция «Запуск» (обычно написанная на ассемблере) вызывает main. Однако этот код запуска не имеет механизма для сбора возвращаемого значения задачи, и поэтому задача должна выполняться в бесконечном цикле, чтобы сохранить управление внутри самой задачи. Если нет, у CPU/MCU не будет обратного адреса для перехода.
Однако задачу можно завершить с помощью API управления задачами, предоставляемого RTOS. в этом случае управление перейдет к коду, вызвавшему task_kill()
(репрезентативный) API из RTOS.