AHTOXA 14 20 февраля, 2020 Опубликовано 20 февраля, 2020 · Жалоба В IdleProc нельзя вызывать ни sleep(), ни другие сервисы оси, на то она и IdleProc :-) Ну чудес-то не бывает. Простым изменением участка кода программы нельзя запретить/разрешить прерывания. Где-то вы их запрещаете. При переключении процесса происходит сохранение контекста одного процесса, и восстановление другого. Раз в одном процессе прерывания работают, а в другом - нет, то запрет происходит именно при переключении контекста. Вот и всё. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
abi 0 25 февраля, 2020 Опубликовано 25 февраля, 2020 · Жалоба On 2/20/2020 at 1:23 PM, AHTOXA said: Раз в одном процессе прерывания работают, а в другом - нет, то запрет происходит именно при переключении контекста. Нашел причину. Попробую объяснить. Проект настроен на прямую передачу управления, т.е. #define scmRTOS_CONTEXT_SWITCH_SCHEME 0. Для примера запускаем проект с одним процессом. template<> void TProc1::exec() { for(;;) { sleep(10); delay_ms(500); } } 1. Заходим в sleep(10), выставляем timeout, сбрасываем флаг готовности процесса и выполняем перепланировку Kernel.scheduler(), т.к. рабочий процесс один и он ушел в спячку, система переключится на процесс IdleProc. 2. Периодически через заданный интервал времени от системного таймера возникают прерывания, в обработчике функция Kernel.system_timer() проверяет флаг готовности процесса Proc1. Если готовности нет, прерывание завершается без перепланировки и система продолжает оставаться в IdleProc. Тут отмечу, что выход из обработчика прерывания без перепланировки выполняется командой RETI, контроллер прерываний при этом сбрасывает флаг в PMIC.STATUS. Далее контроллер готов к выполнению других прерываний, если они есть в очереди или когда возникнут новые. 3. Если флаг готовности процесса Proc1 установлен, в обработчике прерывания системного таймера произойдет перепланировка процессов в функции os_context_switcher. Тут немного подробнее, при вызове этой функции в RStаck процесса IdleProc запишется адрес возврата, в CStack сохранится SP, сохранятся состояние регистров, далее для выполнения Proc1, из стека Proc1 восстановится SP и регистры, т.е. все готово для продолжения выполнения этого процесса. В конце функции os_context_switcher выполняется команда RET, в результате которой попадаем сразу в Proc1 и продолжаем его выполнение. В итоге получается, что обработка прерывания осталась не завершена, команды RETI не было, флаг в PMIC.STATUS = 1, прерывания одного уровня работать не будут даже при SREG = 0x80. 4. Далее по коду в Proc1, функция delay_ms(500) отработает без прерываний, зайдет в sleep(10), в которой произойдет перепланировка, восстановится процесс IdleProc, а т.к. он был ранее сохранен в обработчике прерывания, завершит его код с командой выхода RETI, и прерывания снова будут выполняться. Подскажите, пожалуйста, может есть какие мысли? Пока думаю над таким вариантом: в конце функции os_context_switcher сделать проверку флага PMIC.STATUS, если флаг установлен, то выполнять выход командой RETI, если нет, то RET. Но тут есть один момент, IdleProc при возобновлении в обработчике прерывания будет завершать его командой RETI, т.е. прерывание уже было завершено ранее командой RETI, и тут снова RETI. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 14 25 февраля, 2020 Опубликовано 25 февраля, 2020 · Жалоба Хм. Очень интересно. Неужели это косяк в порте под AVR? Или всё же это особенность работы XMEGA... К сожалению, я не знаком с АВР-ками, поэтому не знаю, что посоветовать. Возможно, @dxp что-то подскажет. Если вспомнит, конечно :-) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dxp 34 26 февраля, 2020 Опубликовано 26 февраля, 2020 · Жалоба 9 часов назад, AHTOXA сказал: Возможно, @dxp что-то подскажет. Если вспомнит, конечно :-) Почти всё забыл (17 лет уж тому), но насколько ещё что-то помню, в тех AVR не было никиких PMIC и система прерываний была одноуровневая. Потом портом под AVR занимался другой человек, может он бы что-то мог сказать, но, к сожалению, он давно не выходит на связь. Я даже не в курсе, что включает поддержку XMEGA и есть ли она там. P.S. Насколько помню, прямую передачу управления использовать не рекомендуется, этот способ только если по-другому уже никак. Неужели в xmega нельзя найти свободное прерывание? В примерах даже обычные AVR через прерывание передают управление. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexG 1 11 марта, 2020 Опубликовано 11 марта, 2020 · Жалоба У меня есть стабильно работающий порт ScmRTOS 4.0 на Xmega/IAR и нестабильный порт ScmRTOS 5.1 (бросил разбирательства когда проект с 4.0 заработал). Также, если поискать, были чужие порты на Xmega/GCC. Могу выложить, если кому-то нужно. Отличий от портов на обычные AVR там много. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 14 11 марта, 2020 Опубликовано 11 марта, 2020 · Жалоба Конечно выкладывайте, думаю, кому-нибудь непременно пригодится. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexG 1 14 марта, 2020 Опубликовано 14 марта, 2020 · Жалоба Выкладываю фрагмент из одного из текущих проектов. Внутри 4.00 рабочая и 5.1.0 - не очень. scmrtos4xmega.zip Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться