参考博客链接
记录一下移植STemWin
使用的是自己写的LCD驱动文件
1.官方文件介绍
文件夹 | 说明 |
---|---|
Config | 其中的 GUIConf.c 文件用于配置 emWin 的存储空间分配,GUIConf.h 文 件 用 于 裁 剪 emWin 的 功 能 。 其 余 的 GUIDRV_Template.c 、LCDConf_FlexColor.c、 GUIDRV_wf.c 是 emWin 应用在不同液晶时使用的不同驱动模板 |
Lib | 包含了 emWin 的代码库文件,针对 Cortex-M0、 M3 和 M4 这些不同 CPU 内核以及是否优化,都有一个相对应的 emWin 库,在使用的时候我们要根据自己的平台选择合适的库文件 |
inc | 包含了全部的 emWin 库核心的头文件,各种关于库函数的声明、定义都在这些文件里面 |
OS | 包含了 GUI_X.c 及 GUI_X_FreeRTOS.c 文件,分别是对应裸机平台的 GUI 延时,和多任务系统平台的关于进程调度之类的一些 emWin 所需要的底层接口 |
现在开始新建工程,假定我们已经实现了以下函数
LCD初始化函数 | void xxLCD_Init(void) |
---|---|
LCD画点函数 | void LCD_DrawPoint(uint16_t x, uint16_t y, uint32_t color) |
LCD读点函数 | uint32_t LCD_ReadPoint(uint16_t x, uint16_t y); |
/**
* @功能说明: LCD画点函数
* @参数: x:x坐标
* y:y坐标
* color:颜色
* @返回值: 无
*/
void LCD_DrawPoint(uint16_t x, uint16_t y, uint32_t color)
{
}
/**
* @功能说明: LCD读点函数
* @参数: x:x坐标
* y:y坐标
* @返回值: 像素值
*/
uint32_t LCD_ReadPoint(uint16_t x, uint16_t y)
{
}
2.添加文件进工程
-
将Inc里面的文件全部添加进工程,因为全是头文件,只需要添加头文件路径即可
-
添加Lib文件夹中合适的库文件,并注意添加为库文件
如图
-
OS文件夹中选裸机文件添加进工程
-
Config文件夹中需要添加的文件
-
完成之后如下图
箭头指向的库文件略有不同
编辑文件
- GUIconf.h文件
这里需要根据自己的需要配置STemWin
简要介绍宏定义
GUI_NUM_LAYERS 图层数目
OS_SUPPORT 是否支持操作系统
GUI_SUPPORT_TOUCH 是否支持触摸屏
GUI_DEFAULT_FONT 字体大小
#ifndef GUICONF_H
#define GUICONF_H
/*********************************************************************
*
* Multi layer/display support
*/
#define GUI_NUM_LAYERS 1 // Maximum number of available layers
/*********************************************************************
*
* Multi tasking support
*/
#ifdef OS_SUPPORT
#define GUI_OS (1) // Compile with multitasking support
#else
#define GUI_OS (0)
#endif
/*********************************************************************
*
* Configuration of touch support
*/
#ifndef GUI_SUPPORT_TOUCH
#define GUI_SUPPORT_TOUCH (0) // Support touchscreen
#endif
/*********************************************************************
*
* Default font
*/
#define GUI_DEFAULT_FONT &GUI_Font8x16
/*********************************************************************
*
* Configuration of available packages
*/
#define GUI_SUPPORT_MOUSE (1) /* Support a mouse */
#define GUI_WINSUPPORT (1) /* Use window manager */
#define GUI_SUPPORT_MEMDEV (1) /* Memory device package available */
#define GUI_SUPPORT_DEVICES (1) /* Enable use of device pointers */
#endif /* Avoid multiple inclusion */
- GUIConf.c
#include "GUI.h"
#include "myLCD.h"
/*********************************************************************
*
* Defines
*
**********************************************************************
*/
//
// Define the available number of bytes available for the GUI
//
#define GUI_NUMBYTES 1024 * 1024 * 8 //8MB
#define GUI_EXTBUFADD (LCD_FRAME_BUFFER + 800 * 480 * 3)
static U32 aMemory[GUI_NUMBYTES / 4] __attribute__((at(GUI_EXTBUFADD)));
/*********************************************************************
*
* Public code
*
**********************************************************************
*/
/*********************************************************************
*
* GUI_X_Config
*
* Purpose:
* Called during the initialization process in order to set up the
* available memory for the GUI.
*/
void GUI_X_Config(void) {
//
// 32 bit aligned memory area
//
//static U32 *aMemory = [GUI_NUMBYTES / 4];
//
// Assign memory to emWin
//
GUI_ALLOC_AssignMemory(aMemory, GUI_NUMBYTES);
//
// Set default font
//
GUI_SetDefaultFont(GUI_DEFAULT_FONT);
}
/*************************** End of file ****************************/
一些重要的宏定义
GUI_NUMBYTES STemWin动态内存大小 单位字节
我使用的外部SDRAM作为STemWIN的动态内存
GUI_EXTBUFADD 外部SDRAM的地址
attribute((at(GUI_EXTBUFADD)));分配地址空间
static U32 aMemory[GUI_NUMBYTES / 4] STemWin的动态内存单位 字
如果使用内部RAM作为STemWin的动态内存 可以把
#define GUI_EXTBUFADD (LCD_FRAME_BUFFER + 800 * 480 * 3)
static U32 aMemory[GUI_NUMBYTES / 4] __attribute__((at(GUI_EXTBUFADD)));
改为
#define GUI_NUMBYTES 1024 * 8 //8KB
static U32 aMemory[GUI_NUMBYTES / 4];
具体大小自行设置
之后调用GUI_ALLOC_AssignMemory分配内存
GUI_SetDefaultFont 设置默认字体
- LCDConf_Lin_Template.c
/*********************************************************************
* SEGGER Microcontroller GmbH & Co. KG *
* Solutions for real time microcontroller applications *
**********************************************************************
* *
* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG *
* *
* Internet: www.segger.com Support: support@segger.com *
* *
**********************************************************************
** emWin V5.44 - Graphical user interface for embedded applications **
All Intellectual Property rights in the Software belongs to SEGGER.
emWin is protected by international copyright laws. Knowledge of the
source code may not be used to write a similar product. This file may
only be used in accordance with the following terms:
The software has been licensed to STMicroelectronics International
N.V. a Dutch company with a Swiss branch and its headquarters in Plan-
les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the
purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_
troller products commercialized by Licensee only, sublicensed and dis_
tributed under the terms and conditions of the End User License Agree_
ment supplied by STMicroelectronics International N.V.
Full source code is available at: www.segger.com
We appreciate your understanding and fairness.
----------------------------------------------------------------------
File : LCDConf_Lin_Template.c
Purpose : Display controller configuration (single layer)
---------------------------END-OF-HEADER------------------------------
*/
/**
******************************************************************************
* @attention
*
* <h2><center>© Copyright (c) 2018 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license SLA0044,
* the "License"; You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
* http://www.st.com/SLA0044
*
******************************************************************************
*/
#include "GUI.h"
#include "GUIDRV_Lin.h"
#include "MyLCD.h"
/*********************************************************************
*
* Layer configuration (to be modified)
*
**********************************************************************
*/
//
// Physical display size
//
#define XSIZE_PHYS TFTLCD_WIDTH //定义宽度
#define YSIZE_PHYS TFTLCD_HEIGHT//定义长度
//
// Color conversion
//
#define COLOR_CONVERSION GUICC_M565
//
// Display driver
//
#define DISPLAY_DRIVER &GUIDRV_Template_API
//
// Buffers / VScreens
//
#define NUM_BUFFERS 1 // Number of multiple buffers to be used
#define NUM_VSCREENS 1 // Number of virtual screens to be used
/*********************************************************************
*
* Configuration checking
*
**********************************************************************
*/
#ifndef VRAM_ADDR
#define VRAM_ADDR 0 // TBD by customer: This has to be the frame buffer start address
#endif
#ifndef XSIZE_PHYS
#error Physical X size of display is not defined!
#endif
#ifndef YSIZE_PHYS
#error Physical Y size of display is not defined!
#endif
#ifndef COLOR_CONVERSION
#error Color conversion not defined!
#endif
#ifndef DISPLAY_DRIVER
#error No display driver defined!
#endif
#ifndef NUM_VSCREENS
#define NUM_VSCREENS 1
#else
#if (NUM_VSCREENS <= 0)
#error At least one screeen needs to be defined!
#endif
#endif
#if (NUM_VSCREENS > 1) && (NUM_BUFFERS > 1)
#error Virtual screens and multiple buffers are not allowed!
#endif
/*********************************************************************
*
* Public code
*
**********************************************************************
*/
/*********************************************************************
*
* LCD_X_Config
*
* Purpose:
* Called during the initialization process in order to set up the
* display driver configuration.
*
*/
void LCD_X_Config(void) {
//
// At first initialize use of multiple buffers on demand
//
#if (NUM_BUFFERS > 1)
GUI_MULTIBUF_Config(NUM_BUFFERS);
#endif
//
// Set display driver and color conversion for 1st layer
//
GUI_DEVICE_CreateAndLink(DISPLAY_DRIVER, COLOR_CONVERSION, 0, 0);
//
// Display driver configuration, required for Lin-driver
//
if (LCD_GetSwapXY()) {
LCD_SetSizeEx (0, YSIZE_PHYS, XSIZE_PHYS);
LCD_SetVSizeEx(0, YSIZE_PHYS * NUM_VSCREENS, XSIZE_PHYS);
} else {
LCD_SetSizeEx (0, XSIZE_PHYS, YSIZE_PHYS);
LCD_SetVSizeEx(0, XSIZE_PHYS, YSIZE_PHYS * NUM_VSCREENS);
}
LCD_SetVRAMAddrEx(0, (void *)VRAM_ADDR);
//
// Set user palette data (only required if no fixed palette is used)
//
#if defined(PALETTE)
LCD_SetLUTEx(0, PALETTE);
#endif
//
// Set custom functions for several operations to optimize native processes
//
// LCD_SetDevFunc(0, LCD_DEVFUNC_COPYBUFFER, (void(*)(void))CUSTOM_LCD_CopyBuffer);
// LCD_SetDevFunc(0, LCD_DEVFUNC_COPYRECT, (void(*)(void))CUSTOM_LCD_CopyRect);
// LCD_SetDevFunc(0, LCD_DEVFUNC_FILLRECT, (void(*)(void))CUSTOM_LCD_FillRect);
// LCD_SetDevFunc(0, LCD_DEVFUNC_DRAWBMP_8BPP, (void(*)(void))CUSTOM_LCD_DrawBitmap8bpp);
// LCD_SetDevFunc(0, LCD_DEVFUNC_DRAWBMP_16BPP, (void(*)(void))CUSTOM_LCD_DrawBitmap16bpp);
}
/*********************************************************************
*
* LCD_X_DisplayDriver
*
* Purpose:
* This function is called by the display driver for several purposes.
* To support the according task the routine needs to be adapted to
* the display controller. Please note that the commands marked with
* 'optional' are not cogently required and should only be adapted if
* the display controller supports these features.
*
* Parameter:
* LayerIndex - Index of layer to be configured
* Cmd - Please refer to the details in the switch statement below
* pData - Pointer to a LCD_X_DATA structure
*
* Return Value:
* < -1 - Error
* -1 - Command not handled
* 0 - Ok
*/
int LCD_X_DisplayDriver(unsigned LayerIndex, unsigned Cmd, void * pData) {
int r;
switch (Cmd) {
case LCD_X_INITCONTROLLER: {
//
// Called during the initialization process in order to set up the
// display controller and put it into operation. If the display
// controller is not initialized by any external routine this needs
// to be adapted by the customer...
//
// ...
TFTLCD_Init();
return 0;
}
case LCD_X_SETVRAMADDR: {
//
// Required for setting the address of the video RAM for drivers
// with memory mapped video RAM which is passed in the 'pVRAM' element of p
//
LCD_X_SETVRAMADDR_INFO * p;
p = (LCD_X_SETVRAMADDR_INFO *)pData;
//...
return 0;
}
case LCD_X_SETORG: {
//
// Required for setting the display origin which is passed in the 'xPos' and 'yPos' element of p
//
LCD_X_SETORG_INFO * p;
p = (LCD_X_SETORG_INFO *)pData;
//...
return 0;
}
case LCD_X_SHOWBUFFER: {
//
// Required if multiple buffers are used. The 'Index' element of p contains the buffer index.
//
LCD_X_SHOWBUFFER_INFO * p;
p = (LCD_X_SHOWBUFFER_INFO *)pData;
//...
return 0;
}
case LCD_X_SETLUTENTRY: {
//
// Required for setting a lookup table entry which is passed in the 'Pos' and 'Color' element of p
//
LCD_X_SETLUTENTRY_INFO * p;
p = (LCD_X_SETLUTENTRY_INFO *)pData;
//...
return 0;
}
case LCD_X_ON: {
//
// Required if the display controller should support switching on and off
//
return 0;
}
case LCD_X_OFF: {
//
// Required if the display controller should support switching on and off
//
// ...
return 0;
}
default:
r = -1;
}
return r;
}
/*************************** End of file ****************************/
其中GUI_DEVICE_CreateAndLink函数中
GUIDRV_Template_API代表使用自己的LCD驱动函数
GUICC_M565 这个是颜色定义 RGB565
LCD_X_DisplayDriver函数中添加自定义LCD初始化函数
在LCD_X_INITCONTROLLER下面添加自己的LCD初始化函数
/*********************************************************************
*
* LCD_X_DisplayDriver
*
* Purpose:
* This function is called by the display driver for several purposes.
* To support the according task the routine needs to be adapted to
* the display controller. Please note that the commands marked with
* 'optional' are not cogently required and should only be adapted if
* the display controller supports these features.
*
* Parameter:
* LayerIndex - Index of layer to be configured
* Cmd - Please refer to the details in the switch statement below
* pData - Pointer to a LCD_X_DATA structure
*
* Return Value:
* < -1 - Error
* -1 - Command not handled
* 0 - Ok
*/
int LCD_X_DisplayDriver(unsigned LayerIndex, unsigned Cmd, void * pData) {
int r;
switch (Cmd) {
case LCD_X_INITCONTROLLER: {
//
// Called during the initialization process in order to set up the
// display controller and put it into operation. If the display
// controller is not initialized by any external routine this needs
// to be adapted by the customer...
//
// ...
TFTLCD_Init();
return 0;
}
case LCD_X_SETVRAMADDR: {
//
// Required for setting the address of the video RAM for drivers
// with memory mapped video RAM which is passed in the 'pVRAM' element of p
//
LCD_X_SETVRAMADDR_INFO * p;
p = (LCD_X_SETVRAMADDR_INFO *)pData;
//...
return 0;
}
case LCD_X_SETORG: {
//
// Required for setting the display origin which is passed in the 'xPos' and 'yPos' element of p
//
LCD_X_SETORG_INFO * p;
p = (LCD_X_SETORG_INFO *)pData;
//...
return 0;
}
case LCD_X_SHOWBUFFER: {
//
// Required if multiple buffers are used. The 'Index' element of p contains the buffer index.
//
LCD_X_SHOWBUFFER_INFO * p;
p = (LCD_X_SHOWBUFFER_INFO *)pData;
//...
return 0;
}
case LCD_X_SETLUTENTRY: {
//
// Required for setting a lookup table entry which is passed in the 'Pos' and 'Color' element of p
//
LCD_X_SETLUTENTRY_INFO * p;
p = (LCD_X_SETLUTENTRY_INFO *)pData;
//...
return 0;
}
case LCD_X_ON: {
//
// Required if the display controller should support switching on and off
//
return 0;
}
case LCD_X_OFF: {
//
// Required if the display controller should support switching on and off
//
// ...
return 0;
}
default:
r = -1;
}
return r;
}
- GUIDRV_Template.c
添加自己的画点读点函数
在文件中找到_SetPixelIndex函数 画点函数
在注释下面添加自己的画点函数
static void _SetPixelIndex(GUI_DEVICE * pDevice, int x, int y, int PixelIndex) {
//
// Convert logical into physical coordinates (Dep. on LCDConf.h)
//
#if (LCD_MIRROR_X == 1) || (LCD_MIRROR_Y == 1) || (LCD_SWAP_XY == 1)
int xPhys, yPhys;
xPhys = LOG2PHYS_X(x, y);
yPhys = LOG2PHYS_Y(x, y);
#else
#define xPhys x
#define yPhys y
#endif
GUI_USE_PARA(pDevice);
GUI_USE_PARA(x);
GUI_USE_PARA(y);
GUI_USE_PARA(PixelIndex);
{
//
// Write into hardware ... Adapt to your system
//
// TBD by customer...
//
LCD_DrawPoint(x, y, PixelIndex);
}
#if (LCD_MIRROR_X == 0) && (LCD_MIRROR_Y == 0) && (LCD_SWAP_XY == 0)
#undef xPhys
#undef yPhys
#endif
}
读点函数_GetPixelIndex
同样的在注释下面添加自己的读点函数
static unsigned int _GetPixelIndex(GUI_DEVICE * pDevice, int x, int y) {
unsigned int PixelIndex;
//
// Convert logical into physical coordinates (Dep. on LCDConf.h)
//
#if (LCD_MIRROR_X == 1) || (LCD_MIRROR_Y == 1) || (LCD_SWAP_XY == 1)
int xPhys, yPhys;
xPhys = LOG2PHYS_X(x, y);
yPhys = LOG2PHYS_Y(x, y);
#else
#define xPhys x
#define yPhys y
#endif
GUI_USE_PARA(pDevice);
GUI_USE_PARA(x);
GUI_USE_PARA(y);
{
//
// Write into hardware ... Adapt to your system
//
// TBD by customer...
//
PixelIndex = LCD_ReadPoint(x, y);
//PixelIndex = 0;
}
#if (LCD_MIRROR_X == 0) && (LCD_MIRROR_Y == 0) && (LCD_SWAP_XY == 0)
#undef xPhys
#undef yPhys
#endif
return PixelIndex;
}
中断处理
这里设置SysTick为STemWIN的基准时钟
在中断里面将OS_TimeMS加一
extern __IO uint32_t OS_TimeMS;
void SysTick_Handler(void)
{
OS_TimeMS++;
TimingDelay_Decrement();
}
主函数
引用头文件gui.h
打开RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_CRC, ENABLE);
设置SysTick定时器
调用GUI_Init()初始化STemWin
如果使用外部RAM作为STemWin的动态内存,
记得一定要先初始化RAM再初始化STemWin
#include "LED.h"
#include "Systick.h"
#include "USART.h"
#include "GUI.h"
#include "SDRAM.h"
int main()
{
//系统定时器设置
Systick_Init();
//中断分组 2位抢占优先权,2位子优先级
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_CRC, ENABLE);
//LED初始化
LED_Init();
//串口初始化
USART1_Init();
SDRAM_Init();
GUI_Init();
GUI_Clear();
GUI_DispStringAt("Hello World!",0,0);
while(1)
{
LED_G = ~LED_G;
Delay_ms(500);
}
}
优化
GUIDRV_Template.c文件中
找到GUIDRV_Template_API定义
const GUI_DEVICE_API GUIDRV_Template_API = {
//
// Data
//
DEVICE_CLASS_DRIVER,
//
// Drawing functions
//
_DrawBitmap,
_DrawHLine,
_DrawVLine,
_FillRect,
_GetPixelIndex,
_SetPixelIndex,
_XorPixel,
//
// Set origin
//
_SetOrg,
//
// Request information
//
_GetDevFunc,
_GetDevProp,
_GetDevData,
_GetRect,
};
我们可以用自己写的函数来代替这些函数
比如填充函数_FillRect
该函数内部调用了_XorPixel和_SetPixelIndex函数
/*********************************************************************
*
* _FillRect
*/
static void _FillRect(GUI_DEVICE * pDevice, int x0, int y0, int x1, int y1) {
LCD_PIXELINDEX PixelIndex;
int x;
PixelIndex = LCD__GetColorIndex();
if (GUI_pContext->DrawMode & LCD_DRAWMODE_XOR) {
for (; y0 <= y1; y0++) {
for (x = x0; x <= x1; x++) {
_XorPixel(pDevice, x, y0);
}
}
} else {
// for (; y0 <= y1; y0++) {
// for (x = x0; x <= x1; x++) {
// _SetPixelIndex(pDevice, x, y0, PixelIndex);
// }
// }
LCD_Fill(x0, y0, x1, y1, PixelIndex);
}
}
画位图函数
/*********************************************************************
*
* _DrawBitmap
*/
static void _DrawBitmap(GUI_DEVICE * pDevice, int x0, int y0,
int xSize, int ySize,
int BitsPerPixel,
int BytesPerLine,
const U8 GUI_UNI_PTR * pData, int Diff,
const LCD_PIXELINDEX * pTrans) {
int i;
switch (BitsPerPixel) {
case 1:
for (i = 0; i < ySize; i++) {
_DrawBitLine1BPP(pDevice, x0, i + y0, pData, Diff, xSize, pTrans);
pData += BytesPerLine;
}
break;
case 2:
for (i = 0; i < ySize; i++) {
_DrawBitLine2BPP(pDevice, x0, i + y0, pData, Diff, xSize, pTrans);
pData += BytesPerLine;
}
break;
case 4:
for (i = 0; i < ySize; i++) {
_DrawBitLine4BPP(pDevice, x0, i + y0, pData, Diff, xSize, pTrans);
pData += BytesPerLine;
}
break;
case 8:
for (i = 0; i < ySize; i++) {
_DrawBitLine8BPP(pDevice, x0, i + y0, pData, xSize, pTrans);
pData += BytesPerLine;
}
break;
//
// Only required for 16bpp color depth of target. Should be removed otherwise.
//
case 16:
// for (i = 0; i < ySize; i++) {
// _DrawBitLine16BPP(pDevice, x0, i + y0, (const U16 *)pData, xSize);
// pData += BytesPerLine;
// }
//可以直接用自己的画图函数
TFTLCD_DrawBmp16(x0, y0, pData, xSize, ySize);
break;
//
// Only required for 32bpp color depth of target. Should be removed otherwise.
//
case 32:
for (i = 0; i < ySize; i++) {
_DrawBitLine32BPP(pDevice, x0, i + y0, (const U32 *)pData, xSize);
pData += BytesPerLine;
}
break;
}
}
OS的移植
这里以FreeRTOS为例
- 导入FreeRTOS头文件
- 定义互斥量信号量
- 完善函数
#include "GUI.h"
/* FreeRTOS include files */
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
/*********************************************************************
*
* Global data
*/
//static osMutexId osMutex;
//static osSemaphoreId osSemaphore;
static xSemaphoreHandle osMutex = NULL;
static xSemaphoreHandle osSemaphore = NULL;
/*********************************************************************
*
* 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.
*/
int GUI_X_GetTime(void)
{
return ((int) xTaskGetTickCount());
}
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
*/
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
*/
/* Init OS */
void GUI_X_InitOS(void)
{
/* 创建互斥信号量 用于资源共享 */
osMutex = xSemaphoreCreateMutex();
configASSERT (osMutex != NULL);
/* 创建二值信号量 用于事件触发 */
osSemaphore = xSemaphoreCreateBinary();
configASSERT ( osSemaphore != NULL );
}
void GUI_X_Unlock(void)
{
/* 给出互斥量 */
xSemaphoreGive(osMutex);
}
void GUI_X_Lock(void)
{
if(osMutex == NULL)
{
GUI_X_InitOS();
}
/* 获取互斥量 */
xSemaphoreTake(osMutex, /* 互斥量句柄 */
portMAX_DELAY);/* 阻塞等待 */
}
/* Get Task handle */
U32 GUI_X_GetTaskId(void)
{
return ((U32) xTaskGetCurrentTaskHandle());
}
void GUI_X_WaitEvent (void)
{
/* 获取信号量 */
while(xSemaphoreTake( osSemaphore, /* 信号量句柄 */
portMAX_DELAY) != pdTRUE);/* 阻塞等待 */
}
void GUI_X_SignalEvent (void)
{
/* 给出信号量 */
xSemaphoreGive(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)
*/
void GUI_X_Log (const char *s) { }
void GUI_X_Warn (const char *s) { }
void GUI_X_ErrorOut(const char *s) { }