turnon 1 17 марта, 2016 Опубликовано 17 марта, 2016 · Жалоба При использовании семафоров наткнулся на 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 0 17 марта, 2016 Опубликовано 17 марта, 2016 (изменено) · Жалоба ... Конечно смысла в семафорах до старта задач нет, до старта задач поток один. Но это унифицированный код, он используется и из задач, и до старта планировщика. Все работало нормально, но вчера вылез HardFault, трассировка привела к этому участку в queue.c: if( xTaskResumeAll() == pdFALSE ) { portYIELD_WITHIN_API(); } При вызове portYIELD_WITHIN_API() вылетает в HardFault. А это Ваш код? В смысле Вы так придумали или это код совместной работы в команде? А зачем так извращаться вообще? Мне, можно сказать новичку, итак ясно, что при вызове portYIELD_WITHIN_API() работа перейдет к планировщику. А как оно у Вас до сих пор работало интересно? :) Конечно в мире разные бывают любители и пр. Но вот зачем иногда не совсем понятно. Изменено 17 марта, 2016 пользователем AleksBak Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
turnon 1 17 марта, 2016 Опубликовано 17 марта, 2016 · Жалоба А это Ваш код? Нет, это код из queue.c, привел его для понимания что вызывает HardFault Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
esaulenka 7 17 марта, 2016 Опубликовано 17 марта, 2016 · Жалоба Да, очереди/семафоры/sleep() с остановленным шедулером не работают. Я поначалу кинулся расставлять проверки "планировщик работает" прямо в код операционки (мне кажется, это правильнее, чем тыкать во все возможные места xTaskGetSchedulerState() ), но потом просто перенёс большую часть кода в задачи (до того у меня вся инициализация железа была в main() - осталось только самое необходимое). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AleksBak 0 17 марта, 2016 Опубликовано 17 марта, 2016 · Жалоба Нет, это код из queue.c, привел его для понимания что вызывает HardFault Да это понятно. Я неправильно выразился - имел ввиду, что код/проект/структуру программы Вы сами придумали или кто-то "заставляет"(совместная команда, код какой задачи закрытый и пр.) именно так поступить (использовать семафоры до старта). Уже тут esaulenka и написал к чему пришел и как получше тут будет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 1 17 марта, 2016 Опубликовано 17 марта, 2016 · Жалоба (до того у меня вся инициализация железа была в main() - осталось только самое необходимое). В main() действительно самая минимальная инициализация и подъем, например, консоли. После чего или запускается задача инициализации и потом прибивается за ненадобностью, или ставится hook на IdleTask и потом убирается. 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 1 17 марта, 2016 Опубликовано 17 марта, 2016 · Жалоба Да это понятно. Я неправильно выразился - имел ввиду, что код/проект/структуру программы Вы сами придумали или кто-то "заставляет"(совместная команда, код какой задачи закрытый и пр.) именно так поступить (использовать семафоры до старта). Уже тут esaulenka и написал к чему пришел и как получше тут будет. Сам придумал. Код унифицированный, он не знает что работает из задачи или не из задачи. При работе из задачи ресурс должен быть защищен от одновременного использорвания из нескольких потоков, потому в коде семафоры. Я поначалу кинулся расставлять проверки "планировщик работает" прямо в код операционки (мне кажется, это правильнее, чем тыкать во все возможные места xTaskGetSchedulerState() ), но потом просто перенёс большую часть кода в задачи (до того у меня вся инициализация железа была в main() - осталось только самое необходимое). У меня в main только одноразовые инициализации, требующие много стековой памяти. Чтобы не выделять много стека под каждую задачу. А так тоже все остальное в задачах. Также реализовано отслеживание зависания задач. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 1 17 марта, 2016 Опубликовано 17 марта, 2016 · Жалоба потому в коде семафоры. Некоторое количество лет назал, где-то в районе появления FreeRTOS 2.0 я начал с ней копаться. До этого имел за плечами работу с операционными сисиемами, как с чужими, так и со своими. Удивило тогда меня, что всякие семафоры и иже с ними сделаны через макросы очередей. Призадумался я да и понял, что семафоры и иже с ними в общем-то есть ЛИШНЯЯ сущность. И с тех пор не пользую. За ненадобностью. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
turnon 1 17 марта, 2016 Опубликовано 17 марта, 2016 · Жалоба Некоторое количество лет назал, где-то в районе появления FreeRTOS 2.0 я начал с ней копаться. До этого имел за плечами работу с операционными сисиемами, как с чужими, так и со своими. Удивило тогда меня, что всякие семафоры и иже с ними сделаны через макросы очередей. Призадумался я да и понял, что семафоры и иже с ними в общем-то есть ЛИШНЯЯ сущность. И с тех пор не пользую. За ненадобностью. А как вы решаете проблему с одновременной работой участка кода из нескольких задач? Конечно в случае если участок кода критичен чтобы к нему не обращались из нескольких задая одновременно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 1 17 марта, 2016 Опубликовано 17 марта, 2016 · Жалоба А как вы решаете проблему с одновременной работой участка кода из нескольких задач? Конечно в случае если участок кода критичен чтобы к нему не обращались из нескольких задая одновременно. Как оказалось :), система может строится так, что такая задача может быть решена и без лобовых семафоров. Например, чем этот "участок кода" не есть отдельная задача получающая сообщения и их обрабатывающая? Естественно, при этом нужно много тщательнее продумывать структуру, ибо задачи действительно должны быть задачами выполняющими разумны едействия, а не кучей "кусков кода". Семафоры это в общем-то заплатки. Ими удобно и привычно можно латать, а можно и не латать :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
turnon 1 17 марта, 2016 Опубликовано 17 марта, 2016 · Жалоба Как оказалось :), система может строится так, что такая задача может быть решена и без лобовых семафоров. Например, чем этот "участок кода" не есть отдельная задача получающая сообщения и их обрабатывающая? Это слишком расточительно, на тот же лог выделять отдельную задачу. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 1 17 марта, 2016 Опубликовано 17 марта, 2016 · Жалоба Это слишком расточительно, на тот же лог выделять отдельную задачу. Лог дело важное и одновременно он не должен перекашивать систему тормозя задачи, причем с перекосами приоритетов. Так что именно разработке логирования надо уделять особое внимание и не скупится. Если действительно сыпется идет обильная информция с самых разных уровней, причем не всегда, а когда, наример, отладку включили, то надо ОЧЕНЬ крепко думать, как организовать доступ к логу. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
turnon 1 17 марта, 2016 Опубликовано 17 марта, 2016 · Жалоба Если действительно сыпется идет обильная информция с самых разных уровней, причем не всегда, а когда, наример, отладку включили, то надо ОЧЕНЬ крепко думать, как организовать доступ к логу. Не обильная, иначе не переварить человеку. При использовании задачи для того же лога возникает новая проблема - какой длины выделить очередь для сообщений, чтобы лог всегда гарантировано мог принять новое сообщение. В итоге снова приходим к семафорам :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 1 17 марта, 2016 Опубликовано 17 марта, 2016 · Жалоба Не обильная, иначе не переварить человеку, для которого этот лог и ведется. Ну лог, на то и лог, что бы читать его и длинными зимними вечерами :). И лучше хорошо подумать как не тратить целую задачу на это. Затраты одного MCB и стека, который по любому хоть в отдельной, хоть нет, логированим съедаться будет. Плюс при использовании задачи для того же лога возникает новая проблема - какой длины выделить очередь для сообщений, чтобы лог всегда гарантировано мог принять новое сообщение. Средний темп выдачи лога по любому должен быть оценен. Хоть с задачей, хоть без задачи, хоть с семафорами, хоть без ничего, хоть как. Не будет буферизации будет "никак". Где будет буфер в очереди или нет, дело десятое. Если задачам придется непрерывно драться и ждать МЕДЛЕННОГО логирования, то это перекосит всю систему. Если вдруг, при какой то нештатной ситуации темп выдачи лога резко возрос, то тем блее следует аккуратно разбираться с тем, кто может ждать, кто не может, а чья инфрмация вообще сейчас неважна - выкинуть в пропость. В итоге снова приходим к семафорам :) Дались Вам эти семафоры. Это совершенно виртуальная штука, функционал котрых может быть организован разнообразными способами. Естественно НЕ с целью сделать те-же яйца в профиль, а получить дополнительный функционал. Ведь та же реализация семафоров на очередях на самом деле просто усекала функционал очереди, котрый, если подумать, можно использовать БОЛЕЕ полно и эффективно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
turnon 1 17 марта, 2016 Опубликовано 17 марта, 2016 · Жалоба Ведь та же реализация семафоров на очередях на самом деле просто усекала функционал очереди, котрый, если подумать, можно использовать БОЛЕЕ полно и эффективно. Согласен, у FreeRtos только очереди, на базе нее реализовали все примитивы. А вот в новых версиях появилась xTaskNotify() / xTaskNotifyWait(), это тоже на очередях, или там свой механизм? Это эффективнее очередей для ожидания задачей сигнала к старту? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться