1 /*
2 * Copyright (C) 2015-2020 Alibaba Group Holding Limited
3 */
4
5
6 #include "device/object.h"
7 #include "device/aos_device.h"
8
9 #include "aos/kernel.h"
10 #include "k_api.h"
11
12 #define OBJ_ASSERT(test)
13 #define AOS_USING_DEVICE
14
15 #ifdef AOS_USING_HOOK
16 static void (*aos_object_attach_hook)(struct aos_object *object);
17 static void (*aos_object_detach_hook)(struct aos_object *object);
18 #endif
19
20 /*
21 * define object_info for the number of aos_object_container items.
22 */
23 enum aos_object_info_type
24 {
25 AOS_Object_Info_Thread = 0, /**< The object is a thread. */
26 #ifdef AOS_USING_SEMAPHORE
27 AOS_Object_Info_Semaphore, /**< The object is a semaphore. */
28 #endif
29 #ifdef AOS_USING_MUTEX
30 AOS_Object_Info_Mutex, /**< The object is a mutex. */
31 #endif
32 #ifdef AOS_USING_EVENT
33 AOS_Object_Info_Event, /**< The object is a event. */
34 #endif
35 #ifdef AOS_USING_MAILBOX
36 AOS_Object_Info_MailBox, /**< The object is a mail box. */
37 #endif
38 #ifdef AOS_USING_MESSAGEQUEUE
39 AOS_Object_Info_MessageQueue, /**< The object is a message queue. */
40 #endif
41 #ifdef AOS_USING_MEMHEAP
42 AOS_Object_Info_MemHeap, /**< The object is a memory heap */
43 #endif
44 #ifdef AOS_USING_MEMPOOL
45 AOS_Object_Info_MemPool, /**< The object is a memory pool. */
46 #endif
47 #ifdef AOS_USING_DEVICE
48 AOS_Object_Info_Device, /**< The object is a device */
49 #endif
50 AOS_Object_Info_Timer, /**< The object is a timer. */
51 #ifdef AOS_USING_MODULE
52 AOS_Object_Info_Module, /**< The object is a module. */
53 #endif
54 AOS_Object_Info_Unknown, /**< The object is unknown. */
55 };
56
57 #define _OBJ_CONTAINER_LIST_INIT(c) \
58 {&(aos_object_container[c].object_list), &(aos_object_container[c].object_list)}
59 static struct aos_object_information aos_object_container[AOS_Object_Info_Unknown] =
60 {
61 /* initialize object container - thread */
62 {AOS_Object_Class_Thread, _OBJ_CONTAINER_LIST_INIT(AOS_Object_Info_Thread), sizeof(aos_task_t)},
63 #ifdef AOS_USING_SEMAPHORE
64 /* initialize object container - semaphore */
65 {AOS_Object_Class_Semaphore, _OBJ_CONTAINER_LIST_INIT(AOS_Object_Info_Semaphore), sizeof(aos_semt_t)},
66 #endif
67 #ifdef AOS_USING_MUTEX
68 /* initialize object container - mutex */
69 {AOS_Object_Class_Mutex, _OBJ_CONTAINER_LIST_INIT(AOS_Object_Info_Mutex), sizeof(aos_mutex_t)},
70 #endif
71 #ifdef AOS_USING_EVENT
72 /* initialize object container - event */
73 {AOS_Object_Class_Event, _OBJ_CONTAINER_LIST_INIT(AOS_Object_Info_Event), sizeof(aos_event_t)},
74 #endif
75 #ifdef AOS_USING_MAILBOX
76 /* initialize object container - mailbox */
77 {AOS_Object_Class_MailBox, _OBJ_CONTAINER_LIST_INIT(AOS_Object_Info_MailBox), sizeof(aos_queue_t)},
78 #endif
79 #ifdef AOS_USING_MESSAGEQUEUE
80 /* initialize object container - message queue */
81 {AOS_Object_Class_MessageQueue, _OBJ_CONTAINER_LIST_INIT(AOS_Object_Info_MessageQueue), sizeof(struct aos_messagequeue)},
82 #endif
83 #ifdef AOS_USING_MEMHEAP
84 /* initialize object container - memory heap */
85 {AOS_Object_Class_MemHeap, _OBJ_CONTAINER_LIST_INIT(AOS_Object_Info_MemHeap), sizeof(struct memheap)},
86 #endif
87 #ifdef AOS_USING_MEMPOOL
88 /* initialize object container - memory pool */
89 {AOS_Object_Class_MemPool, _OBJ_CONTAINER_LIST_INIT(AOS_Object_Info_MemPool), sizeof(struct aos_mempool)},
90 #endif
91 #ifdef AOS_USING_DEVICE
92 /* initialize object container - device */
93 {AOS_Object_Class_Device, _OBJ_CONTAINER_LIST_INIT(AOS_Object_Info_Device), sizeof(struct aos_device)},
94 #endif
95 /* initialize object container - timer */
96 {AOS_Object_Class_Timer, _OBJ_CONTAINER_LIST_INIT(AOS_Object_Info_Timer), sizeof(aos_timer_t)},
97 #ifdef AOS_USING_MODULE
98 /* initialize object container - module */
99 {AOS_Object_Class_Module, _OBJ_CONTAINER_LIST_INIT(AOS_Object_Info_Module), sizeof(struct aos_dlmodule)},
100 #endif
101 };
102
103 #ifdef AOS_USING_HOOK
104 static void (*aos_object_attach_hook)(struct aos_object *object);
105 static void (*aos_object_detach_hook)(struct aos_object *object);
106 void (*aos_object_trytake_hook)(struct aos_object *object);
107 void (*aos_object_take_hook)(struct aos_object *object);
108 void (*aos_object_put_hook)(struct aos_object *object);
109
110 /**
111 * @addtogroup Hook
112 */
113
114 /**@{*/
115
116 /**
117 * This function will set a hook function, which will be invoked when object
118 * attaches to kernel object system.
119 *
120 * @param hook the hook function
121 */
aos_object_attach_sethook(void (* hook)(struct aos_object * object))122 void aos_object_attach_sethook(void (*hook)(struct aos_object *object))
123 {
124 aos_object_attach_hook = hook;
125 }
126
127 /**
128 * This function will set a hook function, which will be invoked when object
129 * detaches from kernel object system.
130 *
131 * @param hook the hook function
132 */
aos_object_detach_sethook(void (* hook)(struct aos_object * object))133 void aos_object_detach_sethook(void (*hook)(struct aos_object *object))
134 {
135 aos_object_detach_hook = hook;
136 }
137
138 /**
139 * This function will set a hook function, which will be invoked when object
140 * is taken from kernel object system.
141 *
142 * The object is taken means:
143 * semaphore - semaphore is taken by thread
144 * mutex - mutex is taken by thread
145 * event - event is received by thread
146 * mailbox - mail is received by thread
147 * message queue - message is received by thread
148 *
149 * @param hook the hook function
150 */
aos_object_trytake_sethook(void (* hook)(struct aos_object * object))151 void aos_object_trytake_sethook(void (*hook)(struct aos_object *object))
152 {
153 aos_object_trytake_hook = hook;
154 }
155
156 /**
157 * This function will set a hook function, which will be invoked when object
158 * have been taken from kernel object system.
159 *
160 * The object have been taken means:
161 * semaphore - semaphore have been taken by thread
162 * mutex - mutex have been taken by thread
163 * event - event have been received by thread
164 * mailbox - mail have been received by thread
165 * message queue - message have been received by thread
166 * timer - timer is started
167 *
168 * @param hook the hook function
169 */
aos_object_take_sethook(void (* hook)(struct aos_object * object))170 void aos_object_take_sethook(void (*hook)(struct aos_object *object))
171 {
172 aos_object_take_hook = hook;
173 }
174
175 /**
176 * This function will set a hook function, which will be invoked when object
177 * is put to kernel object system.
178 *
179 * @param hook the hook function
180 */
aos_object_put_sethook(void (* hook)(struct aos_object * object))181 void aos_object_put_sethook(void (*hook)(struct aos_object *object))
182 {
183 aos_object_put_hook = hook;
184 }
185
186 /**@}*/
187 #endif
188
189 /**
190 * @ingroup SystemInit
191 *
192 * This function will initialize system object management.
193 *
194 * @deprecated since 0.3.0, this function does not need to be invoked
195 * in the system initialization.
196 */
aos_system_object_init(void)197 void aos_system_object_init(void)
198 {
199 }
200
201 /**
202 * @addtogroup KernelObject
203 */
204
205 /**@{*/
206
207 /**
208 * This function will return the specified type of object information.
209 *
210 * @param type the type of object
211 * @return the object type information or NULL
212 */
213 struct aos_object_information *
aos_object_get_information(enum aos_object_class_type type)214 aos_object_get_information(enum aos_object_class_type type)
215 {
216 int index;
217
218 for (index = 0; index < AOS_Object_Info_Unknown; index ++)
219 if (aos_object_container[index].type == type) return &aos_object_container[index];
220
221 return NULL;
222 }
223
224
225 /**
226 * This function will initialize an object and add it to object system
227 * management.
228 *
229 * @param object the specified object to be initialized.
230 * @param type the object type.
231 * @param name the object name. In system, the object's name must be unique.
232 */
aos_object_init(struct aos_object * object,enum aos_object_class_type type,const char * name)233 void aos_object_init(struct aos_object *object,
234 enum aos_object_class_type type,
235 const char *name)
236 {
237 struct dlist_s *node = NULL;
238 struct aos_object_information *information;
239 #ifdef AOS_USING_MODULE
240 struct aos_dlmodule *module = dlmodule_self();
241 #endif
242
243 CPSR_ALLOC();
244
245 /* get object information */
246 information = aos_object_get_information(type);
247 OBJ_ASSERT(information != NULL);
248
249 /* check object type to avoid re-initialization */
250
251 RHINO_CRITICAL_ENTER();
252
253 /* try to find object */
254 for (node = information->object_list.next;
255 node != &(information->object_list);
256 node = node->next)
257 {
258 struct aos_object *obj;
259
260 obj = dlist_entry(node, struct aos_object, list);
261 if (obj) /* skip warning when disable debug */
262 {
263 OBJ_ASSERT(obj != object);
264 }
265 }
266 /* leave critical */
267 RHINO_CRITICAL_EXIT();
268
269 /* initialize object's parameters */
270 /* set object type to static */
271 object->type = type | AOS_Object_Class_Static;
272 /* copy name */
273 strncpy(object->name, name, AOS_OBJ_NAME_MAX - 1);
274
275 #ifdef AOS_USING_HOOK
276 AOS_OBJECT_HOOK_CALL(aos_object_attach_hook, (object));
277 #endif
278
279 /* lock interrupt */
280 RHINO_CRITICAL_ENTER();
281
282 #ifdef AOS_USING_MODULE
283 if (module)
284 {
285 dlist_add_tail(&(module->object_list), &(object->list));
286 object->module_id = (void *)module;
287 }
288 else
289 #endif
290 {
291 /* insert object into information object list */
292 dlist_add_tail( &(object->list),&(information->object_list));
293 }
294
295 /* unlock interrupt */
296 RHINO_CRITICAL_EXIT();
297 }
298
299 /**
300 * This function will detach a static object from object system,
301 * and the memory of static object is not freed.
302 *
303 * @param object the specified object to be detached.
304 */
aos_object_detach(aos_object_t object)305 void aos_object_detach(aos_object_t object)
306 {
307 /* object check */
308 OBJ_ASSERT(object != NULL);
309
310 #ifdef AOS_USING_HOOK
311 AOS_OBJECT_HOOK_CALL(aos_object_detach_hook, (object));
312 #endif
313
314 CPSR_ALLOC();
315
316 /* reset object type */
317 object->type = 0;
318
319 /* enter critical */
320 RHINO_CRITICAL_ENTER();
321
322 /* remove from old list */
323 dlist_del(&(object->list));
324
325 RHINO_CRITICAL_EXIT();
326 }
327
328 /**
329 * This function will judge the object is system object or not.
330 * Normally, the system object is a static object and the type
331 * of object set to RT_Object_Class_Static.
332 *
333 * @param object the specified object to be judged.
334 *
335 * @return RT_TRUE if a system object, RT_FALSE for others.
336 */
aos_object_is_systemobject(aos_object_t object)337 bool aos_object_is_systemobject(aos_object_t object)
338 {
339 /* object check */
340 OBJ_ASSERT(object != NULL);
341
342 if (object->type & AOS_Object_Class_Static)
343 return true;
344
345 return false;
346 }
347
348 /**
349 * This function will return the type of object without
350 * RT_Object_Class_Static flag.
351 *
352 * @param object the specified object to be get type.
353 *
354 * @return the type of object.
355 */
aos_object_get_type(aos_object_t object)356 uint8_t aos_object_get_type(aos_object_t object)
357 {
358 /* object check */
359 OBJ_ASSERT(object != NULL);
360
361 return object->type & ~AOS_Object_Class_Static;
362 }
363
364 /**
365 * This function will find specified name object from object
366 * container.
367 *
368 * @param name the specified name of object.
369 * @param type the type of object
370 *
371 * @return the found object or RT_NULL if there is no this object
372 * in object container.
373 *
374 * @note this function shall not be invoked in interrupt status.
375 */
aos_object_find(const char * name,uint8_t type)376 aos_object_t aos_object_find(const char *name, uint8_t type)
377 {
378 aos_object_t object = NULL;
379 struct dlist_s *node = NULL;
380 struct aos_object_information *information = NULL;
381
382 CPSR_ALLOC();
383
384 /* parameter check */
385 if ((name == NULL) || (type > AOS_Object_Class_Unknown))
386 return NULL;
387
388 /* enter critical */
389 RHINO_CRITICAL_ENTER();
390
391 /* try to find object */
392 if (information == NULL)
393 {
394 information = aos_object_get_information((enum aos_object_class_type)type);
395 OBJ_ASSERT(information != NULL);
396 }
397 for (node = information->object_list.next;
398 node != &(information->object_list);
399 node = node->next)
400 {
401 object = dlist_entry(node, struct aos_object, list);
402 if (strncmp(object->name, name, AOS_OBJ_NAME_MAX) == 0)
403 {
404 /* leave critical */
405 RHINO_CRITICAL_EXIT();
406
407 return object;
408 }
409 }
410
411 /* leave critical */
412 RHINO_CRITICAL_EXIT();
413
414 return NULL;
415 }
416
417 /**@}*/
418