Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >ucgui在嵌入式linux下的移植

ucgui在嵌入式linux下的移植

作者头像
杨永贞
发布于 2020-08-04 14:50:28
发布于 2020-08-04 14:50:28
2.1K00
代码可运行
举报
运行总次数:0
代码可运行

前几天在研究minigui,照着官方的步骤编译,竟然一堆错,不是缺这库,就是缺那库。好不容易快到了最后一步,竟然再链接时告诉我用的64位系统不兼容32位的minigui。

早不说呀,真折腾,这是让我再重装个32位系统么。想出来个helloworld,竟在编译环境上浪费时间,太坑。也不喜欢minigui的为win32风格,应用都得在他的框架下写,必须得有入口函数。类似于win32的api编程,很原始,连个界面的长宽高都要自己去定义。也没有好用的可视化的窗口设计及仿真环境。其实,如果没有那么多的人机交互,比如车载pos,不需要这些吧。不如直接调用显示接口函数,比如想显示个内容,直接LCD_DisplayString()来的容易。

用 ucgui还有个好处是,只要应用做稳定了,界面根本不会卡死或down掉。因为界面就像一个画布,让显示什么,什么时候显示,都是受应用控制的,界面是被动的。但是,如果应用跑在miniGUI的框架下,如果界面消息循环阻塞,或者minigui挂掉,整个应用就完了。且minigui的让显示什么,就发个消息,然后在主线程对消息就行处理再显示,感觉像是平白无故兜了一圈。完全没有直接操作屏幕爽。让什么时候显示什么直接LCD_Display,安全稳定。当然,这只针对目前的应用而言,界面不那么重要。如果是靠界面取胜的应用,都这么来会很累。

无意间发现了一个好东西,ucgui,这在原来单片机stm32上跑过,以及ucosII。之前也用过。ucgui占用资源很少,在stm32等单片机上都能跑,在linux 上更是没一点儿问题。

而且超轻量级,代码很好移植。甚至因为小巧,可以用来学习研究GUI用,或者增加定制些功能。

同事说这么小巧的东西在linux上有点儿不搭吧,linux那么强大,应该首先考虑minigui和QT。但是我我举得对于目前正在做的新项目而言,不需要界面太花哨,功能稳定就行,先快速出来产品再说吧。先整出来个界面用用,毕竟也不占多少精力。越是简单小巧越容易掌控,不容易掉坑里。

对于一款智能pos来说,从功能上无非是 卡处理、记录存储、通信、显示、这几块功能。目前 通信库,和文件存储库都已封装好。把显示也搞定了,就剩封装读卡库了。最后再实现个多线程框架把这些轮子组装起来,就是一完整 pos 了,也不是什么难事。难在接口封装和风格尽量要做到和原来一致啊,要不那么多地方的应用,移植是件痛苦的事。

进一步查资料发现,用这个 ucgui,电脑上还有模拟器可以用,那么界面设计部分,完全可以在电脑上仿真啦。这样,想设计个漂亮的界面出来,也不难啊。别抱怨说界面原生丑陋,那是没经过设计。至于是否支持中文,以及字体有哪些,那就自己画呗,用工具生成各种需要的中文字库导进去。 想让界面漂亮些,那自己画呗,正好考验下有没艺术细胞。反正画着也挺简单的,最底层的画点画线基本函数都有了。甚至可以移植gif解码库,让支持更多类型的图片动画。后续准备加入常用的中文字库支持。以及gif动画支持。

官方的模拟器 emWin(UCGUI)模拟器。在电脑上有模拟器啊,这是不是很赞。

移植之后,使用也很简单 。就一个libucgui.a库文件和gui.h头文件包含进来即可。

使用类似这样:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <stdio.h>
 #include "GUI.h"

int main(int argc, char* argv[])
 { 
   char c;
   printf("this is ucgui-linux test!\n");


   GUI_Init();
   GUI_SetBkColor(GUI_BLUE);
   GUI_Clear();
   GUI_SetColor(GUI_WHITE);
   GUI_SetTextAlign(GUI_TA_HCENTER);
   GUI_SetFont(&GUI_Font16B_ASCII);
   GUI_DispStringAt("hello world, ucgui-linux",240,100);
   GUI_DrawCircle(100,100,50);//画圆
   printf("system pause\n");
   while ((c = getchar()) != '\n');
   system("pause");
   return 0;
 }

先来张运行成功的截图:

又发现ucGUI一个强大功能,竟可以windows上设计界面自动生成代码,带仿真执行功能。附图:是不是很赞,这是minigui远远不能及的....

连带电脑上的代码编写仿真环境都有,

进入正题,移植minigui,

很好移植,把底层调用的几个函数,用linux上的frambuffer实现就可以了。

具体文件是LCDDummy.c那么文件 里的LCD_L0_Init(void),LCD_L0_SetPixelIndex,LCD_L0_GetPixelIndex,这三个函数,实现这三个函数。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/*********************************************
*
*       LCD_L0_Init
*
**********************************************
Purpose:
  Initialises the LCD-controller.
*/

int  LCD_L0_Init(void) {
  return fb_init();
}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/*********************************************
*
*       LCD_L0_SetPixelIndex
*
**********************************************
Purpose:
  Sets the index of the given pixel. The upper layers of emWin
  calling this routine make sure that the coordinates are in range, so
  that no check on the parameters needs to be performed.
*/

void LCD_L0_SetPixelIndex(int x, int y, int PixelIndex) {
  /* Convert logical into physical coordinates (Dep. on LCDConf.h) */
  #if LCD_SWAP_XY | LCD_MIRROR_X| LCD_MIRROR_Y
    int xPhys = LOG2PHYS_X(x, y);
    int yPhys = LOG2PHYS_Y(x, y);
  #else
    #define xPhys x
    #define yPhys y
  #endif
  /* Write into hardware ... Adapt to your system */
  {
    /* ... */
    fb_setpixel(480, 272, xPhys, yPhys, PixelIndex);
  }
}

/*********************************************
*
*       LCD_L0_GetPixelIndex
*
**********************************************
Purpose:
  Returns the index of the given pixel. The upper layers of emWin
  calling this routine make sure that the coordinates are in range, so
  that no check on the parameters needs to be performed.
*/

unsigned int LCD_L0_GetPixelIndex(int x, int y) {
  LCD_PIXELINDEX PixelIndex;
  /* Convert logical into physical coordinates (Dep. on LCDConf.h) */
  #if LCD_SWAP_XY | LCD_MIRROR_X| LCD_MIRROR_Y
    int xPhys = LOG2PHYS_X(x, y);
    int yPhys = LOG2PHYS_Y(x, y);
  #else
    #define xPhys x
    #define yPhys y
  #endif
  /* Read from hardware ... Adapt to your system */
  {
    PixelIndex = 0;/* ... */
    PixelIndex = fb_readpixel(480, 272, xPhys, yPhys);
  }
  return PixelIndex;
}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <memory.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <sys/mman.h>
#include <linux/fb.h>

static unsigned char*  npu8_fbmem;
static int             ns32_fb;
static unsigned int    nu32_screensize;

static void* _fb_mmap(int fd, unsigned int screensize)
{
    caddr_t fbmem;

    if ((fbmem = mmap(0, screensize, PROT_READ | PROT_WRITE,
                      MAP_SHARED, fd, 0)) == MAP_FAILED) {
        perror(__func__);
        return (void *) (-1);
    }

    return fbmem;
}

static int _fb_munmap(void *start, size_t length)
{
    return (munmap(start, length));
}

static int _fb_stat(int fd, unsigned int *width, unsigned int *height, unsigned int *depth)
{
    //struct fb_fix_screeninfo fb_finfo;
    struct fb_var_screeninfo fb_vinfo;

    //if (ioctl(fd, FBIOGET_FSCREENINFO, &fb_finfo)) {
    //    perror(__func__);
    //    return -1;
    //}

    if (ioctl(fd, FBIOGET_VSCREENINFO, &fb_vinfo)) {
        perror(__func__);
        return -1;
    }

    *width  = fb_vinfo.xres;
    *height = fb_vinfo.yres;
    *depth  = fb_vinfo.bits_per_pixel;

    return 0;
}

int fb_init(void)
{ 
  unsigned int  fbw, fbh, fbd;
  
  ns32_fb = open("/dev/fb0", O_RDWR);
  if(ns32_fb<0){
    printf("can not open fb0\n");
    return -1;
  }
  if( _fb_stat(ns32_fb, &fbw, &fbh, &fbd) < 0 ) return -1;
  printf("%d, %d, %d\n", fbw, fbh, fbd);
  nu32_screensize = fbw * fbh * fbd / 8;
  npu8_fbmem = _fb_mmap(ns32_fb, nu32_screensize);
  return 0;
}

void fb_deinit(void)
{ 
  close(ns32_fb);
  _fb_munmap(npu8_fbmem, nu32_screensize);
}

int fb_setpixel(int width, int height, int x, int y, unsigned short color)
{
    if ((x > width) || (y > height))
        return -1;

    unsigned short *dst = ((unsigned short *)npu8_fbmem + y * width + x);

    *dst = color;
    return 0;
}

unsigned short fb_readpixel(int width, int height, int x, int y)
{
  if ((x > width) || (y > height)) return -1;
  unsigned short *dst = ((unsigned short *)npu8_fbmem + y * width + x);
  return *dst;
}

最后,要在linux上编译,写个makefile吧,简单省事。写完后配置下工具链直接make即可。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
########################################
##makefile
########################################
#****************************************************************************
# Cross complie path
#****************************************************************************
#CHAIN_ROOT=/home/yangyongzhen/imax283/ctools/gcc-4.4.4-glibc-2.11.1-multilib-1.0/arm-fsl-linux-gnueabi/bin

#CROSS_COMPILE=$(CHAIN_ROOT)/arm-none-linux-gnueabi-

CROSS_COMPILE = 

CC     := $(CROSS_COMPILE)gcc
CXX    := $(CROSS_COMPILE)g++
AS	   := $(CROSS_COMPILE)as
AR     := $(CROSS_COMPILE)ar 
LD     := $(CROSS_COMPILE)ld
RANLIB := $(CROSS_COMPILE)ranlib
OBJDUMP:= $(CROSS_COMPILE)objdump
OBJCOPY:= $(CROSS_COMPILE)objcopy
STRIP  := $(CROSS_COMPILE)strip

#****************************************************************************
# Source files
#****************************************************************************
SRC_C=$(shell find . -name "*.c")

OBJ_C=$(patsubst %.c, %.o, $(SRC_C))

SRCS := $(SRC_C) $(SRC_C)

OBJS := $(OBJ_C) 

#****************************************************************************
# Flags
#****************************************************************************

CFLAGS=  -I./GUI_X -I./GUI/Core -I./GUI/WM -I./GUI/Widget
LDSCRIPT= 
LDFLAGS= 
#****************************************************************************
# Targets of the build
#****************************************************************************
TARGET   	:= libucgui

.PHONY: clean
all:  prebuild  $(TARGET).a

#****************************************************************************
# TARGET
#****************************************************************************
prebuild:
	@echo Building lib...

$(TARGET).a : $(OBJS)
	@echo Generating lib...
	ar crv $(TARGET).a $(OBJS) 
	cp $(TARGET).a ../
	@echo OK!

%.o : %.c
	$(CC) -c $(CFLAGS) $< -o  $@
	
clean:
	@echo The following files:
	rm  -f  $(TARGET) *.a
	find . -name "*.[od]" |xargs rm
	@echo Removed!
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017/10/28 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
推荐一款不错的嵌入式GUI(玲珑GUI)及在嵌入式linux上的移植
玲珑GUI(LLGUI)是一套使用简单、低价的单片机GUI解决方案。可以用来代替串口屏、组态,降低产品成本,产品软硬件自主可控。 配套界面开发软件,图形化编辑界面,生成C代码。
杨永贞
2022/01/07
2.2K0
推荐一款不错的嵌入式GUI(玲珑GUI)及在嵌入式linux上的移植
freetype的交叉编译及在嵌入式linux上的简单使用及改变字体背景和颜色
FreeType库是一个完全免费(开源)的、高质量的且可移植的字体引擎,它提供统一的接口来访问多种字体格式文件,包括TrueType, OpenType, Type1, CID, CFF, Windows FON/FNT, X11 PCF等。它支持单色位图、反走样位图的渲染。FreeType库是高度模块化的程序库,虽然它是使用ANSI C开发,但是采用面向对象的思想,因此,FreeType的用户可以灵活地对它进行裁剪。关于freetype的详细信息可以参考freetype的官方网站:https://www.freetype.org/来获取更多相关的信息。
杨永贞
2020/12/16
5.5K0
freetype的交叉编译及在嵌入式linux上的简单使用及改变字体背景和颜色
littlevgl(Lvgl)最新版V7.4移植
LittleVGL最新已经更新到V7,网上大多数移植教程的版本比较老,很多特性没有,界面也不够酷炫。
杨永贞
2020/09/02
3.5K0
Linux应用开发:嵌入式Linux下矢量字体运用
FreeType库是一个完全免费(开源)的、高质量的且可移植的字体引擎,它提供统一的接口来访问多种字体格式文件,可以非常方便我们开发字体显示相关的程序功能。它支持单色位图、反走样位图的渲染。FreeType库是高度模块化的程序库,虽然它是使用ANSI C开发,但是采用面向对象的思想,因此,FreeType的用户可以灵活地对它进行裁剪。关于freetype的详细信息可以参考freetype的官方网站:https://www.freetype.org/来获取更多相关的信息。
DS小龙哥
2022/01/12
4.9K0
Linux应用开发:嵌入式Linux下矢量字体运用
嵌入式Linux下LCD应用编程: 读取摄像头画面完成本地视频监控画面显示
完整项目代码下载地址(包含矢量字库源码和编译安装方法): https://download.csdn.net/download/xiaolong1126626497/16680219
DS小龙哥
2022/01/12
2.4K0
嵌入式Linux下LCD应用编程: 读取摄像头画面完成本地视频监控画面显示
Linux驱动开发: FrameBuffe(LCD)驱动开发
帧缓冲(framebuffer)是Linux 系统为显示设备提供的一个接口,它将显示缓冲区抽象,屏蔽图像硬件的底层差异,允许上层应用程序在图形模式下直接对显示缓冲区进行读写操作。用户不必关心物理显示缓冲区的具体位置及存放方式,这些都由帧缓冲设备驱动本身来完成。
DS小龙哥
2022/01/12
50.4K0
Linux驱动开发: FrameBuffe(LCD)驱动开发
荔枝派Zero(全志V3S)驱动开发之RGB LCD屏幕显示bmp图片
显示设备例如 LCD,在 Linux 中用 Framebuffer 来表征, Framebuffer 翻译过来就是帧缓冲,简称 fb,在 /dev 目录下显示设备一般表示成这样:/dev/fbn,应用程序通过访问这个设备来访问 LCD,实际上应用程序通过操作显存来操作显示设备,显存由驱动程序设置。说白了,我们要在 linux 下操作屏幕进行显示那么直接对 /dev/fbn 进行操作即可。
Gnep@97
2023/08/10
1.1K0
荔枝派Zero(全志V3S)驱动开发之RGB LCD屏幕显示bmp图片
sm2,sm3,sm4国密算法的纯c语言版本,使用于任何嵌入式平台
国密即国家密码局认定的国产密码算法。主要有SM1,SM2,SM3,SM4。密钥长度和分组长度均为128位。
杨永贞
2020/08/04
14.3K1
i.MX6ULL嵌入式Linux开发2-uboot移植实践
上篇文章,我们介绍了如何使用NXP原厂的uboot进行编译和烧写,将uboot运行在自己的开发板上。NXP原厂的uboot,直接烧录到我的开发板中,LCD的驱动是不正常的,需要进行修改。本篇我们就来继续研究uboot,「使得uboot能匹配我们自己的开发板」。
xxpcb
2021/07/20
1.6K0
将jpeg图片显示在framebuffer上
点击(此处)折叠或打开 /************************************************** * example5.c * Author: T-bagwell * * Compile:gcc -Wall example5.c -o example5 *************************************************/ #include <stdio.h> #inclu
用户3765803
2019/03/05
1.6K0
Linux小项目-数码相册设计
这是基于Linux系统开发板设计一个小项目-数码相册,在LCD屏上可以显示完成常见的图片显示,翻页、旋转、缩放等功能。
DS小龙哥
2022/05/11
1.5K0
Linux小项目-数码相册设计
ucgui在windows上的移植,及为go语言打造简易跨平台GUI的想法
go语言缺乏官方GUI的支持,这点有时候很不方便。 虽然网上有很多开源的实现,但都不太满意,不太好用。 网上开源的有哪些?参见《2019,Go GUI项目爆发的一年?》https://studygol
杨永贞
2020/08/04
1.3K0
基于STM32移植UCGUI图形界面框架(3.9.0源码版本)
3.9.0是源码版本,可以看到全部源码,也方便学习;后续的版本都是提供lib库文件,不再提供源码了。
DS小龙哥
2022/01/12
3.6K0
基于STM32移植UCGUI图形界面框架(3.9.0源码版本)
Linux应用开发【第一章】Framebuffer应用开发
​ LCD Framebuffer 就是一块显存,在嵌入式系统中,显存是被包含在内存中。LCD Framebuffer里的若干字节(根据驱动程序对LCD控制器的配置而定)表示LCD屏幕中的一个像素点,一一对应整个LCD屏幕。举个例子,LCD屏幕是800*600的分辨率,即LCD屏幕存在480000个像素点,若每个像素点4个字节表示,那么LCD Framebuffer显存大小为480000 *4=960000字节,即1.92MB。因此我们的内存将会分割至少1.92MB的空间用作显存。具体地址在哪里,这个就是又驱动程序去定,应用程序只需直接使用即可,硬件相关操作已由驱动程序封装好。
韦东山
2021/12/15
1.9K0
Linux应用开发【第一章】Framebuffer应用开发
Linux应用开发-libjpeg库交叉编译与使用
在开发板上如果想要显示jpeg格式的图片,必须用到libjpeg库,不可能自己去编写jpg的解码代码。
DS小龙哥
2022/05/09
4.2K0
Linux应用开发-libjpeg库交叉编译与使用
i.MX6ULL嵌入式Linux开发3-Kernel移植
NXP 会从linux内核官网下载某个版本,然后将其移植到自己的 CPU上,测试成功后就会将其开放给NXP的CPU开发者。开发者下载 NXP 提供的 Linux 内核,然后将其移植到自己的产品上。
xxpcb
2021/08/13
1.7K0
嵌入式Linux下LCD应用编程: 调用giflib库解码显示GIF动态图
生活中常用图片格式有BMP、PNG、JPG、GIF等。BMP图片的显示很简单,可以直接从图片文件里读取RGB数据进行显示.。PNG格式图片显示,直接调用libpng库里的接口函数解码显示;JPG格式图片也一样,调用libjpeg库的接口函数完成解码即可得到原始RGB数据完成显示;如果要在LCD屏上显示GIF图片,那么也是调用giflib库的接口函数完成解码显示。
DS小龙哥
2022/01/12
3.2K0
嵌入式Linux下LCD应用编程: 调用giflib库解码显示GIF动态图
Linux应用开发-LCD显示BMP图片
BMP是一种与硬件设备无关的图像文件格式,是Windows环境中交换与图有关的数据的一种标准,在Windows环境中运行的图形图像软件都支持BMP图像格式。BMP格式的图片存放的就是原始的RGB数据,一般没有做压缩,也就是图片的画质是最原始的,也导致BMP图片占用的内存非常大。现在常用的jpg、jpeg格式都是压缩格式,保存的时候通过算法编码压缩,显示的时候再解压成RGB数据渲染显示。
DS小龙哥
2022/05/11
4.4K0
Linux应用开发-LCD显示BMP图片
Linux驱动开发-编写OLED显示屏驱动
OLED显示屏在是智能手环,智能手表上用的非常的多,功耗低,不刺眼,优点特别多。本篇文章就介绍,在Linux系统里如何使用OLED显示屏,要使用OLED显示屏,大致分为两步: (1) 针对OLED显示屏编写一个驱动 (2) 编写应用层程序进行测试。
DS小龙哥
2022/04/08
5.9K0
Linux驱动开发-编写OLED显示屏驱动
嵌入式linux之go语言开发(二)c动态库驱动调用
linux上的串口驱动,这个较简单,有标准的模块可用。操作的是标准的设备文件。如:ttys0等。
杨永贞
2020/08/04
2.3K0
推荐阅读
相关推荐
推荐一款不错的嵌入式GUI(玲珑GUI)及在嵌入式linux上的移植
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验