`
jiagou
  • 浏览: 2529789 次
文章分类
社区版块
存档分类
最新评论

rt-thread的内核对象管理系统分析

 
阅读更多

rt-thread采用内核对象管理系统来访问和管理所有内核对象.首先来看看rt-thread的内核对象是如何定义的:

1 数据结构

1.1 对象控制块

在include/rtdef.h头文件中可以找到内核对象有结构定义:

/**
 * Base structure of Kernel object
 */
struct rt_object
{
    char       name[RT_NAME_MAX];//名称
    rt_uint8_t type;//内核对象类型 
    rt_uint8_t flag;//内核对象标志        

#ifdef RT_USING_MODULE
    void      *module_id;//模块ID
#endif
    rt_list_t  list;//内核对象链表节点
};
typedef struct rt_object *rt_object_t;


这里需要注意地是,上述内核对象控制块包含了一rt_list_t类型的成员list,这个是一链表节点,便于将此内核对象加入到一链表中,其结构如下定义:

struct rt_list_node
{
    struct rt_list_node *next; //指向下一节点
    struct rt_list_node *prev; //指向前一节点
};
typedef struct rt_list_node rt_list_t;

另内核对象类型取值有如下类型:

/**
 *  The object type can be one of the follows with specific
 *  macros enabled:
 *  - Thread
 *  - Semaphore
 *  - Mutex
 *  - Event
 *  - MailBox
 *  - MessageQueue
 *  - MemHeap
 *  - MemPool
 *  - Device
 *  - Timer
 *  - Module
 *  - Unknown
 *  - Static
 */
enum rt_object_class_type
{
    RT_Object_Class_Thread = 0, //线程
#ifdef RT_USING_SEMAPHORE
    RT_Object_Class_Semaphore, //信号量
#endif
#ifdef RT_USING_MUTEX
    RT_Object_Class_Mutex,   //互斥锁
#endif
#ifdef RT_USING_EVENT
    RT_Object_Class_Event,  //事件
#endif
#ifdef RT_USING_MAILBOX
    RT_Object_Class_MailBox,  //邮箱
#endif
#ifdef RT_USING_MESSAGEQUEUE
    RT_Object_Class_MessageQueue,  //消息队列
#endif
#ifdef RT_USING_MEMHEAP
    RT_Object_Class_MemHeap,      //内存堆
#endif
#ifdef RT_USING_MEMPOOL
    RT_Object_Class_MemPool,     //内存池
#endif
#ifdef RT_USING_DEVICE
    RT_Object_Class_Device,     //设备驱动
#endif
    RT_Object_Class_Timer,      //时钟
#ifdef RT_USING_MODULE
    RT_Object_Class_Module,     //模块
#endif
    RT_Object_Class_Unknown,      //未知内核对象类型
    RT_Object_Class_Static = 0x80  //rt-thread以此位标志是否为系统内核对象
};

需要注意的是,rt-thread将内核对象的type的最高位若为1,则表示此内核对象为系统内核对象,否则非系统内核对象.


1.2 内核对象容器

RTT使用内核对象容器来管理同一类型的内核对象,并将其放入同一链表中,便于访问.内核对象信息的结构如下定义:

/**
 * The information of the kernel object
 */
struct rt_object_information
{
    enum rt_object_class_type type;          //内核对象类型
    rt_list_t                 object_list;   //内核对象链表
    rt_size_t                 object_size;   //内核对象所占的大小
};


1.3 内核对象管理系统

RTT中,每一类型的内核对象都会有一内核对象容器来包容,这个类型的内核对象容器实际上是用一链表(见1.2节所示的内核对象容器结构定义),这个链表将所有相同类型的内核对象链接起来.由于每一类型都对应着有一个这样的内核对象容器来管理,那么所有内核对象容器整体就叫做内核对象管理系统.

如下图示:


RTT中,内核对象管理系统是用一个rt_object_information数组来实现的,如下:

#define _OBJ_CONTAINER_LIST_INIT(c)\//内核对象容器的链表初始化,这里用一个宏来定义,链表的前一节点和后一节点在初始化时都指向本身所在地址
    {&(rt_object_container[c].object_list), &(rt_object_container[c].object_list)}

//内核对象管理系统,这里用rt_object_information数组来实现
struct rt_object_information rt_object_container[RT_Object_Class_Unknown] =
{
    /* initialize object container - thread */)},//线程对象信息
    {RT_Object_Class_Thread, _OBJ_CONTAINER_LIST_INIT(RT_Object_Class_Thread), sizeof(struct rt_thread#ifdef RT_USING_SEMAPHORE
    /* initialize object container - semaphore *///信号量对象信息
    {RT_Object_Class_Semaphore, _OBJ_CONTAINER_LIST_INIT(RT_Object_Class_Semaphore), sizeof(struct rt_semaphore)},
#endif
#ifdef RT_USING_MUTEX
    /* initialize object container - mutex *///互斥锁对象信息
    {RT_Object_Class_Mutex, _OBJ_CONTAINER_LIST_INIT(RT_Object_Class_Mutex), sizeof(struct rt_mutex)},
#endif
#ifdef RT_USING_EVENT
    /* initialize object container - event *///事件对象信息
    {RT_Object_Class_Event, _OBJ_CONTAINER_LIST_INIT(RT_Object_Class_Event), sizeof(struct rt_event)},
#endif
#ifdef RT_USING_MAILBOX
    /* initialize object container - mailbox *///邮箱对象信息
    {RT_Object_Class_MailBox, _OBJ_CONTAINER_LIST_INIT(RT_Object_Class_MailBox), sizeof(struct rt_mailbox)},
#endif
#ifdef RT_USING_MESSAGEQUEUE
    /* initialize object container - message queue *///消息队列对象信息
    {RT_Object_Class_MessageQueue, _OBJ_CONTAINER_LIST_INIT(RT_Object_Class_MessageQueue), sizeof(struct rt_messagequeue)},
#endif
#ifdef RT_USING_MEMHEAP
    /* initialize object container - memory heap *///内存堆对象信息
    {RT_Object_Class_MemHeap, _OBJ_CONTAINER_LIST_INIT(RT_Object_Class_MemHeap), sizeof(struct rt_memheap)},
#endif
#ifdef RT_USING_MEMPOOL
    /* initialize object container - memory pool *///内存池对象信息
    {RT_Object_Class_MemPool, _OBJ_CONTAINER_LIST_INIT(RT_Object_Class_MemPool), sizeof(struct rt_mempool)},
#endif
#ifdef RT_USING_DEVICE
    /* initialize object container - device *///设备驱动对象信息
    {RT_Object_Class_Device, _OBJ_CONTAINER_LIST_INIT(RT_Object_Class_Device), sizeof(struct rt_device)},
#endif
    /* initialize object container - timer *///时钟对象信息
    {RT_Object_Class_Timer, _OBJ_CONTAINER_LIST_INIT(RT_Object_Class_Timer), sizeof(struct rt_timer)},
#ifdef RT_USING_MODULE
    /* initialize object container - module *///模块对象信息
    {RT_Object_Class_Module, _OBJ_CONTAINER_LIST_INIT(RT_Object_Class_Module), sizeof(struct rt_module)},
#endif
};


2 内核对象接口

2.1 内核对象初始化

RTT提供静态和动态两种初始化接口,如下:

静态初始化是将一个已经存在的且占有内存空间的对象初始化,它的接口如下:

/**
 * 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_object_information *information;      //对象容器

#ifdef RT_USING_MODULE //如果使用了模块,那么对象容器指向本线程所包含的对象窗口,否则指向全局对象管理系统中对应的容器
    /* get module object information */
    information = (rt_module_self() != RT_NULL) ? 
        &rt_module_self()->module_object[type] : &rt_object_container[type];
#else
    /* get object information */
    information = &rt_object_container[type];
#endif

    /* initialize object's parameters */

    /* set object type to static */
    object->type = type | RT_Object_Class_Static;//设置系统对象标志

    /* copy name */
    rt_strncpy(object->name, name, RT_NAME_MAX);//给名字赋值

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

    /* lock interrupt */
    temp = rt_hw_interrupt_disable();//关中断

    /* insert object into information object list */
    rt_list_insert_after(&(information->object_list), &(object->list));//将初始化的内核对象加入到对应容器中

    /* unlock interrupt */
    rt_hw_interrupt_enable(temp);//开中断
}

动态初始化是指对象原本并不存在,在不内存中,需要动态为其分配内存,其接口如下:


/**
 * 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;//对象容器

    RT_DEBUG_NOT_IN_INTERRUPT;

#ifdef RT_USING_MODULE//同上面那个接口一样,获取对象容器
    /*
     * get module object information,
     * module object should be managed by kernel object container
     */
    information = (rt_module_self() != RT_NULL && (type != RT_Object_Class_Module)) ?
                  &rt_module_self()->module_object[type] : &rt_object_container[type];
#else
    /* get object information */
    information = &rt_object_container[type];
#endif

    object = (struct rt_object *)rt_malloc(information->object_size);//为对象动态分配内存空间
    if (object == RT_NULL)
    {
        /* no memory can be allocated */
        return RT_NULL;
    }
    
    /* initialize object's parameters */

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

    /* set object flag */
    object->flag = 0;//设置标志为0

#ifdef RT_USING_MODULE
    if (rt_module_self() != RT_NULL)
    {
        object->flag |= RT_OBJECT_FLAG_MODULE;//如果使用了模块功能,则将flag标志设置为模块标志
    }
    object->module_id = (void *)rt_module_self();//设置模块ID
#endif

    /* copy name */
    rt_strncpy(object->name, name, RT_NAME_MAX);//给名称赋值

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

    /* lock interrupt */
    temp = rt_hw_interrupt_disable();//关中断

    /* 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;
}


2.2 脱离或删除对象

如果对象是静态初始化的,那么对应的是脱离,如果是动态初始化的,则是删除.

脱离接口如下:

/**
 * 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;

    /* object check */
    RT_ASSERT(object != RT_NULL);

    RT_OBJECT_HOOK_CALL(rt_object_detach_hook, (object));//使用钩子函数
    /* lock interrupt */
    temp = rt_hw_interrupt_disable();//关中断

    /* remove from old list */
    rt_list_remove(&(object->list));//从窗口中移除

    /* unlock interrupt */
    rt_hw_interrupt_enable(temp);//开中断
}

删除接口如下:


/**
 * 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;

    /* object check */
    RT_ASSERT(object != RT_NULL);
    RT_ASSERT(!(object->type & RT_Object_Class_Static));//删除的对象必须是非系统对象
    RT_OBJECT_HOOK_CALL(rt_object_detach_hook, (object));//使用钩子函数

    /* lock interrupt */
    temp = rt_hw_interrupt_disable();//关中断

    /* remove from old list */
    rt_list_remove(&(object->list));//从对应的容器中移除

    /* unlock interrupt */
    rt_hw_interrupt_enable(temp);//开中断

#if defined(RT_USING_MODULE) && defined(RT_USING_SLAB)//如果使用了模块功能且采用的是SLAB动态内存管理模式
    if (object->flag & RT_OBJECT_FLAG_MODULE) 
        rt_module_free((rt_module_t)object->module_id, object);//释放模块ID所占空间
    else
#endif

    /* free the memory of object */
    rt_free(object);//释放内核对象所占空间
}


其中rt_list_remove会自动找到对象的前一节点和后一节点,然后删除本身节点.

2.3 判断是否为系统内核对象

/**
 * 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_bool_t rt_object_is_systemobject(rt_object_t object)
{
    /* object check */
    RT_ASSERT(object != RT_NULL);

    if (object->type & RT_Object_Class_Static)//RTT是通过内核对象的type的最高位是否为1来判断此对象是否为系统内核对象的
        return RT_TRUE;

    return RT_FALSE;
}

2.4查找内核对象


/**
 * This function will find specified name object from object
 * container.
 *
 * @param name the specified name of object.
 * @param type the type of object
 *
 * @return the found object or RT_NULL if there is no this object
 * in object container.
 *
 * @note this function shall not be invoked in interrupt status.
 */
rt_object_t rt_object_find(const char *name, rt_uint8_t type)
{
    struct rt_object *object;
    struct rt_list_node *node;
    struct rt_object_information *information;
    extern volatile rt_uint8_t rt_interrupt_nest;

    /* parameter check *///输入系统检查
    if ((name == RT_NULL) || (type > RT_Object_Class_Unknown))
        return RT_NULL;

    /* which is invoke in interrupt status */
    if (rt_interrupt_nest != 0)//确保当前没有中断嵌套
        RT_ASSERT(0);

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

    /* try to find object */
    information = &rt_object_container[type];//获取对应的对象容器
    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;
        }
    }

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

    return RT_NULL;
}

3 内核对象系统初始化

/**
 * @ingroup SystemInit
 *
 * This function will initialize system object management.
 *
 * @deprecated since 0.3.0, this function does not need to be invoked
 * in the system initialization.
 */
void rt_system_object_init(void)
{
}


从源代码可以看出,自从0.3.0以后,RTT就已经没有必须再使用此接口来对内核对象初始化了,因此,此函数是空的,但在系统初始化时还会保留调用些函数.


至此,RTT的内核对象系统源码分析已完!

分享到:
评论

相关推荐

    rt-thread源码

    硬实时内核,这层是RT-Thread的核心,包括了内核系统中对象的实现,例如多线程及其调度,信号量,邮箱,消息队列,内存管理,定时器等实现。 组件层,这些是基于RT-Thread核心基础上的外围组件,例如文件系统,...

    RT-Thread Studio-v2.2.6-setup-x86-64-202305191040

    针对资源受限的微控制器(MCU)系统,可通过方便易用的工具,裁剪出仅需要 3KB Flash、1.2KB RAM 内存资源的 NANO 版本(NANO 是 RT-Thread 官方于 2017 年 7 月份发布的一个极简版内核);而对于资源丰富的物联网...

    RT-Thread-1.0.2.zip_rt-thread gcc_其他嵌入式

    Kernel内核部分包括了RT-Thread的核心代码,包括对象管理器,线程管理及调度,线 程间通信等的微小内核实现(最小能够到达4k ROM,1k RAM体积占用)。内核库是为了保证 内核能够独立运作的一套小型类似C库实现(这...

    RT-Thread是一个来自中国的开源物联网操作系统,它提供了非常强的可伸缩能力:从一个可以运行在ARM Cortex-M0芯片

    RT-Thread诞生于2006年...RT-Thread是一个集实时操作系统(RTOS)内核、中间件组件的物联网操作系统,架构如下:内核层:RT-Thread内核,是 RT-Thread的核心部分,包括了内核系统中对象的实现,例如多线程及其调度、信

    rt-thread-master.zip

    RT-Thread把面向对象的设计方法应用到实时系统设计中,使得代码风格优雅、架构清晰、系统模块化并且可裁剪性非常好。 RT-Thread有完整版和Nano版,对于资源受限的微控制器(MCU)系统,可通过简单易用的工具,裁剪...

    rt-thread物联网操作系统-其他

    架构如下:内核层:RT-Thread内核,是 RT-Thread的核心部分,包括了内核系统中对象的实现,例如多线程及其调度、信号量、邮箱、消息队列、内存管理、定时器等;libcpu/BSP(芯片移植相关文件 / 板级支持包)与硬件...

    RT-Thread一个来自中国的开源物联网操作系统它提供了非常强的可伸缩能力

    RT-Thread是一个来自中国的开源物联网操作系统,它提供了非常强的可伸缩能力:从一个可以运行在ARM Cortex-M0芯片上的极小内核,到中等的ARM Cortex-M3/4/7系统,甚至是多核,64位的ARM Cortex-A,MIPS32/64处理器的...

    合作伙伴-基于RT-Thread 实现的绘本故事机实例.pdf

    rt-thread 操作系统,绘本故事机开发文档,内核“小”而“美”,• 线程及其调度、 • 信号量、 • 消息队列和邮箱、 • 内存管理、 • 定时器、 • 设备管理

    开发者-RT-Thread在智能物流与仓储行业中的使用案例.pdf

    rt-thread 操作系统,绘本故事机开发文档,内核“小”而“美”,• 线程及其调度、 • 信号量、 • 消息队列和邮箱、 • 内存管理、 • 定时器、 • 设备管理

    RT-Thread是一个来自中国的开源物联网操作系统,它提供了非常强的可伸缩能力

    RT-Thread把面向对象的设计方法应用到实时系统设计中,使得代码风格优雅、架构清晰、系统模块化并且可裁剪性非常好。RT-Thread有完整版和Nano版,对于资源受限的微控制器(MCU)系统,可通过简单易用的工具,裁剪出...

    rt-thread:RT-Thread是一个开源物联网操作系统

    对于资源丰富的物联网设备,RT-Thread可以使用在线软件包管理工具以及系统配置工具来实现直观,快速的模块化切割,无缝导入丰富的软件包,从而实现诸如Android图形界面之类的复杂功能。以及触摸滑动效果,智能语音...

    开发者-RT-Thread在服务机器人领域的探索与应用.pdf

    rt-thread 操作系统,绘本故事机开发文档,内核“小”而“美”,• 线程及其调度、 • 信号量、 • 消息队列和邮箱、 • 内存管理、 • 定时器、 • 设备管理

    【RT-Thread作品秀】基于RT-Thread的智能家居应用平台-电路方案

    RT-Thread使用情况概述(1)内核部分:调度器,信号量,消息队列,libcpu/BSP。 调度器:创建多个线程来实现不同的工作。 信号量:用来同步线程。 消息队列:用来实现线程之间传递的数据。 libcpu/BSP:外设CAN驱动、UART...

    rtthread-manual-doc:英文RT-Thread编程手册

    RT线程 RT-Thread(实时线程)是一个开源的嵌入式实时操作系统,根据Apache License v2.0发布。 它具有强大的可伸缩性:从运行在... 组件:它是RT-Thread内核层上的软件单元,例如命令行(FinSH),设备驱动程序框架

    【RT-Thread作品秀】基于RT-thread与ZigBee的智能家居控制系统-电路方案

    总控子系统采用了完整版的RT-Thread系统,内核部分使用了调度器,信号量等;驱动部分使用了UART、SPI、BT、WiFi等;协议栈使用了MQTT等。软件包部分使用了Onenet、cJSON等。 系统架构本文所提出的智能家居系统解决...

    rt-thread:RT-Thread是一个开源物联网操作系统

    对于资源丰富的物联网设备,RT-Thread可以使用在线软件包管理工具以及系统配置工具来实现直观,快速的模块化切割,无缝导入丰富的软件包,从而实现诸如Android图形界面之类的复杂功能以及触摸滑动效果,智能语音...

    【RT-Thread作品秀】数采一期下位机-电路方案

    RT-Thread使用情况概述内核部分:调度器。 软件包:CJSON v1.7.7 硬件框架ART-Pi是 RT-Thread 团队经过半年的精心准备,专门为嵌入式软件工程师、开源创客设计的一款极具扩展功能的 DIY 开源硬件。 软件框架说明本项目...

    【RT-Thread作品秀】风速监测报警-电路方案

    我对RT-Thread有了全新的认识,他不仅仅是一个嵌入式RTOS,当各种组件有序结合起来,必能够发挥出更大能量,体现无与伦比的扩展性和灵活性,无愧小而美物联网操作系统的称呼,现在RT-Thread smart已经上线了,无疑...

Global site tag (gtag.js) - Google Analytics