移植LittlevGL到三星T200记录

5 篇文章 0 订阅
3 篇文章 0 订阅

LittlevGL 是一个开源免费的GUI,支持触摸屏操作,移植简单方便,开发者一直在不断完善更新。LittlevGL 自带了丰富的控件:窗口、按键、标签、list、图表等,还可以自定义控件;支持很多特效:透明、阴影、自动显示隐藏滚动条、界面切换动画、图标打开关闭动画、平滑的拖拽控件、分层显示、反锯齿等等。
三星T200是一颗带WIFI的MCU,主频可到320M,对LittlevGL来说速度是足够了。主要难点是t200的系统用的是三星自己的TizenOS RT,是一个nuttX核的RTOS。这里简单记录一下我的移植步骤。

1.首先当然是下载源码包,得到lv_drivers.zip,lv_examples.zip,lvgl_v5_3.zip这三个源码包。

2.lv_drivers.zip可以暂时先不用,把lv_examples.zip和lvgl_v5_3.zip解压到APP Demo目录,.复制lvgl文件夹下的lv_conf_templ.h文件到文件夹lvgldemo下面,并重命名为lv_conf.h。修改lv_conf.h里的几个参数。最基本的3个:LCD的长和宽,像素位深。其他参数暂时不管。还需要将文件开头的#if 0 改为 #if 1;复制lv_examples文件夹下的lv_ex_conf_templ.h文件到文件夹lvgldemo下面,并重命名为lv_ex_conf.h。将文件开头的#if 0 改为 #if 1.

3.修改Makefile文件,以及LittleVGL的MK文件,让编译通过。生成相应的目标文件,其中可能需要修改一些宏来让其顺利编译。

4.在lvgldemo下面添加以下lv_main.c文件,来运行lvgl demo.在源码的移植中有三个重要文件lv_hal_disp.c,lv_hal_indev.c,lv_hal_tick.c在\lvgl\lv_hal目录,包括显示接口的移植,输入接口的移植以及tick移植。现在没有触摸,所以输入先不管。

5.因为我没有加载专业的driver做显示接口,所以我的显示接口在函数static void ex_disp_flush(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const lv_color_t * color_p)里来实现。

6.根据系统修改tick_get

    uint32_t lv_tick_get(void){

struct timeval tv;
    if (gettimeofday(&tv, NULL) != 0)
        return 0;
    return (tv.tv_sec * 1000) + (tv.tv_usec / 1000);

}

 

以下是lv_main.c文件源码。

#include "lvgl/lvgl.h"
#include "kmrtm28028.h"
#include "lv_examples/lv_apps/demo/demo.h"

/**********************
 *  STATIC PROTOTYPES
 **********************/
static void ex_disp_flush(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const lv_color_t * color_p);
static void ex_disp_map(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const lv_color_t * color_p);
static void ex_disp_fill(int32_t x1, int32_t y1, int32_t x2, int32_t y2,  lv_color_t color);
#if USE_LV_GPU
static void ex_mem_blend(lv_color_t * dest, const lv_color_t * src, uint32_t length, lv_opa_t opa);
static void ex_mem_fill(lv_color_t * dest, uint32_t length, lv_color_t color);
#endif
static bool ex_tp_read(lv_indev_data_t * data);

/**********************
 *  STATIC VARIABLES
 **********************/
/* 添加 fb 支持 */
//#include "lv_drivers/display/fbdev.h"
EPD epd;

int lv_main(void)
{
    /*LittlevGL init*/
    lv_init();

    /*Linux frame buffer device init*/
    //fbdev_init();
    
      if (kmrtm_Init(&epd) != 0) {
            printf("e-Paper init failed\n");
            return 0;
      }

    //Lcd_Init();   //tft初始化
    kmrtm_Clear(&epd,BLACK); //清屏

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

    /*Set up the functions to access to your display*/
    disp_drv.disp_flush = ex_disp_flush;            /*Used in buffered mode (LV_VDB_SIZE != 0  in lv_conf.h)*/

    disp_drv.disp_fill = ex_disp_fill;              /*Used in unbuffered mode (LV_VDB_SIZE == 0  in lv_conf.h)*/
    disp_drv.disp_map = ex_disp_map;                /*Used in unbuffered mode (LV_VDB_SIZE == 0  in lv_conf.h)*/
    printf("use_lv_gpu in\r\n");
#if USE_LV_GPU
    /*Optionally add functions to access the GPU. (Only in buffered mode, LV_VDB_SIZE != 0)*/
    disp_drv.mem_blend = ex_mem_blend;              /*Blend two color array using opacity*/
    disp_drv.mem_fill = ex_mem_fill;                /*Fill a memory array with a color*/
    printf("use_lv_gpu in+++\r\n");
#endif
printf("use_lv_gpu out\r\n");
    /*Finally register the driver*/
    lv_disp_drv_register(&disp_drv);
    /*************************
     * Input device interface
     *************************/
    /*Add a touchpad in the example*/
    /*touchpad_init();*/                            /*Initialize your touchpad*/
    lv_indev_drv_t indev_drv;                       /*Descriptor of an input device driver*/
    lv_indev_drv_init(&indev_drv);                  /*Basic initialization*/
    indev_drv.type = LV_INDEV_TYPE_POINTER;         /*The touchpad is pointer type device*/
    indev_drv.read = ex_tp_read;                 /*Library ready your touchpad via this function*/
    lv_indev_drv_register(&indev_drv);              /*Finally register the driver*/

    printf("register touchpad driver\r\n");
    /*************************************
     * Run the task handler of LittlevGL
     *************************************/
    /* 选择示例启动 */
    //benchmark_create();
    //demo_create();
    sysmon_create();
    printf("benchmark_create out\r\n");
    /*Handle LitlevGL tasks (tickless mode)*/
    while(1) {
        lv_tick_inc(5);
        lv_task_handler();
        usleep(5000);
    }

    return 0;
}

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

/* 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_flush_ready()' has to be called when finished
 * This function is required only when LV_VDB_SIZE != 0 in lv_conf.h*/
static void ex_disp_flush(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const lv_color_t * color_p)
{
    /*The most simple case (but also the slowest) to put all pixels to the screen one-by-one*/

    int32_t x;
    int32_t y;
    int i=0;
    
    printf("ex_disp_flush,x1=%d,y1=%d,x2=%d,y2=%d.\r\n",x1,y1,x2,y2);
    for(y = y1; y <= y2; y++) {
        for(x = x1; x <= x2; x++) {
            /* Put a pixel to the display. For example: */
            /* put_px(x, y, *color_p)*/
         kmrtm_lvgl_mem(i,(u16)color_p->full);
         //kmrtm_lcd_mem(&epd,(u16)color_p->full);
         //kmrtm_Paint(&epd,x,y,1,1);
         i++;
            color_p++;
        }
    }
    if(x1==0)
        kmrtm_lvgl_Paint(&epd,x1,y1,x2-x1+1,y2-y1+1);
    else
    kmrtm_lvgl_Paint(&epd,x1,y1,x2-x1,y2-y1);
    /* IMPORTANT!!!
     * Inform the graphics library that you are ready with the flushing*/
    lv_flush_ready();
}


/* Write a pixel array (called 'map') to the a specific area on the display
 * This function is required only when LV_VDB_SIZE == 0 in lv_conf.h*/
static void ex_disp_map(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const lv_color_t * color_p)
{
    /*The most simple case (but also the slowest) to put all pixels to the screen one-by-one*/

    int32_t x;
    int32_t y;
    printf("ex_disp_map\r\n");
    for(y = y1; y <= y2; y++) {
        for(x = x1; x <= x2; x++) {
            /* Put a pixel to the display. For example: */
            /* put_px(x, y, *color_p)*/
            kmrtm_lvgl_mem(&epd,(u16)color_p->full);
            kmrtm_lvgl_Paint(&epd,x,y,1,1);
            color_p++;
        }
    }
}


/* Write a pixel array (called 'map') to the a specific area on the display
 * This function is required only when LV_VDB_SIZE == 0 in lv_conf.h*/
static void ex_disp_fill(int32_t x1, int32_t y1, int32_t x2, int32_t y2,  lv_color_t color)
{
    /*The most simple case (but also the slowest) to put all pixels to the screen one-by-one*/

    int32_t x;
    int32_t y;
    printf("ex_disp_fill\r\n");
    
    for(y = y1; y <= y2; y++) {
        for(x = x1; x <= x2; x++) {
            /* Put a pixel to the display. For example: */
            /* put_px(x, y, *color)*/
            kmrtm_lvgl_mem(&epd,(u16)color.full);
            kmrtm_lvgl_Paint(&epd,x,y,1,1);
        }
    }

    (void)color; /*Just to avid warnings*/
}

#if USE_LV_GPU

/* If your MCU has hardware accelerator (GPU) then you can use it to blend to memories using opacity
 * It can be used only in buffered mode (LV_VDB_SIZE != 0 in lv_conf.h)*/
static void ex_mem_blend(lv_color_t * dest, const lv_color_t * src, uint32_t length, lv_opa_t opa)
{
    /*It's an example code which should be done by your GPU*/

    uint32_t i;
    for(i = 0; i < length; i++) {
        dest[i] = lv_color_mix(dest[i], src[i], opa);
    }
}

/* If your MCU has hardware accelerator (GPU) then you can use it to fill a memory with a color
 * It can be used only in buffered mode (LV_VDB_SIZE != 0 in lv_conf.h)*/
static void ex_mem_fill(lv_color_t * dest, uint32_t length, lv_color_t color)
{
    /*It's an example code which should be done by your GPU*/

    uint32_t i;
    for(i = 0; i < length; i++) {
        dest[i] = color;
    }
}

#endif

/* Read the touchpad and store it in 'data'
 * Return false if no more data read; true for ready again */
static bool ex_tp_read(lv_indev_data_t * data)
{
    /* Read your touchpad */
    /* data->state = LV_INDEV_STATE_REL or LV_INDEV_STATE_PR */
    /* data->point.x = tp_x; */
    /* data->point.y = tp_y; */
    
    /*In LV_INDEV_STATE_REL state you should use the last pressed coordinates*/

    (void)data; /*Just to avid warnings*/

    return false;   /*false: no more data to read because we are no buffering*/

LittlevGL里面有个简单的时间片调度系统,刷新显示和触摸处理等任务会周期的被调用处理。LCD刷新采用了局部缓存刷新,这样能避免闪烁出现。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值