STemWin的移植

参考博客链接

记录一下移植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.添加文件进工程

  1. 将Inc里面的文件全部添加进工程,因为全是头文件,只需要添加头文件路径即可
    在这里插入图片描述

  2. 添加Lib文件夹中合适的库文件,并注意添加为库文件
    如图
    在这里插入图片描述

在这里插入图片描述

  1. OS文件夹中选裸机文件添加进工程
    在这里插入图片描述

  2. Config文件夹中需要添加的文件
    在这里插入图片描述

  3. 完成之后如下图

在这里插入图片描述
箭头指向的库文件略有不同

编辑文件

  1. 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 */

  1. 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 设置默认字体

  1. 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>&copy; 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;
}
  1. 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为例

  1. 导入FreeRTOS头文件
  2. 定义互斥量信号量
  3. 完善函数

#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) { }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值