Jump to content
    

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

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

Share this post


Link to post
Share on other sites

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

 

 

 

Share this post


Link to post
Share on other sites

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

 

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...