RTOS支持STemWin(以RT-Thread為例)
之前在小熊派上移植過一個(gè)裸機(jī)版本的STemWin,耍了不少例程:
實(shí)戰(zhàn)貼:STemWin在小熊派上的移植
1.獲取項(xiàng)目:
git clone https://gitee.com/morixinguan/bear-pi.git
以下是其中一到兩個(gè)裸機(jī)項(xiàng)目的顯示效果:
2.漸變色條顯示實(shí)驗(yàn):
多文本控件實(shí)驗(yàn):
后面計(jì)劃在小熊派的屏幕上實(shí)現(xiàn)一個(gè)串口終端,支持RT-Thread的shell哈,那一定非常有趣!
目前RTOS的使用率越來越高,STemWin也提供了RTOS的配置模板:
源文件如下:
#include "GUI.h" /* FreeRTOS include files */ #include "cmsis_os.h" /*********************************************************************
*
* Global data
*/
//定義一個(gè)互斥鎖
static osMutexId osMutex;
//定義一個(gè)信號量
static osSemaphoreId osSemaphore;
/*********************************************************************
*
* Timing:
* GUI_X_GetTime()
* GUI_X_Delay(int)
Some timing dependent routines require a GetTime
and delay function. Default time unit (tick), normally is
1 ms.
*/
//獲取Tick
int GUI_X_GetTime(void)
{ return ((int) xTaskGetTickCount());
}
//GUI延時(shí)函數(shù)
void GUI_X_Delay(int ms)
{
vTaskDelay( ms );
}
/*********************************************************************
*
* GUI_X_Init()
*
* Note:
* GUI_X_Init() is called from GUI_Init is a possibility to init
* some hardware which needs to be up and running before the GUI.
* If not required, leave this routine blank.
*/
//一般不填寫
void GUI_X_Init(void) {
}
/*********************************************************************
*
* GUI_X_ExecIdle
*
* Note:
* Called if WM is in idle state
*/
//WM空閑狀態(tài)接口
void GUI_X_ExecIdle(void) {}
/*********************************************************************
*
* Multitasking:
*
* GUI_X_InitOS()
* GUI_X_GetTaskId()
* GUI_X_Lock()
* GUI_X_Unlock()
*
* Note:
* The following routines are required only if emWin is used in a
* true multi task environment, which means you have more than one
* thread using the emWin API.
* In this case the
* #define GUI_OS 1 * needs to be in GUIConf.h
*/
//針對OS通信需要初始化的內(nèi)容
/* Init OS */
void GUI_X_InitOS(void)
{
/* Create Mutex lock */
osMutexDef(MUTEX);
/* Create the Mutex used by the two threads */
osMutex = osMutexCreate(osMutex(MUTEX));
/* Create Semaphore lock */
osSemaphoreDef(SEM);
/* Create the Semaphore used by the two threads */
osSemaphore= osSemaphoreCreate(osSemaphore(SEM), 1);
}
//給出互斥量
void GUI_X_Unlock(void)
{
osMutexRelease(osMutex);
}
//獲取互斥量
void GUI_X_Lock(void)
{
osMutexWait(osMutex , osWaitForever) ;
}
//獲取當(dāng)前線程句柄
/* Get Task handle */
U32 GUI_X_GetTaskId(void)
{ return ((U32) osThreadGetId());
}
//獲取信號量
void GUI_X_WaitEvent (void)
{
osSemaphoreWait(osSemaphore , osWaitForever) ;
}
//釋放信號量
void GUI_X_SignalEvent (void)
{
osMutexRelease(osSemaphore);
}
/*********************************************************************
*
* Logging: OS dependent
Note:
Logging is used in higher debug levels only. The typical target
build does not use logging and does therefor not require any of
the logging routines below. For a release build without logging
the routines below may be eliminated to save some space.
(If the linker is not function aware and eliminates unreferenced functions automatically)
*/
//LOG相關(guān),一般不實(shí)現(xiàn)
void GUI_X_Log (const char *s) { }
void GUI_X_Warn (const char *s) { }
void GUI_X_ErrorOut(const char *s) { }
/*************************** End of file ****************************/
那么如何用RT-Thread的接口來代替呢??只要按照要求實(shí)現(xiàn)如下常用的接口就行了,其它不常用的就不用管:
int GUI_X_GetTime(void);
void GUI_X_Delay(int ms);
void GUI_X_Init(void);
void GUI_X_ExecIdle(void);
void GUI_X_InitOS(void);
void GUI_X_Unlock(void);
void GUI_X_Lock(void);
U32 GUI_X_GetTaskId(void) ;
void GUI_X_WaitEvent (void) ;
void GUI_X_SignalEvent (void) ;
void GUI_X_Log (const char *s);
void GUI_X_Warn (const char *s);
void GUI_X_ErrorOut(const char *s);
于是,我們復(fù)制GUI_X_OS這個(gè)文件,然后改名為GUI_X_RT_Thread,也就相當(dāng)于定義了一個(gè)基于RT-Thread的配置模板,然后基于新的配置模板對一些接口的實(shí)現(xiàn)和修改:
然后只要按照要求實(shí)現(xiàn)以下常用的接口就行了:
int GUI_X_GetTime(void);
void GUI_X_Delay(int ms);
void GUI_X_ExecIdle(void);
void GUI_X_InitOS(void);
void GUI_X_Unlock(void);
void GUI_X_Lock(void);
U32 GUI_X_GetTaskId(void) ;
void GUI_X_WaitEvent (void) ;
void GUI_X_SignalEvent (void) ;
接下來對文件的內(nèi)容進(jìn)行修改:
-
包含對應(yīng)的頭文件
/* RT-Thread include files */
//#include "cmsis_os.h" #include
-
將全局變量定義進(jìn)行修改
//static osMutexId osMutex;
//static osSemaphoreId osSemaphore;
/*定義一個(gè)互斥鎖*/
static rt_mutex_t osMutex = RT_NULL;
/*定義一個(gè)信號量*/
static rt_sem_t osSemaphore = RT_NULL;
-
實(shí)現(xiàn)GUI_X_GetTime和GUI_X_Delay函數(shù)
int GUI_X_GetTime(void) //主要用于時(shí)機(jī)觸發(fā),代替裸機(jī)下的OS_TimeMS變量
{
//return ((int) xTaskGetTickCount());
//使用RT-Thread的rt_tick_get函數(shù)獲取tick return rt_tick_get();
}
void GUI_X_Delay(int ms)
{
//vTaskDelay( ms );
//使用RT-Thread的延時(shí)函數(shù),單位ms
rt_thread_mdelay(ms);
}
-
實(shí)現(xiàn)GUI_X_ExecIdle函數(shù)
void GUI_X_ExecIdle(void) {
//空閑狀態(tài)下1ms延時(shí)即可
GUI_X_Delay(1);
}
-
實(shí)現(xiàn)GUI_X_InitOS函數(shù)
void GUI_X_InitOS(void)
{
/*創(chuàng)建互斥信號量,用于資源共享*/
osMutex = rt_mutex_create("osMutex", RT_IPC_FLAG_FIFO);
RT_ASSERT(osMutex != RT_NULL);
/*創(chuàng)建信號量,用于事件觸發(fā)*/
osSemaphore = rt_sem_create("osSem", 0, RT_IPC_FLAG_FIFO);
RT_ASSERT(osSemaphore != RT_NULL);
}
-
實(shí)現(xiàn)GUI_X_Unlock函數(shù)
void GUI_X_Unlock(void)
{
//osMutexRelease(osMutex);
//給出互斥量
rt_mutex_release(osMutex);
}
-
實(shí)現(xiàn)GUI_X_Lock函數(shù)
void GUI_X_Lock(void)
{
//osMutexWait(osMutex , osWaitForever) ; if(osMutex == RT_NULL)
{
GUI_X_InitOS();
}
//獲取互斥量
rt_mutex_take(osMutex, RT_WAITING_FOREVER);
}
-
實(shí)現(xiàn)GUI_X_GetTaskId函數(shù)
U32 GUI_X_GetTaskId(void)
{
//return ((U32) osThreadGetId());
/*獲取當(dāng)前線程句柄*/ return (U32) rt_thread_self();
}
-
實(shí)現(xiàn)GUI_X_WaitEvent函數(shù)
void GUI_X_WaitEvent (void)
{
// osSemaphoreWait(osSemaphore , osWaitForever) ;
/*獲取信號量*/ while(rt_sem_take(osSemaphore, RT_WAITING_FOREVER) != RT_EOK);
}
-
實(shí)現(xiàn)GUI_X_SignalEvent函數(shù)
void GUI_X_SignalEvent (void)
{
//osMutexRelease(osSemaphore);
/*給出信號量*/
rt_sem_release(osSemaphore);
}
這樣模板就修改完了,接下來,將之前裸機(jī)的工程的EMWIN目錄拷貝到我移植好的RT-Thread工程上:(移植的工程來源于以下作品,我把里面很多邏輯裁掉了)
開源作品:基于RT-Thread 智慧農(nóng)業(yè)監(jiān)測系統(tǒng)產(chǎn)品級開發(fā)
并添加好對應(yīng)的文件:
然后GUIConf.h中,要讓GUI支持OS,則需要在Keil菜單對定義一個(gè)全局宏,使其全局生效,這樣STemWin就支持RTOS了,其它配置參數(shù)和裸機(jī)驅(qū)動STemWin配置毫無二致,參考文初那篇文章的配置方法就可以了,唯一不同的地方就是使用的模板不同。
最后我定義了一個(gè)任務(wù),編寫了一個(gè)簡單的STemWin顯示實(shí)驗(yàn)和按鍵切換背景色的demo,實(shí)現(xiàn)效果如下:
獲取項(xiàng)目:
git clone https://gitee.com/morixinguan/bear-pi.git
免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺僅提供信息存儲服務(wù)。文章僅代表作者個(gè)人觀點(diǎn),不代表本平臺立場,如有問題,請聯(lián)系我們,謝謝!