Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Как остановить переключение процессов?
Форум разработчиков электроники ELECTRONIX.ru > Cистемный уровень проектирования > Операционные системы > scmRTOS
sonycman
Доброго времени суток!

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

К примеру, в программе возникла аварийная ситуация, и потребовалось отобразить информацию на ЖКИ и остановить процессор:

1. LCD_Mutex.Lock(); - так как ЖКИ расшаренный ресурс, ждём его освобождения
2. __disable_irq(); - запрещаем прерывания
3. LCD.Print(); - выводим на дисплей, в процессе будет несколько раз выполняться LCD_Mutex.Unlock()
4. while (1); - остановка процессора.

Возможно ли переключение на другой процесс после вызова LCD_Mutex.Unlock() при запрещённых прерываниях?

ЗЫ:чёрт, посмотрел в исходниках ОС - переключение задач производится не зависимо от того, разрешены прерывания или нет.

Как же мне заставить систему не переключаться? sad.gif
AHTOXA
Цитата(sonycman @ Aug 22 2010, 19:21) *
ЗЫ:чёрт, посмотрел в исходниках ОС - переключение задач производится не зависимо от того, разрешены прерывания или нет.

Это как это?! rolleyes.gif
Цитата
Как же мне заставить систему не переключаться? sad.gif

Вот вопрос на засыпку: в критической секции - система переключается? smile.gif

sonycman
Цитата(AHTOXA @ Aug 22 2010, 20:05) *
Это как это?! rolleyes.gif

А просто - выполняя Mutex.Unlock() попадаем в планировщик - TKernel::Sched(), который разрешает прерывания для форсирования переключения задач.

То есть пофигу - были запрещены до этого прерывания или нет - система будет переключать задачи sad.gif
А мне бы этого избежать...

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

Пока что вышел из ситуации запрещением в приложении использования сервисов ОС после того, как прерывания были запрещены.
AHTOXA
Естественно, если продолжать пользоваться сервисами оси, то система будет переключать задачи.
Для аварийного завершения придётся либо с этим смириться (дождались захвата мьютекса, запретили прерывания, вывели сообщение и повисли), либо писать процедуры вывода на дисплей, не использующие сервисы оси.


---
Кстати, а что плохого в том, что задачи ещё немного попереключаются? Ну закончит текущая активная задача вывод на экран, до того, как вы захватите мутекс. Что в этом такого?
Вот я недавно задавался подобным вопросом, но там мне вызывать сервисы оси было смерти подобно, ибо ось ещё не стартовалаsmile.gif
sonycman
Цитата(AHTOXA @ Aug 22 2010, 22:53) *
Кстати, а что плохого в том, что задачи ещё немного попереключаются? Ну закончит текущая активная задача вывод на экран, до того, как вы захватите мутекс. Что в этом такого?

Нет, ничего плохого в том, что задачи поработают ДО того, как захватывается мьютекс нет.
Главное, чтобы ПОСЛЕ не переключались.

Видите ли, у меня каждая функция вывода на ЖКИ оформлена мьютексом.
Например:
Код
void    LCD_IF::PrintText(const char *text, int xs, int ys, dword flags, dword fcolor, ...)
{
    LCD_Mutex.Lock();
    //тело функции
    LCD_Mutex.Unlock();
}

и я их буду вызывать последовательно несколько раз.

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

Пришлось ввести флаг, запрещающий пользоваться мьютексами внутри таких функций после запрета прерываний.
AHTOXA
Цитата(sonycman @ Aug 23 2010, 01:29) *
Видите ли, у меня каждая функция вывода на ЖКИ оформлена мьютексом.

А, вон оно что. Теперь понятно.
Тогда да, флаг. Либо отделить процедуры собственно рисования от процедур захвата/освобождения мутекса:
Код
void LCD_IF::PrintText(...)
{
    LCD_Mutex.Lock();
    DoPrintText(...);     // собственно рисование
    LCD_Mutex.Unlock();
}
,
и при аварии захватывать мутекс вручную один раз, и потом вызывать функции DoPrintXXX()...
sonycman
Цитата(AHTOXA @ Aug 23 2010, 09:53) *
Либо отделить процедуры собственно рисования от процедур захвата/освобождения мутекса:
Код
void LCD_IF::PrintText(...)
{
    LCD_Mutex.Lock();
    DoPrintText(...);     // собственно рисование
    LCD_Mutex.Unlock();
}
,
и при аварии захватывать мутекс вручную один раз, и потом вызывать функции DoPrintXXX()...

Тоже думал об этом.
А таким образом можно передавать аргументы функции с их переменным количеством (...)?
AHTOXA
Здесь я нарисовал многоточие просто для краткостиsmile.gif Список аргументов у функций PrintXXX и DoPrintXXX будет фиксированным и одинаковым.
А если вообще, то va_start()/va_arg()/va_end().
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.