RT-Thread源码阅读

内核对象管理架构--上

内核对象类型

线程、信号量、互斥量、事件、邮箱、消息队列、定时器、内存池、设备驱动等

位与rtdef.h中的对象类型定义

enum rt_object_class_type
{
    RT_Object_Class_Null   = 0,                         /**< The object is not used. */
    RT_Object_Class_Thread,                             /**< The object is a thread. */
    RT_Object_Class_Semaphore,                          /**< The object is a semaphore. */
    RT_Object_Class_Mutex,                              /**< The object is a mutex. */
    RT_Object_Class_Event,                              /**< The object is a event. */
    RT_Object_Class_MailBox,                            /**< The object is a mail box. */
    RT_Object_Class_MessageQueue,                       /**< The object is a message queue. */
    RT_Object_Class_MemHeap,                            /**< The object is a memory heap */
    RT_Object_Class_MemPool,                            /**< The object is a memory pool. */
    RT_Object_Class_Device,                             /**< The object is a device */
    RT_Object_Class_Timer,                              /**< The object is a timer. */
    RT_Object_Class_Module,                             /**< The object is a module. */
    RT_Object_Class_Unknown,                            /**< The object is unknown. */
    RT_Object_Class_Static = 0x80                       /**< The object is a static object. */
};

对象管理器

(实际上是一个数组),其中的元素是

/**
 * The information of the kernel object
 */
struct rt_object_information
{
    enum rt_object_class_type type;                     /**< object class type */
    rt_list_t                 object_list;              /**< object list */
    rt_size_t                 object_size;              /**< object size */
};

这个管理器被定义为一个静态数组变量 rt_object_container , 位与object.c中

#define _OBJ_CONTAINER_LIST_INIT(c)     \
    {&(rt_object_container[c].object_list), &(rt_object_container[c].object_list)}

static struct 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)},
...
}

分析一下这个对象管理器数组,每个元素包括:1、对象类型,2、该类型对象(循环)链表,3、该类型对象的大小。其中 _OBJ_CONTAINER_LIST_INIT(c)  负责初始化一个循环链表,链表的元素为对象类型。(其中关于rtthread中的链表可见文章:占位符

有个这些信息,可以大致将这个对象管理器画出来

各类型之间存在如下继承关系

给出一个例子:互斥量的创建

__ROM_USED rt_mutex_t rt_mutex_create(const char *name, rt_uint8_t flag)
{
    struct rt_mutex *mutex;

    RT_DEBUG_NOT_IN_INTERRUPT;

    /* allocate object */
    mutex = (rt_mutex_t)rt_object_allocate(RT_Object_Class_Mutex, name);
    if (mutex == RT_NULL)
        return mutex;

    /* init ipc object */
    rt_ipc_object_init(&(mutex->parent));

    mutex->value              = 1;
    mutex->owner              = RT_NULL;
    mutex->original_priority  = 0xFF;
    mutex->hold               = 0;

    /* set flag */
    mutex->parent.parent.flag = flag;

    return mutex;
}
RTM_EXPORT(rt_mutex_create);

这个create负责创建动态创建一个互斥锁,来就看一下他都做了什么

1、创建一个对象  rt_object_allocate

mutex = (rt_mutex_t)rt_object_allocate(RT_Object_Class_Mutex, name);
__ROM_USED rt_object_t rt_object_allocate(enum rt_object_class_type type, const char *name)
{
    struct rt_object *object;
    register rt_base_t temp;
    struct rt_object_information *information;
    //1、从静态的对对象管理器数组中去除对应类型的元素
    information = rt_object_get_information(type);
    RT_ASSERT(information != RT_NULL);
    //2、根据大小申请内存
    object = (struct rt_object *)RT_KERNEL_MALLOC(information->object_size);
    if (object == RT_NULL)
    {
        /* no memory can be allocated */
        return RT_NULL;
    }
    //3、清空内存
    /* clean memory data of object */
    rt_memset(object, 0x0, information->object_size);

    /* initialize object's parameters */
    //4、为申请的内存赋值(类型、flag、name)
    /* set object type */
    object->type = type;

    /* set object flag */
    object->flag = 0;

    /* copy name */
    rt_strncpy(object->name, name, RT_NAME_MAX);

    /* lock interrupt */
    temp = rt_hw_interrupt_disable();
    //5、将该节点插入到静态对象管理器数组上对应的链表中
    /* insert object into information object list */
    rt_list_insert_after(&(information->object_list), &(object->list));

    /* unlock interrupt */
    rt_hw_interrupt_enable(temp);

    /* return object */
    return object;
}

第二步,初始化 特定链表,rt_ipc_object_init

这一步在每个类型对象中表现不一样,此处以ipc中的互斥量为例子

rt_ipc_object_init(&(mutex->parent));

rt_inline void rt_list_init(rt_list_t *l)
{
    l->next = l->prev = l;
}

rt_inline rt_err_t rt_ipc_object_init(struct rt_ipc_object *ipc)
{
    /* init ipc object */
    rt_list_init(&(ipc->suspend_thread));

    return RT_EOK;
}

到这里就不得不介绍一下 rt_mutex 结构体了

//互斥锁结构体
struct rt_ipc_object
{
    struct rt_object parent;                   /**< inherit from rt_object */

    rt_list_t        suspend_thread;           /**< threads pended on this resource */
};

//互斥锁结构体
struct rt_mutex
{
    struct rt_ipc_object parent;             /**< inherit from ipc_object */

    rt_uint16_t          value;               /**< value of mutex */

    rt_uint8_t           original_priority;  /**< priority of last thread hold the mutex */
    rt_uint8_t           hold;                 /**< numbers of thread hold the mutex */

    struct rt_thread    *owner;                 /**< current owner of mutex */
};

这里特殊一点的是  rt_mutex  结构体又包含了 rt_ipc_object 结构体,这里是因为将ipc对象的共有部分抽离了出来,(即一个阻塞线程队列)。

因此,这里所谓的初始化 特定链表,也是对该列表的初始化。

第三步、互斥锁赋值

    mutex->value              = 1;
    mutex->owner              = RT_NULL;
    mutex->original_priority  = 0xFF;
    mutex->hold               = 0;

    /* set flag */
    mutex->parent.parent.flag = flag;

这就没什么可说的了。

至此,就利用对象管理器数组创建了一个互斥锁对象

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值
OSZAR »