Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >littlevgl(Lvgl)最新版V7.4移植

littlevgl(Lvgl)最新版V7.4移植

作者头像
杨永贞
发布于 2020-09-02 11:19:53
发布于 2020-09-02 11:19:53
3.5K00
代码可运行
举报
运行总次数:0
代码可运行

LittleVGL最新已经更新到V7,网上大多数移植教程的版本比较老,很多特性没有,界面也不够酷炫。

原子最近更新的 LittleVGL 教程则是基于V6版本的,基本上搬过来全是报错,无法参考。新旧版本一致还是有很大区别的,这里介绍下最新版本的移植要点,针对嵌入式linux的framebuffer(dev/fb0)移植。

当然最最新的版本是V7.4.0,源码可以在github下载https://github.com/lvgl/lvgl

关于lvgl的官网及介绍,在https://lvgl.io,Online demo:https://lvgl.io/demos,Docs:https://docs.lvgl.io

移植比较简单,主要区别是几个接口跟老版本的不一样了。不过最终都是实现disp_flush显示驱动接口即可。

接口原型新版本的是这样的:

void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)

移植说明:

新建个工程文件夹,我这取名叫test,

然后在test文件夹下新建个lvgl文件夹,把下载到的源码中的src文件夹整个拷贝出来放进去。

把lv_conf_template.h拷贝出来,到工程的文件夹下,重命名为lv_conf.h.

编辑下,根据实际情况改下相关的配置:

#define LV_HOR_RES_MAX (480) #define LV_VER_RES_MAX (272) #define LV_COLOR_DEPTH 16 #define LV_USE_GPU 0

/* 1: Enable file system (might be required for images */ #define LV_USE_FILESYSTEM 1 。。。

在工程的文件夹下建个lv_drivers文件夹,用于实现的驱动文件。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/**
 * @file fbdev.c
 *
 */

/*********************
 *      INCLUDES
 *********************/
#include "fbdev.h"
#if USE_FBDEV

#include <stdlib.h>
#include <unistd.h>
#include <stddef.h>
#include <stdio.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/mman.h>
#include <sys/ioctl.h>

/*********************
 *      DEFINES
 *********************/
#ifndef FBDEV_PATH
#define FBDEV_PATH  "/dev/fb0"
#endif

/**********************
 *      TYPEDEFS
 **********************/

/**********************
 *  STATIC PROTOTYPES
 **********************/

/**********************
 *  STATIC VARIABLES
 **********************/
static struct fb_var_screeninfo vinfo;
static struct fb_fix_screeninfo finfo;
static char *fbp = 0;
static long int screensize = 0;
static int fbfd = 0;

/**********************
 *      MACROS
 **********************/

/**********************
 *   GLOBAL FUNCTIONS
 **********************/

void fbdev_init(void)
{
    // Open the file for reading and writing
    fbfd = open(FBDEV_PATH, O_RDWR);
    if (fbfd == -1) {
        perror("Error: cannot open framebuffer device");
        return;
    }
    printf("The framebuffer device was opened successfully.\n");

    // Get fixed screen information
    if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo) == -1) {
        perror("Error reading fixed information");
        return;
    }

    // Get variable screen information
    if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo) == -1) {
        perror("Error reading variable information");
        return;
    }

    printf("%dx%d, %dbpp\n", vinfo.xres, vinfo.yres, vinfo.bits_per_pixel);

    // Figure out the size of the screen in bytes
    screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;

    // Map the device to memory
    fbp = (char *)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fbfd, 0);
    if ((int)fbp == -1) {
        perror("Error: failed to map framebuffer device to memory");
        return;
    }
    printf("The framebuffer device was mapped to memory successfully.\n");

}


/**
 * Flush a buffer to the marked area
 * @param x1 left coordinate
 * @param y1 top coordinate
 * @param x2 right coordinate
 * @param y2 bottom coordinate
 * @param color_p an array of colors
 */
void fbdev_flush(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const lv_color_t * color_p)
{
    if(fbp == NULL) return;

    /*Return if the area is out the screen*/
    if(x2 < 0) return;
    if(y2 < 0) return;
    if(x1 > vinfo.xres - 1) return;
    if(y1 > vinfo.yres - 1) return;

    /*Truncate the area to the screen*/
    int32_t act_x1 = x1 < 0 ? 0 : x1;
    int32_t act_y1 = y1 < 0 ? 0 : y1;
    int32_t act_x2 = x2 > vinfo.xres - 1 ? vinfo.xres - 1 : x2;
    int32_t act_y2 = y2 > vinfo.yres - 1 ? vinfo.yres - 1 : y2;

    long int location = 0;

    /*32 or 24 bit per pixel*/
    if(vinfo.bits_per_pixel == 32 || vinfo.bits_per_pixel == 24) {
        uint32_t *fbp32 = (uint32_t*)fbp;
        uint32_t x;
        uint32_t y;
        for(y = act_y1; y <= act_y2; y++) {
            for(x = act_x1; x <= act_x2; x++) {
                location = (x+vinfo.xoffset) + (y+vinfo.yoffset) * vinfo.xres;
                fbp32[location] = color_p->full;
                color_p++;
            }

            color_p += x2 - act_x2;
        }
    }
    /*16 bit per pixel*/
    else if(vinfo.bits_per_pixel == 16) {
        uint16_t *fbp16 = (uint16_t*)fbp;
        uint32_t x;
        uint32_t y;
        for(y = act_y1; y <= act_y2; y++) {
            for(x = act_x1; x <= act_x2; x++) {
                location = (x+vinfo.xoffset) + (y+vinfo.yoffset) * vinfo.xres;
                fbp16[location] = color_p->full;
                color_p++;
            }

            color_p += x2 - act_x2;
        }
    }
    /*8 bit per pixel*/
    else if(vinfo.bits_per_pixel == 8) {
        uint8_t *fbp8 = (uint8_t*)fbp;
        uint32_t x;
        uint32_t y;
        for(y = act_y1; y <= act_y2; y++) {
            for(x = act_x1; x <= act_x2; x++) {
                location = (x+vinfo.xoffset) + (y+vinfo.yoffset) * vinfo.xres;
                fbp8[location] = color_p->full;
                color_p++;
            }

            color_p += x2 - act_x2;
        }
    } else {
        /*Not supported bit per pixel*/
    }

    //May be some direct update command is required
    //ret = ioctl(state->fd, FBIO_UPDATE, (unsigned long)((uintptr_t)rect));

    //lv_flush_ready();
    /* IMPORTANT!!!
     * Inform the graphics library that you are ready with the flushing*/
}

/* Flush the content of the internal buffer the specific area on the display
 * You can use DMA or any hardware acceleration to do this operation in the background but
 * 'lv_disp_flush_ready()' has to be called when finished. */
void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
{
    /* IMPORTANT!!!
     * Inform the graphics library that you are ready with the flushing*/
    fbdev_flush(area->x1,area->y1,area->x2,area->y2,color_p);
    lv_disp_flush_ready(disp_drv);
}

/**
 * Fill out the marked area with a color
 * @param x1 left coordinate
 * @param y1 top coordinate
 * @param x2 right coordinate
 * @param y2 bottom coordinate
 * @param color fill color
 */
void fbdev_fill(int32_t x1, int32_t y1, int32_t x2, int32_t y2, lv_color_t color)
{
    if(fbp == NULL) return;

    /*Return if the area is out the screen*/
    if(x2 < 0) return;
    if(y2 < 0) return;
    if(x1 > vinfo.xres - 1) return;
    if(y1 > vinfo.yres - 1) return;

    /*Truncate the area to the screen*/
    int32_t act_x1 = x1 < 0 ? 0 : x1;
    int32_t act_y1 = y1 < 0 ? 0 : y1;
    int32_t act_x2 = x2 > vinfo.xres - 1 ? vinfo.xres - 1 : x2;
    int32_t act_y2 = y2 > vinfo.yres - 1 ? vinfo.yres - 1 : y2;

    uint32_t x;
    uint32_t y;

    long int location = 0;

    /*32 or 24 bit per pixel*/
    if(vinfo.bits_per_pixel == 32 || vinfo.bits_per_pixel == 24) {
        uint32_t *fbp32 = (uint32_t*)fbp;
        for(x = act_x1; x <= act_x2; x++) {
            for(y = act_y1; y <= act_y2; y++) {
                location = (x+vinfo.xoffset) + (y+vinfo.yoffset) * vinfo.xres;
                fbp32[location] = color.full;
            }
        }
    }
    else if(vinfo.bits_per_pixel == 16) {
        uint16_t *fbp16 = (uint16_t*)fbp;
        for(x = act_x1; x <= act_x2; x++) {
            for(y = act_y1; y <= act_y2; y++) {
                location = (x+vinfo.xoffset) + (y+vinfo.yoffset) * vinfo.xres;
                fbp16[location] = color.full;
            }
        }
    }
    else if(vinfo.bits_per_pixel == 8) {
        uint8_t *fbp8 = (uint8_t*)fbp;
        for(x = act_x1; x <= act_x2; x++) {
            for(y = act_y1; y <= act_y2; y++) {
                location = (x+vinfo.xoffset) + (y+vinfo.yoffset) * vinfo.xres;
                fbp8[location] = color.full;
            }
        }
    } else {
        /*Not supported bit per pixel*/
    }

    //May be some direct update command is required
    //ret = ioctl(state->fd, FBIO_UPDATE, (unsigned long)((uintptr_t)rect));

}

/**
 * Put a color map to the marked area
 * @param x1 left coordinate
 * @param y1 top coordinate
 * @param x2 right coordinate
 * @param y2 bottom coordinate
 * @param color_p an array of colors
 */
void fbdev_map(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const lv_color_t * color_p)
{

    if(fbp == NULL) return;

    /*Return if the area is out the screen*/
    if(x2 < 0) return;
    if(y2 < 0) return;
    if(x1 > vinfo.xres - 1) return;
    if(y1 > vinfo.yres - 1) return;

    /*Truncate the area to the screen*/
    int32_t act_x1 = x1 < 0 ? 0 : x1;
    int32_t act_y1 = y1 < 0 ? 0 : y1;
    int32_t act_x2 = x2 > vinfo.xres - 1 ? vinfo.xres - 1 : x2;
    int32_t act_y2 = y2 > vinfo.yres - 1 ? vinfo.yres - 1 : y2;

    long int location = 0;

    /*32 or 24 bit per pixel*/
    if(vinfo.bits_per_pixel == 32 || vinfo.bits_per_pixel == 24) {
        uint32_t *fbp32 = (uint32_t*)fbp;
        uint32_t x;
        uint32_t y;
        for(y = act_y1; y <= act_y2; y++) {
            for(x = act_x1; x <= act_x2; x++) {
                location = (x+vinfo.xoffset) + (y+vinfo.yoffset) * vinfo.xres;
                fbp32[location] = color_p->full;
                color_p++;
            }

            color_p += x2 - act_x2;
        }
    }
    /*16 bit per pixel*/
    else if(vinfo.bits_per_pixel == 16) {
        uint16_t *fbp16 = (uint16_t*)fbp;
        uint32_t x;
        uint32_t y;
        for(y = act_y1; y <= act_y2; y++) {
            for(x = act_x1; x <= act_x2; x++) {
                location = (x+vinfo.xoffset) + (y+vinfo.yoffset) * vinfo.xres;
                fbp16[location] = color_p->full;
                color_p++;
            }

            color_p += x2 - act_x2;
        }
    }
    /*8 bit per pixel*/
    else if(vinfo.bits_per_pixel == 8) {
        uint8_t *fbp8 = (uint8_t*)fbp;
        uint32_t x;
        uint32_t y;
        for(y = act_y1; y <= act_y2; y++) {
            for(x = act_x1; x <= act_x2; x++) {
                location = (x+vinfo.xoffset) + (y+vinfo.yoffset) * vinfo.xres;
                fbp8[location] = color_p->full;
                color_p++;
            }

            color_p += x2 - act_x2;
        }
    } else {
        /*Not supported bit per pixel*/
    }

    //May be some direct update command is required
    //ret = ioctl(state->fd, FBIO_UPDATE, (unsigned long)((uintptr_t)rect));
}


/**********************
 *   STATIC FUNCTIONS
 **********************/

#endif

附上一个小测试demo:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include "lvgl.h"
#include "lv_drivers/display/fbdev.h"
#include <unistd.h>
//#include "lv_examples/lv_apps/demo/demo.h"

static lv_disp_buf_t disp_buf_2;
static lv_color_t buf2_1[LV_HOR_RES_MAX * 10];                        /*A buffer for 10 rows*/
static lv_color_t buf2_2[LV_HOR_RES_MAX * 10];                        /*An other buffer for 10 rows*/
//extern void demo_create(void);
int main(void)
{
    /*LittlevGL init*/
    lv_init();

    /*Linux frame buffer device init*/
    fbdev_init();

    /*Add a display the LittlevGL sing the frame buffer driver*/
    lv_disp_drv_t disp_drv;
    lv_disp_drv_init(&disp_drv);

    disp_drv.flush_cb = disp_flush;
    /*Set a display buffer*/
    lv_disp_buf_init(&disp_buf_2, buf2_1, buf2_2, LV_HOR_RES_MAX * 10);   /*Initialize the display buffer*/
    disp_drv.buffer = &disp_buf_2;
    //disp_drv.disp_flush = fbdev_flush;      /*It flushes the internal graphical buffer to the frame buffer*/
    lv_disp_drv_register(&disp_drv);

    /*Create a "Hello world!" label*/
    lv_obj_t * label = lv_label_create(lv_scr_act(), NULL);
    lv_label_set_text(label, "hello worldaaa!v7.4");
    lv_obj_align(label, NULL, LV_ALIGN_CENTER, 0, 0);

    /*Handle LitlevGL tasks (tickless mode)*/
	
	//demo_create();
    while(1) {
        lv_tick_inc(5);
        lv_task_handler();
        usleep(5000);
    }

    return 0;
}

如何运行?直接make即可生成可执行文件。

附makefile文件:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
########################################
#makefile
########################################
#****************************************************************************
# Cross complie path
#****************************************************************************
CHAIN_ROOT= /home/yang/crosstool/ctools/gcc-linaro-arm-linux-gnueabihf-4.9-2014.09_linux/bin
CROSS_COMPILE=$(CHAIN_ROOT)/arm-linux-gnueabihf-

#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
#编译主程序
BINARY  := littlevgl
OBJ_DIR := ./

INCS := -I ./   -I./lvgl/src/
CFLAGS= -Wall -g  -std=c99 -fno-common -fsanitize=address  -fno-stack-protector -fno-omit-frame-pointer -fno-var-tracking 


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

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

SRCS := $(SRC_C) $(SRC_C)

OBJS := $(OBJ_C) 
LDSCRIPT=  -lasan 
LDFLAGS= -Llibs  
#LDSCRIPT= -lNC_FileSys
#LDFLAGS= -Llib 

#SRC  = $(wildcard *.c)
#DIR  = $(notdir $(SRC))
#OBJS = $(patsubst %.c,$(OBJ_DIR)%.o,$(DIR))
#OBJS=  main.o myutils.o  inirw.o  cmdpboc.o cputest.o bustcp.o ansrec.o m1cmd.o m1api.o m1test.o upcash.o myother.o getsys.o
#CFLAGS=-std=c99
#@echo Building lib...
#$(call make_subdir)
.PHONY: clean 
all:  prebuild  $(BINARY)

prebuild:
	@echo Building app...

$(BINARY) : $(OBJS)
	@echo Generating ...
	$(CC) -o $(BINARY) $(OBJS) $(LDFLAGS) $(LDSCRIPT) 
	@echo OK!

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

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

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

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

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
全志V831基于pjsip的双向视频通话实现
注意显示设备的注册顺序,video_dev.c中,注册显示设备的时候,要放到camera适配设备的后面,这样子默认的capture设备,即时不配置,也能找到第一个。
呱牛笔记
2024/07/18
3690
全志V831基于pjsip的双向视频通话实现
STM32CubeMX6.0 + HAL + LittleVGL7.6 等学习[最全附工程源码]
https://sxf1024.lanzoui.com/b09rf2dwj 密码:bgvi
小锋学长生活大爆炸
2020/10/26
2.7K0
STM32CubeMX6.0 + HAL + LittleVGL7.6 等学习[最全附工程源码]
06-HAL库硬件SPI DMA驱动LCD并移植LVGL 8.3
源码地址:https://gitee.com/MR_Wyf/hal-cubemx-rt-thread/tree/hal_rttNano_st7789_menu/
用户8913398
2024/06/17
1.7K0
06-HAL库硬件SPI DMA驱动LCD并移植LVGL 8.3
【喂到嘴边了的模块】害怕追新?LVGL8发布稳定性更新(附部署教程)
LVGL的刚刚完成了对LVGL8的维护更新,发布了v8.3.5版。相对master分支上正在开发的LVGL9,该版本是一个吐血推荐的稳定版本:
GorgonMeducer 傻孩子
2023/02/28
3.6K3
【喂到嘴边了的模块】害怕追新?LVGL8发布稳定性更新(附部署教程)
实战贴:开源GUI LittlevGL在MCU上的移植
前几天看见正点原子发布了LittlevGL的教程,这个GUI貌似又火了,于是应读者要求,我也来移植一下,将正点原子的这个GUI移植到小熊派上,不到一会功夫就搞定了,总的来说挺简单,没遇到什么特别的障碍,因为正点原子把坑都帮我们绕过了,直接改下一些基本配置就可以成功显示,但是从头开始移植一个可不简单噢,要详细看官方文档和说明。
杨源鑫
2020/06/10
4K1
实战贴:开源GUI LittlevGL在MCU上的移植
【喂到嘴边了的模块】关于我在MDK中部署LVGL只用了10分钟这件小事
说实话,LVGL这么有牌面的项目,其维护者居然没听说过cmsis-pack,这着实让我略为破防:
GorgonMeducer 傻孩子
2022/01/25
2.7K1
【喂到嘴边了的模块】关于我在MDK中部署LVGL只用了10分钟这件小事
【喂到嘴边了的模块】LVGL9发布稳定性更新
LVGL在2月份发布LVGL9后,于3月19日发布了第一个维护更新,即v9.1.0版,而LVGL8也迎来了更为稳定的强化版本v8.4.0。从吃螃蟹的角度来说,此时入手LVGL9风险较小,是一个不错的选择。
GorgonMeducer 傻孩子
2024/04/10
5.6K0
【喂到嘴边了的模块】LVGL9发布稳定性更新
MTCNN人脸检测 附完整C++代码
Joint Face Detection and Alignment using Multi-task Cascaded Convolutional Neural Networks
cpuimage
2018/05/07
4.6K8
MTCNN人脸检测 附完整C++代码
【喂到嘴边了的模块】关于我在MDK中部署LVGL只用了5分钟这件小事
距离我为LVGL制作第一个版本的 cmsis-pack已经过去一月有余,实际上现在LVGL已经直接入住了MDK的Pack-Installer——只要你的网络有能力访问Github,你就可以直接通过MDK的官方渠道安装LVGL的最新版本。
GorgonMeducer 傻孩子
2022/04/02
2.1K1
【喂到嘴边了的模块】关于我在MDK中部署LVGL只用了5分钟这件小事
图解LCD硬件原理 && 调色板与Framebuffer原理
1.从内存中(FrameBuffer)取出某个像素的数据:把FrameBuffer的地址告诉LCD控制器,BPP,分辨率
杨源鑫
2021/07/07
1.8K0
图解LCD硬件原理 && 调色板与Framebuffer原理
推荐一款不错的嵌入式GUI(玲珑GUI)及在嵌入式linux上的移植
玲珑GUI(LLGUI)是一套使用简单、低价的单片机GUI解决方案。可以用来代替串口屏、组态,降低产品成本,产品软硬件自主可控。 配套界面开发软件,图形化编辑界面,生成C代码。
杨永贞
2022/01/07
2.2K0
推荐一款不错的嵌入式GUI(玲珑GUI)及在嵌入式linux上的移植
全志V853开发板移植基于 LVGL 的 2048 小游戏
这一节将以一个已经编写好的 lvgl 小游戏 2048 描述如何将已经编写完成的 lvgl 程序移植到开发板上。
阿志小管家
2024/02/02
4070
全志V853开发板移植基于 LVGL 的 2048 小游戏
lvgl最新版本在STM32上的移植使用
LittlevGL是一个免费的开源图形库,提供了创建嵌入式GUI所需的一切,具有易于使用的图形元素、漂亮的视觉效果和低内存占用。
用户8913398
2021/08/16
4.5K0
lvgl最新版本在STM32上的移植使用
STM32CubeMX6.0 + HAL + LittleVGL7.6 等学习[最全附工程源码]
问题1: 打印正常,但是加入接收中断后,开始出bug,最后锁定接收中断挂掉了。 原因: HAL库的串口接收发送函数有bug,就是收发同时进行的时候,会出现锁死的现象。 解决: 需要注释掉 HAL_UART_Receive_IT 和 HAL_UART_Transmit_IT 中的 __HAL_LOCK(huart) 函数。或者不要在接收里面,每接收到一个字符就printf一下。
小锋学长生活大爆炸
2025/05/24
1110
STM32CubeMX6.0 + HAL + LittleVGL7.6 等学习[最全附工程源码]
嵌入式Linux高级案例-移植LVGL到Linux开发板
​ 本篇主要是记录将LVGL移植到百问网STM32MP157开发板上,并且仅是跑一下LVGL的一些例程。
韦东山
2022/06/30
4.1K0
为全志D1开发板移植LVGL日历控件和显示天气
Linux还真是逐步熟悉中,现在才了解到Linux即没有原生的GUI,也没有应用层协议栈,所以要实现HTTP应用,必须利用TCP然后自己封装HTTP数据包。本篇即记录封装HTTP数据包,到心知天气请求天气信息的案例实现过程。
阿志小管家
2024/02/22
3320
为全志D1开发板移植LVGL日历控件和显示天气
野火指南者开发板移植 lvgl 库
由于近期要做一个装置 ,想着把装置做的好看一点,就打算使用 GUI 来做一个信息的相关显示,之前听说过一款比较轻量级的图形库,也就是 lvgl,手头又正好有一块搭配屏幕的野火指南者开发板,单片机型号是 STM32F103VET6,Flash 为 512KB,RAM 为 64KB,屏幕为 3.2 寸电阻触摸屏,我们在来看一下运行 lvgl 这个 GUI 需要的资源,所需资源如下图所示:
wenzid
2021/03/04
2.2K0
野火指南者开发板移植 lvgl 库
荔枝派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图片
基于RT-THREAD的桌面小工具
摘要 这个桌面小盒子是之前的东西,一直放着没有整理好。最近有空了就把他整理整理。 小盒子主要用来显示时间和天气预报,功能比较简单,其实还有很多可以玩的,懒得弄,所以就把最简单的整理出来。 软件是基于rt-thread, UI采用lvgl。 功能主要分为两个部分 第一部分--功能 功能部分主要分为两个部分,一个是NTP获取实时时间,一个是天气等信息。 NTP比较简单,RTT提供了相关API。代码如下: void get_local_time(void) { time_t now; now =
Rice加饭
2022/05/10
7860
基于RT-THREAD的桌面小工具
Linux小项目-数码相册设计
这是基于Linux系统开发板设计一个小项目-数码相册,在LCD屏上可以显示完成常见的图片显示,翻页、旋转、缩放等功能。
DS小龙哥
2022/05/11
1.5K0
Linux小项目-数码相册设计
推荐阅读
相关推荐
全志V831基于pjsip的双向视频通话实现
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验