嵌入式技术william hill官网
直播中

hsdou月半

9年用户 486经验值
擅长:MEMS/传感技术
私信 关注
[问答]

stemwin软件包支持GUI_OS画面却无法显示怎么解决呢

官方默认给出的stemwin软件包都是支持GUI_OS的,只不过对应的库文件需要自己去官方进行下载,在这里调试过程中出现了如下的问题:

1、GUI初始化放在一个线程中,执行也在一个线程中,使用GUI_Exec();来不断的刷新GUI任务。

2、GUI的应用画图等等API在另外一个线程中

3、但是初始化完成后出现无法正常显示GUI的情况,经检查后屏蔽下面的三段代码就可以正常显示了。GUI_Exec()执行过程中没有执行到底层相关的代码(就是指执行窗口或者画点等等函数,而是直接跳出,由于stemwin官方的库文件没有源码,所以来求助)

void GUI_X_Unlock(void)

{

rt_mutex_release(osMutex);

}

void GUI_X_Lock(void)

{

rt_mutex_take(osMutex, RT_WAITING_FOREVER);

}

/* Get Task handle */

U32 GUI_X_GetTaskId(void)

{

rt_uint8_t id = rt_thread_self()->current_priority;

return ((U32)id);

}

初步怀疑是这里互斥量、id和emwin库文件之间存在关系,导致一些执行程序无法很好的执行。

下面是本工程中涉及的一些初始代码:用于图片的显示:

static rt_sem_t dynamic_sem = RT_NULL;

/*********************************************************************************************
名称:emwin_init()

功能:emWin

初始化

参数:无

返回:无

修改:

注释:

*********************************************************************************************/

void emwin_init(void)

{

__HAL_RCC_CRC_CLK_ENABLE(); // 开启CRC时钟

GUI_Init(); // emWin初始化

WM_SetCreateFlags(WM_CF_MEMDEV); // 窗口启用内存设备

GUI_UC_SetEncodeUTF8(); // 使用UTF-8编码

}

/*********************************************************************************************
名称:emwin_timer_handle()

功能:emWin定时器超时回调函数

参数:*parameter -> 传入参数(暂无)

返回:无

修改:

注释:

*********************************************************************************************/

void gui_thread_handle(void *parameter)

{

(void)parameter;

static unsigned char count = 0;

emwin_init();

rt_sem_release(dynamic_sem);

while(1){

count++;

  if(count % 2 == 0)

    GUI_Exec();                                                 // 执行所有挂起的 emWin 任务

#if EMWIN_USE_TOUCH                                             // 是否使用触摸屏

  GUI_TOUCH_Exec();                                             // 传输触摸信息到 emWin

#endif

  rt_thread_delay(10);

}

}

/*********************************************************************************************
名称:gui_init()

功能:emWin gui初始化

参数:无

返回:初始化是否成功

修改:

注释:

*********************************************************************************************/

int gui_init(void)

{

rt_thread_t tid;

dynamic_sem = rt_sem_create("dsem", 0, RT_IPC_FLAG_PRIO);

tid = rt_thread_create("gui_thread",

                        gui_thread_handle, RT_NULL,

                       2048,

                       RT_THREAD_PRIORITY_MAX - 2, 10);

if (tid != RT_NULL)

    rt_thread_startup(tid);

rt_sem_take(dynamic_sem, RT_WAITING_FOREVER);

rt_sem_delete(dynamic_sem);

return RT_EOK;

}

INIT_APP_EXPORT(gui_init);

以上是gui线程的初始化,不断执行GUI_Exec()

#include "gui_thread.h"

#include "STemWin-latest/emwin_thread.h"

extern GUI_CONST_STORAGE GUI_BITMAP bmrtt;

extern GUI_CONST_STORAGE GUI_BITMAP bmfavicon;

/*********************************************************************************************

名称:gui_thread_entry()

功能:GUI线程入口函数

参数:*parameter -> 入口参数(暂无)

返回:无

修改:

注释:

*********************************************************************************************/

void gui_thread_entry(void *parameter)

{

(void)parameter;

GUI_SetBkColor(GUI_WHITE); // 设置背景颜色

GUI_Clear(); // 清除当前窗口,刷新为背景颜色

GUI_DrawBitmap(&bmfavicon, 128, 40); // 在指定位置显示图片

GUI_SetFont(&GUI_Font8x16); // 设置当前字体

GUI_GotoXY(128, 115); // 跳转到指定位置

GUI_SetColor(GUI_BLACK); // 设置当前前景色

GUI_DispString("Zonesion"); // 在当前位置显示字符串

GUI_DrawBitmap(&bmrtt, 57, 135); // 在指定位置显示图片

}

/*********************************************************************************************

名称:gui_thread_init()

功能:GUI线程初始化

参数:无

返回:初始化是否成功

修改:

注释:

*********************************************************************************************/

int gui_thread_init(void)

{

rt_thread_t gui_thread = RT_NULL;

gui_thread = rt_thread_create("gui", // 线程名称

gui_thread_entry,               // 线程入口函数

                            RT_NULL,                        // 线程入口函数传入参数

                            1024,                           // 线程堆栈大小

                            10,                             // 线程优先级

                            20);                            // 时间片

if(gui_thread == RT_NULL)

return -1;

return rt_thread_startup(gui_thread); // 启动线程

}

以上是启动显示图片的线程

/*********************************************************************************************
文件:main.c

作者:Zhouchj 2020.09.23

描述:用户main函数源文件

修改:

注释:

*********************************************************************************************/

#include "gui_thread.h"

#include "STemWin-latest/emwin_thread.h"

int main(void)

{

// gui_init(); // 初始化GUI线程

gui_thread_init(); // GUI线程初始化

return 0;

}

main只是起到启动gui显示的应用

如上三个就是主要的代码,最终显示不成功,屏蔽的gui 中OS的支持就可以正常,请问问题出在哪儿,是初始化GUI的方式不对么?

回帖(5)

申换换

2022-7-29 10:52:08
GUI_X_Lock 被调用到了吗?
gui_thread_entry 这个函数执行结束退出了也没有显示?
举报

hsdou月半

2022-7-29 10:52:28
都调用了,因为库函数封装的,就推荐放在一个线程中调用最好
举报

申换换

2022-7-29 10:52:39
确实是,gui最好是在一个线程内操作。所以这个时候消息机制就派上用场了
举报

hsdou月半

2022-7-29 10:52:56
经过一番测试,按照emwin的正常逻辑,是可以在一个线程中完成GUI的显示工作的,因为它所有的画面显示都是可以通过消息机制进行管理。但是在使用它的OS版本,RTT会出现一些BUG导致emwin卡死,通过屏蔽GUI_X_OS.c如下代码

void GUI_X_Unlock(void)
{
//    rt_mutex_release(osMutex);
}
void GUI_X_Lock(void)
{
//    rt_mutex_take(osMutex, RT_WAITING_FOREVER);
}
/* Get Task handle */
U32 GUI_X_GetTaskId(void)
{
//    rt_uint8_t id = rt_thread_self()->current_priority;
//    return ((U32)id);
    return 0;
}
可以避免卡死情况,卡死出现在按键消息过于快时会偶尔出现,将如上屏蔽后这种情况消失。
而且问题不仅仅反映在如上情况上,还包括初始化过程中出现初始化失败而卡死的情况,由于没有源码,不知道问题出现在哪儿。

不过可以不使用OS库,使用单线程也是一样可行的。
举报

hsdou月半

2022-7-29 10:53:07
根据别人提示,最好是单任务执行GUI的相关代码。多任务执行好像兼容性不是很好
举报

更多回帖

发帖
×
20
完善资料,
赚取积分