乐趣区

关于开源:RTThread-内核学习笔记-内核对象初始化链表组织方式

RT-Thread 内核学习笔记 – 内核对象 rt_object

RT-Thread 内核学习笔记 – 内核对象治理

RT-Thread 内核学习笔记 – 内核对象操作 API

RT-Thread 内核学习笔记 – 内核对象初始化链表组织形式

RT-Thread 内核学习笔记 – 内核对象链表构造深刻了解

RT-Thread 内核学习笔记 – 设施模型 rt_device 的了解

RT-Thread 内核学习笔记 – 了解 defunct 僵尸线程
背景

最近在看 RT-Thread 内核的源码,内核对象应用链表组织。RT-Thread 外部有残缺的【双向链表】与【单向链表】的操作 API 与理论用例
内核对象,内核派生的如线程、定时器、设施等,都是由链表链起来治理的。

链表介绍

/**

  • Double List structure
    */

struct rt_list_node
{

struct rt_list_node *next;                          /**< point to next node. */
struct rt_list_node *prev;                          /**< point to prev node. */

};
typedef struct rt_list_node rt_list_t; /*< Type for lists. /

链表是一种数据结构,跟其余的构造体相似,初始化后,自身占用内存空间,本身有内存地址。个别双向链表,外部的成员,是链表自身构造体的指针,留神,指针的指向,初始化后,并没有确定。RT-Thread 的双向链表,初始化时,外部的指针,指向本人自身的地址,也就是给链表的成员,赋好了初值(指针内容,个别是地址)。链表应用,节点个别都是【全局构造体变量】,全局动态初始化,或动态内存申请(全局)。不必全局的链表节点,留神不要链入链表构造,否则节点地址因为【生命周期】完结内存开释了,地址就不对了,就无奈治理各个链表的节点了。

双向链表 API

这里注要提一下链表节点的插入【秩序】,因为遇到了一点小困惑,所以深刻的钻研了下。了解:【最新节点】【前一个节点】【最早节点】链表的头的问题:内核对象应用【对象容器】,全局的,对象初始化后,用了 rt_list_insert_after

/ 来自:object.c:rt_object_init /

    /* insert object into information object list */
    rt_list_insert_after(&(information->object_list), &(object->list));

留神,rt_list_insert_after,插入的地位,【不是链表的尾部插入,是第一个链表节点【第一个参数】的前面。】也就是说,如果创立了 3 个内核对象,默认的排序如下:

不是:【容器 head】— [obj1] — [obj2] — [obj2]
而是:【容器 head】— [obj3] — [obj2] — [obj1]

如果把链表插入到【尾部】前面,就要先把链表指针移到尾部,再执行:rt_list_insert_after.

查看内核对象

其实,thread,device 等对象,都是内核对象【派生】进去的。RT-Thread 提供 list_thread、list_device 等,查看内核的对象。查看线程初始化【秩序】,看看最初打印的线程,就是【最先】首个创立的线程。个别从链表【头部】开始遍历各个链表节点。如下:最初一个节点是:main 线程.
其实,main 线程,是第一个创立的。

msh />list_thread
thread pri status sp stack size max used left tick error


persim 16 suspend 0x000001ec 0x0000c000 08% 0x00000003 000
sens 28 suspend 0x000000d8 0x00001000 13% 0x00000019 000
hws 28 suspend 0x000000d8 0x00000800 10% 0x00000032 000
dcm_tpo 10 suspend 0x00000090 0x00000800 14% 0x00000004 000
dcm_tpo 10 suspend 0x00000090 0x00000800 14% 0x00000002 000
dcm_tpo 10 suspend 0x00000090 0x00000800 15% 0x00000004 000
tshell 20 running 0x000001fc 0x00001000 26% 0x0000000a 000
touch 16 suspend 0x00000098 0x00000800 18% 0x00000013 000
usbd 8 suspend 0x000000ac 0x00001000 04% 0x00000014 000
at_clnt 9 suspend 0x000000c0 0x00000600 12% 0x00000002 000
ulog_asy 30 suspend 0x00000084 0x00000c00 09% 0x00000006 000
mmcsd_de 22 suspend 0x000000a0 0x00000400 48% 0x00000014 000
alarmsvc 10 suspend 0x000000a8 0x00000800 27% 0x00000003 000
rils 12 suspend 0x000000b0 0x00000800 08% 0x0000001e 000
tidle0 31 ready 0x00000058 0x00000800 04% 0x0000001d 000
timer 4 suspend 0x00000074 0x00000800 08% 0x00000009 000
main 10 suspend 0x00000120 0x00000800 41% 0x00000012 000 / 最先创立的线程,最初打印 /

内核对象初始化的链表【秩序】:

2021-01-29_085157.png
总结

应用链表时,留神插入的秩序,尤其是 FIFO 的缓冲区的读写解决
相熟 RT-Thread 内核对象,对象治理办法。深入研究根本数据结构的应用:链表

退出移动版