pokk 0 18 января, 2021 Опубликовано 18 января, 2021 · Жалоба Как правильно заблокировать задачу. Есть vTaskMenu, она с определенным интервалом запускает функции из модуля LCD на перерисовку экрана с учетом как было сконфигурировано устройство (данные во внешнем ПЗУ модуль mem) поэтому в момент включения устройства ставлю ожидание, на инициализации LCD и mem (MemWaitInitLcd() и WaitInitMem() находяться в соответственных модулях (LCD и Mem).) void vTaskMenu (void *pvParameters){ WaitInitLcd(); WaitInitMem(); xEventGroupSetBits(xEventMenuStart,WAIT_EVENT_INIT_MENU); while(1){ MsgDisplayUpdate((uint8_t*)LcdMsgShow.msg,TEXT_NORMAL); vTaskDelay( LcdMsgShow.time/ portTICK_RATE_MS ); } void WaitInitLcd(void){ xEventGroupSync(xCreatedEventLcdInit,0,WAIT_EVENT_INIT_LCD,portMAX_DELAY); } void WaitInitMem(void){ xEventGroupSync(xCreatedEventGroup,0,WAIT_EVENT_INIT_MEMORY,portMAX_DELAY); } Так вот проблема возникла, когда я случайно поменял местами WaitInitMem(); WaitInitLcd(); получилось из за того что WaitInitMem(); инициализируеться гораздо дольше за это время задача инициализации LCD уже отрабатывает и выставляет xEventGroupSetBits(xCreatedEventLcdInit,WAIT_EVENT_INIT_LCD); и после отработки WaitInitMem программа зависает на WaitInitLcd(); Знаю, что можно xEventGroupSync поставить ждать несколько флагов Но как это сделать в рамках трех модулей menu LCD и mem ? Где создать общую переменную xCreatedEvent.... (для всех задач ?) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
juvf 17 18 января, 2021 Опубликовано 18 января, 2021 · Жалоба #define WAIT_EVENT_INIT_MEM (1<<0) #define WAIT_EVENT_INIT_LCD (1<<1) void vTaskMenu (void *pvParameters){ xEventGroupWaitBits(xEventAnyName,WAIT_EVENT_INIT_MEM | WAIT_EVENT_INIT_LCD, 0, pdTRUE, portMAX_DELAY); while(1){ MsgDisplayUpdate((uint8_t*)LcdMsgShow.msg,TEXT_NORMAL); vTaskDelay( LcdMsgShow.time/ portTICK_RATE_MS ); } Зачем столько много групп эвентов? Общий эвент не нужен. гденить создаем группу эвентов xEventAnyName. не один эвент, а ГРУППУ эвентов. Задачу vTaskMenu блокируем на xEventGroupWaitBits. ждем в группе эвентов xEventAnyName выстовление ОБОИХ флагов. Ждем бесконечно долго. Пока оба флага и WAIT_EVENT_INIT_MEM, и WAIT_EVENT_INIT_LCD не встанут, vTaskMenu будет заблокирован. И ините LCD выставляем флаг WAIT_EVENT_INIT_LCD, в инте памяти флаг WAIT_EVENT_INIT_MEM. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
pokk 0 18 января, 2021 Опубликовано 18 января, 2021 · Жалоба 16 minutes ago, juvf said: гденить создаем группу эвентов xEventAnyName. Да вот это и меня мучило, не хотел вводить ещё одни модуль, но по ходу без него не как Заведу модуль InitTask В си файле будет void WaitInitTask(uint16_t event) // WaitInitTask(WAIT_EVENT_INIT_MEM | WAIT_EVENT_INIT_LCD) xEventGroupWaitBits(xEventAnyName,event, 0, pdTRUE, portMAX_DELAY); } В H файле #define WAIT_EVENT_INIT_MEM (1<<0) #define WAIT_EVENT_INIT_LCD (1<<1) Он будет иклудиться практически во все задачи. Надеюсь 8-16 бит хватит. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
juvf 17 18 января, 2021 Опубликовано 18 января, 2021 · Жалоба 22 минуты назад, pokk сказал: Да вот это и меня мучило, не хотел вводить ещё одни модуль, но по ходу без него не как Зачем заводить ещё один модуль? Что такое модуль? У вас в исходном варианте ТРИ группы эвентов (три модуля). Я вам предложил вариант с одиной группой эвентов (с одни модулем). Зачем вы создаёте ещё одну задачу WaitInitTask? Она не нужна. (или это функция.... просто слово Task обычно используют в именах задач) 2 часа назад, pokk сказал: Знаю, что можно xEventGroupSync поставить ждать несколько флагов Но как это сделать в рамках трех модулей menu LCD и mem ? Где создать общую переменную xCreatedEvent.... (для всех задач ?) 1) Забудьте про xEventGroupSync 2) создаем 3 задачи - menu, lcd и mem. 3) создаем группу флагов xEventAnyName пусть будет как у вас название xEventMenuStart. Это и будет общая переменная, которая свяжет все 3 задачи. 4) определяем дефайны (необязательно) #define WAIT_EVENT_INIT_MEM (1<<0) #define WAIT_EVENT_INIT_LCD (1<<1) 5) запускаем freertos void vTaskMenu (void *pvParameters){ xEventGroupWaitBits(xEventMenuStart,WAIT_EVENT_INIT_MEM | WAIT_EVENT_INIT_LCD, 0, pdTRUE, portMAX_DELAY); while(1){ MsgDisplayUpdate((uint8_t*)LcdMsgShow.msg,TEXT_NORMAL); vTaskDelay( LcdMsgShow.time/ portTICK_RATE_MS ); } void vTaskLCD (void *pvParameters){ initLCD(); xEventGroupSetBits(xEventMenuStart,WAIT_EVENT_INIT_LCD); ... } void vTaskMEM (void *pvParameters){ initMem(); xEventGroupSetBits(xEventMenuStart,WAIT_EVENT_INIT_MEM); ... } Если у вас есть ещё задачи, и они не должны выполняться до тех пор, пока не проинитится lcd и mem, то другие задачи блокируйте также, как и vTaskMenu xEventGroupWaitBits(xEventMenuStart,WAIT_EVENT_INIT_MEM | WAIT_EVENT_INIT_LCD, 0, pdTRUE, portMAX_DELAY); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Andrew_Q 0 22 апреля, 2021 Опубликовано 22 апреля, 2021 · Жалоба Если есть задачи, успех запуска которых зависит от последовательности запуска задач, то стоит порождать (запускать) эти задачи одну из другой. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться