pokk 0 Posted January 18 · Report post Как правильно заблокировать задачу. Есть 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.... (для всех задач ?) Quote Ответить с цитированием Share this post Link to post Share on other sites
juvf 0 Posted January 18 · Report post #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. Quote Ответить с цитированием Share this post Link to post Share on other sites
pokk 0 Posted January 18 · Report post 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 бит хватит. Quote Ответить с цитированием Share this post Link to post Share on other sites
juvf 0 Posted January 18 · Report post 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); Quote Ответить с цитированием Share this post Link to post Share on other sites