Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Использование семафоров до старта планировщика
Форум разработчиков электроники ELECTRONIX.ru > Cистемный уровень проектирования > Операционные системы > FreeRTOS
turnon
При использовании семафоров наткнулся на HardFault и задумался, а можно ли их использовать до старта планирощика?

Или перед использовением (xSemaphoreTake(Recursive) / xSemaphoreGive(Recursive)) нужно проверять xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED ?

Подробности такие. До старта планировщика задач (vTaskStartScheduler()) создается семафор _semaphore = xSemaphoreCreateRecursiveMutex() и потом используется в виде пары:

xSemaphoreTakeRecursive(_semaphore, (portTickType)portMAX_DELAY)
...
xSemaphoreGiveRecursive(_semaphore)

Конечно смысла в семафорах до старта задач нет, до старта задач поток один. Но это унифицированный код, он используется и из задач, и до старта планировщика.

Все работало нормально, но вчера вылез HardFault, трассировка привела к этому участку в queue.c:

if( xTaskResumeAll() == pdFALSE )
{
portYIELD_WITHIN_API();
}

При вызове portYIELD_WITHIN_API() вылетает в HardFault.
AleksBak
Цитата(turnon @ Mar 17 2016, 12:33) *
...
Конечно смысла в семафорах до старта задач нет, до старта задач поток один. Но это унифицированный код, он используется и из задач, и до старта планировщика.
Все работало нормально, но вчера вылез HardFault, трассировка привела к этому участку в queue.c:

if( xTaskResumeAll() == pdFALSE )
{
portYIELD_WITHIN_API();
}

При вызове portYIELD_WITHIN_API() вылетает в HardFault.

А это Ваш код? В смысле Вы так придумали или это код совместной работы в команде? А зачем так извращаться вообще? Мне, можно сказать новичку, итак ясно, что при вызове portYIELD_WITHIN_API() работа перейдет к планировщику. А как оно у Вас до сих пор работало интересно? sm.gif Конечно в мире разные бывают любители и пр. Но вот зачем иногда не совсем понятно.
turnon
Цитата(AleksBak @ Mar 17 2016, 13:22) *
А это Ваш код?

Нет, это код из queue.c, привел его для понимания что вызывает HardFault
esaulenka
Да, очереди/семафоры/sleep() с остановленным шедулером не работают.
Я поначалу кинулся расставлять проверки "планировщик работает" прямо в код операционки (мне кажется, это правильнее, чем тыкать во все возможные места xTaskGetSchedulerState() ), но потом просто перенёс большую часть кода в задачи (до того у меня вся инициализация железа была в main() - осталось только самое необходимое).
AleksBak
Цитата(turnon @ Mar 17 2016, 13:55) *
Нет, это код из queue.c, привел его для понимания что вызывает HardFault

Да это понятно. Я неправильно выразился - имел ввиду, что код/проект/структуру программы Вы сами придумали или кто-то "заставляет"(совместная команда, код какой задачи закрытый и пр.) именно так поступить (использовать семафоры до старта). Уже тут esaulenka и написал к чему пришел и как получше тут будет.
zltigo
QUOTE (esaulenka @ Mar 17 2016, 13:17) *
(до того у меня вся инициализация железа была в main() - осталось только самое необходимое).

В main() действительно самая минимальная инициализация и подъем, например, консоли. После чего или запускается задача инициализации и потом прибивается за ненадобностью, или ставится hook на IdleTask и потом убирается.
CODE
int main(void)
{
int id = iap_getid();
    init_clock( configQUARC_HZ, configCPU_CLOCK_HZ );
    gpio_init();
    init_system_heap( id );
    xIdleTaskCreate( IDLE_TASK_STACK_SIZE );
    // Start Console and Console Task.
    init_console( CONSOLE_BAUD_RATE, CONSOLE_PRIORITY, CONSOLE_TASK_STACK_SIZE );
    hellomessage();
    vSetIdleHook( init_system );
    vTaskStartScheduler( INTERNAL_TIMER );           
}
turnon
Цитата(AleksBak @ Mar 17 2016, 15:47) *
Да это понятно. Я неправильно выразился - имел ввиду, что код/проект/структуру программы Вы сами придумали или кто-то "заставляет"(совместная команда, код какой задачи закрытый и пр.) именно так поступить (использовать семафоры до старта). Уже тут esaulenka и написал к чему пришел и как получше тут будет.

Сам придумал. Код унифицированный, он не знает что работает из задачи или не из задачи. При работе из задачи ресурс должен быть защищен от одновременного использорвания из нескольких потоков, потому в коде семафоры.

Цитата(esaulenka @ Mar 17 2016, 15:17) *
Я поначалу кинулся расставлять проверки "планировщик работает" прямо в код операционки (мне кажется, это правильнее, чем тыкать во все возможные места xTaskGetSchedulerState() ), но потом просто перенёс большую часть кода в задачи (до того у меня вся инициализация железа была в main() - осталось только самое необходимое).

У меня в main только одноразовые инициализации, требующие много стековой памяти. Чтобы не выделять много стека под каждую задачу. А так тоже все остальное в задачах. Также реализовано отслеживание зависания задач.
zltigo
QUOTE (turnon @ Mar 17 2016, 15:41) *
потому в коде семафоры.

Некоторое количество лет назал, где-то в районе появления FreeRTOS 2.0 я начал с ней копаться. До этого имел за плечами работу с операционными сисиемами, как с чужими, так и со своими. Удивило тогда меня, что всякие семафоры и иже с ними сделаны через макросы очередей. Призадумался я да и понял, что семафоры и иже с ними в общем-то есть ЛИШНЯЯ сущность. И с тех пор не пользую. За ненадобностью.
turnon
Цитата(zltigo @ Mar 17 2016, 17:48) *
Некоторое количество лет назал, где-то в районе появления FreeRTOS 2.0 я начал с ней копаться. До этого имел за плечами работу с операционными сисиемами, как с чужими, так и со своими. Удивило тогда меня, что всякие семафоры и иже с ними сделаны через макросы очередей. Призадумался я да и понял, что семафоры и иже с ними в общем-то есть ЛИШНЯЯ сущность. И с тех пор не пользую. За ненадобностью.

А как вы решаете проблему с одновременной работой участка кода из нескольких задач? Конечно в случае если участок кода критичен чтобы к нему не обращались из нескольких задая одновременно.
zltigo
QUOTE (turnon @ Mar 17 2016, 15:55) *
А как вы решаете проблему с одновременной работой участка кода из нескольких задач? Конечно в случае если участок кода критичен чтобы к нему не обращались из нескольких задая одновременно.

Как оказалось sm.gif, система может строится так, что такая задача может быть решена и без лобовых семафоров. Например, чем этот "участок кода" не есть отдельная задача получающая сообщения и их обрабатывающая? Естественно, при этом нужно много тщательнее продумывать структуру, ибо задачи действительно должны быть задачами выполняющими разумны едействия, а не кучей "кусков кода". Семафоры это в общем-то заплатки. Ими удобно и привычно можно латать, а можно и не латать sm.gif
turnon
Цитата(zltigo @ Mar 17 2016, 18:13) *
Как оказалось sm.gif, система может строится так, что такая задача может быть решена и без лобовых семафоров. Например, чем этот "участок кода" не есть отдельная задача получающая сообщения и их обрабатывающая?

Это слишком расточительно, на тот же лог выделять отдельную задачу.
zltigo
QUOTE (turnon @ Mar 17 2016, 16:36) *
Это слишком расточительно, на тот же лог выделять отдельную задачу.

Лог дело важное и одновременно он не должен перекашивать систему тормозя задачи, причем с перекосами приоритетов. Так что именно разработке логирования надо уделять особое внимание и не скупится. Если действительно сыпется идет обильная информция с самых разных уровней, причем не всегда, а когда, наример, отладку включили, то надо ОЧЕНЬ крепко думать, как организовать доступ к логу.

turnon
Цитата(zltigo @ Mar 17 2016, 18:50) *
Если действительно сыпется идет обильная информция с самых разных уровней, причем не всегда, а когда, наример, отладку включили, то надо ОЧЕНЬ крепко думать, как организовать доступ к логу.

Не обильная, иначе не переварить человеку. При использовании задачи для того же лога возникает новая проблема - какой длины выделить очередь для сообщений, чтобы лог всегда гарантировано мог принять новое сообщение. В итоге снова приходим к семафорам sm.gif
zltigo
QUOTE (turnon @ Mar 17 2016, 18:33) *
Не обильная, иначе не переварить человеку, для которого этот лог и ведется.

Ну лог, на то и лог, что бы читать его и длинными зимними вечерами sm.gif.
QUOTE
И лучше хорошо подумать как не тратить целую задачу на это.

Затраты одного MCB и стека, который по любому хоть в отдельной, хоть нет, логированим съедаться будет.
QUOTE
Плюс при использовании задачи для того же лога возникает новая проблема - какой длины выделить очередь для сообщений, чтобы лог всегда гарантировано мог принять новое сообщение.

Средний темп выдачи лога по любому должен быть оценен. Хоть с задачей, хоть без задачи, хоть с семафорами, хоть без ничего, хоть как. Не будет буферизации будет "никак". Где будет буфер в очереди или нет, дело десятое. Если задачам придется непрерывно драться и ждать МЕДЛЕННОГО логирования, то это перекосит всю систему.
Если вдруг, при какой то нештатной ситуации темп выдачи лога резко возрос, то тем блее следует аккуратно разбираться с тем, кто может ждать, кто не может, а чья инфрмация вообще сейчас неважна - выкинуть в пропость.
QUOTE
В итоге снова приходим к семафорам sm.gif

Дались Вам эти семафоры. Это совершенно виртуальная штука, функционал котрых может быть организован разнообразными способами. Естественно НЕ с целью сделать те-же яйца в профиль, а получить дополнительный функционал. Ведь та же реализация семафоров на очередях на самом деле просто усекала функционал очереди, котрый, если подумать, можно использовать БОЛЕЕ полно и эффективно.


turnon
Цитата(zltigo @ Mar 17 2016, 22:26) *
Ведь та же реализация семафоров на очередях на самом деле просто усекала функционал очереди, котрый, если подумать, можно использовать БОЛЕЕ полно и эффективно.

Согласен, у FreeRtos только очереди, на базе нее реализовали все примитивы. А вот в новых версиях появилась xTaskNotify() / xTaskNotifyWait(), это тоже на очередях, или там свой механизм? Это эффективнее очередей для ожидания задачей сигнала к старту?
zltigo
QUOTE (turnon @ Mar 17 2016, 20:49) *
Это эффективнее очередей для ожидания задачей сигнала к старту?

Да, они как-бы более вырожденный вариант и ввиду этого для своей ПРОСТЕЙШЕЙ функции эффективнее. Но я вооюще то призывал использовать НЕ более простые средства, а более сложные sm.gif.
Я вообще-то от FreeRTOS уж совсем в свободное плавание (то есть вообще перестал следить, что там твориться) отошел где-то в районе 4 версии. Уж слишком много своего добавил, котрое НЕ получило одобрения у Автора. За какую нибудь очепятку - рассыпался в благодарностях, на серьезные правки - тишина в ответ. Потом заметил несколько своих предложений реализованными с задержкой в полгода-год sm.gif. Несколько месяцев назад ради интереса скачал свежайшую и обнаружил, что практически все, что есть у меня, есть уже и там sm.gif. Ради интереса добавил минимум своего необходимого/привычного и запустил, как вариант сборки проектов. Работает, естветвенно, и на "оригинальном" ядре sm.gif. Но в общем то, что там сейчас творится не вычитывал (исходники стали еще более мутными sad.gif ), так что особо влет не расскажу, что и как.
turnon
Цитата(zltigo @ Mar 17 2016, 23:02) *
Потом заметил несколько своих предложений реализованными с задержкой в полгода-год sm.gif.

Мне конечно до такого уровня еще долго, чтобы дописывать ОС.
zltigo
QUOTE (turnon @ Mar 17 2016, 22:35) *
Мне конечно до такого уровня еще долго, чтобы дописывать ОС.

Да на самом деле стоит только начать. Потом в голову все загружается и становится в какой то степени уже "своим".
Первое, что было добавлено, это отдельное создание IdleTask, поскольку у Автора она создавалось и создается до сих пор sad.gif
ПОСЛЕДНЕЙ при запуске шедулера. Если НЕ хватило динамической памяти, то этой самой главной задачи, то она не создавалась. А поскольку она единственная из всех АБСОЛЮТНО необходима, то без все неработоспособно. Что у меня при первом запуске Авторской! демки и случилось sm.gif. Следующим шагом стал вменяемый менеджер памяти отдающий ВСЮ статически нераспределенную память под хип, потом пакет системных вызовов из прерываний... Понеслось...
turnon
Цитата(zltigo @ Mar 18 2016, 01:05) *
Следующим шагом стал вменяемый менеджер памяти отдающий ВСЮ статически нераспределенную память под хип, потом пакет системных вызовов из прерываний... Понеслось...

А где-то опубликованы Ваши наработки? Или это закрытый проект?
zltigo
QUOTE (turnon @ Mar 17 2016, 23:43) *
А где-то опубликованы Ваши наработки? Или это закрытый проект?

Нет, не публиковал. Менеджер памяти на этом форуме выкладывал. Остальное не секрет, но... Вообще на данный момент 8.2.2 версия, как уже писал, вполне продвинута по функциналу. Даже внутри есть измения "как у меня" sm.gif, например, объединенные блоки памяти под QCB и собственно очередь, правда под TCB и стек задачи нет sm.gif - по прежнему два отдельных блока.



SMaster
Я вот жду релиза версии 9.0, в нем запилили возможность статически выделять память TCB/стек, QCB/очередь.
zltigo
QUOTE (SMaster @ Apr 8 2016, 14:23) *
Я вот жду релиза версии 9.0, в нем запилили возможность статически выделять память TCB/стек, QCB/очередь.

Более бесполезное "улучшение" трудно придумать. У Автора есть вариация SafeRTOS, так там сия муть хоть используется для для того, что бы было чем ФОРМАЛЬНО отмазыватся в качестве "принятых мер" по яко-бы "обеспечению безопасности".
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.