Sunday, May 20th 2018, 7:58pm UTC+2

You are not logged in.

  • Login
  • Register

kenmux

Beginner

Date of registration: Jan 18th 2016

Posts: 50

1

Friday, January 5th 2018, 2:38pm

Question about restarting GUI in multi-task system

Hello,

In my project, there's a requirement for restarting GUI.

My debugging code as follows:

1) In the main UI task:

C/C++ Source code

1
2
3
4
5
6
7
8
9
10
11
12
13
  // Exit task
  EXIT :
#if (GUI_X_SINGLE_TASK == 0)
  GUI_X_Task_Delete();  //Delete background GUI task
#endif
  GUI_Exit();
  vTaskDelay(10);
  GUI_Init();
  WM_SelectWindow(WM_GetDesktopWindowEx(0));
  GUI_DrawBitmap(UI_ImageTable[IMG_SPLASH_1_INDEX], 0, 0);
  GUI_Delay(500);
  UI_NotifyFTTask(TASK_EVENT_MISC_RETURN_TO_FT);  //Ask test UI task to continue
  vTaskDelete(NULL);


2) In the test UI task

C/C++ Source code

1
2
3
4
5
6
7
	// Clear Key Message Buffer before starting UI
	START : GUI_ClearKeyBuffer();

	// Start UI
	DEBUG_MSG("FT\r\n");
	UI_EnterFTMenu(WM_HBKWIN);
	vTaskDelay(50);


3) Background task:

C/C++ Source code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#if (GUI_X_SINGLE_TASK == 0)
/*******************************************************************
*
*       _GUI_Task
*
* This task does the background processing.
* The MainTask job is to update invalid windows, but other things such as
* evaluating mouse or touch input may also be done.
*/
static void _GUI_Task( void *pvParameters ) {
  (void)pvParameters;
  DEBUG_MSG ("<I> _GUI_Task Up\r\n");

  while (1) {
    /* Do the background work */
    GUI_Exec();
    GUI_X_ExecIdle();
  }
}
#endif


4) GUI Init custom code:

C/C++ Source code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/*********************************************************************
*
*      GUI_X_Init()
*
* Note:
*   This routine is called from GUI_Init() in any case whether there
*   is an RTOS or not. You can use it for additional initializations
*   needed.
*/

void GUI_X_Init(void) {
#if (GUI_X_SINGLE_TASK == 0)
  BaseType_t result = xTaskCreate(_GUI_Task, "XBKG", configUI_BKG_TASK_STACK_SIZE,
                                  NULL, mainQUEUE_UI_BG_TASK_PRIORITY, &_pGUITask);
  if (result != pdPASS) for (;;) ;
#endif
}


It's all okay if I don't use the background task (GUI_X_SINGLE_TASK == 1).
But, the codes always stop at calling the first "GUI_XXX" function in the test UI task when using background task.

So, my question is:
Is deleting background task is the only work to do during restarting GUI?
Am I missing something crucial else?

emWin Version: v5.44b
Also, I use the FreeRTOS.

Any idea or advice? Thanks.

Kenmux

This post has been edited 1 times, last edit by "kenmux" (Jan 5th 2018, 2:42pm)


SEGGER - Schoenen

Super Moderator

Date of registration: Aug 13th 2015

Posts: 584

2

Monday, January 8th 2018, 2:34pm

Hi,

Is the define GUI_OS set to 1 in GUIConf.h?

Did you implemented the functions GUI_X_InitOS(), GUI_X_Unlock(), GUI_X_Lock(), GUI_X_GetTaskId() properly?

Where exactly does it crash (check how far you get when stepping into the code)?

Is the test UI task still running after GUI_Exit()?
I think it should also be terminated because it's calling GUI functions.

Also, we recommend to call GUI_Exec() from only one task (GUI_Exec() gets called indirectly from GUI_Delay()).

Regards
Sven

kenmux

Beginner

Date of registration: Jan 18th 2016

Posts: 50

3

Monday, January 8th 2018, 3:17pm

Hello Sven,

Thanks for your reply!

I checked carefully with the code, and did some modifications:

1) In the main UI task, calling GUI_Exec() before calling GUI_Exit():

C/C++ Source code

1
2
3
4
5
6
7
8
9
10
11
  // Exit task
  EXIT : GUI_Exec();
  GUI_X_Exit();
  GUI_Exit();
  vTaskDelay(10);
  GUI_Init();
  WM_SelectWindow(WM_GetDesktopWindowEx(0));
  GUI_DrawBitmap(UI_ImageTable[IMG_SPLASH_1_INDEX], 0, 0);
  GUI_Delay(500);
  UI_NotifyFTTask(TASK_EVENT_MISC_RETURN_TO_FT);
  vTaskDelete(NULL);


2) To make sure all resources released, I added this function:

C/C++ Source code

1
2
3
4
5
6
7
8
9
10
11
12
void GUI_X_Exit(void) {
#if (GUI_X_SINGLE_TASK == 0)
  if (_pGUITask) {
    vTaskDelete(_pGUITask);
    _pGUITask = NULL;
  }
#endif
  if (_Semaphore) {
    vSemaphoreDelete(_Semaphore);
    _Semaphore = NULL;
  }
}


Then it worked perfectly.
Yes you are right! There should be ONLY ONE task to call GUI_Exec()...
I'll look into the code to make sure it!

Best regards,
Kenmux

This post has been edited 5 times, last edit by "kenmux" (Jan 8th 2018, 3:31pm)