RT-Thread系统内核对象介绍

RT-Thread内核采用面向对象的设计思想进行设计,系统级的基础设施都是一种内核对象,例如线程,信号量,互斥量,定时器等。内核对象分为两类:静态内核对象和动态内核对象,静态内核对象通常放在RW段和ZI段中,在系统启动后在程序中初始化;动态内核对象则是从内存堆中创建的,而后手工做初始化。

静态对象会占用RAM空间,不依赖于内存堆管理器,内存分配时间确定。动态对象则依赖于内存堆管理器,运行时申请RAM空间,当对象被删除后,占用的RAM空间被释放。这两种方式各有利弊,可以根据实际环境需求选择具体使用方式。

内核中对象主要有以下几种类型。

enum rt_object_class_type
{
    RT_Object_Class_Null   = 0,                         /**< The object is not used. */
    RT_Object_Class_Thread,                             /**< 线程对象 */
    RT_Object_Class_Semaphore,                          /**< 信号量对象 */
    RT_Object_Class_Mutex,                              /**< 互斥量对象 */
    RT_Object_Class_Event,                              /**< 事件集对象 */
    RT_Object_Class_MailBox,                            /**< 邮箱对象 */
    RT_Object_Class_MessageQueue,                       /**< 消息队列对象 */
    RT_Object_Class_MemHeap,                            /**< The object is a memory heap */
    RT_Object_Class_MemPool,                            /**< The object is a memory pool. */
    RT_Object_Class_Device,                             /**< 设备对象 */
    RT_Object_Class_Timer,                              /**< 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. 静态对象 */
};

RT-Thread采用内核对象管理系统来访问/管理所有内核对象,内核对象包含了内核中绝大部分设施,这些内核对象可以是静态分配的静态对象,也可以是从系统内存堆中分配的动态对象。

RT-Thread内核对象包括:线程,信号量,互斥量,事件,邮箱,消息队列和定时器,内存池,设备驱动等。对象容器中包含了每类内核对象的信息,包括对象类型,大小等。对象容器给每类内核对象分配了一个链表,所有的内核对象都被链接到该链表上,如图 RT-Thread的内核对象容器及链表如下图所示:

下图则显示了 RT-Thread 中各类内核对象的派生和继承关系。对于每一种具体内核对象和对象控制块,除了基本结构外,还有自己的扩展属性(私有属性),例如,对于线程控制块,在基类对象基础上进行扩展,增加了线程状态、优先级等属性。这些属性在基类对象的操作中不会用到,只有在与具体线程相关的操作中才会使用。因此从面向对象的观点,可以认为每一种具体对象是抽象对象的派生,继承了基本对象的属性并在此基础上扩展了与自己相关的属性。

内核中的对象由对象控制块来表示,结构体定义如下:

struct rt_object
{
    char       name[RT_NAME_MAX];                       /**< 对象名称 */
    rt_uint8_t type;                                    /**< 对象类型;参加 rt_object_class_type 枚举定义 */
    rt_uint8_t flag;                                    /**< 保存对象标志 */

#ifdef RT_USING_MODULE
    void      *module_id;                               /**< id of application module */
#endif
    rt_list_t  list;                                    /**< 对象链表;内核会将创建的对象插入到其对象容器中,使用链表来管理 */
};
typedef struct rt_object *rt_object_t;                  /**< Type for kernel objects. */

内核中的每一类对象由对象容器进行管理,结构体定义如下:

struct rt_object_information
{
    enum rt_object_class_type type;                     /**< 对象类型 */
    rt_list_t                 object_list;              /**< 管理此种类型对象的链表头 */
    rt_size_t                 object_size;              /**< 对象大小 */
};

内核中操作对象或对象容器的函数介绍如下。

1.根据对象类型,找到对应的对象容器结构体指针

/**
 * This function will return the specified type of object information.
 *
 * @param type the type of object
 * @return the object type information or RT_NULL
 * @根据对象类型,获取相应对象容器结构体指针
 */
struct rt_object_information * rt_object_get_information(enum rt_object_class_type type)
{
    int index;

    for (index = 0; index < RT_Object_Info_Unknown; index ++)
    {
        if (rt_object_container[index].type == type) 
            return &rt_object_container[index];
    }

    return RT_NULL;
}

2. 初始化一个静态对象

/**
 * This function will initialize an object and add it to object system
 * management.
 *
 * @param object the specified object to be initialized.
 * @param type the object type.
 * @param name the object name. In system, the object's name must be unique.
 * @初始化对象;静态对象
 */
void rt_object_init(struct rt_object         *object,           //要初始化的对象指针
                    enum rt_object_class_type type,             //对象类型
                    const char               *name)             //对象名称
{
    register rt_base_t temp;
    struct rt_list_node *node = RT_NULL;
    struct rt_object_information *information;

#ifdef RT_USING_MODULE
    struct rt_dlmodule *module = dlmodule_self();
#endif

    /* 找到相应的对象容器 */
    information = rt_object_get_information(type);
    RT_ASSERT(information != RT_NULL);

    /* 关闭线程调度器 */
    rt_enter_critical();

    /* 检查是否已经初始化过此对象;如果之前被初始化过,产生Assert */
    for (node  = information->object_list.next; node != &(information->object_list); node  = node->next)
    {
        struct rt_object *obj;
        obj = rt_list_entry(node, struct rt_object, list);
        RT_ASSERT(obj != object);
    }
    /* 退出临界区,开启线程调度器 */
    rt_exit_critical();

    /* initialize object's parameters */
    /* 标记此对象是静态对象*/
    object->type = type | RT_Object_Class_Static;

    /* 设置名称 */
    rt_strncpy(object->name, name, RT_NAME_MAX);

    RT_OBJECT_HOOK_CALL(rt_object_attach_hook, (object));

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

#ifdef RT_USING_MODULE
    if (module)
    {
        rt_list_insert_after(&(module->object_list), &(object->list));
        object->module_id = (void *)module;
    }
    else
#endif
    {
        /* 将此对象插入到其对应的对象容器中 */
        rt_list_insert_after(&(information->object_list), &(object->list));
    }

    /* 使能中断 */
    rt_hw_interrupt_enable(temp);
}

3.将一个静态对象从内核中脱离,脱离之后不再受到内核控制

/**
 * This function will detach a static object from object system,
 * and the memory of static object is not freed.
 *
 * @param object the specified object to be detached.
 * @脱离对象;只能脱离静态方式初始化过的对象
 */
void rt_object_detach(rt_object_t object)
{
    register rt_base_t temp;

    /* 参数检查 */
    RT_ASSERT(object != RT_NULL);
    RT_OBJECT_HOOK_CALL(rt_object_detach_hook, (object));

    /* 复位对象类型 */
    object->type = 0;

    /* 禁止中断 */
    temp = rt_hw_interrupt_disable();

    /* 将对象从对象容器链表中移除 */
    rt_list_remove(&(object->list));

    /* 使能中断 */
    rt_hw_interrupt_enable(temp);
}

4.动态方式创建内核对象

/**
 * This function will allocate an object from object system
 *
 * @param type the type of object
 * @param name the object name. In system, the object's name must be unique.
 *
 * @return object
 * @创建动态对象;
 * @注意:此函数不能在中断服务函数中调用.
 */
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;

#ifdef RT_USING_MODULE
    struct rt_dlmodule *module = dlmodule_self();
#endif

    RT_DEBUG_NOT_IN_INTERRUPT;

    /* 根据对象类型,获取相应的对象容器变量指针 */
    information = rt_object_get_information(type);
    RT_ASSERT(information != RT_NULL);

    /* 根据对象大小,分配空间 */
    object = (struct rt_object *)RT_KERNEL_MALLOC(information->object_size);
    if (object == RT_NULL)
    {
        /* no memory can be allocated */
        return RT_NULL;
    }

    /* 清空间 */
    rt_memset(object, 0x0, information->object_size);

    /* initialize object's parameters */

    /* 设置类型 */
    object->type = type;

    /* 标志清零 */
    object->flag = 0;

    /* 设置名称 */
    rt_strncpy(object->name, name, RT_NAME_MAX);

    /* 钩子函数 */
    RT_OBJECT_HOOK_CALL(rt_object_attach_hook, (object));

    /* 禁止中断 */
    temp = rt_hw_interrupt_disable();

#ifdef RT_USING_MODULE
    if (module)
    {
        rt_list_insert_after(&(module->object_list), &(object->list));
        object->module_id = (void *)module;
    }
    else
#endif
    {
        /* 将对象插入到对象容器中 */
        rt_list_insert_after(&(information->object_list), &(object->list));
    }

    /* 使能中断 */
    rt_hw_interrupt_enable(temp);

    /* return object */
    return object;
}

5.删除动态对象

/**
 * This function will delete an object and release object memory.
 *
 * @param object the specified object to be deleted.
 * @删除对象,一定是动态分配的对象
 */
void rt_object_delete(rt_object_t object)
{
    register rt_base_t temp;

    /* 参数检查 */
    RT_ASSERT(object != RT_NULL);
    RT_ASSERT(!(object->type & RT_Object_Class_Static));

    RT_OBJECT_HOOK_CALL(rt_object_detach_hook, (object));

    /* 清零 */
    object->type = 0;

    /* 禁止中断 */
    temp = rt_hw_interrupt_disable();

    /* 将对象从起所在对象容器链表中移除 */
    rt_list_remove(&(object->list));

    /* 使能中断 */
    rt_hw_interrupt_enable(temp);

    /* 释放对象占用的内存空间 */
    RT_KERNEL_FREE(object);
}

6.判断对象是静态或动态,如果是静态对象返回RT_TRUE

/**
 * This function will judge the object is system object or not.
 * Normally, the system object is a static object and the type
 * of object set to RT_Object_Class_Static.
 *
 * @param object the specified object to be judged.
 *
 * @return RT_TRUE if a system object, RT_FALSE for others.
 * @判断对象是否静态或动态; 如果是静态对象,返回RT_TRUE
 */
rt_bool_t rt_object_is_systemobject(rt_object_t object)
{
    /* 参数检查 */
    RT_ASSERT(object != RT_NULL);

    if (object->type & RT_Object_Class_Static)
        return RT_TRUE;

    return RT_FALSE;
}

7.获取对象的类型

/**
 * This function will return the type of object without
 * RT_Object_Class_Static flag.
 *
 * @param object the specified object to be get type.
 * @获取对象类型
 * @return the type of object.
 */
rt_uint8_t rt_object_get_type(rt_object_t object)
{
    /* 参数检查 */
    RT_ASSERT(object != RT_NULL);

    /* 返回对象类型 */
    return object->type & ~RT_Object_Class_Static;
}

8.根据对象名称和类型,查找对象

rt_object_t rt_object_find(const char *name, rt_uint8_t type)
{
    struct rt_object *object = RT_NULL;
    struct rt_list_node *node = RT_NULL;
    struct rt_object_information *information = RT_NULL;

    /* 参数检查 */
    if ((name == RT_NULL) || (type > RT_Object_Class_Unknown))
        return RT_NULL;

    /* which is invoke in interrupt status */
    RT_DEBUG_NOT_IN_INTERRUPT;

    /* 进入临界区 */
    rt_enter_critical();

    /* 如果为NULL,执行 */
    if (information == RT_NULL)
    {
        /* 根据对象类型,查找对象容器 */
        information = rt_object_get_information((enum rt_object_class_type)type);
        RT_ASSERT(information != RT_NULL);
    }

    /* 遍历对象容器,查找名称一致的对象 */
    for (node  = information->object_list.next; node != &(information->object_list); node  = node->next)
    {
        object = rt_list_entry(node, struct rt_object, list);

        /* 如果名称相同,退出临界区,并返回对象指针 */
        if (rt_strncmp(object->name, name, RT_NAME_MAX) == 0)
        {
            /* leave critical */
            rt_exit_critical();

            return object;
        }
    }

    /* 退出临界区 */
    rt_exit_critical();

    return RT_NULL;
}

备注:在实际开发项目中,开发者不会直接接触内核对象的创建、删除等操作。但是,将内核对象分析清楚,有利于对整个系统架构的理解。

本文完毕!

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值