object.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713
  1. /*
  2. * Copyright (c) 2006-2021, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2006-03-14 Bernard the first version
  9. * 2006-04-21 Bernard change the scheduler lock to interrupt lock
  10. * 2006-05-18 Bernard fix the object init bug
  11. * 2006-08-03 Bernard add hook support
  12. * 2007-01-28 Bernard rename RT_OBJECT_Class_Static to RT_Object_Class_Static
  13. * 2010-10-26 yi.qiu add module support in rt_object_allocate and rt_object_free
  14. * 2017-12-10 Bernard Add object_info enum.
  15. * 2018-01-25 Bernard Fix the object find issue when enable MODULE.
  16. * 2022-01-07 Gabriel Moving __on_rt_xxxxx_hook to object.c
  17. * 2023-09-15 xqyjlj perf rt_hw_interrupt_disable/enable
  18. */
  19. #include <rtthread.h>
  20. #include <rthw.h>
  21. #ifdef RT_USING_MODULE
  22. #include <dlmodule.h>
  23. #endif /* RT_USING_MODULE */
  24. #ifdef RT_USING_SMART
  25. #include <lwp.h>
  26. #endif
  27. struct rt_custom_object
  28. {
  29. struct rt_object parent;
  30. rt_err_t (*destroy)(void *);
  31. void *data;
  32. };
  33. /*
  34. * define object_info for the number of _object_container items.
  35. */
  36. enum rt_object_info_type
  37. {
  38. RT_Object_Info_Thread = 0, /**< The object is a thread. */
  39. #ifdef RT_USING_SEMAPHORE
  40. RT_Object_Info_Semaphore, /**< The object is a semaphore. */
  41. #endif
  42. #ifdef RT_USING_MUTEX
  43. RT_Object_Info_Mutex, /**< The object is a mutex. */
  44. #endif
  45. #ifdef RT_USING_EVENT
  46. RT_Object_Info_Event, /**< The object is a event. */
  47. #endif
  48. #ifdef RT_USING_MAILBOX
  49. RT_Object_Info_MailBox, /**< The object is a mail box. */
  50. #endif
  51. #ifdef RT_USING_MESSAGEQUEUE
  52. RT_Object_Info_MessageQueue, /**< The object is a message queue. */
  53. #endif
  54. #ifdef RT_USING_MEMHEAP
  55. RT_Object_Info_MemHeap, /**< The object is a memory heap */
  56. #endif
  57. #ifdef RT_USING_MEMPOOL
  58. RT_Object_Info_MemPool, /**< The object is a memory pool. */
  59. #endif
  60. #ifdef RT_USING_DEVICE
  61. RT_Object_Info_Device, /**< The object is a device */
  62. #endif
  63. RT_Object_Info_Timer, /**< The object is a timer. */
  64. #ifdef RT_USING_MODULE
  65. RT_Object_Info_Module, /**< The object is a module. */
  66. #endif
  67. #ifdef RT_USING_HEAP
  68. RT_Object_Info_Memory, /**< The object is a memory. */
  69. #endif
  70. #ifdef RT_USING_SMART
  71. RT_Object_Info_Channel, /**< The object is a IPC channel */
  72. #endif
  73. #ifdef RT_USING_HEAP
  74. RT_Object_Info_Custom, /**< The object is a custom object */
  75. #endif
  76. RT_Object_Info_Unknown, /**< The object is unknown. */
  77. };
  78. #define _OBJ_CONTAINER_LIST_INIT(c) \
  79. {&(_object_container[c].object_list), &(_object_container[c].object_list)}
  80. static struct rt_object_information _object_container[RT_Object_Info_Unknown] =
  81. {
  82. /* initialize object container - thread */
  83. {RT_Object_Class_Thread, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_Thread), sizeof(struct rt_thread), RT_SPINLOCK_INIT},
  84. #ifdef RT_USING_SEMAPHORE
  85. /* initialize object container - semaphore */
  86. {RT_Object_Class_Semaphore, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_Semaphore), sizeof(struct rt_semaphore), RT_SPINLOCK_INIT},
  87. #endif
  88. #ifdef RT_USING_MUTEX
  89. /* initialize object container - mutex */
  90. {RT_Object_Class_Mutex, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_Mutex), sizeof(struct rt_mutex), RT_SPINLOCK_INIT},
  91. #endif
  92. #ifdef RT_USING_EVENT
  93. /* initialize object container - event */
  94. {RT_Object_Class_Event, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_Event), sizeof(struct rt_event), RT_SPINLOCK_INIT},
  95. #endif
  96. #ifdef RT_USING_MAILBOX
  97. /* initialize object container - mailbox */
  98. {RT_Object_Class_MailBox, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_MailBox), sizeof(struct rt_mailbox), RT_SPINLOCK_INIT},
  99. #endif
  100. #ifdef RT_USING_MESSAGEQUEUE
  101. /* initialize object container - message queue */
  102. {RT_Object_Class_MessageQueue, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_MessageQueue), sizeof(struct rt_messagequeue), RT_SPINLOCK_INIT},
  103. #endif
  104. #ifdef RT_USING_MEMHEAP
  105. /* initialize object container - memory heap */
  106. {RT_Object_Class_MemHeap, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_MemHeap), sizeof(struct rt_memheap), RT_SPINLOCK_INIT},
  107. #endif
  108. #ifdef RT_USING_MEMPOOL
  109. /* initialize object container - memory pool */
  110. {RT_Object_Class_MemPool, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_MemPool), sizeof(struct rt_mempool), RT_SPINLOCK_INIT},
  111. #endif
  112. #ifdef RT_USING_DEVICE
  113. /* initialize object container - device */
  114. {RT_Object_Class_Device, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_Device), sizeof(struct rt_device), RT_SPINLOCK_INIT},
  115. #endif
  116. /* initialize object container - timer */
  117. {RT_Object_Class_Timer, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_Timer), sizeof(struct rt_timer), RT_SPINLOCK_INIT},
  118. #ifdef RT_USING_MODULE
  119. /* initialize object container - module */
  120. {RT_Object_Class_Module, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_Module), sizeof(struct rt_dlmodule), RT_SPINLOCK_INIT},
  121. #endif
  122. #ifdef RT_USING_HEAP
  123. /* initialize object container - small memory */
  124. {RT_Object_Class_Memory, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_Memory), sizeof(struct rt_memory), RT_SPINLOCK_INIT},
  125. #endif
  126. #ifdef RT_USING_SMART
  127. /* initialize object container - module */
  128. {RT_Object_Class_Channel, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_Channel), sizeof(struct rt_channel), RT_SPINLOCK_INIT},
  129. {RT_Object_Class_Custom, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_Custom), sizeof(struct rt_custom_object), RT_SPINLOCK_INIT},
  130. #endif
  131. };
  132. #ifndef __on_rt_object_attach_hook
  133. #define __on_rt_object_attach_hook(obj) __ON_HOOK_ARGS(rt_object_attach_hook, (obj))
  134. #endif
  135. #ifndef __on_rt_object_detach_hook
  136. #define __on_rt_object_detach_hook(obj) __ON_HOOK_ARGS(rt_object_detach_hook, (obj))
  137. #endif
  138. #ifndef __on_rt_object_trytake_hook
  139. #define __on_rt_object_trytake_hook(parent) __ON_HOOK_ARGS(rt_object_trytake_hook, (parent))
  140. #endif
  141. #ifndef __on_rt_object_take_hook
  142. #define __on_rt_object_take_hook(parent) __ON_HOOK_ARGS(rt_object_take_hook, (parent))
  143. #endif
  144. #ifndef __on_rt_object_put_hook
  145. #define __on_rt_object_put_hook(parent) __ON_HOOK_ARGS(rt_object_put_hook, (parent))
  146. #endif
  147. #if defined(RT_USING_HOOK) && defined(RT_HOOK_USING_FUNC_PTR)
  148. static void (*rt_object_attach_hook)(struct rt_object *object);
  149. static void (*rt_object_detach_hook)(struct rt_object *object);
  150. void (*rt_object_trytake_hook)(struct rt_object *object);
  151. void (*rt_object_take_hook)(struct rt_object *object);
  152. void (*rt_object_put_hook)(struct rt_object *object);
  153. /**
  154. * @addtogroup Hook
  155. */
  156. /**@{*/
  157. /**
  158. * @brief This function will set a hook function, which will be invoked when object
  159. * attaches to kernel object system.
  160. *
  161. * @param hook is the hook function.
  162. */
  163. void rt_object_attach_sethook(void (*hook)(struct rt_object *object))
  164. {
  165. rt_object_attach_hook = hook;
  166. }
  167. /**
  168. * @brief This function will set a hook function, which will be invoked when object
  169. * detaches from kernel object system.
  170. *
  171. * @param hook is the hook function
  172. */
  173. void rt_object_detach_sethook(void (*hook)(struct rt_object *object))
  174. {
  175. rt_object_detach_hook = hook;
  176. }
  177. /**
  178. * @brief This function will set a hook function, which will be invoked when object
  179. * is taken from kernel object system.
  180. *
  181. * The object is taken means:
  182. * semaphore - semaphore is taken by thread
  183. * mutex - mutex is taken by thread
  184. * event - event is received by thread
  185. * mailbox - mail is received by thread
  186. * message queue - message is received by thread
  187. *
  188. * @param hook is the hook function.
  189. */
  190. void rt_object_trytake_sethook(void (*hook)(struct rt_object *object))
  191. {
  192. rt_object_trytake_hook = hook;
  193. }
  194. /**
  195. * @brief This function will set a hook function, which will be invoked when object
  196. * have been taken from kernel object system.
  197. *
  198. * The object have been taken means:
  199. * semaphore - semaphore have been taken by thread
  200. * mutex - mutex have been taken by thread
  201. * event - event have been received by thread
  202. * mailbox - mail have been received by thread
  203. * message queue - message have been received by thread
  204. * timer - timer is started
  205. *
  206. * @param hook the hook function.
  207. */
  208. void rt_object_take_sethook(void (*hook)(struct rt_object *object))
  209. {
  210. rt_object_take_hook = hook;
  211. }
  212. /**
  213. * @brief This function will set a hook function, which will be invoked when object
  214. * is put to kernel object system.
  215. *
  216. * @param hook is the hook function
  217. */
  218. void rt_object_put_sethook(void (*hook)(struct rt_object *object))
  219. {
  220. rt_object_put_hook = hook;
  221. }
  222. /**@}*/
  223. #endif /* RT_USING_HOOK */
  224. /**
  225. * @addtogroup KernelObject
  226. */
  227. /**@{*/
  228. /**
  229. * @brief This function will return the specified type of object information.
  230. *
  231. * @param type is the type of object, which can be
  232. * RT_Object_Class_Thread/Semaphore/Mutex... etc
  233. *
  234. * @return the object type information or RT_NULL
  235. */
  236. struct rt_object_information *
  237. rt_object_get_information(enum rt_object_class_type type)
  238. {
  239. int index;
  240. type = (enum rt_object_class_type)(type & ~RT_Object_Class_Static);
  241. for (index = 0; index < RT_Object_Info_Unknown; index ++)
  242. if (_object_container[index].type == type) return &_object_container[index];
  243. return RT_NULL;
  244. }
  245. RTM_EXPORT(rt_object_get_information);
  246. /**
  247. * @brief This function will return the length of object list in object container.
  248. *
  249. * @param type is the type of object, which can be
  250. * RT_Object_Class_Thread/Semaphore/Mutex... etc
  251. *
  252. * @return the length of object list
  253. */
  254. int rt_object_get_length(enum rt_object_class_type type)
  255. {
  256. int count = 0;
  257. rt_base_t level;
  258. struct rt_list_node *node = RT_NULL;
  259. struct rt_object_information *information = RT_NULL;
  260. information = rt_object_get_information((enum rt_object_class_type)type);
  261. if (information == RT_NULL) return 0;
  262. level = rt_spin_lock_irqsave(&(information->spinlock));
  263. rt_list_for_each(node, &(information->object_list))
  264. {
  265. count ++;
  266. }
  267. rt_spin_unlock_irqrestore(&(information->spinlock), level);
  268. return count;
  269. }
  270. RTM_EXPORT(rt_object_get_length);
  271. /**
  272. * @brief This function will copy the object pointer of the specified type,
  273. * with the maximum size specified by maxlen.
  274. *
  275. * @param type is the type of object, which can be
  276. * RT_Object_Class_Thread/Semaphore/Mutex... etc
  277. *
  278. * @param pointers is the pointer will be saved to.
  279. *
  280. * @param maxlen is the maximum number of pointers can be saved.
  281. *
  282. * @return the copied number of object pointers.
  283. */
  284. int rt_object_get_pointers(enum rt_object_class_type type, rt_object_t *pointers, int maxlen)
  285. {
  286. int index = 0;
  287. rt_base_t level;
  288. struct rt_object *object;
  289. struct rt_list_node *node = RT_NULL;
  290. struct rt_object_information *information = RT_NULL;
  291. if (maxlen <= 0) return 0;
  292. information = rt_object_get_information(type);
  293. if (information == RT_NULL) return 0;
  294. level = rt_spin_lock_irqsave(&(information->spinlock));
  295. /* retrieve pointer of object */
  296. rt_list_for_each(node, &(information->object_list))
  297. {
  298. object = rt_list_entry(node, struct rt_object, list);
  299. pointers[index] = object;
  300. index ++;
  301. if (index >= maxlen) break;
  302. }
  303. rt_spin_unlock_irqrestore(&(information->spinlock), level);
  304. return index;
  305. }
  306. RTM_EXPORT(rt_object_get_pointers);
  307. /**
  308. * @brief This function will initialize an object and add it to object system
  309. * management.
  310. *
  311. * @param object is the specified object to be initialized.
  312. *
  313. * @param type is the object type.
  314. *
  315. * @param name is the object name. In system, the object's name must be unique.
  316. */
  317. void rt_object_init(struct rt_object *object,
  318. enum rt_object_class_type type,
  319. const char *name)
  320. {
  321. rt_base_t level;
  322. #ifdef RT_USING_DEBUG
  323. struct rt_list_node *node = RT_NULL;
  324. #endif
  325. struct rt_object_information *information;
  326. #ifdef RT_USING_MODULE
  327. struct rt_dlmodule *module = dlmodule_self();
  328. #endif /* RT_USING_MODULE */
  329. /* get object information */
  330. information = rt_object_get_information(type);
  331. RT_ASSERT(information != RT_NULL);
  332. #ifdef RT_USING_DEBUG
  333. /* check object type to avoid re-initialization */
  334. /* enter critical */
  335. level = rt_spin_lock_irqsave(&(information->spinlock));
  336. /* try to find object */
  337. for (node = information->object_list.next;
  338. node != &(information->object_list);
  339. node = node->next)
  340. {
  341. struct rt_object *obj;
  342. obj = rt_list_entry(node, struct rt_object, list);
  343. RT_ASSERT(obj != object);
  344. }
  345. /* leave critical */
  346. rt_spin_unlock_irqrestore(&(information->spinlock), level);
  347. #endif
  348. /* initialize object's parameters */
  349. /* set object type to static */
  350. object->type = type | RT_Object_Class_Static;
  351. #if RT_NAME_MAX > 0
  352. rt_strncpy(object->name, name, RT_NAME_MAX); /* copy name */
  353. #else
  354. object->name = name;
  355. #endif /* RT_NAME_MAX > 0 */
  356. RT_OBJECT_HOOK_CALL(rt_object_attach_hook, (object));
  357. level = rt_spin_lock_irqsave(&(information->spinlock));
  358. #ifdef RT_USING_MODULE
  359. if (module)
  360. {
  361. rt_list_insert_after(&(module->object_list), &(object->list));
  362. object->module_id = (void *)module;
  363. }
  364. else
  365. #endif /* RT_USING_MODULE */
  366. {
  367. /* insert object into information object list */
  368. rt_list_insert_after(&(information->object_list), &(object->list));
  369. }
  370. rt_spin_unlock_irqrestore(&(information->spinlock), level);
  371. }
  372. /**
  373. * @brief This function will detach a static object from object system,
  374. * and the memory of static object is not freed.
  375. *
  376. * @param object the specified object to be detached.
  377. */
  378. void rt_object_detach(rt_object_t object)
  379. {
  380. rt_base_t level;
  381. struct rt_object_information *information;
  382. /* object check */
  383. RT_ASSERT(object != RT_NULL);
  384. RT_OBJECT_HOOK_CALL(rt_object_detach_hook, (object));
  385. information = rt_object_get_information((enum rt_object_class_type)object->type);
  386. RT_ASSERT(information != RT_NULL);
  387. level = rt_spin_lock_irqsave(&(information->spinlock));
  388. /* remove from old list */
  389. rt_list_remove(&(object->list));
  390. rt_spin_unlock_irqrestore(&(information->spinlock), level);
  391. object->type = 0;
  392. }
  393. #ifdef RT_USING_HEAP
  394. /**
  395. * @brief This function will allocate an object from object system.
  396. *
  397. * @param type is the type of object.
  398. *
  399. * @param name is the object name. In system, the object's name must be unique.
  400. *
  401. * @return object
  402. */
  403. rt_object_t rt_object_allocate(enum rt_object_class_type type, const char *name)
  404. {
  405. struct rt_object *object;
  406. rt_base_t level;
  407. struct rt_object_information *information;
  408. #ifdef RT_USING_MODULE
  409. struct rt_dlmodule *module = dlmodule_self();
  410. #endif /* RT_USING_MODULE */
  411. RT_DEBUG_NOT_IN_INTERRUPT;
  412. /* get object information */
  413. information = rt_object_get_information(type);
  414. RT_ASSERT(information != RT_NULL);
  415. object = (struct rt_object *)RT_KERNEL_MALLOC(information->object_size);
  416. if (object == RT_NULL)
  417. {
  418. /* no memory can be allocated */
  419. return RT_NULL;
  420. }
  421. /* clean memory data of object */
  422. rt_memset(object, 0x0, information->object_size);
  423. /* initialize object's parameters */
  424. /* set object type */
  425. object->type = type;
  426. /* set object flag */
  427. object->flag = 0;
  428. #if RT_NAME_MAX > 0
  429. rt_strncpy(object->name, name, RT_NAME_MAX); /* copy name */
  430. #else
  431. object->name = name;
  432. #endif /* RT_NAME_MAX > 0 */
  433. RT_OBJECT_HOOK_CALL(rt_object_attach_hook, (object));
  434. level = rt_spin_lock_irqsave(&(information->spinlock));
  435. #ifdef RT_USING_MODULE
  436. if (module)
  437. {
  438. rt_list_insert_after(&(module->object_list), &(object->list));
  439. object->module_id = (void *)module;
  440. }
  441. else
  442. #endif /* RT_USING_MODULE */
  443. {
  444. /* insert object into information object list */
  445. rt_list_insert_after(&(information->object_list), &(object->list));
  446. }
  447. rt_spin_unlock_irqrestore(&(information->spinlock), level);
  448. return object;
  449. }
  450. /**
  451. * @brief This function will delete an object and release object memory.
  452. *
  453. * @param object is the specified object to be deleted.
  454. */
  455. void rt_object_delete(rt_object_t object)
  456. {
  457. rt_base_t level;
  458. struct rt_object_information *information;
  459. /* object check */
  460. RT_ASSERT(object != RT_NULL);
  461. RT_ASSERT(!(object->type & RT_Object_Class_Static));
  462. RT_OBJECT_HOOK_CALL(rt_object_detach_hook, (object));
  463. information = rt_object_get_information((enum rt_object_class_type)object->type);
  464. RT_ASSERT(information != RT_NULL);
  465. level = rt_spin_lock_irqsave(&(information->spinlock));
  466. /* remove from old list */
  467. rt_list_remove(&(object->list));
  468. rt_spin_unlock_irqrestore(&(information->spinlock), level);
  469. /* reset object type */
  470. object->type = RT_Object_Class_Null;
  471. /* free the memory of object */
  472. RT_KERNEL_FREE(object);
  473. }
  474. #endif /* RT_USING_HEAP */
  475. /**
  476. * @brief This function will judge the object is system object or not.
  477. *
  478. * @note Normally, the system object is a static object and the type
  479. * of object set to RT_Object_Class_Static.
  480. *
  481. * @param object is the specified object to be judged.
  482. *
  483. * @return RT_TRUE if a system object, RT_FALSE for others.
  484. */
  485. rt_bool_t rt_object_is_systemobject(rt_object_t object)
  486. {
  487. /* object check */
  488. RT_ASSERT(object != RT_NULL);
  489. if (object->type & RT_Object_Class_Static)
  490. return RT_TRUE;
  491. return RT_FALSE;
  492. }
  493. /**
  494. * @brief This function will return the type of object without
  495. * RT_Object_Class_Static flag.
  496. *
  497. * @param object is the specified object to be get type.
  498. *
  499. * @return the type of object.
  500. */
  501. rt_uint8_t rt_object_get_type(rt_object_t object)
  502. {
  503. /* object check */
  504. RT_ASSERT(object != RT_NULL);
  505. return object->type & ~RT_Object_Class_Static;
  506. }
  507. /**
  508. * @brief This function will find specified name object from object
  509. * container.
  510. *
  511. * @param name is the specified name of object.
  512. *
  513. * @param type is the type of object
  514. *
  515. * @return the found object or RT_NULL if there is no this object
  516. * in object container.
  517. *
  518. * @note this function shall not be invoked in interrupt status.
  519. */
  520. rt_object_t rt_object_find(const char *name, rt_uint8_t type)
  521. {
  522. struct rt_object *object = RT_NULL;
  523. struct rt_list_node *node = RT_NULL;
  524. struct rt_object_information *information = RT_NULL;
  525. rt_base_t level;
  526. information = rt_object_get_information((enum rt_object_class_type)type);
  527. /* parameter check */
  528. if ((name == RT_NULL) || (information == RT_NULL)) return RT_NULL;
  529. /* which is invoke in interrupt status */
  530. RT_DEBUG_NOT_IN_INTERRUPT;
  531. /* enter critical */
  532. level = rt_spin_lock_irqsave(&(information->spinlock));
  533. /* try to find object */
  534. rt_list_for_each(node, &(information->object_list))
  535. {
  536. object = rt_list_entry(node, struct rt_object, list);
  537. if (rt_strncmp(object->name, name, RT_NAME_MAX) == 0)
  538. {
  539. rt_spin_unlock_irqrestore(&(information->spinlock), level);
  540. return object;
  541. }
  542. }
  543. rt_spin_unlock_irqrestore(&(information->spinlock), level);
  544. return RT_NULL;
  545. }
  546. /**
  547. * @brief This function will return the name of the specified object container
  548. *
  549. * @param object the specified object to be get name
  550. * @param name buffer to store the object name string
  551. * @param name_size maximum size of the buffer to store object name
  552. *
  553. * @return -RT_EINVAL if any parameter is invalid or RT_EOK if the operation is successfully executed
  554. *
  555. * @note this function shall not be invoked in interrupt status
  556. */
  557. rt_err_t rt_object_get_name(rt_object_t object, char *name, rt_uint8_t name_size)
  558. {
  559. rt_err_t result = -RT_EINVAL;
  560. if ((object != RT_NULL) && (name != RT_NULL) && (name_size != 0U))
  561. {
  562. const char *obj_name = object->name;
  563. (void) rt_strncpy(name, obj_name, (rt_size_t)name_size);
  564. result = RT_EOK;
  565. }
  566. return result;
  567. }
  568. #ifdef RT_USING_HEAP
  569. /**
  570. * This function will create a custom object
  571. * container.
  572. *
  573. * @param name the specified name of object.
  574. * @param data the custom data
  575. * @param data_destroy the custom object destroy callback
  576. *
  577. * @return the found object or RT_NULL if there is no this object
  578. * in object container.
  579. *
  580. * @note this function shall not be invoked in interrupt status.
  581. */
  582. rt_object_t rt_custom_object_create(const char *name, void *data, rt_err_t (*data_destroy)(void *))
  583. {
  584. struct rt_custom_object *cobj = RT_NULL;
  585. cobj = (struct rt_custom_object *)rt_object_allocate(RT_Object_Class_Custom, name);
  586. if (!cobj)
  587. {
  588. return RT_NULL;
  589. }
  590. cobj->destroy = data_destroy;
  591. cobj->data = data;
  592. return (struct rt_object *)cobj;
  593. }
  594. /**
  595. * This function will destroy a custom object
  596. * container.
  597. *
  598. * @param obj the specified name of object.
  599. *
  600. * @note this function shall not be invoked in interrupt status.
  601. */
  602. rt_err_t rt_custom_object_destroy(rt_object_t obj)
  603. {
  604. rt_err_t ret = -1;
  605. struct rt_custom_object *cobj = (struct rt_custom_object *)obj;
  606. if (obj && obj->type == RT_Object_Class_Custom)
  607. {
  608. if (cobj->destroy)
  609. {
  610. ret = cobj->destroy(cobj->data);
  611. }
  612. rt_object_delete(obj);
  613. }
  614. return ret;
  615. }
  616. #endif
  617. /**@}*/