木子剑
生命不熄,学习不止!

第1步:

将LVGL v8.0.2下载并解压到TencentOS-tiny\components\gui\LittlevGL如下图:

  

 第2步: 

我用IAR SYSTEM 是V9.10版本,将不用的文件全部删除掉,保留必要的 .c  .h  .bin 这些文件夹.

这个可以参靠之前的LVGL V6或LVGL V7版本,或找一个DEMO,总之要明确保留的具体文件.

 

如上就这么2个文件夹了, 我们先将 lv_conf_template.h 变更为lv_conf.h,并打开改为如下:

 

 

第3步:

将TencentOS-tiny\components\gui\LittlevGL\lvgl-8.0.2\examples\porting下的所有文件名'_template'去掉,如下

 

 如上内容都是后期要用的, 因为是先移植UI显示的,所以先打开lv_port_disp.h,更改如下:

 

 

第4步:

将如下内容的.H .C文件和路经,加载到IAR  SYSTEM去,这个过程很无聊,要有耐心和细心。。正在进行中。。。

          另外先提示一下---> 

 

最后在IAR的TencentOS-tiny新增LVGL文件项如下图所示:

假设还不会移植TencentOS-tiny,阅读另一个随记--->腾讯开源精简操作系统TencentOS-tiny与SWM320初试 

 

IAR新增LVGL文件路经为如下:

 

 

第5步:

为LVGL安装tick心跳,先让它活起来,如下所示:

找到tos_config.h内的TOS_CFG_TIMER_AS_PROC项,将它设为如下:

#define TOS_CFG_CPU_CLOCK     (SystemCoreClock)        // 当前CPU频率
#define TOS_CFG_TIMER_AS_PROC           1u             // 时间为函数模式:1

 

在mcu_init.c内找到systick中断入口函数void SysTick_Handler(void),改为如下:

 这个时候,LVGL已经拥有心跳了,上面图片打错一个字。。。 

 

第6步:

我们先适配LVGL的lv_conf.h文件,以屏的分辨率为准,新增如下:

 

 

再找到LV_COLOR_DEPTH改为,当前屏为RGB565对应上 

/*Color depth: 1 (1 byte per pixel), 8 (RGB332), 16 (RGB565), 32 (ARGB8888)*/
#define LV_COLOR_DEPTH     16

 

再找到LV_USE_PERF_MONITOR,打开FPS监视.

/*1: Show CPU usage and FPS count in the right bottom corner*/
#define LV_USE_PERF_MONITOR     1

 

再找到 LV_THEME_DEFAULT_DARK,配置为暗夜模式,默认是灯光模式,这个是LVGL主题,和手机主题一个意思的

/*0: Light mode; 1: Dark mode*/
# define LV_THEME_DEFAULT_DARK     1

然后保存lv_conf.h,这个文件我们已经适配完成了。

 

下面来适配lv_port_disp.c文件,先从裸机上找到SWM32S的SDRAM  LCD驱动的例子,

将芯片LCD外设的参数单独测试好,实现正常刷图显示功能,保证和芯片都是OK的。

在TencentOS-tiny\board\SWM320_DISCOVERY\BSP\Hardware下新建文件,先完成

硬件上的.C  .H文件移植,如下所示:

 

 

 

下面来就可以正试适配lv_port_disp.c文件了,直接给出适配好的文件吧,因为之前移植过了

V8.0.1版本,和这个V8.0.2应相差不大。。。。

把TencentOS-tiny\components\gui\LittlevGL\lvgl-8.0.2\examples\porting下的lv_port_disp.c和

lv_port_disp.h加入到IAR工程,并把它们的路经,能走这里应该比较容易了。。。

测试过的lv_port_disp.h文件如下:

/**
 * @file lv_port_disp_templ.h
 *
 */

 /*Copy this file as "lv_port_disp.h" and set this value to "1" to enable content*/
#if 1

#ifndef LV_PORT_DISP_H
#define LV_PORT_DISP_H

#ifdef __cplusplus
extern "C" {
#endif

/*********************
 *      INCLUDES
 *********************/
#include "lvgl.h"

/*********************
 *      DEFINES
 *********************/

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

/**********************
 * GLOBAL PROTOTYPES
 **********************/
void lv_port_disp_init(void);

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

#ifdef __cplusplus
} /*extern "C"*/
#endif

#endif /*LV_PORT_DISP_TEMPL_H*/

#endif /*Disable/Enable content*/

 

测试过的lv_port_disp.c文件如下:

/**
 * @file lv_port_disp_templ.c
 *
 */

 /*Copy this file as "lv_port_disp.c" and set this value to "1" to enable content*/
#if 1

/*********************
 *      INCLUDES
 *********************/
#include "lv_port_disp.h"
#include "../../lvgl.h"

#include "lv_hal_disp.h"
#include "SWM320.h"

/*********************
 *      DEFINES
 *********************/

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

/**********************
 *  STATIC PROTOTYPES
 **********************/
static void disp_init(void);
static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p);

/**********************
 *  STATIC VARIABLES
 **********************/
static uint32_t *lcdbuf_show = (uint32_t *)SDRAMM_BASE;   // ok显示

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

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

void lv_port_disp_init(void)
{
    /*-------------------------
     * Initialize your display
     * -----------------------*/
    disp_init();

    /*-----------------------------
     * Create a buffer for drawing
     *----------------------------*/

    /**
     * LVGL requires a buffer where it internally draws the widgets.
     * Later this buffer will passed to your display driver's `flush_cb` to copy its content to your display.
     * The buffer has to be greater than 1 display row
     *
     * There are 3 buffering configurations:
     * 1. Create ONE buffer:
     *      LVGL will draw the display's content here and writes it to your display
     *
     * 2. Create TWO buffer:
     *      LVGL will draw the display's content to a buffer and writes it your display.
     *      You should use DMA to write the buffer's content to the display.
     *      It will enable LVGL to draw the next part of the screen to the other buffer while
     *      the data is being sent form the first buffer. It makes rendering and flushing parallel.
     *
     * 3. Double buffering
     *      Set 2 screens sized buffers and set disp_drv.full_refresh = 1.
     *      This way LVGL will always provide the whole rendered screen in `flush_cb`
     *      and you only need to change the frame buffer's address.
     */

    /* Example for 1) */
    //static lv_disp_draw_buf_t draw_buf_dsc_1;
    //static lv_color_t buf_1[MY_DISP_HOR_RES * 10];                          /*A buffer for 10 rows*/
    //lv_disp_draw_buf_init(&draw_buf_dsc_1, buf_1, NULL, MY_DISP_HOR_RES * 10);   /*Initialize the display buffer*/

    /* Example for 2) */
    static lv_disp_draw_buf_t draw_buf_dsc_2;
    static lv_color_t buf_2_1[LV_HOR_RES_MAX * 10];                        /*A buffer for 10 rows*/
    static lv_color_t buf_2_2[LV_HOR_RES_MAX * 10];                        /*An other buffer for 10 rows*/
    lv_disp_draw_buf_init(&draw_buf_dsc_2, buf_2_1, buf_2_2, LV_HOR_RES_MAX * 10);   /*Initialize the display buffer*/

    /* Example for 3) also set disp_drv.full_refresh = 1 below*/
    //static lv_disp_draw_buf_t draw_buf_dsc_3;
    //static lv_color_t buf_3_1[MY_DISP_HOR_RES * MY_DISP_VER_RES];            /*A screen sized buffer*/
    //static lv_color_t buf_3_1[MY_DISP_HOR_RES * MY_DISP_VER_RES];            /*An other screen sized buffer*/
    //lv_disp_draw_buf_init(&draw_buf_dsc_3, buf_3_1, buf_3_2, MY_DISP_VER_RES * LV_VER_RES_MAX);   /*Initialize the display buffer*/

    /*-----------------------------------
     * Register the display in LVGL
     *----------------------------------*/

    static lv_disp_drv_t disp_drv;                         /*Descriptor of a display driver*/
    lv_disp_drv_init(&disp_drv);                    /*Basic initialization*/

    /*Set up the functions to access to your display*/

    /*Set the resolution of the display*/
    disp_drv.hor_res = LV_HOR_RES_MAX;
    disp_drv.ver_res = LV_VER_RES_MAX;

    /*Used to copy the buffer's content to the display*/
    disp_drv.flush_cb = disp_flush;

    /*Set a display buffer*/
    disp_drv.draw_buf = &draw_buf_dsc_2;

    /*Required for Example 3)*/
    //disp_drv.full_refresh = 1

    /* Fill a memory array with a color if you have GPU.
     * Note that, in lv_conf.h you can enable GPUs that has built-in support in LVGL.
     * But if you have a different GPU you can use with this callback.*/
    //disp_drv.gpu_fill_cb = gpu_fill;

    /*Finally register the driver*/
    lv_disp_drv_register(&disp_drv);
}

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

/*Initialize your display and the required peripherals.*/
#include "lcd_RGB565.h"
#include "lv_disp.h"
static void disp_init(void)///////////////////////////////////////////////////
{
    /*You code here*/
    lcd_rgb_init();
    LCD->SRCADDR = (uint32_t)lcdbuf_show; //显示
    LCD_Start(LCD);
}

/*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.*/
static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
{
    /*The most simple case (but also the slowest) to put all pixels to the screen one-by-one*/

    uint32_t temp;
    uint32_t index;
    uint32_t pos;
    lv_coord_t x;
    lv_coord_t y;

    //y=area->y1;
    for(y=area->y1; y <= area->y2; y++) {

        //x = area->x1;
        for(x=area->x1; x <= area->x2; x++) {
            /* Put a pixel to the display. For example: */
            /* put_px(x, y, *color_p)*/
            //drawpoint(x, y, color_p->full);

            index = (y*LV_HOR_RES+x) / 2;
            pos = ((x%2) == 0 ? 0 : 16);
            temp = lcdbuf_show[index];
            temp &= ~(0xFFFF << pos);
            temp |=  (color_p->full << pos);
            lcdbuf_show[index] = temp;

            color_p++;
        }
    }

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

/*OPTIONAL: GPU INTERFACE*/

#else /*Enable this file at the top*/

/*This dummy typedef exists purely to silence -Wpedantic.*/
typedef int keep_pedantic_happy;
#endif

 

将mcu_init.c更改为如下,主要是在 board_init()对LVGL进行初始化。。

 

 

然后再对TOS之前软件定时器进行更改,main.C只开启软件定时器测试,如下:

 

 

最后在线仿真看效果,可以看到显示屏有FPS了,说明TOS与LVGL移植成功。。。

   

 如果要下载源码,请到华芯微特技术支持群492524359,已经上传QQ群里了,如下所示

 

 

接下来可以跑跑\lvgl-8.0.2\examples的DEMO,也可以自行学习LVGL的其他功能,结束了,再见!!

posted on 2021-08-29 17:57  木子剑  阅读(1199)  评论(0编辑  收藏  举报