LVGL在rt-thread上的移植是怎样的

发布时间:2021-12-17 14:55:53 作者:柒染
来源:亿速云 阅读:836

LVGL在rt-thread上的移植是怎样的,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。

显示驱动的编写

首先按照rt-thread的lcd驱动框架完成驱动的编写,可参考如下结构体,完成相关函数的实现。

struct rt_device_graphic_ops
{
    void (*set_pixel) (const char *pixel, int x, int y);
    void (*get_pixel) (char *pixel, int x, int y);

    void (*draw_hline)(const char *pixel, int x1, int x2, int y);
    void (*draw_vline)(const char *pixel, int x, int y1, int y2);

    void (*blit_line) (const char *pixel, int x, int y, rt_size_t size);
};

在完成函数编写后,进行操作结构体的定义。

struct rt_device_graphic_ops fsmc_lcd_ops =
{
    LCD_DrawPoint,
    LCD_ReadPoint,
    LCD_HLine,
    RT_NULL,
    LCD_BlitLine,
};

然后,按照显示屏设备的具体信息进行填写,并将设备挂载到设备驱动列表。

int drv_lcd_hw_init(void)
{
    rt_err_t result = RT_EOK;
    struct rt_device *device = &_lcd.parent;

    /* memset _lcd to zero */
    memset(&_lcd, 0x00, sizeof(_lcd));

    _lcd.lcd_info.bits_per_pixel = 16;
    _lcd.lcd_info.pixel_format = RTGRAPHIC_PIXEL_FORMAT_RGB565;

    device->type = RT_Device_Class_Graphic;
#ifdef RT_USING_DEVICE_OPS
    device->ops = &lcd_ops;
#else
    device->init = drv_lcd_init;
    device->control = drv_lcd_control;
#endif
    device->user_data = &fsmc_lcd_ops;
    rt_device_register(device, "lcd", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_STANDALONE);

    return result;
}
INIT_DEVICE_EXPORT(drv_lcd_hw_init);

rt-thread显示驱动与LVGL对接

关于lvgl的相关参数设备及移植的详细说明见 官方移植说明,在此不做过多说明。

此部分对接主要针对lv_port_disp.c文件中lvgl显示驱动和rt-thread驱动接口的对接部分做下介绍。

显示初始化

此部分主要完成显示设备的查找和打开操作。

/* Initialize your display and the required peripherals. */
static void disp_init(void)
{
    /*You code here*/
    lcd_device = rt_device_find("lcd");
    if (!lcd_device)
    {
        LOG_E("find %s failed!", "lcd");
        return;
    }

    rt_device_open(lcd_device, RT_DEVICE_FLAG_RDWR);
}

显示数据的刷写

该部分需要完成指定区域的显示像素内容的写入,可以进行像素点操作或行列操作,可以结合自己显示屏的特性进行调整,此部分刷入的方案也是会影响显示的刷新率,需要尽可以选择刷新速度最快的方案。

/* 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*/

    // int32_t x;
    // int32_t y;
    // for (y = area->y1; y <= area->y2; y++)
    // {
    //     for (x = area->x1; x <= area->x2; x++)
    //     {
    //         /* Put a pixel to the display. For example: */
    //         /* put_px(x, y, *color_p)*/
    //         rt_graphix_ops(lcd_device)->set_pixel((const char *)&color_p->full, x, y);
    //         color_p++;
    //     }
    // }

    int32_t y;
    int32_t width;

    for (y = area->y1; y <= area->y2; y++)
    {
        width =  (area->x2 - area->x1 + 1);
        rt_graphix_ops(lcd_device)->blit_line((const char *)&color_p->full, area->x1, y, width);
        color_p += width;
    }

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

系统调用

在lvgl中有两个函数是依赖于系统的调用:lv_tick_inc和lv_task_handler(),注意这两个函数不能放到一个线程中,就避免相关事件响应机制出错。 我们可以创建一个软件定时器和一个任务分别来处理lvgl的系统调用。

    rt_thread_t tid;

    tid = rt_thread_create("lvgl_task", lvgl_task, RT_NULL, 4096, 20, 4);
    if (tid != RT_NULL)
        rt_thread_startup(tid);

    rt_timer_t timer1 = rt_timer_create("timer1", lvgl_tick, RT_NULL, 10, RT_TIMER_FLAG_PERIODIC);
    if (timer1 != RT_NULL)
        rt_timer_start(timer1);

在lvgl_task中,我们周期调用lv_task_handler()函数即可。

static void lvgl_task(void *parameter)
{
    while (true)
    {
        rt_thread_delay(10);
        lv_task_handler();
    }
}

相应的,在软定时器中,我们根据软件定时器的间隔,在超时处理中对lv_tick_inc注入时间间隔即可。

static void lvgl_tick(void *parameter)
{
    lv_tick_inc(10);
}

至此,已经完成rt-thread与lvgl的移植对接工作,可以进行应用层代码的编写。

关于LVGL在rt-thread上的移植是怎样的问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注亿速云行业资讯频道了解更多相关知识。

推荐阅读:
  1. linux程序移植到android上
  2. RT-Thread内存管理是怎么进行的

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

lvgl rt-thread

上一篇:RT-Thread中$Sub$$main与$Super$$main扩展main函数的示例分析

下一篇:如何进行springboot配置templates直接访问的实现

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》