Перейти к содержанию
    

Блокировка задачи (на время инициализаци)

Как правильно заблокировать задачу. Есть 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.... (для всех задач ?)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

#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.

 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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 бит хватит.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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);

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если есть задачи, успех запуска которых зависит от последовательности запуска задач, то стоит порождать (запускать) эти задачи одну из другой.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...