良许Linux教程网 干货合集 【RT-Thread笔记】对象容器与双链表

【RT-Thread笔记】对象容器与双链表

前言

在嵌入式开发中,一些人可能认为与数据结构和算法相关的知识并不实用,很少会用到。

我以前也有过这样的想法,觉得那些知识很难学,好像又用不上,所以干脆就不去学了。

直到后来深入学习了一些东西后,才发现原来那些知识并不是毫无用处的,只是当时我们的认知还不够。废话不多说,下面进入正题:

对象容器与双链表

1、RT-Thread中的对象容器

RT-Thread 内核中的对象包括线程、信号量、互斥量、事件、邮箱、消息队列、定时器、内存池、设备驱动等。

对象容器用于存储每个对象的信息,包括对象类型和大小等。

对象容器为每种对象类型分配了一个双链表,所有的对象都被链接到相应的链表上。RT-Thread的对象容器和双链表示例如下图:

image-20231008203938427
image-20231008203938427

这个对象容器对应到代码上是一个结构体数组,这个结构体数组在object.c里定义,其内容如下(已做删减):

staticstruct rt_object_information 
rt_object_container[RT_Object_Info_Unknown] =
{
    /* 初始化对象容器 - 线程 */
    {
      RT_Object_Class_Thread,
      _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_Thread),
      sizeof(struct rt_thread)
    },
 
#ifdef RT_USING_SEMAPHORE
    /* 初始化对象容器 - 信号量 */
    {
      RT_Object_Class_Semaphore,
      _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_Semaphore),
      sizeof(struct rt_semaphore)
    },
#endif

    /* 省略部分代码。。。。。。。。。。。。。。。。。*/
 
    /* 初始化对象容器 - 定时器 */
    {
      RT_Object_Class_Timer,
      _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_Timer),
      sizeof(struct rt_timer)
    },

    /* 省略部分代码。。。。。。。。。。。。。。。。。*/
};

其中,内核对象信息结构体 struct rt_object_information 的定义如下:

struct rt_object_information
{
  enum rt_object_class_type type; /**

RT-Thread 的内核对象的继承关系如:

image-20231008203943099
image-20231008203943099

在代码阅读器Source Insight中(相关笔记:《Source Insight的使用》)也可以看出这样的关系:

image-20231008203946402
image-20231008203946402

每个内核对象的初始化函数里都有调用对象初始化函数rt_object_init

而对象初始化函数里做了什么呢?看其内部实现(已做删减):

void rt_object_init(struct rt_object         *object,
                    enum rt_object_class_type type,
                    const char               *name)
{
  registerrt_base_t temp;
  struct rt_object_information *information;

  /* 获取对象信息,即从容器里拿到对应对象列表头指针 */
  information = rt_object_get_information(type);
  RT_ASSERT(information != RT_NULL);

  /* 设置对象类型为静态 */
  object->type = type | RT_Object_Class_Static;

  /* 拷贝名字 */
  rt_strncpy(object->name, name, RT_NAME_MAX);

  /* 关中断 */
  temp = rt_hw_interrupt_disable();

  /* 把对象信息插入到对象链表中 */
  rt_list_insert_after(&(information->object_list), &(object->list));

  /* 开中断 */
  rt_hw_interrupt_enable(temp);
}

这里用到的rt_list_insert_after函数就是双链表插入函数。

2、RT-Thread中双链表的操作

RT-Thread的对象容器是依赖于双链表(双向循环链表)的,其双链表的相关操作在文件rtservice.h中:

image-20231008203949490
image-20231008203949490

其节点结构体为:

struct rt_list_node
{
    struct rt_list_node *next;/**

下面介绍几个基本的操作接口(截图来自野火的RT-Thread书籍):

(1)初始化链表节点:

image-20231008203952121
image-20231008203952121
rt_inline void rt_list_init(rt_list_t *l)
{
  l->next = l->prev = l;/* 节点的next指针与prev指针都指向其本身 */
}

(2) 在双向链表表头后面插入一个节点:

image-20231008203954760
image-20231008203954760
rt_inline void rt_list_insert_after(rt_list_t *l, rt_list_t *n)
{
  l->next->prev = n; /* 第(1)步 */
  n->next = l->next; /* 第(2)步 */

  l->next = n;      /* 第(3)步 */
  n->prev = l;      /* 第(4)步 */
}

**
**

(3)在双向链表表头前面(表尾后面)插入一个节点:

image-20231008203957124
image-20231008203957124
rt_inline void rt_list_insert_before(rt_list_t *l, rt_list_t *n)
{
  l->prev->next = n; /* 第(1)步 */
  n->prev = l->prev; /* 第(2)步 */

  l->prev = n;       /* 第(3)步 */
  n->next = l;      /* 第(4)步 */
}

**
**

(4)从双向链表删除一个节点:

image-20231008204000242
image-20231008204000242
rt_inline void rt_list_remove(rt_list_t *n)
{
  n->next->prev = n->prev; /* 第(1)步 */
  n->prev->next = n->next; /* 第(2)步 */

  n->next = n->prev = n;   /* 第(3)步 */
}

初始化对象列表节点头里面的 next 和 prev 两个节点指针分别指向自身,如:

image-20231008204003338
image-20231008204003338

若创建两个led线程对象,则对象容器里变为:

image-20231008204006105
image-20231008204006105

顺便提一个关于链表的一个名词上的疑惑,是节点还是结点?我之前也看过一些书,有的书写为节点,有的书写为结点,我也不知道哪个更准确。不纠结了,知道这么一回事就可以了,不影响我们学习。

最后

看到了吧,数据结构在嵌入式中还是很有用的吧,更多的细节可以阅读其源码。

以上就是本次的笔记分享,如有错误,欢迎指出!如果觉得文章不错,转发、在看,也是我们继续更新得动力。

以上就是良许教程网为各位朋友分享的Linu系统相关内容。想要了解更多Linux相关知识记得关注公众号“良许Linux”,或扫描下方二维码进行关注,更多干货等着你 !

137e00002230ad9f26e78-265x300
本文由 良许Linux教程网 发布,可自由转载、引用,但需署名作者且注明文章出处。如转载至微信公众号,请在文末添加作者公众号二维码。
良许

作者: 良许

良许,世界500强企业Linux开发工程师,公众号【良许Linux】的作者,全网拥有超30W粉丝。个人标签:创业者,CSDN学院讲师,副业达人,流量玩家,摄影爱好者。
上一篇
下一篇

发表评论

联系我们

联系我们

公众号:良许Linux

在线咨询: QQ交谈

邮箱: yychuyu@163.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

关注微博
返回顶部