你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

开源GUI LittlevGL 移植  

[复制链接]
creep 发布时间:2017-9-7 22:39
本帖最后由 creep 于 2018-1-13 19:14 编辑

    推荐阅读最新的Littlevgl移植(更新时间:2018-1-13):
  
    开源GUI  LittlevGL  V5.0版本移植      


LittlevGL 是一个开源免费的GUI,支持触摸屏操作,移植简单方便,开发者一直在不断完善更新。LittlevGL 自带了丰富的控件:窗口、按键、标签、list、图表等,还可以自定义控件;支持很多特效:透明、阴影、自动显示隐藏滚动条、界面切换动画、图标打开关闭动画、平滑的拖拽控件、分层显示、反锯齿等等。


下面是我在STM32F769-DISCO上移植的演示模式的效果图片.




TIM图片20170907220239.jpg TIM图片20170907220247.jpg

主要控件可以通过下面的图片有个基本的了解:


2017-09-06_115730.png
1、移植

LittlevGL 的移植非常简单,用户只需要提供systick、触摸屏、LCD显示接口即可。源码里面有3个文件用于分别添加这3个接口,具体如下:

0895ef3e-bcca-43d2-9e1d-7a9a21b4723e.png

也就是下面几个函数:


  • hal/disp disp_fill(x1, y1, x2, y2, color) to fill area with a color
  • hal/disp disp_map(x1, y1, x2, y2, &color_array) copy a color map to an area
  • hal/disp disp_color_cpy(dest, src, length, opa) copy pixel, optional for GPU
  • hal/indev indev_get(id, &x, &y) get the x and y coordinates from an input device (e.g. touch pad)
  • hal/systick systick_get() get a system tick with 1 ms resolution
  • hal/systick systick_elapse(prev_time) get the elapsed milliseconds sience prev_time

a)systick的移植直接使用的是HAL库里面提供的

  1. /**
  2. * Get the elapsed milliseconds since start up
  3. * @return the elapsed milliseconds
  4. */
  5. uint32_t systick_get(void)
  6. {
  7.         return HAL_GetTick();
  8. }
  9. /**
  10. * Get the elapsed milliseconds science a previous time stamp
  11. * @param prev_tick a previous time stamp from 'systick_get'
  12. * @return the elapsed milliseconds since 'prev_tick'
  13. */
  14. uint32_t systick_elaps(uint32_t prev_tick)
  15. {
  16.         volatile uint32_t act_time = systick_get();

  17.         /*If there is no overflow in sys_time
  18.          simple subtract*/
  19.         if(act_time >= prev_tick) {
  20.                 prev_tick = act_time - prev_tick;
  21.         } else {
  22.                 prev_tick = UINT32_MAX - prev_tick + 1;
  23.                 prev_tick += act_time;
  24.         }
  25.         return prev_tick;
  26. }
复制代码
b)提供触摸屏的函数,用于初始化触摸屏和返回触摸屏扫描结果
  1. /**
  2. * Initialize your input devices here
  3. */
  4. void indev_init(void)
  5. {
  6.   BSP_TS_Init(DISP_HOR_RES, DISP_VER_RES);
  7. }

  8. /**
  9. * Read an input device
  10. * @param indev_id id of the input device to read
  11. * @param x put the x coordinate here
  12. * @param y put the y coordinate here
  13. * @return true: the device is pressed, false: released
  14. */
  15. bool indev_get(uint8_t indev_id, int16_t * x, int16_t * y)
  16. {
  17.         if(indev_id != 0) {
  18.                 *x = 0;
  19.                 *y = 0;
  20.                 return false;
  21.         }
  22.         static int16_t last_x = 0;
  23.         static int16_t last_y = 0;
  24.         bool press;
  25.         BSP_TS_GetState(&TS_State);
  26.         if(TS_State.touchDetected != 0) {
  27.                 *x = TS_State.touchX[0];
  28.                 *y = TS_State.touchY[0];
  29.                 press = true;
  30.         } else {
  31.                 *x = last_x;
  32.                 *y = last_y;
  33.                 press = false;
  34.         }

  35.         return press;
  36. }
复制代码
c)LCD的移植分为几个函数,

1)一个是用单一色填充矩形区域,这个实际调用的次数较小


  1. /**
  2. * Fill a rectangular area with a color
  3. * @param x1 left coordinate of the rectangle
  4. * @param x2 right coordinate of the rectangle
  5. * @param y1 top coordinate of the rectangle
  6. * @param y2 bottom coordinate of the rectangle
  7. * @param color fill color
  8. */
  9. void disp_fill(int32_t x1, int32_t y1, int32_t x2, int32_t y2, color_t color)
  10. {
  11.     /*Return if the area is out the screen*/
  12.     if(x2 < 0) return;

  13.     if(y2 < 0) return;

  14.     if(x1 > DISP_HOR_RES - 1) return;

  15.     if(y1 > DISP_VER_RES - 1) return;

  16.     /*Truncate the area to the screen*/
  17.     int32_t act_x1 = x1 < 0 ? 0 : x1;
  18.     int32_t act_y1 = y1 < 0 ? 0 : y1;
  19.     int32_t act_x2 = x2 > DISP_HOR_RES - 1 ? DISP_HOR_RES - 1 : x2;
  20.     int32_t act_y2 = y2 > DISP_VER_RES - 1 ? DISP_VER_RES - 1 : y2;

  21.     LCD_FillRectPart(act_x1, act_y1, act_x2 - act_x1 + 1, act_y2 - act_y1 + 1, ((color.full)));
  22. }
复制代码
2)这个是用一个颜色map填充一个矩形区域,这个主要用显示时局部刷新使用,是LCD显示调用的底层接口,使用非常频繁,如果需要优先显示速度,可以从这个函数入手,使用块内存复制或者DMA2D来实现。
  1. /**
  2. * Put a color map to a rectangular area
  3. * @param x1 left coordinate of the rectangle
  4. * @param x2 right coordinate of the rectangle
  5. * @param y1 top coordinate of the rectangle
  6. * @param y2 bottom coordinate of the rectangle
  7. * @param color_p pointer to an array of colors
  8. */
  9. void disp_map(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const color_t * color_p)
  10. {
  11.     /*Return if the area is out the screen*/
  12.     if(x2 < 0) return;

  13.     if(y2 < 0) return;

  14.     if(x1 > DISP_HOR_RES - 1) return;

  15.     if(y1 > DISP_VER_RES - 1) return;

  16.     /*Truncate the area to the screen*/
  17.     int32_t act_x1 = x1 < 0 ? 0 : x1;
  18.     int32_t act_y1 = y1 < 0 ? 0 : y1;
  19.     int32_t act_x2 = x2 > DISP_HOR_RES - 1 ? DISP_HOR_RES - 1 : x2;
  20.     int32_t act_y2 = y2 > DISP_VER_RES - 1 ? DISP_VER_RES - 1 : y2;


  21.     uint32_t y;

  22.     for(y = act_y1; y <= act_y2; y++)
  23.     {
  24.         memcpy(&my_fb[y * DISP_HOR_RES + act_x1],
  25.                color_p,
  26.                (act_x2 - act_x1 + 1) * sizeof(my_fb[0]));
  27.         color_p += x2 - x1 + 1;    /*Skip the parts out of the screen*/
  28.     }

  29. }
复制代码
3)硬件加速可选项打开后可以使用下面的函数复制加速填充复制内存
  1. /**
  2. * Copy pixels to destination memory using opacity
  3. * @param dest a memory address. Copy 'src' here.
  4. * @param src pointer to pixel map. Copy it to 'dest'.
  5. * @param length number of pixels in 'src'
  6. * @param opa opacity (0, OPA_TRANSP: transparent ... 255, OPA_COVER, fully cover)
  7. */
  8. void disp_color_cpy(color_t * dest, const color_t * src, uint32_t length, opa_t opa)
  9. {
  10.     /*Wait for the previous operation*/
  11.     HAL_DMA2D_PollForTransfer(&Dma2dHandle, 100);

  12.     Dma2dHandle.LayerCfg[1].InputAlpha = opa;
  13.     HAL_DMA2D_ConfigLayer(&Dma2dHandle, 1);
  14.     HAL_DMA2D_BlendingStart(&Dma2dHandle, (uint32_t) src, (uint32_t) dest, (uint32_t)dest, length, 1);
  15. }
复制代码
移植了上面接口之后基本问题就不大了,littlevgl 目前的代码结构有点乱,分为core、hal、misc 几个部分,我是分别建立一个文件夹然后把相应的文件全部添加到里面了,官网也没有详细的移植说明文档。所有的源码如下:
830d99b5-4b7a-45d6-bdbc-e56085de3ef1.png
添加到工程中后如下整体如下:



3446ef89-270c-4dd3-8658-84f3ba39c9c6.png

将所有的文件添加到工程中后用keil编译可能会有一些错误和警告出现,但都很好解决。


2、运行效果

LittlevGL内置一个类似桌面系统的演示例子,通过打开相应的宏定义即可



6b77cfc1-d927-422c-9a91-f5f6b01ed4d7.png

LittlevGL有个桌面上模拟的工程,下面是论坛网友 @QianFan  在linux下运行官方例子的运行效果:


X$SK81@USA577AHK@1B@E_C.gif

除此之外官网还有一个在STM32F429-DISOC上移植的例子,在youtube上可以观看,因为转换为了gif可能看起来不是很流畅,实际演示效果很不错。


test1.gif

下面是我在STM32F769-DISOC上面的移植,和linux下模拟运行的差不多。因为769-disco的分辨率很高,移植后我没有使用优化,所以可以看到画面切换有些闪烁。
IMG_0253.GIF

3、关于LittlevGL

    LittlevGL里面有个简单的时间片调度系统,刷新显示和触摸处理等任务会周期的被调用处理。LCD刷新采用了局部缓存刷新,这样能避免闪烁出现。LittlevGL目前只有一个开发者在业余时间维护更新,但是开发者热情很高,可以在github上看到更新很频繁,我测试的使用的V4.2版本,开发者正在开发4.3版本并加入了不少新的功能,有建议可以在github和作者讨论互动。
目前代码结构看上去有点乱,有人在也提到了这个问题,计划好像是在5.0版本引入新的代码组织结构,感兴趣的可以去github提意见,开发者很乐意沟通讨论。官网也有不少控件的使用介绍和例子参考。



9360da2f-c19f-499f-950b-613fb29b2857.png


官网和github地址如下:

LittlevGL官网:http://www.gl.littlev.hu/
LittlevGLgithub :http://github.com/littlevgl   和  http://github.com/littlevgl/lvgl

下面2个视频是在PC Simulator (Linux)和F4-DICO上的移植演示可能需要科学的方式才能打开。
How to Run Littlev Graphics Library in PC Simulator (Linux):http://youtu.be/ZzLdct2ymvg
Embedded GUI on STM32 Discovery with Littlev Free Graphics Library:http://youtu.be/DcJdK137WKM

  和众多开源的RTOS不一样,目前GUI开源的不是很多,虽然很多商用的GUI也很炫酷,但是我们没法知道具体效果的实现细节,也没法学习到这种能力,LittlevGL目前实现的一些特性和控件我认为是开源的GUI里面水平非常高的了。但是目前LittlevGL资料不是很多,只能通过阅读源码去学习和研究。


测试代码:

LittlevGL-STM32F769-DISCO.rar (4.72 MB, 下载次数: 867)

评分

参与人数 2 ST金币 +21 收起 理由
mcbot + 1 little VGL群,526465246 大家一起来学习.
zero99 + 20 大佬玩的好溜

查看全部评分

收藏 12 评论37 发布时间:2017-9-7 22:39

举报

37个回答
creep 最优答案 回答时间:2018-12-2 17:03:42
ioremap 发表于 2018-11-30 17:25
我遇到个大问题,求回复,空间没颜色的

看到一个别人分享的开源中文教程。
开源GUI-littevGL应用教程 V0.1.pdf (3.14 MB, 下载次数: 497)
creep 回答时间:2017-9-8 14:53:07
ljt8015 发表于 2017-9-8 13:47
LittlevGL有个桌面上模拟的工程,下面是论坛网友 @QianFan  在linux下运行官方例子的运行效果:

http://github.com/littlevgl/proj_pc
creep 回答时间:2018-7-23 18:11:44
chen849928055 发表于 2018-7-23 16:10
版主Littlevgl移植 没有硬件mcu的限制吧,只要mcu的ram,rom等硬件条件符合要求,就能跑起Littlevgl吧 ...

是的,没有限制,移植吧。
Paderboy 回答时间:2017-9-7 23:33:35
跟着大佬学习。。。
淡定的H羊 回答时间:2017-9-8 07:34:07
wow。感觉真不错
谢谢楼主分享
@乔木 回答时间:2017-9-8 08:02:24
厉害厉害
qianfan 回答时间:2017-9-8 08:48:53
现在的代码有点乱,图形界面依赖其他的misc,HAL等库。在github中提意见,将gui部分确实需要的部分集成到gui中,其余没用的部分剥离出去。
anobodykey 回答时间:2017-9-8 08:53:59
这个不错,赞一个
MrJiu 回答时间:2017-9-8 09:22:45
已经关注了一波。。。可以看看!!!!
Xinfeng 回答时间:2017-9-8 09:23:21
学习新知识,快乐
ljt8015 回答时间:2017-9-8 13:47:08
LittlevGL有个桌面上模拟的工程,下面是论坛网友 @QianFan  在linux下运行官方例子的运行效果:


如何模拟?  如何在linux中运行?

ljt8015 回答时间:2017-9-8 14:30:15
LittlevGL 相比 ucgui 的优势?

ljt8015 回答时间:2017-9-8 14:51:50

文档很少

creep 回答时间:2017-9-8 14:54:15

文档是很少,只能通过看代码学习了,如果感兴趣的话可以一起讨论。
Veiko 回答时间:2017-9-8 16:41:52
感谢楼主,这个很好
freeelectron 回答时间:2017-9-8 17:07:53
好6啊
123下一页
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版