FreeRTOS相关:linux中的侵入式链表设计

本文深入探讨了Linux内核与FreeRTOS中的侵入式链表设计,详细解析了Linux中container_of宏的巧妙运用及其实现原理,同时讨论了FreeRTOS未采用相似设计的原因,可能出于对实时性和目标平台性能的考量。

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

FreeRTOS相关:linux中的侵入式链表设计

相关博客FreeRTOS解析:List

Linux内核中也有侵入式的链表的设计,在Linux中提供的链表项的定义为

struct list_head 
        {
            struct list_head *next, *prev;
        };

使用链表时只需要将其包含进定义的对象中即可

struct node 
        {
            // 一些其它成员定义....
            char i;
            // 侵入式链表项
            struct list_head list_item;
            // 一些其它成员定义....
            char j;
        };

在此它没有定义类似ListItem_t中pxContainer这样的成员变量,其获得包含该链表项的对象地址是通过一段巧妙的宏定义实现的

#define offsetof(s,m) (size_t)&(((s *)0)->m

        #define container_of(ptr, type, member)                        \ 
        ({                                                          \
            const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
            (type *)( (char *)__mptr - offsetof(type,member) );        \
        })

各输入参数的含义为

  • ptr:结构体实例成员地址。

  • type:结构体名。

  • member:成员名。

使用示例

// 包含链表项的对象实例
        struct node test;
        // 假设通过某种方式(如遍历)获得了链表项地址
        struct list_head *list_item_add = &test.list_item;
        // 计算对象地址
        struct node *test_add = container_of(list_item_add,struct node,list_item);
        // test_add即为包含list_item_add指向的链表项的对象地址

container_of()的实现思路简单概括就是:将成员变量地址减去成员变量在结构体类型中的便宜量便是实例对象的存储地址。以struct node结构体为例,其实例test在内存中的存储方式如下图左侧所示。如何获得成员在结构体存储中的偏移量呢?下图右侧给出了解决方法,当&test=0x00时,其成员的地址便是所需要的偏移量。

在这里插入图片描述

回过头来看offsetof()宏,其所作的事就是获得偏移量。而container_of()宏中的

(type *)( (char *)__mptr - offsetof(type,member) );

便是用成员地址减去偏移量来获得实例的地址。至于container_of()宏中的前一句

const typeof( ((type *)0)->member ) *__mptr = (ptr);

实时上是起到一个类型检验的作用,拓展关键字typeof可以获得变量的类型,如果传入的ptr的类型与成员变量类型不符,那么编译器便会抛出警告,便于检查是否出错。注意typeof并不是标准C中的关键字,如果所用的编译器不支持,可以将第一句删除,将第二句中的__mptr替换为ptr,宏container_of()仍然是正确的。

个人认为,FreeRTOS并未借鉴这一设计的一个原因可能是出于系统实时性的考虑,毕竟这样的操作是需要耗费一定时间的,而FreeRTOS内核中需要频繁使用这一功能,这样的设计必定会降低内核效率。另外FreeRTOS的目标平台一般运行速度相对较低,使得内核效率降低更为明显。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值