object.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463
  1. /*
  2. * File : object.c
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
  5. *
  6. * The license and distribution terms for this file may be
  7. * found in the file LICENSE in this distribution or at
  8. * http://www.rt-thread.org/license/LICENSE
  9. *
  10. * Change Logs:
  11. * Date Author Notes
  12. * 2006-03-14 Bernard the first version
  13. * 2006-04-21 Bernard change the scheduler lock to interrupt lock
  14. * 2006-05-18 Bernard fix the object init bug
  15. * 2006-08-03 Bernard add hook support
  16. * 2007-01-28 Bernard rename RT_OBJECT_Class_Static to RT_Object_Class_Static
  17. * 2010-10-26 yi.qiu add module support in rt_object_allocate and rt_object_free
  18. */
  19. #include <rtthread.h>
  20. #include <rthw.h>
  21. #include "kservice.h"
  22. #define _OBJ_CONTAINER_LIST_INIT(c) \
  23. {&(rt_object_container[c].object_list), &(rt_object_container[c].object_list)}
  24. struct rt_object_information rt_object_container[RT_Object_Class_Unknown] =
  25. {
  26. /* initialize object container - thread */
  27. {RT_Object_Class_Thread, _OBJ_CONTAINER_LIST_INIT(RT_Object_Class_Thread), sizeof(struct rt_thread)},
  28. #ifdef RT_USING_SEMAPHORE
  29. /* initialize object container - semaphore */
  30. {RT_Object_Class_Semaphore, _OBJ_CONTAINER_LIST_INIT(RT_Object_Class_Semaphore), sizeof(struct rt_semaphore)},
  31. #endif
  32. #ifdef RT_USING_MUTEX
  33. /* initialize object container - mutex */
  34. {RT_Object_Class_Mutex, _OBJ_CONTAINER_LIST_INIT(RT_Object_Class_Mutex), sizeof(struct rt_mutex)},
  35. #endif
  36. #ifdef RT_USING_EVENT
  37. /* initialize object container - event */
  38. {RT_Object_Class_Event, _OBJ_CONTAINER_LIST_INIT(RT_Object_Class_Event), sizeof(struct rt_event)},
  39. #endif
  40. #ifdef RT_USING_MAILBOX
  41. /* initialize object container - mailbox */
  42. {RT_Object_Class_MailBox, _OBJ_CONTAINER_LIST_INIT(RT_Object_Class_MailBox), sizeof(struct rt_mailbox)},
  43. #endif
  44. #ifdef RT_USING_MESSAGEQUEUE
  45. /* initialize object container - message queue */
  46. {RT_Object_Class_MessageQueue, _OBJ_CONTAINER_LIST_INIT(RT_Object_Class_MessageQueue), sizeof(struct rt_messagequeue)},
  47. #endif
  48. #ifdef RT_USING_MEMPOOL
  49. /* initialize object container - memory pool */
  50. {RT_Object_Class_MemPool, _OBJ_CONTAINER_LIST_INIT(RT_Object_Class_MemPool), sizeof(struct rt_mempool)},
  51. #endif
  52. #ifdef RT_USING_DEVICE
  53. /* initialize object container - device */
  54. {RT_Object_Class_Device, _OBJ_CONTAINER_LIST_INIT(RT_Object_Class_Device), sizeof(struct rt_device)},
  55. #endif
  56. /* initialize object container - timer */
  57. {RT_Object_Class_Timer, _OBJ_CONTAINER_LIST_INIT(RT_Object_Class_Timer), sizeof(struct rt_timer)},
  58. #ifdef RT_USING_MODULE
  59. /* initialize object container - module */
  60. {RT_Object_Class_Module, _OBJ_CONTAINER_LIST_INIT(RT_Object_Class_Module), sizeof(struct rt_module)},
  61. #endif
  62. };
  63. #ifdef RT_USING_HOOK
  64. static void (*rt_object_attach_hook)(struct rt_object* object);
  65. static void (*rt_object_detach_hook)(struct rt_object* object);
  66. void (*rt_object_trytake_hook)(struct rt_object* object);
  67. void (*rt_object_take_hook)(struct rt_object* object);
  68. void (*rt_object_put_hook)(struct rt_object* object);
  69. /**
  70. * @addtogroup Hook
  71. */
  72. /*@{*/
  73. /**
  74. * This function will set a hook function, which will be invoked when object
  75. * attaches to kernel object system.
  76. *
  77. * @param hook the hook function
  78. */
  79. void rt_object_attach_sethook(void (*hook)(struct rt_object* object))
  80. {
  81. register rt_base_t temp;
  82. /* disable interrupt */
  83. temp = rt_hw_interrupt_disable();
  84. rt_object_attach_hook = hook;
  85. /* enable interrupt */
  86. rt_hw_interrupt_enable(temp);
  87. }
  88. /**
  89. * This function will set a hook function, which will be invoked when object
  90. * detaches from kernel object system.
  91. *
  92. * @param hook the hook function
  93. */
  94. void rt_object_detach_sethook(void (*hook)(struct rt_object* object))
  95. {
  96. register rt_base_t temp;
  97. /* disable interrupt */
  98. temp = rt_hw_interrupt_disable();
  99. rt_object_detach_hook = hook;
  100. /* enable interrupt */
  101. rt_hw_interrupt_enable(temp);
  102. }
  103. /**
  104. * This function will set a hook function, which will be invoked when object
  105. * is taken from kernel object system.
  106. *
  107. * The object is taken means:
  108. * semaphore - semaphore is taken by thread
  109. * mutex - mutex is taken by thread
  110. * event - event is received by thread
  111. * mailbox - mail is received by thread
  112. * message queue - message is received by thread
  113. *
  114. * @param hook the hook function
  115. */
  116. void rt_object_trytake_sethook(void (*hook)(struct rt_object* object))
  117. {
  118. register rt_base_t temp;
  119. /* disable interrupt */
  120. temp = rt_hw_interrupt_disable();
  121. rt_object_trytake_hook = hook;
  122. /* enable interrupt */
  123. rt_hw_interrupt_enable(temp);
  124. }
  125. /**
  126. * This function will set a hook function, which will be invoked when object
  127. * have been taken from kernel object system.
  128. *
  129. * The object have been taken means:
  130. * semaphore - semaphore have been taken by thread
  131. * mutex - mutex have been taken by thread
  132. * event - event have been received by thread
  133. * mailbox - mail have been received by thread
  134. * message queue - message have been received by thread
  135. * timer - timer is started
  136. *
  137. * @param hook the hook function
  138. */
  139. void rt_object_take_sethook(void (*hook)(struct rt_object* object))
  140. {
  141. register rt_base_t temp;
  142. /* disable interrupt */
  143. temp = rt_hw_interrupt_disable();
  144. rt_object_take_hook = hook;
  145. /* enable interrupt */
  146. rt_hw_interrupt_enable(temp);
  147. }
  148. /**
  149. * This function will set a hook function, which will be invoked when object
  150. * is put to kernel object system.
  151. *
  152. * @param hook the hook function
  153. */
  154. void rt_object_put_sethook(void (*hook)(struct rt_object* object))
  155. {
  156. register rt_base_t temp;
  157. /* disable interrupt */
  158. temp = rt_hw_interrupt_disable();
  159. rt_object_put_hook = hook;
  160. /* enable interrupt */
  161. rt_hw_interrupt_enable(temp);
  162. }
  163. /*@}*/
  164. #endif
  165. /**
  166. * @ingroup SystemInit
  167. *
  168. * This function will initialize system object management.
  169. *
  170. * @deprecated since 0.3.0, this function does not need to be invoked
  171. * in the system initialization.
  172. */
  173. void rt_system_object_init(void)
  174. {
  175. }
  176. /**
  177. * @addtogroup KernelObject
  178. */
  179. /*@{*/
  180. /**
  181. * This function will return the specified type of object information.
  182. *
  183. * @param type the type of object
  184. * @return the object type information or RT_NULL
  185. */
  186. struct rt_object_information *rt_object_get_information(enum rt_object_class_type type)
  187. {
  188. return &rt_object_container[type];
  189. }
  190. /**
  191. * This function will initialize an object and add it to object system management.
  192. *
  193. * @param object the specified object to be initialized.
  194. * @param type the object type.
  195. * @param name the object name. In system, the object's name must be unique.
  196. */
  197. void rt_object_init(struct rt_object* object, enum rt_object_class_type type, const char* name)
  198. {
  199. register rt_base_t temp;
  200. struct rt_object_information* information;
  201. #ifdef RT_USING_MODULE
  202. /* get module object information */
  203. information = (rt_module_self() != RT_NULL) ?
  204. &rt_module_self()->module_object[type] : &rt_object_container[type];
  205. #else
  206. /* get object information */
  207. information = &rt_object_container[type];
  208. #endif
  209. /* initialize object's parameters */
  210. /* set object type to static */
  211. object->type = type | RT_Object_Class_Static;
  212. /* copy name */
  213. for (temp = 0; temp < RT_NAME_MAX; temp ++)
  214. {
  215. object->name[temp] = name[temp];
  216. }
  217. RT_OBJECT_HOOK_CALL(rt_object_attach_hook, (object));
  218. /* lock interrupt */
  219. temp = rt_hw_interrupt_disable();
  220. /* insert object into information object list */
  221. rt_list_insert_after(&(information->object_list), &(object->list));
  222. /* unlock interrupt */
  223. rt_hw_interrupt_enable(temp);
  224. }
  225. /**
  226. * This function will detach a static object from object system,
  227. * and the memory of static object is not freed.
  228. *
  229. * @param object the specified object to be detached.
  230. */
  231. void rt_object_detach(rt_object_t object)
  232. {
  233. register rt_base_t temp;
  234. /* object check */
  235. RT_ASSERT(object != RT_NULL);
  236. RT_OBJECT_HOOK_CALL(rt_object_detach_hook, (object));
  237. /* lock interrupt */
  238. temp = rt_hw_interrupt_disable();
  239. /* remove from old list */
  240. rt_list_remove(&(object->list));
  241. /* unlock interrupt */
  242. rt_hw_interrupt_enable(temp);
  243. }
  244. #ifdef RT_USING_HEAP
  245. /**
  246. * This function will allocate an object from object system
  247. *
  248. * @param type the type of object
  249. * @param name the object name. In system, the object's name must be unique.
  250. *
  251. * @return object
  252. */
  253. rt_object_t rt_object_allocate(enum rt_object_class_type type, const char* name)
  254. {
  255. struct rt_object* object;
  256. register rt_base_t temp;
  257. struct rt_object_information* information;
  258. RT_DEBUG_NOT_IN_INTERRUPT;
  259. #ifdef RT_USING_MODULE
  260. /* get module object information, module object should be managed by kernel object container */
  261. information = (rt_module_self() != RT_NULL && (type != RT_Object_Class_Module)) ?
  262. &rt_module_self()->module_object[type] : &rt_object_container[type];
  263. #else
  264. /* get object information */
  265. information = &rt_object_container[type];
  266. #endif
  267. object = (struct rt_object*)rt_malloc(information->object_size);
  268. if (object == RT_NULL)
  269. {
  270. /* no memory can be allocated */
  271. return RT_NULL;
  272. }
  273. /* initialize object's parameters */
  274. /* set object type */
  275. object->type = type;
  276. /* set object flag */
  277. object->flag = 0;
  278. #ifdef RT_USING_MODULE
  279. if(rt_module_self() != RT_NULL)
  280. {
  281. object->flag |= RT_OBJECT_FLAG_MODULE;
  282. }
  283. object->module_id = (void*)rt_module_self();
  284. #endif
  285. /* copy name */
  286. for (temp = 0; temp < RT_NAME_MAX; temp ++)
  287. {
  288. object->name[temp] = name[temp];
  289. }
  290. RT_OBJECT_HOOK_CALL(rt_object_attach_hook, (object));
  291. /* lock interrupt */
  292. temp = rt_hw_interrupt_disable();
  293. /* insert object into information object list */
  294. rt_list_insert_after(&(information->object_list), &(object->list));
  295. /* unlock interrupt */
  296. rt_hw_interrupt_enable(temp);
  297. /* return object */
  298. return object;
  299. }
  300. /**
  301. * This function will delete an object and release object memory.
  302. *
  303. * @param object the specified object to be deleted.
  304. */
  305. void rt_object_delete(rt_object_t object)
  306. {
  307. register rt_base_t temp;
  308. /* object check */
  309. RT_ASSERT(object != RT_NULL);
  310. RT_ASSERT(!(object->type & RT_Object_Class_Static));
  311. RT_OBJECT_HOOK_CALL(rt_object_detach_hook, (object));
  312. /* lock interrupt */
  313. temp = rt_hw_interrupt_disable();
  314. /* remove from old list */
  315. rt_list_remove(&(object->list));
  316. /* unlock interrupt */
  317. rt_hw_interrupt_enable(temp);
  318. #ifdef RT_USING_MODULE
  319. if(object->flag & RT_OBJECT_FLAG_MODULE)
  320. rt_module_free((rt_module_t)object->module_id, object);
  321. else
  322. #endif
  323. /* free the memory of object */
  324. rt_free(object);
  325. }
  326. #endif
  327. /**
  328. * This function will judge the object is system object or not.
  329. * Normally, the system object is a static object and the type
  330. * of object set to RT_Object_Class_Static.
  331. *
  332. * @param object the specified object to be judged.
  333. *
  334. * @return RT_EOK if a system object, RT_ERROR for others.
  335. */
  336. rt_err_t rt_object_is_systemobject(rt_object_t object)
  337. {
  338. /* object check */
  339. RT_ASSERT(object != RT_NULL);
  340. if (object->type & RT_Object_Class_Static) return RT_EOK;
  341. return -RT_ERROR;
  342. }
  343. /**
  344. * This function will find specified name object from object
  345. * container.
  346. *
  347. * @param name the specified name of object.
  348. * @param type the type of object
  349. *
  350. * @return the found object or RT_NULL if there is no this object
  351. * in object container.
  352. *
  353. * @note this function shall not be invoked in interrupt status.
  354. */
  355. rt_object_t rt_object_find(const char* name, rt_uint8_t type)
  356. {
  357. struct rt_object* object;
  358. struct rt_list_node* node;
  359. struct rt_object_information *information;
  360. extern volatile rt_uint8_t rt_interrupt_nest;
  361. /* parameter check */
  362. if ((name == RT_NULL) ||
  363. (type > RT_Object_Class_Unknown))
  364. return RT_NULL;
  365. /* which is invoke in interrupt status */
  366. if (rt_interrupt_nest != 0)
  367. RT_ASSERT(0);
  368. /* enter critical */
  369. rt_enter_critical();
  370. /* try to find object */
  371. information = &rt_object_container[type];
  372. for (node = information->object_list.next; node != &(information->object_list); node = node->next)
  373. {
  374. object = rt_list_entry(node, struct rt_object, list);
  375. if (rt_strncmp(object->name, name, RT_NAME_MAX) == 0)
  376. {
  377. /* leave critical */
  378. rt_exit_critical();
  379. return (rt_object_t)object;
  380. }
  381. }
  382. /* leave critical */
  383. rt_exit_critical();
  384. return RT_NULL;
  385. }
  386. /*@}*/