нужно из середины второй задачи перейти в начало(!) первой задачи
Схема памяти heap1, т.е. статическое выделение, поэтому vTaskDelete - Create невозможно применить
Остаётся goto
Но не сломает ли goto внутреннюю логику FreeRTOS?..
vTaskDelete - Create никто не мешает применять и в статик - но идея так себе Остаётся goto - прямо из задачи в задачу ??? - сорри, оторвать руки почему нормальные механизмы нельзя использовать типа семафоров для передачи управления из задачи в задачу ?
... Или нотификацию.
Freertos запрещает, ну и чисто логически, vtaskdelete это очищение памяти по сути, а не "удаление" Нормальные механизмы нельзя, так как первый процесс длительный с vtaskdelay и его нельзя прервать, например, нотификацией Я сейчас пришёл к xTaskAbortDelay и флагу Но ещё не тестил Goto работать не будет в функциях как я понял, подробнее не разбирался Ещё думал про set jump long jump, но оставлю на будущее))
Ответил выше
Freertos запрещает ?? - хотелось бы первоисточник - не вижу никаких проблем удалить задачу из шедулера - https://forums.freertos.org/t/vtaskdelete-of-a-static-task/8354 vtaskdelay прервать - ну так и поставьте вместо vtaskdelay тот же семафор или нотификацию - xSemaphoreTake( SemaphoreHandle_t xSemaphore, TickType_t xTicksToWait ) - чем вам не vtasdelay? будет ждать пока не пройдет xTicksToWait или семафор не отдадут ( то же с очередями и нотификациями ) set jump long jump - большие знания большие печали ))) дерзайте !!!!
Сделайте очередь и команды. Одна из команд - ресарт
vTaskDelete использует vPortFree (heap1.c) void vPortFree( void *pv ) { /* Memory cannot be freed using this scheme. See heap_2.c, heap_3.c and heap_4.c for alternative implementations, and the memory management pages of http://www.FreeRTOS.org for more information. */ ( void ) pv; /* Force an assert as it is invalid to call this function. */ configASSERT( pv == NULL ); }
Delay и xSemaphoreTake c xTicksToWait это разное конечно же. В случае с простым delay первая задача (в которой delay) не ждёт вторую задачу, она от неё не зависит. Можно конечно, прикрутить освобождение семафора во второй задаче, но так как вторая задача опять же длительный процесс это становится нетривиальным
Звучит как мем "а теперь рисуем остаток совы" Вопрос был именно в том, как организовать рестарт длительной задачи из другой задачи
Ммм я вот ща подприкинул, вы это технически никак не можете сделать ПРАВИЛЬНО.
не понял ? вторая задача ( это с ваших слов ) должна перезагрузить первую ( значит есть условие ) ? Значит это тривиально ? А послать сигнал первой ( освободить семафор по тому же условию ) о том что нужно произвести определенные действия это не тривиально ?? и поставить в первой задаче if по условию выхода из семафора ( по delay или по сигналу перезагрузки ) ..... т-е использовать штатные способы межпроцессного взаимодействия это нетривиально а taskDelete, xTaskAbortDelay, longjamp.....
я думаю там имелось ввиду то, что по команде задачи В, задача А начнет немедленное выполнение с начала
Пример: первая задача выполняет delay(10 секунд), вторая задача не может прервать в лоб delay на 5 секунде. Значит уже нужно делить делить delay по 1 секунде и проверять, например, семафор, тогда в худшем случае я потеряю одну секунду. Хотелось бы без блокирующих ожиданий
После делея проверять флаг на удаление и удалятся\резетится. Просто на примере делея это не видно. А представьте себе, что задача не в делее висит, а хз, динамически объекты создает в куче. Вот она половину создала. А вы ее взяли и прихлопнули. Где память аллоковски? Где чертова память ликхед?
Непосредственно проблема удаления задачи меня не интересует. Мне бы прыгнуть в начало. Попробую с xTaskAbortDelay, отпишусь
Вот из коробки у вас следующие варианты: 1) Состояние и команды для задачи. При выходе из делея, задача проверит команды, и установит новое состояние. А еще лучше, если она заснет на чтении из очереди и проснется по первой же команде, которая и будет резетом. 2) Динамически создавать задачу, передавая\отбирая интерфейс с внешним миром (который защищен мутексом будет). Т.е. задача проснется, полезет в интерфейс а там ничего нет, после чего она завершится. А новая стартанет с ним и начнет все по новой. (аккуратнее с дедлоком только тут). Может еще есть варианты.
Спасибо 1) Здесь блокирующее ожидание 2) У меня heap_1, что не подразумевает операцию освобождения памяти
Так у вас и с delay тоже
Да. А хотелось бы, чтобы нет)
Т.е. вы хотите, что бы задача резетилась в любой момент, в том числе, если она даже преостановлена диспетчером во время каких-то действий? А не только в блокирующем ожидании.
Если первая задача ждёт 10 секунд вторая может просыпаться хоть 1000 раз, вы путаете делей и ожидание в freertos
В блокирующем ожидании. "Блокирующее" применительно к первой задаче
Пока выйдет delay
а она не может ждать сигнала от "главной" задачи?
Пока задача находится в delay, она заблокирована и не может обновить своё состояние
Не может, потому что как и я написал выше - задача находится в delay, она заблокирована и не может обновить своё состояние
т.е. код этой задачи менять нельзя?
Не понял вопроса
что мешает переписать задачу чтобы она вместо тупого delay ждала сигнал от "главной" задачи?
Ну наверное то, что у задачи своя логика, время выполнения )
Если у вас там делей как времязадающая сущность - сами себе злобный буратино, для этого есть таймеры.
так никто же не мешает вместо тупого delay воткнуть ожидание сигнала с тем же самым временем таймаута. Таймаут вышел работаем дальше, пришёл сигнал, всё бросаем и начинаем сначала.
ну в плане, если там 15 делеев подряд, то каждый раз читать\проверять очередь это будет жестко.
омг. vTaskDelay по вашему не на таймере?)
Нет. Это синхронный блок задачи
ну а какие ещё варианты? Можно конечно удалить задачу из шедуллера и запустить её снова, но, имхо, в этом случае гораздо сложнее обеспечить корректность работы.
Этот вариант возможен и я его уже описывал
Но вы хотите найти способ, сделать архитектурно кривое, не правильное и опасное решение, которое противоречит философии статического выделения и хипа1 в частности?
Не хочу, с чего вы решили?
Тип просто в данный момент это выглядит как вопрос - а как заменить колесо на едущем автомобиле? Ну технически это можно. Но это дурная идея, опасная. Для этого есть автозаплатки и подкачка. Но вы не хотите что бы в колесе что то было или делать систему автоподкачки, просто хотите заменить колесо на ходу. Вот примерно так это выглядит ща =)
По-моему, вы почему-то зацепились за удаление задачи и мыслите вокруг этого, а это не так.
Вы хотите перезапустить задачу с нулевой инструкции. (грубо говоря)
Не совсем. Меня бы устроило выйти из delay, проверить флаг (событие, семафор , etc) и я автоматически окажусь в начале задачи в силу цикличности процесса
Ок. ЖдатьСемафор(100) Это не значит, что он будет ждать семафор и через 100 сек сообщит результат, а значит что как только разлочиться семафор, он тут же стартанет. ЛИБО он стартанет через 100 секунд. Через сколько он стартанул - будет в результате (получено владение семафором или нет) А вот че дальше делать - пишете вы. (ничто не мешает забить хрен и зайти в зону семафора без его получения)
Я отвечал на этот вопрос другому человеку. Повторюсь. Семафор не всегда будет разлочен. Когда-то будет, а когда-то нет. А процесс в задаче должен идти своим чередом Так как дискуссия пошла по кругу, я на этом остановлюсь. Коллеги, спасибо за советы и мнение
Вы можете взводить семафор при рестарте задачи.
Семафор же не общественный туалет, там кто угодно не передергивает. Только 2 задачи о нем знают. 1я пытается попасть раз, занимая его. (ну или при рестарте сразу его занимает, что бы потом на нем встать). И тут же сразу еще раз на нем блочится. Другая разблочивает, если он взведен. Но тут надо тоже с атомарностью не потеряться . Но очереди тут сподручнее будут конечно.
Обсуждают сегодня