Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
内核学习营
RT-Thread--内核学习object(一)
发布于 2018-09-28 17:39:40 浏览:3351
订阅该版
* 本帖最后由 yushigengyu 于 2018-9-29 14:47 编辑 * RTT这个RTOS虽然是全部是用C编写,但全程使用的都是面向对象的编程方式。所以最好的研究方式,就是从对象入手,分析代码各部分所包含的对象以及对象的方法函数。 首先先了解下与thread相关的对象,主要有三个: 1、RTT最基本的对象:rt_object 2、线程对象:rt_thread 3、定时器对象:rt_timer ![thread uml class.png](/uploads/201809/28/173934cocu2jocs9v8socj.png) 这里发现一个现象,按正常逻辑来说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对象,并返回
查看更多
5
个回答
默认排序
按发布时间排序
yqiu
2018-09-28
这家伙很懒,什么也没写!
挺好的的记录和分享。
yushigengyu
认证专家
2018-09-29
这家伙很懒,什么也没写!
>挺好的的记录和分享。 --- 我会继续更新该内容:lol
Digod
2018-11-29
这家伙很懒,什么也没写!
[i=s] 本帖最后由 Digod 于 2018-11-29 10:31 编辑 [/i] [attach]6889[/attach] 现在遇到个问题 mqtt pub若干包(不定)数据后 报 rt_timer_control中line468 RT_ASSERT(rt_object_get_type(&timer->parent)== RT_Object_Class_Timer); ASSERT FAIL错误 打印了log下发现是rt_object_get_type(&timer->parent)获取到的RT_obj_type值为0 对应RT_Object_Class_Thread 请问有没有人知道这是为啥 rt_timer_control中传入的timer的obj->type不应该总是RT_Object_Class_Timer么 怎么会有别的类型传进来呢?
Digod
2018-12-03
这家伙很懒,什么也没写!
>现在遇到个问题 mqtt pub若干包(不定)数据后 >报 rt_timer_control中line468 RT_ASSERT(rt_object_ge ... --- 找到问题了 好像是我在连接断线后在pub任务中调用了rt_thread_delete删除了任务自身导致的 注释掉那个代码就没问题了。。。
yuexiaoban
2018-12-22
这家伙很懒,什么也没写!
【你的内核学习帖子,感觉少了几个章节,建议给这个系列做个目录帖子方便有条理的学习和阅读】
撰写答案
登录
注册新账号
关注者
0
被浏览
3.4k
关于作者
yushigengyu
这家伙很懒,什么也没写!
提问
15
回答
25
被采纳
0
关注TA
发私信
相关问题
1
【内核学习】rtthread内核移植记录-STM32F103ZET6-HAL库
2
《内核学习营》+水一方+自用STM32F103VC 板RT-Thread内核移植分享
3
《内核学习营》+水一方+项目中创建标准的 RT-Thread工程
4
内核学习营+坦然+探索者stm32f407板子RT-thread循环点亮led灯
5
<内核学习营>+坦然+探索者stm32f407板子RT-thread串口字符点灯
6
<内核学习营>+坦然+探索者stm32f407板子RT-thread的pwm点灯实验
7
<内核学习营>+坦然+探索者stm32f407板子RT-thread串口实验
8
<内核学习营>+坦然+野火stm32f103板子RT-thread读写SD卡实验
9
<内核学习营>+坦然+探索者stm32f407板子RT-thread的RTC闹钟实验
10
【内核学习营】+王秀峰+led_rgb
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
最新文章
1
在用clangd开发RTT吗,快来试试如何简单获得清晰干净的工作区
2
GD32F450 片内 flash驱动适配
3
STM32H7R7运行CherryUSB
4
RT-Smart首次线下培训,锁定2024 RT-Thread开发者大会!
5
使用RC522软件包驱动FM1722
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
UART
WIZnet_W5500
ota在线升级
freemodbus
PWM
flash
cubemx
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
flashDB
GD32
socket
中断
编译报错
Debug
SFUD
rt_mq_消息队列_msg_queue
msh
keil_MDK
ulog
C++_cpp
MicroPython
本月问答贡献
a1012112796
10
个答案
1
次被采纳
踩姑娘的小蘑菇
4
个答案
1
次被采纳
红枫
4
个答案
1
次被采纳
张世争
4
个答案
1
次被采纳
Ryan_CW
4
个答案
1
次被采纳
本月文章贡献
catcatbing
3
篇文章
6
次点赞
YZRD
2
篇文章
5
次点赞
qq1078249029
2
篇文章
2
次点赞
xnosky
2
篇文章
1
次点赞
Woshizhapuren
1
篇文章
5
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部