一文了解LVGL的链表数据结构

本文深入探讨了LVGL中链表数据结构的应用及其C语言实现技巧。介绍了LVGL链表的结构定义、内存布局特点,并详细讲解了链表节点操作方法及全局链表管理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 引言

      本本探究下LVGL使用的数据结构:链表, LVGL使用的链表是带链表头,尾的双列表。

2 数据结构定义

2.1 链表节点的定义

typedef struct {
    uint32_t n_size;
    lv_ll_node_t * head;
    lv_ll_node_t * tail;
} lv_ll_t;

2.2 链表节点的内存分布图

注意: 链表节点的数据结构定义和内存分布是不对应的(64位cpu时)

在这里插入图片描述

3. LVGL链表结构示意图

在这里插入图片描述

4. 链表的基本操作

在这里插入图片描述

5. 常用链表数据

       LVGL在头文件lv_gc.h, 定义一组跟链表全局变量,用于进行各种类型数据链表的动态管理。

#define LV_ITERATE_ROOTS(f)                                                                 \
    LV_DISPATCH(f, lv_ll_t, _lv_timer_ll) /*Linked list to store the lv_timers*/            \
    LV_DISPATCH(f, lv_ll_t, _lv_disp_ll)  /*Linked list of display device*/                 \
    LV_DISPATCH(f, lv_ll_t, _lv_indev_ll) /*Linked list of input device*/                   \
    LV_DISPATCH(f, lv_ll_t, _lv_fsdrv_ll)                                                   \
    LV_DISPATCH(f, lv_ll_t, _lv_anim_ll)                                                    \
    LV_DISPATCH(f, lv_ll_t, _lv_group_ll)                                                   \
    LV_DISPATCH(f, lv_ll_t, _lv_img_decoder_ll)                                             \
    LV_DISPATCH(f, lv_ll_t, _lv_obj_style_trans_ll)                                         \
    LV_DISPATCH(f, lv_layout_dsc_t *, _lv_layout_list)      \
    LV_DISPATCH_COND(f, _lv_img_cache_entry_t*, _lv_img_cache_array, LV_IMG_CACHE_DEF, 1)    \
    LV_DISPATCH_COND(f, _lv_img_cache_entry_t, _lv_img_cache_single, LV_IMG_CACHE_DEF, 0)    \
    LV_DISPATCH(f, lv_timer_t*, _lv_timer_act)                                              \
    LV_DISPATCH(f, lv_mem_buf_arr_t , lv_mem_buf)                                           \
    LV_DISPATCH_COND(f, _lv_draw_mask_saved_arr_t , _lv_draw_mask_list, LV_DRAW_COMPLEX, 1) \
    LV_DISPATCH(f, void * , _lv_theme_default_styles)                                       \
    LV_DISPATCH_COND(f, uint8_t *, _lv_font_decompr_buf, LV_USE_FONT_COMPRESSED, 1)

6. LVGL 常用数据链表

LVGL定义了一组全局链表,用于对一些常用的数据进行动态管理,这个常用的链表咋lvgl初始化时进行初始化,
具体如下。
在这里插入图片描述

7. LVGL链表使用的C技巧

如前所述,LVGL链表节点的结构体所占内容和节点实际所占内存(64位cpu)是不一致的,因此定位成员变量head, tail内存地址
需特殊处理。
LVGL 定义了3个宏来用作成员变量偏移计算:
#define LL_NODE_META_SIZE (sizeof(lv_ll_node_t *) + sizeof(lv_ll_node_t *))
#define LL_PREV_P_OFFSET(ll_p) (ll_p->n_size)
#define LL_NEXT_P_OFFSET(ll_p) (ll_p->n_size + sizeof(lv_ll_node_t *))

成员实际地址 = 成员结构体内偏移地址+节点其实地址

static void node_set_prev(lv_ll_t * ll_p, lv_ll_node_t * act, lv_ll_node_t * prev)
{
    if(act == NULL) return; /*Can't set the prev node of `NULL`*/

    uint8_t * act8 = (uint8_t *)act;

    act8 += LL_PREV_P_OFFSET(ll_p);			//计算成员head的 实际地址				

    lv_ll_node_t ** act_node_p = (lv_ll_node_t **) act8;
    lv_ll_node_t ** prev_node_p = (lv_ll_node_t **) &prev;

    *act_node_p = *prev_node_p;
}

8. 总结

      本文总结了链表数据结构在LVGL的应用,也讨论了在链表数据结构应用时使用的一些C语言技巧。了解LVGL的链表数据结构,对我们加深理解LVGL的代码执行,底层数据(对象)如何动态管理很有帮助。

9. 关注我

创作不易,如帮助请点赞,关注。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值