Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Проблемы с приоритетами процессов
Форум разработчиков электроники ELECTRONIX.ru > Cистемный уровень проектирования > Операционные системы > scmRTOS
Anatoly74
Игрался с китом Discovery STM32F401. Состряпал для порта М4 простейший пример из 3-х процессов. Все они ждут одного события Flag.signal и зажигают один из 3-х светодиодов. Событие Flag.signal формируется каждые 0.5 сек по системному таймеру. Если scmRTOS_PRIORITY_ORDER = 1 все работает нормально и процессы переключаются в порядке их приоритетов: pr0 -> pr1 -> pr2.
Устанавливаю scmRTOS_PRIORITY_ORDER = 0 и вижу, что порядок переключения остался тем же: pr0 -> pr1 -> pr2. Он не изменяется.
Тогда я взял порт для М3 и прогнал тест на нем. Все то же самое.
Объясните дураку, что я делаю не так.
Вот тексты:

Код
//---------------------------------------------------------------------------
//      Process types
//
typedef OS::process<OS::pr0, 400> TProc1;
typedef OS::process<OS::pr1, 400> TProc2;
typedef OS::process<OS::pr2, 400> TProc3;

TProc1 Proc1;
TProc2 Proc2;
TProc3 Proc3;

OS::TEventFlag Flag;
//---------------------------------------------------------------------------

template<> OS_PROCESS void TProc1::exec()
{
    for(;;)
    {    
               Flag.wait();
        clear_all_VD();
        SetPORT(GPIOD, VD_ORANGE);
    }
}
//---------------------------------------------------------------------------
template<> OS_PROCESS void TProc2::exec()
{
    for(;;)
    {    Flag.wait();
        
        clear_all_VD();
        SetPORT(GPIOD, VD_RED);
     }
}
//---------------------------------------------------------------------------
template<> OS_PROCESS void TProc3::exec()
{
    for(;;)
    {    Flag.wait();
        
        clear_all_VD();
        SetPORT(GPIOD, VD_BLUE);
     }
}
//===================================================

void OS::system_timer_user_hook()
{
    static int16U Tics=0, Cnt=0;
    
    if (++Tics < 250)    return;
    
    Tics = 0;                        // 0.5 сек
    if (++Cnt >= 4)        Cnt = 0;

        Flag.signal_isr();
}

AHTOXA
А что делает clear_all_VD()? Гасит все светодиоды? Если так, то первые два светодиода будут гореть совсем короткое время, порядка 2 мкс. Вы смотрите осциллографом? Для наглядности я бы сделал иначе: гасил бы диоды в OS::system_timer_user_hook(), перед взводом флага. И в каждой задаче после зажигания диода вставил бы задержку глухим циклом тысяч на 100. Вот тогда будет видно.
(Замечу, что scmRTOS_PRIORITY_ORDER = 0 в кортексах работает гораздо медленнее, чем scmRTOS_PRIORITY_ORDER = 1. Так что смысла в scmRTOS_PRIORITY_ORDER = 0 нет, разве что в познавательных целях).

ЗЫ. В OS::system_timer_user_hook() Cnt у вас ни на что не влияет (не хватает скобочек).
Anatoly74
Цитата(AHTOXA @ Apr 16 2015, 14:58) *
А что делает clear_all_VD()? Гасит все светодиоды? Если так, то первые два светодиода будут гореть совсем короткое время, порядка 2 мкс. Вы смотрите осциллографом? Для наглядности я бы сделал иначе: гасил бы диоды в OS::system_timer_user_hook(), перед взводом флага. И в каждой задаче после зажигания диода вставил бы задержку глухим циклом тысяч на 100. Вот тогда будет видно.
(Замечу, что scmRTOS_PRIORITY_ORDER = 0 в кортексах работает гораздо медленнее, чем scmRTOS_PRIORITY_ORDER = 1. Так что смысла в scmRTOS_PRIORITY_ORDER = 0 нет, разве что в познавательных целях).

ЗЫ. В OS::system_timer_user_hook() Cnt у вас ни на что не влияет (не хватает скобочек).

Да, clear_all_VD() гасит все светодиоды. Порядок переключение задач я смотрел по точкам останова с помощью внутрисхемного эмулятора.
Осциллографом было бы менее наглядно.
Поставил задержки, как вы советовали. Да, стало визуально видно, но проблема осталась.
Содержимое scmRTOS_PRIORITY_ORDER не влияет на порядок переключения.
AHTOXA
Цитата(Anatoly74 @ Apr 16 2015, 17:51) *
Содержимое scmRTOS_PRIORITY_ORDER не влияет на порядок переключения.

Я что-то затупил. Конечно не влияет! sm.gif
При любом значении scmRTOS_PRIORITY_ORDER OS::pr0 - это наивысший приоритет, OS::pr1 - следующий, и так далее.
scmRTOS_PRIORITY_ORDER влияет лишь на внутреннее представление значений приоритета.
Anatoly74
Цитата(AHTOXA @ Apr 16 2015, 21:12) *
scmRTOS_PRIORITY_ORDER влияет лишь на внутреннее представление значений приоритета.

Из документации на V4.0 я понял, что scmRTOS_PRIORITY_ORDER задает порядок старшинства приоритетов процессов.
Например, если у нас описан процесс:
typedef OS::process<OS::pr0, 400> TProc1;
Тогда при scmRTOS_PRIORITY_ORDER=0, pr0 - это наивысший приоритет.
А при scmRTOS_PRIORITY_ORDER=1, pr0 - это низший приоритет, т.е. в этом случае TProc1 будет иметь наименьший приоритет.
Я не правильно понял?

Кажется, я разобрался. Приоритет pr0 - это в любом случае всегда самый наивысший приоритет.
А значение scmRTOS_PRIORITY_ORDER задает место pr0 (старший или младший бит) во внутренней карте процессов.
Я не правильно истолковал смысл фразы на стр. 42: " scmRTOS_PRIORITY_ORDER 0/1 - Задаёт порядок старшинства
приоритетов."

Я думаю, чтобы не возникало всяких кривотолков надо заменить на стр. 42 фразу "Задаёт порядок старшинства
приоритетов"
на "задает место pr0 (старший или младший бит) во внутренней карте процессов".
AHTOXA
Цитата(Anatoly74 @ Apr 17 2015, 10:36) *
Я думаю, чтобы не возникало всяких кривотолков надо заменить на стр. 42 фразу "Задаёт порядок старшинства
приоритетов"
на "задает место pr0 (старший или младший бит) во внутренней карте процессов".

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