• rt_container_of 已知一个结构体里面的成员的地址,反推出该结构体的首地址


    /**
     * rt_container_of - return the member address of ptr, if the type of ptr is the
     * struct type.
     */
    #define rt_container_of(ptr, type, member) 
        ((type *)((char *)(ptr) - (unsigned long)(&((type *)0)->member)))
    
    /**
     * @brief get the struct for this entry
     * @param node the entry point                  表示一个节点的地址
     * @param type the type of structure            该节点所在的结构体的类型
     * @param member the name of list in structure  该节点在该结构体中的成员名称
     */
    #define rt_list_entry(node, type, member) 
        rt_container_of(node, type, member)

    具体实现算法:

    我们知道了一个节点 tlist 的地址 ptr,现在要推算出该节点所在的 type 类型的结构体的起始地址 f_struct_ptr。我们可以将 ptr的值减去图中灰色部分的偏移的大小就可以得到 f_struct_ptr 的地址,现在的关键是如何计算出灰色部分的偏移大小。这里采取的做法是将 0 地址强制类型类型转换为 type,即(type *)0,然后通过指针访问结构体成员的方式获取到偏移的大小,即(&((type *)0)->member),最后即可算出 f_struct_ptr = ptr -(&((type *)0)->member)。


    这个偏移的计算和<stddef.h>中的宏offsetof(s,m)一样

    用法举例:

    /* 启动系统调度器 */
    void rt_system_scheduler_start(void)
    {
      register struct rt_thread *to_thread;
    
      /* 手动指定第一个运行的线程 */ (1)
      to_thread = rt_list_entry(rt_thread_priority_table[0].next,struct rt_thread,tlist);
       rt_current_thread = to_thread; (2)//将获取到的第一个要运行的线程控制块指针传到全局变量rt_current_thread 中
      /* 切换到第一个线程,该函数在 context_rvds.S 中实现,
         在 rthw.h 声明,用于实现第一次线程切换。
         当一个汇编函数在 C 文件中调用的时候,如果有形参,
         则执行的时候会将形参传人到 CPU 寄存器 r0。*/
      rt_hw_context_switch_to((rt_uint32_t)&to_thread->sp); (3)
    }

    这里只关心rt_list_entry的用法,rt_thread的结构体定义如下(简化了的)。要获取一个rt_thread,则根据链表通过rt_list_entry获得对应的线程。

     struct rt_thread
     {
     void *sp; /* 线程栈指针 */
     void *entry; /* 线程入口地址 */
     void *parameter; /* 线程形参 */
     void *stack_addr; /* 线程栈起始地址 */
     rt_uint32_t stack_size; /* 线程栈大小,单位为字节 */
    
     rt_list_t tlist; /* 线程链表节点 */ (1)
     };
    
    
    
  • 相关阅读:
    天翼网关获取超级密码
    Wirte-up:攻防世界Web解题过程新手区01-06
    F#周报2019年第12期
    F#周报2019年第11期
    F#周报2019年第10期
    F#周报2019年第9期
    F#周报2019年第8期
    F#周报2019年第7期
    ML.NET 0.10特性简介
    F#周报2019年第6期
  • 原文地址:https://www.cnblogs.com/Rainingday/p/13802374.html
Copyright © 2020-2023  润新知