嵌入式技术论坛
直播中

马祥

7年用户 774经验值
私信 关注
[经验]

RT-Thread所包含的对象以及对象的方法函数分析

  RTT这个RTOS虽然是全部是用C编写,但全程使用的都是面向对象的编程方式。所以最好的研究方式,就是从对象入手,分析代码各部分所包含的对象以及对象的方法函数。
  首先先了解下与thread相关的对象,主要有三个:
  1、RTT最基本的对象:rt_object
  2、线程对象:rt_thread
  3、定时器对象:rt_timer
2.jpg
  这里发现一个现象,按正常逻辑来说rt_thread应该和rt_timer一样,有一个成员直接是rt_object,这样就是明显的继承关系,但是实际代码中rt_thread中申明了和rt_object相同的一组成员:
  name,type,flag,以及list这里和其他类的不统一具体原因还需要之后继续研究,这不能说是个bug,只能算是代码风格上的一点不统一。
  先从rt_object的成员说起:
  rt_object(基本版),这个说明下什么叫做基本版,来看下代码:
  ```struct rt_object
  {
  char name[RT_NAME_MAX]; /《 name of kernel object */
  rt_uint8_t type; /《 type of kernel object /
  rt_uint8_t flag; /**《 flag of kernel object /
  ifdef RT_USING_MODULE
  void *module_id; /**《 id of application module */
  endif
  rt_list_t list; /**《 list node of kernel object */
  };
  typedef struct rt_object rt_object_t; /**《 Type for kernel objects. /```
  一个类的声明中有一些成员会因为一些宏定义而增加,这些宏一般代表的是功能的扩展。现在我想分析的是不带最基本的类的成员,所以暂时会去掉所有的宏定义。
  可以看到rt_object主要包含4个成员:
  1.字符串name,既类的名字。
  2.类型type,既类的类型,RTT定义如下12种类型:
  enum rt_object_class_type { RT_Object_Class_Thread = 0, /**《 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. */ };
  3.标志flag(好像并没什么用,只是在动态创建的时候置0了)。
  4.一个双向链表的数据结构,用来把实例化的类添加到相应type的双向链表中。在rt_object初始化时,每种类型的class都有一个链表结构将他们连接起来。
  与rt_object相关的函数
  RTT中基本上对应class的函数就在相应名字的.c文件中,例如object相关函数就在object.c文件中。
  void rt_system_object_init(void); struct rt_object_information * rt_object_get_information(enum rt_object_class_type type); void rt_object_init(struct rt_object *object, enum rt_object_class_type type, const char *name); void rt_object_detach(rt_object_t object); rt_object_t rt_object_allocate(enum rt_object_class_type type, const char *name); void rt_object_delete(rt_object_t object); rt_bool_t rt_object_is_systemobject(rt_object_t object); rt_uint8_t rt_object_get_type(rt_object_t object); rt_object_t rt_object_find(const char *name, rt_uint8_t type);
  1.object初始化函数,object初始化有两个函数,分别对应使用静态内存的object初始化,和动态分配内存的object初始化。
  void rt_object_init(struct rt_object *object, enum rt_object_class_type type, const char *name); rt_object_t rt_object_allocate(enum rt_object_class_type type, const char *name);
  在初始化函数中主要做以下几件事情:
  1、为object申请内存(若使用动态初始化)
  2、设置object的type成员为指定的类型
  3、为object的name成员赋值
  4、调用rt_object_attach_hook钩子函数
  5、将object加入对应type的container双向链表中
  有一点区别需要提出,在voidrt_object_init();中,没有对object的flag成员进行赋值。
  ```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;
  /* get object information */
  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;
  }
  /* clean memory data of object */
  rt_memset(object, 0x0, information-》object_size);
  /*/
  /* initialize object‘s parameters */
  /*初始化成员**/
  / set object type /
  object-》type = type;
  /* set object flag */
  object-》flag = 0;
  /* 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();
  ifdef RT_USING_MODULE
  if (module)
  {
  rt_list_insert_after(&(module-》object_list), &(object-》list));
  object-》module_id = (void *)module;
  }
  else
  endif
  {
  /* 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、object删除以及detach
  只有动态创建的object才能被删除,静态创建的object通过detach脱离object system。
  删除/detach object主要完成以下动作:
  1、执行rt_object_detach_hook钩子函数
  2、将type重置为0
  3、将object从对应的双向链表中删除
  4、释放分配的内存(动态创建的object)
  ```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));
  /*/
  /* reset object type */
  object-》type = 0;
  /**移出链表*/
  / lock interrupt /
  temp = rt_hw_interrupt_disable();
  /* remove from old list */
  rt_list_remove(&(object-》list));
  /* unlock interrupt */
  rt_hw_interrupt_enable(temp);
  /*/
  /**释放内存*/
  / free the memory of object /
  RT_KERNEL_FREE(object);
  /*/
  }```
  3、其他与object相关函数。
  还有几个与object相关的函数放在一起来说:
  (1)void rt_system_object_init(void);
  (1)号函数是个空函数,没有被实现
  (2)号函数的功能是找到对应class type的双向链表结构,在object初始化中被调用
  (3)号函数查询object的type位,以此判断指针指向的是否为object对象
  (4)号函数返回object的type成员,返回的对象不包含RT_Object_Class_Static标志
  (5)号函数可以在对应的object type中通过name成员寻找对应的object对象,并返回。




原作者:yushigengyu

更多回帖

发帖
×
20
完善资料,
赚取积分