Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: TNeo: тщательно протестированная РТОС для Cortex-M0/M0+/M3/M4/M4F, PIC24/dsPIC, PIC32MX.
Форум разработчиков электроники ELECTRONIX.ru > Cистемный уровень проектирования > Операционные системы
Страницы: 1, 2
AlexandrY
Цитата(dimonomid @ Jan 21 2015, 14:29) *
Не плохие и хорошие, а подходящие или не подходящие для решения конкретной задачи.


"подходящие или не подходящие" - это, что, намек на существование объективности в этом вопросе?
Как по мне, то TNeo более похожа на неподходящие решение.

С удивлением только что узнал, что во FreeRTOS есть таки аналог Event group connection и это xQueueCreateSet
dimonomid
Цитата(AlexandrY @ Jan 22 2015, 13:03) *
"подходящие или не подходящие" - это, что, намек на существование объективности в этом вопросе?

Подходящие или неподходящие - это значит, что в одной ситуации отдельная задача на ресурс (типа вот "менеджер SPI шины") окажется более удачным решением, чем использование мютекса, а в другой ситуации - наоборот, мютекс будет более удачным решением.

Вы же говорите об отдельной задаче как о панацее, а о мютексах как о безусловном зле.

Цитата(AlexandrY @ Jan 22 2015, 13:03) *
Как по мне, то TNeo более похожа на неподходящие решение.

В TNeo, как и в TNKernel, вы можете применять любое решение: и мютекс, и отдельную задачу. И даже семафор, если вам очень хочется использовать его для блокировки ресурсов. Так что не совсем понятно, что вы имеете в виду под "TNeo более похожа на неподходящие решение".
ViKo
Здесь много разговора про мьютексы. В Keil CMSIS-RTOS RTX, например, есть и мьютексы, и семафоры, и события... Я использую мьютекс для ограничения доступа к образу изображения на ЖКИ, чтобы одна задача не стирала что-то, нарисованное другой. И у него нет владельца. Не вижу принципиальной разницы с семафором. Каждый автор сочиняет ОС, как хочет. Зачем же продвигать именно свою точку зрения, как истинно верную? Еще назывались "бинарные семафоры" - мьютексы, в отличие от "счетных семафоров". И т.д.
AlexandrY
Цитата(dimonomid @ Jan 22 2015, 11:52) *
Подходящие или неподходящие - это значит, что в одной ситуации отдельная задача на ресурс (типа вот "менеджер SPI шины") окажется более удачным решением, чем использование мютекса, а в другой ситуации - наоборот, мютекс будет более удачным решением.


Я ожидал услышать пример "удачного" применения мьютекса, и хоть какие-то аргументы говорящие об "удачности", и в сравнении конечно.

Цитата(dimonomid @ Jan 22 2015, 11:52) *
Вы же говорите об отдельной задаче как о панацее, а о мютексах как о безусловном зле.

Давайте не передергивать.

Цитата(dimonomid @ Jan 22 2015, 11:52) *
В TNeo, как и в TNKernel, вы можете применять любое решение: и мютекс, и отдельную задачу. И даже семафор, если вам очень хочется использовать его для блокировки ресурсов. Так что не совсем понятно, что вы имеете в виду под "TNeo более похожа на неподходящие решение".


Имел в виду, что TNeo слишком нефункциональна по сравнению с той же FreeRTOS.
Тогда хотя бы обосновать такой минимализм.
_Pasha
Мне вообще даже эти все разговоры про ртосы не нравятся rolleyes.gif
очень много шума из ничего. Как и оверхеда и бессмысленных оберток.
dimonomid
Цитата(AlexandrY @ Jan 22 2015, 15:16) *
Я ожидал услышать пример "удачного" применения мьютекса, и хоть какие-то аргументы говорящие об "удачности", и в сравнении конечно.

На вскидку:

Отдельная задача - в контексте вытесняющей РТОС это означает, как минимум, выделение в RAM отдельного стека для нее, и двойное переключение контекста каждый раз, когда нам нужно выполнить какие-то действия (если вернуться к тому же примеру, то речь идет о действиях с SPI).

1) Задача требует значительно большего кол-ва RAM. Например, на MIPS минимально необходимый размер стека - 36 слов (144 байта), это если задача вообще ничего делать не будет, только крутиться в цикле. Соответственно, чтобы она делала что-то полезное, этот размер стека еще значительно увеличится, раза в два легко - т.е. около 300 байт если без жира. Плюс еще нужна память для структуры очереди сообщений, и буфер для этой очереди. Еще минимум 50 байт, это если буфер совсем маленький. Мютекс занимает в RAM 36 байт - грубо говоря, в 10 раз меньше. Если на каждый ресурс лепить отдельную задачу - RAM кончается слишком быстро. Если у вас полмегабайта RAM - ерунда конечно, но в моих embedded-проектах на камне никогда не было больше 32К RAM.

2) Оверхед по времени выше: любое использование SPI ведет, как минимум, к двойному переключению контекста. Например, рассмотрим последовательность действий, когда шина SPI свободна. Отправляем сообщение из задачи А в задачу SPI, которая свободна (ждет сообщений) :

* отправляем сообщение из A в SPI,
* сохраняем контекст (32 слова для MIPS) в стек задачи А,
* восстанавливаем контекст задачи SPI,
* задача SPI принимает сообщение и делает свою работу,
* сохраняем весь контекст в стек задачи SPI,
* восстанавливаем контекст задачи А.

В случае с мютексом, действий нужно гораздо меньше:

* блокируем мютекс,
* модуль SPI делает свою работу,
* разблокируем мютекс.

Так что использование мютекса работает несколько быстрее и требует значительно меньше RAM. Плюс еще можно упомянуть, что их использовать проще, чем городить отдельную задачу, набор команд для нее, очередь сообщений. Поэтому, как правило, я использую мютексы. Если такое решение меня не устраивает по каким-то причинам, то тогда уже использую отдельную задачу.


Цитата(AlexandrY @ Jan 22 2015, 15:16) *
Имел в виду, что TNeo слишком нефункциональна по сравнению с той же FreeRTOS.

А в чем именно заключается нефункциональность?

Цитата(_Pasha @ Jan 22 2015, 15:18) *
Мне вообще даже эти все разговоры про ртосы не нравятся rolleyes.gif
очень много шума из ничего. Как и оверхеда и бессмысленных оберток.

А, _Pasha, то есть вы никогда не используете РТОС, правильно? Класс, я ждал, пока кто-нибудь отпишется, спасибо.
Вот видите, AlexandrY, есть тут люди, которые пишут без РТОС! sm.gif
Ждем человека, который пишет исключительно на асме.
Alex B._
dimonomid – можно рассмотреть кейс, когда на SPI висит не только «память», а, например, Flash, FRAM, RF-трансивер, акселерометр. И вся эта периферия имет разный приоритет (отправить пакет через RF важнее, чем сделать запись лога во Flash, потому что таймаут).
Одна задача, обслуживающая интерфейс через очередь – это хороший подход и он может быть действительно удобнее мютексов, если интефейс нужен только двум задачам с одинаковым приоритетом.
dimonomid
Цитата(Alex B._ @ Jan 22 2015, 16:26) *
dimonomid – можно рассмотреть кейс, когда на SPI висит не только «память», а, например, Flash, FRAM, RF-трансивер, акселерометр. И вся эта периферия имет разный приоритет (отправить пакет через RF важнее, чем сделать запись лога во Flash, потому что таймаут).
Одна задача, обслуживающая интерфейс через очередь – это хороший подход и он может быть действительно удобнее мютексов, если интефейс нужен двум задачам с одинаковым приоритетом.

Согласен: иногда, действительно, задача удобнее мютексов. А иногда наоборот. Я где-то противоречил этому?
Alex B._
Цитата(dimonomid @ Jan 22 2015, 14:35) *
Я где-то противоречил этому?

Нет. Я просто привел тебе пример, чтобы помочь отбрехаться. В котором мютексы будут очевидно удобнее задачи с очередью.
AHTOXA
Цитата(ViKo @ Jan 22 2015, 15:01) *
Я использую мьютекс для ограничения доступа к образу изображения на ЖКИ, чтобы одна задача не стирала что-то, нарисованное другой. И у него нет владельца.

То есть, если одна задача захватит мьютекс при помощи wait(), то другая задача может его освободить, вызвав release()?
ViKo
Цитата(AHTOXA @ Jan 22 2015, 14:56) *
То есть, если одна задача захватит мьютекс при помощи wait(), то другая задача может его освободить, вызвав release()?

Нет. Мьютекс достается только одной задаче. Если одна задача получила мьютекс, то, значит, у другой его не было. То есть, и отдавать другой задаче нечего.
Я не пробовал выполнять osMutexRelease до его получения. Но, думаю, просто ничего не произойдет.
AHTOXA
Цитата(ViKo @ Jan 22 2015, 17:07) *
Нет. Мьютекс достается только одной задаче.

Вот это и называется - задача владеет мьютексом. Захватила, и владеет единолично, пока не отдаст. Это я к вашей фразе
Цитата(ViKo @ Jan 22 2015, 15:01) *
И у него нет владельца. Не вижу принципиальной разницы с семафором.

Теперь видите разницу?
ViKo
Цитата(AHTOXA @ Jan 22 2015, 18:37) *
Вот это и называется - задача владеет мьютексом. Захватила, и владеет единолично, пока не отдаст. Это я к вашей фразе
Теперь видите разницу?

Почитайте выше, что пишет топикстартер, У него мьютекс всегда принадлежит одной и той же задаче. Вот ему я и пишу, что у Кейла - не так. Мьютекс создает ОС, задачи им пользуются.

Перечитал сообщение 26. В начале говорится о заблокированном мьютексе, а потом уже просто о владельце. Я неправильно понял.
dimonomid
Цитата(ViKo @ Jan 22 2015, 21:51) *
Почитайте выше, что пишет топикстартер, У него мьютекс всегда принадлежит одной и той же задаче. Вот ему я и пишу, что у Кейла - не так. Мьютекс создает ОС, задачи им пользуются.

Вы меня совершенно неправильно поняли. Где именно я так неясно выразился?

Конечно, мютекс принадлежит той задаче, которая его захватила. Когда задача его разблокирует, он снова ничей.
А семафор ничей даже когда задача его "захватила" (в кавычках - потому что некорректный термин для семафора). И в этом главное отличие семафоров от мютексов.

Когда задача А заблокировала мютекс, задача Б не может его разблокировать.
Когда задача А "заблокировала" семафор, задача Б (или даже прерывание) может его "разблокировать".

Не знаю как у Кейла, может, и не так. Это не новость, что эти термины постоянно путаются, к сожалению. Ну еще раз дам ссылку на статью: Mutexes and Semaphores Demystified, почитайте там хотя бы The Myth: Mutexes and semaphores are similar or even interchangeable, а также The History of Semaphores and Mutexes.
ViKo
Хотите семафоров? - их есть у Кейла. Как говорится, найдите отличие от мьютекса. Нажмите для просмотра прикрепленного файла
То же, что в статье и dimonomid называют семафором, у Кейла выполняют "сигналы" (osSignalSet, osSignalClear, osSignalWait), они же в девичестве "события" (Event), они же "флаги". Они принадлежат задаче (по умолчанию у каждой задачи их 16 штук), и могут обрабатываться поодиночке или группой.

Еще предлагаю посмотреть документ от Кейла:
http://www.keil.com/product/brochures/rl-arm_gs.pdf
Синтаксис устарел, но принципы остались теми же. В-частности, там показано, как используются семафоры: Сигнализация, Мультиплекс, Рандеву, Турникет.
Valentine Loginov
Ай пошли войны. Создали бы тему или блог какой и обсуждали бы краеугольные камни архитектуры ПО.
Мне бы больше хотелось увидеть сравнение времени переключения контекста от количества задач между TNeo и той же FreeRTOS (порт для pic32 wink.gif ) . Да и по памяти выделяемой на те же объекты синхронизации.
У меня пока что руки дошли запустить-помигать. Исходный код у проекта выглядит очень приятно. Попробую прикрутить гармониевский стек, заодно буду смотреть что у TNeo с менеджером динамической памяти.
ViKo
Нашел принципиальное отличие мьютекса от семафора.
Мьютекс при инициализации получает значение (условно) 1. При использовании, когда мьютекс забирается, он становится равным 0. Когда возвращается, снова 1.
Семафор при инициализации может получить любое значение, N, в том числе и 0 (закрыт). Вот этот 0 и позволяет использовать семафор в различных иных применениях, кроме доступа к ограниченному количеству ресурсов.
Так что, разница есть. Но и говорить, что мьютекс - частный случай семафора - тоже верно.
LightElf
QUOTE (ViKo @ Jan 23 2015, 11:04) *
Так что, разница есть. Но и говорить, что мьютекс - частный случай семафора - тоже верно.

Принципиальная разница в том, что освободить мьютекс может только тот, кто им в настоящий момент владеет. У семафора нет такого ограничения.
ViKo
Цитата(LightElf @ Jan 23 2015, 15:01) *
Принципиальная разница в том, что освободить мьютекс может только тот, кто им в настоящий момент владеет. У семафора нет такого ограничения.

Точно.
zaicev_ekb
Прошу прошения.
А почему такой древний компилятор XC32 v1.21?
dimonomid
Цитата(zaicev_ekb @ Feb 9 2015, 15:47) *
Прошу прошения.
А почему такой древний компилятор XC32 v1.21?

Нет особых причин, соберите новым компилятором, проблем быть не должно.
dimonomid
Насчет FreeRTOS:

Цитата(Mahagam @ Jan 20 2015, 12:17) *
Aner, фриртос действительно тормознее других переключалок. в некоторых моментах - существенно. после одного из таких сравнений задали вопрос автору. в итоге в лицензии фриртос появился пункт запрещающий её сравнивать с другими )))

Цитата(Aner @ Jan 20 2015, 14:20) *
кроме bla-bla-bla пример тормознутости в студию!

Цитата(dimonomid @ Jan 20 2015, 02:14) *
Если я заморочусь когда-нибудь на подобное сравнение, я напишу. Пока нечего сказать.

Ради интереса, таки провел сравнение, вопреки лицензии FreeRTOS. Пример простейший: две задачи: А (высокоприоритетная) и B (низкоприоритетная). А ждет семафора, B через определенный интервал сигналит семафором. Т.к. А высокоприоритетная, то как только B сигналит семафором, управление передается задаче А.

Измерял время от момента вызова сервиса сигнализирования из задачи B до получения управления задачей А.

В TNeo: 624 тиков (594 с отключенной проверкой переполнения стека),
в FreeRTOS: 1215 тиков (1075 с отключенной проверкой переполнения стека).
UPD: в FreeRTOS: 863 тиков (699 с отключенной проверкой переполнения стека). Я по запаре накосячил с измерениями первый раз, см. след. сообщение.

Измерения производились на PIC32MX с помощью stopwatch в MPLABX.

TNeo:
Код
volatile int i;

/*
* Low-priority task (2). The lower value, the higher priority.
*/
void task_b_body(void *par)
{
   for(;;)
   {
      tn_task_sleep(10);
      i = 0;   //-- stopwatch start
      tn_sem_signal(&sem);
   }
}

/*
* High-priority task (1). The lower value, the higher priority.
*/
void task_a_body(void *par)
{
   for(;;)
   {
      tn_sem_wait(&sem, TN_WAIT_INFINITE);
      i = 1;   //-- stopwatch stop: 624 cycles (594 without stack overflow check)
   }
}


FreeRTOS:
Код
volatile int i;

/*
* Low-priority task (tskIDLE_PRIORITY + 1)
*/
void prvTaskB (void* pvParameters)
{
   for (;;) {
      vTaskDelay(10);
      i = 1;   //-- stopwatch start
      xSemaphoreGive( mySem );
   }
}

/*
* High-priority task (tskIDLE_PRIORITY + 2)
*/
void prvTaskA (void* pvParameters)
{        
   for (;;) {
      xSemaphoreTake( mySem, portMAX_DELAY );
      i = 0;   //-- stopwatch stop: 863 cycles (624 without stack overflow check)
   }
}
dimonomid
Так, отставить, я ерунду написал в прошлом сообщении: для TNeo-то я взял существующий настроенный проект, а для FreeRTOS создал новый, и забыл в нем оптимизацию включить. Пардон.

Так что отличия поскромнее:

В TNeo: 624 тиков (594 с отключенной проверкой переполнения стека),
в FreeRTOS: 863 тиков (699 с отключенной проверкой переполнения стека).
LightElf
QUOTE (dimonomid @ Apr 8 2015, 13:03) *
Так, отставить, я ерунду написал в прошлом сообщении: для TNeo-то я взял существующий настроенный проект, а для FreeRTOS создал новый, и забыл в нем оптимизацию включить. Пардон.

Так что отличия поскромнее:

В TNeo: 624 тиков (594 с отключенной проверкой переполнения стека),
в FreeRTOS: 863 тиков (699 с отключенной проверкой переполнения стека).

Насколько я помню, автор FreeRTOS всегда упирал на большую предсказуемость. Т.е. две задачи - не показатель, а вот что будет с 20 задачами - вопрос интересный.
Простой пример: TNeo реализует таймеры как callback-и из обработчика таймерного прерывания (я не ошибся?). Какой смысл говорить о времени переключения контекста в таком раскладе? Переключение реально не произойдет до тех пор, пока не будут отработаны все таймеры. Т.е. задержка не детерминирована, совсем.
dimonomid
Цитата(LightElf @ Apr 8 2015, 17:42) *
Насколько я помню, автор FreeRTOS всегда упирал на большую предсказуемость. Т.е. две задачи - не показатель, а вот что будет с 20 задачами - вопрос интересный.

Как в FreeRTOS - не знаю, а в TNeo, как и в TNKernel, количество задач не влияет на скорость переключения контекста: для каждого приоритета есть связанный список задач, готовых к запуску. И есть битовая маска, каждый бит которой отражает приоритет, в котором есть готовые к запуску задачи. Таким образом, когда ядро выясняет, какую задачу нужно запустить, оно делает следующее:

- Находит номер младшего установленного бита в маске. Некоторые архитектуры имеют специальную инструкцию для этой операции (Find first set). Если такой инструкции нет, то приходится вручную проверять каждый бит, но тогда время выполнения зависит не от количества задач, а от количества приоритетов.
- Передает управление первой задаче из связанного списка для соответствующего приоритета. Время константное.

Цитата(LightElf @ Apr 8 2015, 17:42) *
Особенно такой скользкий параметр, как максимальная задержка входа в прерывание.

От количества задач эта задержка тоже не зависит.
LightElf
QUOTE (dimonomid @ Apr 8 2015, 17:02) *
т количества задач эта задержка тоже не зависит.

Хм. И по спискам задач (семафоров, мутексов и т.д.) под запрещенными прерываниями не ходите?
dimonomid
Цитата(LightElf @ Apr 8 2015, 18:23) *
Хм. И по спискам задач (семафоров, мутексов и т.д.) под запрещенными прерываниями не ходите?

Мда, поторопился я ответить. sm.gif Прямой зависимости от количества задач нет, но, действительно, критические секции добавляют задержку: если говорить про мютексы, то чем больше задач одновременно ожидают мютекс, тем больше времени требуется, чтобы определить приоритет той задачи, которая захватила этот мютекс. Вы правы.

Другое дело, что на некоторых платформах (пока только dsPIC/PIC24) есть возможность запрещать в критических секциях не все прерывания, а только определенный диапазон приоритетов прерываний. Но тогда из остальных прерываний нельзя вызывать сервисы ядра.

LightElf
QUOTE (dimonomid @ Apr 8 2015, 17:38) *
Мда, поторопился я ответить. sm.gif Прямой зависимости от количества задач нет, но, действительно, критические секции добавляют задержку: если говорить про мютексы, то чем больше задач одновременно ожидают мютекс, тем больше времени требуется, чтобы определить приоритет той задачи, которая захватила этот мютекс. Вы правы.

Во! Значиццо есть куда стремиться. sm.gif Поскольку мутексы (по логике вещей) не используются из прерываний, логично было бы обойтись без критических секций в данном случае.
QUOTE (dimonomid @ Apr 8 2015, 17:38) *
Другое дело, что на некоторых платформах (пока только dsPIC/PIC24) есть возможность запрещать в критических секциях не все прерывания, а только определенный диапазон приоритетов прерываний. Но тогда из остальных прерываний нельзя вызывать сервисы ядра.

Эта фишка во FreeRTOS тоже искаропки идет, как минимум на ARM Cortex-M3 и Renesas RX. Но описанные минусы напрягают.
dimonomid
Цитата(LightElf @ Apr 8 2015, 19:46) *
Во! Значиццо есть куда стремиться. sm.gif Поскольку мутексы (по логике вещей) не используются из прерываний, логично было бы обойтись без критических секций в данном случае.

Вам нужен AVIX тогда. sm.gif http://avix-rt.com/ Она никогда не запрещает прерывания, вообще. Но денег стоит.
LightElf
QUOTE (dimonomid @ Apr 8 2015, 17:56) *
Вам нужен AVIX тогда. sm.gif http://avix-rt.com/ Она никогда не запрещает прерывания, вообще. Но денег стоит.

Это наверно оверкилл, хотя давно у меня чешется что-нить подобное наваять (естественно на архитектурах, где такое вообще возможно). Но речь здесь о TNeo vs FreeRTOS. Так вот, FreeRTOS под запрещенными прерываниями списки не обходит. Отсюда и "большие задержки".
dimonomid
Цитата(LightElf @ Apr 8 2015, 19:05) *
Так вот, FreeRTOS под запрещенными прерываниями списки не обходит. Отсюда и "большие задержки".

Хм. Насчет мютексов примерно ясно: действительно, можно запрещать только планировщик, а не все прерывания, т.к. мютексы в прерываниях не используются. Ок, но как, например, с таймерами? Если запущено много таймеров, то эту очередь надо как-то обслуживать, и чем больше таймеров в очереди, тем больше времени это занимает.

Ладно, спасибо за инфу, когда будет время, попробую разобраться. sm.gif
LightElf
QUOTE (dimonomid @ Apr 8 2015, 18:13) *
Хм. Насчет мютексов примерно ясно: действительно, можно запрещать только планировщик, а не все прерывания, т.к. мютексы в прерываниях не используются.

Это один из вариантов. Можно еще:
1) хранить список ожидающих задач в отсортированном виде.
2) запрещать прерывания только на время работы с конкретным элементом
QUOTE (dimonomid @ Apr 8 2015, 18:13) *
Ок, но как, например, с таймерами? Если запущено много таймеров, то эту очередь надо как-то обслуживать, и чем больше таймеров в очереди, тем больше времени это занимает.

Логично. Поэтому таймеры в виде коллбэков из прерывания - зло.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.