Перейти к содержанию
    

Активировать задачу из не системного прерывания

2 minutes ago, Arlleex said:

а в критические секции оборачиваются практически со входа до выхода соотв. функций.

На самом деле - согласен! Ведь я использую FreeRTOS на работе, это наш стандарт, тут выбирать не могу, и я наблюдаю в ней то же самое. Но мне было интересно услышать именно Ваше мнение!

P.S. Там, где я могу выбирать, например, для домашних проектов, я выбираю scmRTOS.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3 часа назад, haker_fox сказал:

На самом деле - согласен! Ведь я использую FreeRTOS на работе, это наш стандарт, тут выбирать не могу, и я наблюдаю в ней то же самое. Но мне было интересно услышать именно Ваше мнение!

Да, на работе я пользуюсь, в основном, тоже FreeRTOS, потому что Free, но это для нас, на самом деле, не так важно. Просто ее хватает на большую часть проектов.

А так - есть проекты с банальным суперциклом (и не сказать, что прям весьма простые), есть на самодельных переключателях контектса (кооперативных и вытесняющих принципов).

Коллеги пользуются еще "зашитими" в IDE ОСРВ (Keil-RTOS, например). Но код FreeRTOS открыт, "смотри и плачь", как говорится:whistle3:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

47 minutes ago, Arlleex said:

Просто ее хватает на большую часть проектов.

Мне тоже. Все шустрые процессы, которые только можно, исполняются преимущественно за счёт имеющейся аппаратной периферии. 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

/**
 * @brief Задача, инициирующая процесс обмена
 * и прерывание по его завершению.
 * @param pvParameters нет
 */
void Task1_Foo(void *pvParameters)
{
	/* Создаем очередь для передачи принятого */
	xQueue = xQueueCreate(5, sizeof(uint8_t));

	/* Основной цикл задачи */
	for(;;)
	{
		/* Повышаем приоритет задачи, чтобы она находилась
		 * в активности наибольшее время */
		vTaskPrioritySet(task1, 2);

		/* Запускаем процесс обмена, который в конце
		 * вызовет прерывание, и ожидаем выставления флага,
		 * означающего завершение процесса и готовность
		 * результатов */
		while(!flag);

		/* После этого полученные результаты заносим в очередь */
		xQueueSend(xQueue, buf, 0);

		/* Снижаем приоритет задачи или блокируем её до следующего раза */
		vTaskPrioritySet(task1, 0);
	}
}

void xxxIRQHandler(void)
{
	/* Устанавливается флаг готовности результатов */
	flag = 1;
	// ... 
}

По теме темы:

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

21 час назад, Arlleex сказал:

Насколько быстро надо обработать?

Ну раз нельзя приоритеты перестраивать, то можно активировать IdleHook(), в нем смотреть некий глобальный volatile-флажок, который будет подниматься в нужном быстром прерывании.

Как только поднялся - сбрасываем и активируем задачу уже средствами RTOS.

Скорость хотелось бы такую же как при использовании direct to task notification.

Подведу итоги:

1) через вспомогательное прерывание;
2) с помощью флажка и IdleHook;
3) с помощью флажка и поллинга (прощай многозадачность)

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Нет, ну вы же сами определили столь жесткие условия. А вычислительное ядро - оно одно, и многозадачность - она с приставкой "псевдо". 

1. Вспомогательное прерывание с приоритетом ниже MAX_API создаст точно такую же (и даже бОльшую) задержку конечной обработки, как если бы сразу напрямую снизить приоритет прерывания. (Кстати, для вспомогательных прерываний лучше всего подходят неиспользуемые номера EXTI).

2. Вообще тормоз, ибо в Idle будет уходить только в том случае, когда вообще нет активных задач с приоритетом выше Idle.

3. Ну это хоть как-то реализует быстрый отклик. Впрочем, можете не повышать приоритет задачи и тогда отклик будет варьироваться от условного 0 до числа активных задач, помноженных на период систика.

Следовательно, построение работы с RTOS - это своего рода искусство поиска компромиссных решений. Не хотите мириться - не используйте RTOS вовсе. Многозадачность и параллельность - она условная, псевдо.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

4) дописать RTOS, чтобы из того самого приоритетного прерывания, которое должно было разбудить задачу, управление вернулось сразу в эту задачу (разумеется, с корректными установками параметров TCB).

Этот вариант вообще, наверное, быстрее всех.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

39 минут назад, EdgeAligned сказал:

Нет, ну вы же сами определили столь жесткие условия. А вычислительное ядро - оно одно, и многозадачность - она с приставкой "псевдо". 

1. Вспомогательное прерывание с приоритетом ниже MAX_API создаст точно такую же (и даже бОльшую) задержку конечной обработки, как если бы сразу напрямую снизить приоритет прерывания. (Кстати, для вспомогательных прерываний лучше всего подходят неиспользуемые номера EXTI).

Ненамного большую, только на вызов вспомогательного прерывания.
А почему именно EXTI ?

Изменено пользователем _3m

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не стоит дописывать исходники RTOS, дабы не поломать её невзначай, да и чтобы при обновлении версии RTOS ничего не менять в ней.

А порядок разблокировки задач определяется еёными приоритетами. Поставьте для задачи обработки результатов приоритет выше остальных и заблокируйте её, отправив в ожидание. После наступления события разблокировки она сама запустится первой.

Я ж говорю - написание под RTOS - это искусство поиска компромиссов. Задача в том, чтобы найти компромисс между временем реакции и сохранением многозадачности. Не все события требуют моментальной реакции. Например, нажатие кнопки допускает реакцию в течение десятков миллисекунд. Прием данных от термометра с целью показа на дисплее допускает реакцию в сотни миллисекунд. 

15 минут назад, _3m сказал:

А почем именно EXTI ?

А потому что это самое "безобидное", так сказать, и не имеющее побочных явлений. Оно легко запускается вручную штатной установкой бита SWIER - программный вызов прерывания. Таких прерываний как минимум 16, с 7 раздельными векторами.

15 минут назад, _3m сказал:

Ненамного большую, только на вызов вспомогательного прерывания.

Допустим. Но каков в этом смысел? Поскольку если в системе есть иные высокоприоритетные прерывания с приоритетом выше MAX_API, они всё равно заблокируют это вспомогательное прерывание в случае совпадения по времени. Это как "проскочил на первом светофоре, но застрял на красный на втором светофоре".

Изменено пользователем EdgeAligned

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

12 часов назад, haker_fox сказал:

Мне подумалось, а насколько быстро нужно разбудить задачу после готовности данных? Всё может свестись к банальному опросу volatile-флага поллингом этой же задачей.

Таким образом сразу гробятся все нижележащие (по приоритету) задачи.  :hang3:

12 часов назад, haker_fox сказал:

Да, знаю, что поллинг и ОСРВ - обычно вещи несовместимые. Но иногда так приходится делать.

Если "так приходится делать", то скорее всего нужно открывать учебник и читать: что такое "event-driven программирование" и как его правильно готовить.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну выставили вы событие (тот же флаг) в высокоприоритетном прерывании. Где этот флаг будет прочитан, в какой задаче? А если эта задача в данный момент не активна - сколько придется подождать до её запуска? Напомню - в высокоприоритетных прерываниях API RTOS не может использоваться. 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Следует задуматься, а для чего нужно то прерывание, приоритет которого выше RTOS, если по итогу это событие обрабатывается в задаче RTOS. То есть, все равно так или иначе будем ждать, пока RTOS завершит все критические дела и будет готова переключить контекст на задачу обработки. Тот же результат был бы достигнут если исходное прерывание имело приоритет пониже и работало в рамках правил RTOS, то есть запрещалось бы в критических секциях.

Изменено пользователем amaora

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Так о чем я и толкую! 🙂 Смысел тут нууу тааак себе, если не хуже. Высокоприоритетные прерывания выше API - это как люди, работающие на самом верхнем этаже - они чето бегают, суетятся, но когда нужно спуститься вниз на лифте, то есть два варианта - если лифт свободен и близко - спустятся быстро, а если лифт далеко и занят людьми с нижних этажей - то хренушки, ждите, пока все покатаются.
И события (флаги) тут шибко то не помогут - кнопку вызова лифта нажали, событие зарегистрировано, но лифт придет не раньше, чем он освободится. Или же оставить лифт у себя на этаже и держать двери открытыми - уедешь по первой необходимости, но только с твоего верхнего этажа, а остальные, кто ниже - сосите лапу.

Изменено пользователем EdgeAligned

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

16 минут назад, amaora сказал:

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

 

Результат не будет достигнут если приоритет "пониже": из за длительных блокировок в критических секциях FreeRtos прерывания потеряются.

Задача ртос подготавливает задание для работы, потом высокоприоритетное прерывание быстр-быстро его выполняет (внутри прерывания умная или не очень FSM), потом когда задание выполнено нужно об этом уведомить задачу и тут уже не требуется суперскорость. Такой программный сопроцессор для обслуживания hardware.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

20 minutes ago, _3m said:

Задача ртос подготавливает задание для работы, потом высокоприоритетное прерывание быстр-быстро его выполняет (внутри прерывания умная или не очень FSM), потом когда задание выполнено нужно об этом уведомить задачу и тут уже не требуется суперскорость. Такой программный сопроцессор для обслуживания hardware.

Можно ничего не делать тогда, возврат управления в задачу уже означает, что приоритетное прерывание завершилось.

 

Видимо много прерываний если там FSM, а между ними продолжает работать RTOS, в итоге нужно сообщить результат в задачу, понял.

Изменено пользователем amaora

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...