haker_fox 60 13 декабря, 2006 Опубликовано 13 декабря, 2006 · Жалоба Здравствуйте! Такая вот проблема. Использую ОС scmRTOS на ATmega16. Создано два процесса. Первый: работа с USART, второй - с ЖКИ. Проблема: если во втором процессе применить цикл вида while(PINB & (1 << KEY0)); , то первый процесс не работает. Если цикл исправить на такой while(PINB & (1 << KEY0)) Sleep(50/OS_SWITCH_TASK); то все ок. В этом цикле мы ждем нажатия некой кнопки и в это время первый процесс не работает. При нажатии на кнопку (т.е. когда происходит выход из цикла), первый процесс начинает абсолютно нормально работать. Сложилось впечатление, что если в задаче (процессе) применен бесконечный цикл, то все остальные процессы "падают" до тех пор, пока это цикл не прекратится. Доку перечитал. Не нашел никаких комментариев на эту тему. Сам сообразить, в чем дело, не могу. Прошу помощи у бывалых. Заранее спасибо! Детали: МК ATmega16, кварц 16MHz Время тика ОС 4.096 мс (TCCR0 = 0x04;) Версия ОС 1.10 Компилятор WinAVR 20060421 На всякий случай прикладываю некоторые файлы своего проекта. WAKE_RTOS.rar Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sergeeff 1 13 декабря, 2006 Опубликовано 13 декабря, 2006 · Жалоба Ну тут все очень просто. Чтобы могли крутиться другие процессы, надо чтобы "скоростной" процесс дал им такую возможность - грубо говоря "приспнул" (пардон за жаргон) на некоторое время. Именно это и делает функция Sleep. Без нее процесс никому управление и не отдаст. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Terminator 0 13 декабря, 2006 Опубликовано 13 декабря, 2006 · Жалоба Ну тут все очень просто. Чтобы могли крутиться другие процессы, надо чтобы "скоростной" процесс дал им такую возможность - грубо говоря "приспнул" (пардон за жаргон) на некоторое время. Именно это и делает функция Sleep. Без нее процесс никому управление и не отдаст. Я почему-то считал, что в scmRTOS вытесняющая многозадачность ... Невнимательно читал мануал? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sergeeff 1 13 декабря, 2006 Опубликовано 13 декабря, 2006 · Жалоба Вытесняющая. Но надо же дать возможность другим процессам вытеснить текущий. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
spf 0 13 декабря, 2006 Опубликовано 13 декабря, 2006 · Жалоба Я почему-то считал, что в scmRTOS вытесняющая многозадачность ... Невнимательно читал мануал? Вытесняющая, но вытесняет тот процесс, у кого приоритет выше. Если процесс с наивысшим приоритетом будет крутиться бесконечно, то все остальные будут курить бамбук... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
haker_fox 60 13 декабря, 2006 Опубликовано 13 декабря, 2006 · Жалоба Я почему-то считал, что в scmRTOS вытесняющая многозадачность ... Невнимательно читал мануал? Вытесняющая, но вытесняет тот процесс, у кого приоритет выше. Если процесс с наивысшим приоритетом будет крутиться бесконечно, то все остальные будут курить бамбук... Так чтоже получается, любой процесс может угробить всю ОС простым зацикливанием. И как быть? Оооочень внимательно программировать? И как опеределить, сколько может такой цикл крутиться? Чутье мне подсказывает, что не более, чем один тик ОС. В моем случае 4 мс. Так ли это? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
spf 0 13 декабря, 2006 Опубликовано 13 декабря, 2006 · Жалоба Вытесняющая, но вытесняет тот процесс, у кого приоритет выше. Если процесс с наивысшим приоритетом будет крутиться бесконечно, то все остальные будут курить бамбук... Так чтоже получается, любой процесс может угробить всю ОС простым зацикливанием. И как быть? Оооочень внимательно программировать? И как опеределить, сколько может такой цикл крутиться? Чутье мне подсказывает, что не более, чем один тик ОС. В моем случае 4 мс. Так ли это? Не совсем так. Программирование под OS несколько отличается от "обычного" программирования. 1. Работа должна выполняться на основе "событий". Никаких зацикливаний быть не должно. 2. Когда процессу делать нечего он должен отдать управление, управление будет передано тому, которому есть что делать. Чутье не то чует, тик OS нужен только для таймера OS. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
haker_fox 60 13 декабря, 2006 Опубликовано 13 декабря, 2006 · Жалоба Вытесняющая, но вытесняет тот процесс, у кого приоритет выше. Если процесс с наивысшим приоритетом будет крутиться бесконечно, то все остальные будут курить бамбук... Так чтоже получается, любой процесс может угробить всю ОС простым зацикливанием. И как быть? Оооочень внимательно программировать? И как опеределить, сколько может такой цикл крутиться? Чутье мне подсказывает, что не более, чем один тик ОС. В моем случае 4 мс. Так ли это? Не совсем так. Программирование под OS несколько отличается от "обычного" программирования. 1. Работа должна выполняться на основе "событий". Никаких зацикливаний быть не должно. 2. Когда процессу делать нечего он должен отдать управление, управление будет передано тому, которому есть что делать. Чутье не то чует, тик OS нужен только для таймера OS. А если в моем процессе будет такого рода цикл? for(i = 0; i < 1024; i++) Array[i] = log(c); Пример привел чисто для примера... Тоже получается зацикливание... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
amusin 0 13 декабря, 2006 Опубликовано 13 декабря, 2006 · Жалоба Кстати, сменил приоритет процесса с зацикливанием на более низкий, все работает... Теперь буду знать это... В этом случае, если вы захотите использовать хук задачи Idle, то он не будет выполняться. Кроме того, длительная работа более приоритетной задачи отложит обработку нажатия кнопки (или что там на пине). Насколько это критично, решать вам. Конкретно по вашему случаю. Если ваша задача должна выполнить что-то по внешнему событию, то можно поступить 2 путями: 1. Если отработать нужно срочно (похоже, что у вас так), то сажаете его на прерывание. В ISR шлете семафор задаче. 2. Еще один подход - "поллить" сигнал с таймаутом (что вы и сделали, когда вставили sleep()). Приоритеты задач - это не та штука, которой вертят, "потому что работает". Не обижайтесь, но у вас есть непонимание работы ОСРВ. Документация на scmRTOS хорошая, но, возможно, для новичка (в ОС) стоит прочитать книгу Лябруса, хотя бы первые главы, в которых написано об общих принципах работы ОС: как должен быть организован код задачи, о приоритетах. Где-то в сети был перевод на русский нескольких глав. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
haker_fox 60 13 декабря, 2006 Опубликовано 13 декабря, 2006 · Жалоба Кстати, сменил приоритет процесса с зацикливанием на более низкий, все работает... Теперь буду знать это... В этом случае, если вы захотите использовать хук задачи Idle, то он не будет выполняться. Кроме того, длительная работа более приоритетной задачи отложит обработку нажатия кнопки (или что там на пине). Насколько это критично, решать вам. Конкретно по вашему случаю. Если ваша задача должна выполнить что-то по внешнему событию, то можно поступить 2 путями: 1. Если отработать нужно срочно (похоже, что у вас так), то сажаете его на прерывание. В ISR шлете семафор задаче. 2. Еще один подход - "поллить" сигнал с таймаутом (что вы и сделали, когда вставили sleep()). Приоритеты задач - это не та штука, которой вертят, "потому что работает". Не обижайтесь, но у вас есть непонимание работы ОСРВ. Документация на scmRTOS хорошая, но, возможно, для новичка (в ОС) стоит прочитать книгу Лябруса, хотя бы первые главы, в которых написано об общих принципах работы ОС: как должен быть организован код задачи, о приоритетах. Где-то в сети был перевод на русский нескольких глав. Что Вы... я нисколько не обижаюсь, ибо пока действительно не очень пониаю ОСРВ... но хочу научиться... Ну хорошо, с кнопкой ясно. Но как быть с приведенным ниже примером, ведь там тоже зацикливание? Кстати, последнюю строку своего сообщения (вы ее в цитату взяли) я убрал, потому что спустя минут 10 после запуска все накрылось. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
IEC 0 13 декабря, 2006 Опубликовано 13 декабря, 2006 · Жалоба А в вашем привере цикл можно разбать на несколько подциклов с небольшой длительностью выполнения и периодически передавать управление (Sleep). Все зависит от срочности выполнения цикла. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
spf 0 13 декабря, 2006 Опубликовано 13 декабря, 2006 · Жалоба Ну хорошо, с кнопкой ясно. Но как быть с приведенным ниже примером, ведь там тоже зацикливание? В примере не зацикливание (бесконечный цикл, цикл ожидания медленноного процесса и т.п.), а рабочий, нужный цикл. Он выполняется вполне определенное время, в это время процессор не "толчет воду в ступе", а занимается необходимым делом. Всякие кнопки и т.п. должны обрабатываться по прерываниям или таймерам. Зашел в прерывание (проснулся от таймера), быстро все сделал, если есть нажатие - сформировал событие (флаг, семафор ) и отдал управление (уснул) до следующего момента проверки кнопки. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Wild007 0 13 декабря, 2006 Опубликовано 13 декабря, 2006 · Жалоба ИМХО в основном цикле "влет" проверять состояние "кнопки" и переходить куда надо :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
IgorKossak 0 13 декабря, 2006 Опубликовано 13 декабря, 2006 · Жалоба haker_fox, Вы писали, что у Вас два процесса: UART и индикатор. Не вижу никаких проблем в том, чтобы применять цикл в процессе индикатора если он менее приоритетный, чем UART. Если же процесс UART большую часть времени находится в ожидании событий от его же прерываний (в этом случае они должны обрабатываться ОС, чтобы влечь за собой переключение контекста), то он проснётся сразу же как только возникнет такое событие, обработает его и снова уснёт передав управление процессу индикатора. В Вашем случае процесс индикатора является как бы фоновым и будет тут же вытеснен процессом UART как только наступят соответствующие события. Этим как раз и отличается вытесняющая ОС от кооперативной. Вам не нужно делать принудительного слипа в цикле (если конечно не хотите сэкономить электроэнергию, в этом случае большую часть времени система будет находиться в процессе Idle). И уж тем более не нужно изощряться с машинами состояний. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
amusin 0 13 декабря, 2006 Опубликовано 13 декабря, 2006 (изменено) · Жалоба "cпустя минут 10 после запуска все накрылось." Посмотрел ваш код, вложенный в первое сообщение. В задаче TUserLoop после выхода из цикла while счетчик команд попадет в новый цикл - for (;;) и из него уже не выйдет. Причем, т.к. вы установили приоритет этой задачи выше, чем у задачи обработки пакета по uart, то последняя не получит управление, если внутри методов класса Lcd нет вызовов системных методов. В scmRTOS вызовом sleep (wait etc) вы позволяете ("разрешаете") менее приоритетным _задачам_ сделать их работу. Планировщик, если надо, отберет у задачи управление и без ее "разрешения". В кооперативных ОС вызовом sleep (wait etc) вы отдаете управление _планировщику_, без этого перепланирование невозможно. PS. Заметил, что вы шлете каждый принятый символ в задачу. Этот подход вполне "законен", но не лучший. На каждый принятый символ производится вызов шедулера, время работы которого измеряется десятками микросекунд. При высоких скоростях обмена по uart процессор только и будет заниматься тем, что "щелкать" контекстом. Поэтому, для уменьшения расходов времени на перепланирование, следует принимать пакет в буфер в ОЗУ, а по окончании приема - семафорить в задачу или посылать ей указатель на принятое сообщение (если есть очередь сообщений). Разгребать пакет в задаче. Насколько я понял, у вас протокол wake. Так вот, протокол уровня serial line (байт-стаффинг, фрейминг) разумно перенести в ISR приема по uart, а разбор команды (если она принята корректно) вести в задаче. Изменено 13 декабря, 2006 пользователем amusin Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться