1 /*
2  * Copyright (c) 2006-2024, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2007-01-10     Bernard      the first version
9  * 2008-07-12     Bernard      remove all rt_int8, rt_uint32_t etc typedef
10  * 2010-10-26     yi.qiu       add module support
11  * 2010-11-10     Bernard      add cleanup callback function in thread exit.
12  * 2011-05-09     Bernard      use builtin va_arg in GCC 4.x
13  * 2012-11-16     Bernard      change RT_NULL from ((void*)0) to 0.
14  * 2012-12-29     Bernard      change the RT_USING_MEMPOOL location and add
15  *                             RT_USING_MEMHEAP condition.
16  * 2012-12-30     Bernard      add more control command for graphic.
17  * 2013-01-09     Bernard      change version number.
18  * 2015-02-01     Bernard      change version number to v2.1.0
19  * 2017-08-31     Bernard      change version number to v3.0.0
20  * 2017-11-30     Bernard      change version number to v3.0.1
21  * 2017-12-27     Bernard      change version number to v3.0.2
22  * 2018-02-24     Bernard      change version number to v3.0.3
23  * 2018-04-25     Bernard      change version number to v3.0.4
24  * 2018-05-31     Bernard      change version number to v3.1.0
25  * 2018-09-04     Bernard      change version number to v3.1.1
26  * 2018-09-14     Bernard      apply Apache License v2.0 to RT-Thread Kernel
27  * 2018-10-13     Bernard      change version number to v4.0.0
28  * 2018-10-02     Bernard      add 64bit arch support
29  * 2018-11-22     Jesven       add smp member to struct rt_thread
30  *                             add struct rt_cpu
31  *                             add smp relevant macros
32  * 2019-01-27     Bernard      change version number to v4.0.1
33  * 2019-05-17     Bernard      change version number to v4.0.2
34  * 2019-12-20     Bernard      change version number to v4.0.3
35  * 2020-08-10     Meco Man     add macro for struct rt_device_ops
36  * 2020-10-23     Meco Man     define maximum value of ipc type
37  * 2021-03-19     Meco Man     add security devices
38  * 2021-05-10     armink       change version number to v4.0.4
39  * 2021-11-19     Meco Man     change version number to v4.1.0
40  * 2021-12-21     Meco Man     re-implement RT_UNUSED
41  * 2022-01-01     Gabriel      improve hooking method
42  * 2022-01-07     Gabriel      move some __on_rt_xxxxx_hook to dedicated c source files
43  * 2022-01-12     Meco Man     remove RT_THREAD_BLOCK
44  * 2022-04-20     Meco Man     change version number to v4.1.1
45  * 2022-04-21     THEWON       add macro RT_VERSION_CHECK
46  * 2022-06-29     Meco Man     add RT_USING_LIBC and standard libc headers
47  * 2022-08-16     Meco Man     change version number to v5.0.0
48  * 2022-09-12     Meco Man     define rt_ssize_t
49  * 2022-12-20     Meco Man     add const name for rt_object
50  * 2023-04-01     Chushicheng  change version number to v5.0.1
51  * 2023-05-20     Bernard      add stdc atomic detection.
52  * 2023-09-15     xqyjlj       perf rt_hw_interrupt_disable/enable
53  * 2023-10-10     Chushicheng  change version number to v5.1.0
54  * 2023-10-11     zmshahaha    move specific devices related and driver to components/drivers
55  * 2023-11-21     Meco Man     add RT_USING_NANO macro
56  * 2023-11-17     xqyjlj       add process group and session support
57  * 2023-12-01     Shell        Support of dynamic device
58  * 2023-12-18     xqyjlj       add rt_always_inline
59  * 2023-12-22     Shell        Support hook list
60  * 2024-01-18     Shell        Seperate basical types to a rttypes.h
61  *                             Seperate the compiler portings to rtcompiler.h
62  * 2024-03-30     Meco Man     update version number to v5.2.0
63  */
64 
65 #ifndef __RT_DEF_H__
66 #define __RT_DEF_H__
67 
68 #include "rtsched.h"
69 #include "rttypes.h"
70 
71 #include "klibc/kerrno.h"
72 
73 #ifdef __cplusplus
74 extern "C" {
75 #endif
76 
77 /**
78  * @addtogroup group_basic_definition
79  */
80 
81 /**@{*/
82 
83 /* RT-Thread version information */
84 #define RT_VERSION_MAJOR                5               /**< Major version number (X.x.x) */
85 #define RT_VERSION_MINOR                2               /**< Minor version number (x.X.x) */
86 #define RT_VERSION_PATCH                1               /**< Patch version number (x.x.X) */
87 
88 /* e.g. #if (RTTHREAD_VERSION >= RT_VERSION_CHECK(4, 1, 0) */
89 #define RT_VERSION_CHECK(major, minor, revise)          ((major * 10000U) + (minor * 100U) + revise)
90 
91 /* RT-Thread version */
92 #define RTTHREAD_VERSION                RT_VERSION_CHECK(RT_VERSION_MAJOR, RT_VERSION_MINOR, RT_VERSION_PATCH)
93 
94 /**@}*/
95 
96 /* maximum value of base type */
97 #ifdef RT_USING_LIBC
98 #define RT_UINT8_MAX                    UINT8_MAX       /**< Maximum number of UINT8 */
99 #define RT_UINT16_MAX                   UINT16_MAX      /**< Maximum number of UINT16 */
100 #define RT_UINT32_MAX                   UINT32_MAX      /**< Maximum number of UINT32 */
101 #define RT_UINT64_MAX                   UINT64_MAX      /**< Maximum number of UINT64 */
102 #else
103 #define RT_UINT8_MAX                    0xFFU                 /**< Maximum number of UINT8 */
104 #define RT_UINT16_MAX                   0xFFFFU               /**< Maximum number of UINT16 */
105 #define RT_UINT32_MAX                   0xFFFFFFFFUL          /**< Maximum number of UINT32 */
106 #define RT_UINT64_MAX                   0xFFFFFFFFFFFFFFFFULL /**< Maximum number of UINT64 */
107 #endif /* RT_USING_LIBC */
108 
109 #define RT_TICK_MAX                     RT_UINT32_MAX   /**< Maximum number of tick */
110 
111 /* maximum value of ipc type */
112 #define RT_SEM_VALUE_MAX                RT_UINT16_MAX   /**< Maximum number of semaphore .value */
113 #define RT_MUTEX_VALUE_MAX              RT_UINT16_MAX   /**< Maximum number of mutex .value */
114 #define RT_MUTEX_HOLD_MAX               RT_UINT8_MAX    /**< Maximum number of mutex .hold */
115 #define RT_MB_ENTRY_MAX                 RT_UINT16_MAX   /**< Maximum number of mailbox .entry */
116 #define RT_MQ_ENTRY_MAX                 RT_UINT16_MAX   /**< Maximum number of message queue .entry */
117 
118 /* Common Utilities */
119 
120 #define RT_UNUSED(x)                   ((void)(x))
121 
122 /* compile time assertion */
123 #define RT_STATIC_ASSERT(name, expn) typedef char _static_assert_##name[(expn)?1:-1]
124 
125 /* Compiler Related Definitions */
126 #include "rtcompiler.h"
127 
128 /* initialization export */
129 #ifdef RT_USING_COMPONENTS_INIT
130 typedef int (*init_fn_t)(void);
131 #ifdef _MSC_VER
132 #pragma section("rti_fn$f",read)
133     #ifdef RT_DEBUGING_AUTO_INIT
134         struct rt_init_desc
135         {
136             const char* level;
137             const init_fn_t fn;
138             const char* fn_name;
139         };
140         #define INIT_EXPORT(fn, level)                                  \
141                                 const char __rti_level_##fn[] = ".rti_fn." level;       \
142                                 const char __rti_##fn##_name[] = #fn;                   \
143                                 __declspec(allocate("rti_fn$f"))                        \
144                                 rt_used const struct rt_init_desc __rt_init_msc_##fn =  \
145                                 {__rti_level_##fn, fn, __rti_##fn##_name};
146     #else
147         struct rt_init_desc
148         {
149             const char* level;
150             const init_fn_t fn;
151         };
152         #define INIT_EXPORT(fn, level)                                  \
153                                 const char __rti_level_##fn[] = ".rti_fn." level;       \
154                                 __declspec(allocate("rti_fn$f"))                        \
155                                 rt_used const struct rt_init_desc __rt_init_msc_##fn =  \
156                                 {__rti_level_##fn, fn };
157     #endif /* RT_DEBUGING_AUTO_INIT */
158 #else
159     #ifdef RT_DEBUGING_AUTO_INIT
160         struct rt_init_desc
161         {
162             const char* fn_name;
163             const init_fn_t fn;
164         };
165         #define INIT_EXPORT(fn, level)                                                       \
166             const char __rti_##fn##_name[] = #fn;                                            \
167             rt_used const struct rt_init_desc __rt_init_desc_##fn rt_section(".rti_fn." level) = \
168             { __rti_##fn##_name, fn};
169     #else
170         #define INIT_EXPORT(fn, level)                                                       \
171             rt_used const init_fn_t __rt_init_##fn rt_section(".rti_fn." level) = fn
172     #endif /* RT_DEBUGING_AUTO_INIT */
173 #endif /* _MSC_VER */
174 #else
175 #define INIT_EXPORT(fn, level)
176 #endif /* RT_USING_COMPONENTS_INIT */
177 
178 /* board init routines will be called in board_init() function */
179 #define INIT_BOARD_EXPORT(fn)           INIT_EXPORT(fn, "1")
180 
181 /* init cpu, memory, interrupt-controller, bus... */
182 #define INIT_CORE_EXPORT(fn)            INIT_EXPORT(fn, "1.0")
183 /* init sys-timer, clk, pinctrl... */
184 #define INIT_SUBSYS_EXPORT(fn)          INIT_EXPORT(fn, "1.1")
185 /* init platform, user code... */
186 #define INIT_PLATFORM_EXPORT(fn)        INIT_EXPORT(fn, "1.2")
187 
188 /* pre/device/component/env/app init routines will be called in init_thread */
189 /* components pre-initialization (pure software initialization) */
190 #define INIT_PREV_EXPORT(fn)            INIT_EXPORT(fn, "2")
191 /* device initialization */
192 #define INIT_DEVICE_EXPORT(fn)          INIT_EXPORT(fn, "3")
193 /* components initialization (dfs, lwip, ...) */
194 #define INIT_COMPONENT_EXPORT(fn)       INIT_EXPORT(fn, "4")
195 /* environment initialization (mount disk, ...) */
196 #define INIT_ENV_EXPORT(fn)             INIT_EXPORT(fn, "5")
197 /* application initialization (rtgui application etc ...) */
198 #define INIT_APP_EXPORT(fn)             INIT_EXPORT(fn, "6")
199 
200 /* init after mount fs */
201 #define INIT_FS_EXPORT(fn)              INIT_EXPORT(fn, "6.0")
202 /* init in secondary_cpu_c_start */
203 #define INIT_SECONDARY_CPU_EXPORT(fn)   INIT_EXPORT(fn, "7")
204 
205 #if !defined(RT_USING_FINSH)
206 /* define these to empty, even if not include finsh.h file */
207 #define FINSH_FUNCTION_EXPORT(name, desc)
208 #define FINSH_FUNCTION_EXPORT_ALIAS(name, alias, desc)
209 
210 #define MSH_CMD_EXPORT(command, desc)
211 #define MSH_CMD_EXPORT_ALIAS(command, alias, desc)
212 #elif !defined(FINSH_USING_SYMTAB)
213 #define FINSH_FUNCTION_EXPORT_CMD(name, cmd, desc)
214 #endif
215 
216 /* event length */
217 #define RT_EVENT_LENGTH                 32
218 
219 /* memory management option */
220 #define RT_MM_PAGE_SIZE                 4096
221 #define RT_MM_PAGE_MASK                 (RT_MM_PAGE_SIZE - 1)
222 #define RT_MM_PAGE_BITS                 12
223 
224 /* kernel malloc definitions */
225 #ifndef RT_KERNEL_MALLOC
226 #define RT_KERNEL_MALLOC(sz)            rt_malloc(sz)
227 #endif /* RT_KERNEL_MALLOC */
228 
229 #ifndef RT_KERNEL_FREE
230 #define RT_KERNEL_FREE(ptr)             rt_free(ptr)
231 #endif /* RT_KERNEL_FREE */
232 
233 #ifndef RT_KERNEL_REALLOC
234 #define RT_KERNEL_REALLOC(ptr, size)    rt_realloc(ptr, size)
235 #endif /* RT_KERNEL_REALLOC */
236 
237 /**
238  * @ingroup group_basic_definition
239  *
240  * @def RT_IS_ALIGN(addr, align)
241  * Return true(1) or false(0).
242  *     RT_IS_ALIGN(128, 4) is judging whether 128 aligns with 4.
243  *     The result is 1, which means 128 aligns with 4.
244  * @note If the address is NULL, false(0) will be returned
245  */
246 #define RT_IS_ALIGN(addr, align) ((!(addr & (align - 1))) && (addr != RT_NULL))
247 
248 /**
249  * @ingroup group_basic_definition
250  *
251  * @def RT_ALIGN(size, align)
252  * Return the most contiguous size aligned at specified width. RT_ALIGN(13, 4)
253  * would return 16.
254  * @note align Must be an integer power of 2 or the result will be incorrect
255  */
256 #define RT_ALIGN(size, align)           (((size) + (align) - 1) & ~((align) - 1))
257 
258 /**
259  * @ingroup group_basic_definition
260  *
261  * @def RT_ALIGN_DOWN(size, align)
262  * Return the down number of aligned at specified width. RT_ALIGN_DOWN(13, 4)
263  * would return 12.
264  * @note align Must be an integer power of 2 or the result will be incorrect
265  */
266 #define RT_ALIGN_DOWN(size, align)      ((size) & ~((align) - 1))
267 
268 /**
269  * @addtogroup group_object_management
270  */
271 
272 /**@{*/
273 
274 /*
275  * kernel object macros
276  */
277 #define RT_OBJECT_FLAG_MODULE           0x80            /**< is module object. */
278 
279 /**
280  * Base structure of Kernel object
281  */
282 struct rt_object
283 {
284 #if RT_NAME_MAX > 0
285     char        name[RT_NAME_MAX];                       /**< dynamic name of kernel object */
286 #else
287     const char *name;                                    /**< static name of kernel object */
288 #endif /* RT_NAME_MAX > 0 */
289     rt_uint8_t  type;                                    /**< type of kernel object */
290     rt_uint8_t  flag;                                    /**< flag of kernel object */
291 
292 #ifdef RT_USING_MODULE
293     void      * module_id;                               /**< id of application module */
294 #endif /* RT_USING_MODULE */
295 
296 #ifdef RT_USING_SMART
297     rt_atomic_t lwp_ref_count;                           /**< ref count for lwp */
298 #endif /* RT_USING_SMART */
299 
300     rt_list_t   list;                                    /**< list node of kernel object */
301 };
302 typedef struct rt_object *rt_object_t;                   /**< Type for kernel objects. */
303 
304 /**
305  * iterator of rt_object_for_each()
306  *
307  * data is the data passing in to rt_object_for_each(). iterator can return
308  * RT_EOK to continue the iteration; or any positive value to break the loop
309  * successfully; or any negative errno to break the loop on failure.
310  */
311 typedef rt_err_t (*rt_object_iter_t)(rt_object_t object, void *data);
312 
313 /**
314  *  The object type can be one of the follows with specific
315  *  macros enabled:
316  *  - Thread
317  *  - Semaphore
318  *  - Mutex
319  *  - Event
320  *  - MailBox
321  *  - MessageQueue
322  *  - MemHeap
323  *  - MemPool
324  *  - Device
325  *  - Timer
326  *  - Module
327  *  - Unknown
328  *  - Static
329  */
330 enum rt_object_class_type
331 {
332     RT_Object_Class_Null          = 0x00,      /**< The object is not used. */
333     RT_Object_Class_Thread        = 0x01,      /**< The object is a thread. */
334     RT_Object_Class_Semaphore     = 0x02,      /**< The object is a semaphore. */
335     RT_Object_Class_Mutex         = 0x03,      /**< The object is a mutex. */
336     RT_Object_Class_Event         = 0x04,      /**< The object is a event. */
337     RT_Object_Class_MailBox       = 0x05,      /**< The object is a mail box. */
338     RT_Object_Class_MessageQueue  = 0x06,      /**< The object is a message queue. */
339     RT_Object_Class_MemHeap       = 0x07,      /**< The object is a memory heap. */
340     RT_Object_Class_MemPool       = 0x08,      /**< The object is a memory pool. */
341     RT_Object_Class_Device        = 0x09,      /**< The object is a device. */
342     RT_Object_Class_Timer         = 0x0a,      /**< The object is a timer. */
343     RT_Object_Class_Module        = 0x0b,      /**< The object is a module. */
344     RT_Object_Class_Memory        = 0x0c,      /**< The object is a memory. */
345     RT_Object_Class_Channel       = 0x0d,      /**< The object is a channel */
346     RT_Object_Class_ProcessGroup  = 0x0e,      /**< The object is a process group */
347     RT_Object_Class_Session       = 0x0f,      /**< The object is a session */
348     RT_Object_Class_Custom        = 0x10,      /**< The object is a custom object */
349     RT_Object_Class_Unknown       = 0x11,      /**< The object is unknown. */
350     RT_Object_Class_Static        = 0x80       /**< The object is a static object. */
351 };
352 
353 /**
354  * The information of the kernel object
355  */
356 struct rt_object_information
357 {
358     enum rt_object_class_type type;                     /**< object class type */
359     rt_list_t                 object_list;              /**< object list */
360     rt_size_t                 object_size;              /**< object size */
361     struct rt_spinlock        spinlock;
362 };
363 
364 /**
365  * The hook function call macro
366  */
367 #ifndef RT_USING_HOOK
368 #define RT_OBJECT_HOOK_CALL(func, argv)
369 
370 #else
371 
372 /**
373  * @brief Add hook point in the routines
374  * @note Usage:
375  * void foo() {
376  *     do_something();
377  *
378  *     RT_OBJECT_HOOK_CALL(foo);
379  *
380  *     do_other_things();
381  * }
382  */
383 #define _RT_OBJECT_HOOK_CALL(func, argv) __ON_HOOK_ARGS(func, argv)
384 #define RT_OBJECT_HOOK_CALL(func, argv)  _RT_OBJECT_HOOK_CALL(func, argv)
385 
386     #ifdef RT_HOOK_USING_FUNC_PTR
387         #define __ON_HOOK_ARGS(__hook, argv)        do {if ((__hook) != RT_NULL) __hook argv; } while (0)
388     #else
389         #define __ON_HOOK_ARGS(__hook, argv)
390     #endif /* RT_HOOK_USING_FUNC_PTR */
391 #endif /* RT_USING_HOOK */
392 
393 #ifdef RT_USING_HOOKLIST
394 
395 /**
396  * @brief Add declaration for hook list types.
397  *
398  * @note Usage:
399  * This is typically used in your header. In foo.h using this like:
400  *
401  * ```foo.h
402  *     typedef void (*bar_hook_proto_t)(arguments...);
403  *     RT_OBJECT_HOOKLIST_DECLARE(bar_hook_proto_t, bar_myhook);
404  * ```
405  */
406 #define RT_OBJECT_HOOKLIST_DECLARE(handler_type, name) \
407     typedef struct name##_hooklistnode                 \
408     {                                                  \
409         handler_type handler;                          \
410         rt_list_t list_node;                           \
411     } *name##_hooklistnode_t;                          \
412     extern volatile rt_ubase_t name##_nested;          \
413     void name##_sethook(name##_hooklistnode_t node);   \
414     void name##_rmhook(name##_hooklistnode_t node)
415 
416 /**
417  * @brief Add declaration for hook list node.
418  *
419  * @note Usage
420  * You can add a hook like this.
421  *
422  * ```addhook.c
423  * void myhook(arguments...) { do_something(); }
424  * RT_OBJECT_HOOKLIST_DEFINE_NODE(bar_myhook, myhook_node, myhook);
425  *
426  * void addhook(void)
427  * {
428  *      bar_myhook_sethook(myhook);
429  * }
430  * ```
431  *
432  * BTW, you can also find examples codes under
433  * `examples/utest/testcases/kernel/hooklist_tc.c`.
434  */
435 #define RT_OBJECT_HOOKLIST_DEFINE_NODE(hookname, nodename, hooker_handler) \
436     struct hookname##_hooklistnode nodename = {                            \
437         .handler = hooker_handler,                                         \
438         .list_node = RT_LIST_OBJECT_INIT(nodename.list_node),              \
439     };
440 
441 /**
442  * @note Usage
443  * Add this macro to the source file where your hook point is inserted.
444  */
445 #define RT_OBJECT_HOOKLIST_DEFINE(name)                                      \
446     static rt_list_t name##_hooklist = RT_LIST_OBJECT_INIT(name##_hooklist); \
447     static struct rt_spinlock name##lock = RT_SPINLOCK_INIT;                 \
448     volatile rt_ubase_t name##_nested = 0;                                   \
449     void name##_sethook(name##_hooklistnode_t node)                          \
450     {                                                                        \
451         rt_ubase_t level = rt_spin_lock_irqsave(&name##lock);                \
452         while (name##_nested)                                                \
453         {                                                                    \
454             rt_spin_unlock_irqrestore(&name##lock, level);                   \
455             level = rt_spin_lock_irqsave(&name##lock);                       \
456         }                                                                    \
457         rt_list_insert_before(&name##_hooklist, &node->list_node);           \
458         rt_spin_unlock_irqrestore(&name##lock, level);                       \
459     }                                                                        \
460     void name##_rmhook(name##_hooklistnode_t node)                           \
461     {                                                                        \
462         rt_ubase_t level = rt_spin_lock_irqsave(&name##lock);                \
463         while (name##_nested)                                                \
464         {                                                                    \
465             rt_spin_unlock_irqrestore(&name##lock, level);                   \
466             level = rt_spin_lock_irqsave(&name##lock);                       \
467         }                                                                    \
468         rt_list_remove(&node->list_node);                                    \
469         rt_spin_unlock_irqrestore(&name##lock, level);                       \
470     }
471 
472 /**
473  * @brief Add hook list point in the routines. Multiple hookers in the list will
474  *        be called one by one starting from head node.
475  *
476  * @note Usage:
477  * void foo() {
478  *     do_something();
479  *
480  *     RT_OBJECT_HOOKLIST_CALL(foo);
481  *
482  *     do_other_things();
483  * }
484  */
485 #define _RT_OBJECT_HOOKLIST_CALL(nodetype, nested, list, lock, argv)  \
486     do                                                                \
487     {                                                                 \
488         nodetype iter, next;                                          \
489         rt_ubase_t level = rt_spin_lock_irqsave(&lock);               \
490         nested += 1;                                                  \
491         rt_spin_unlock_irqrestore(&lock, level);                      \
492         if (!rt_list_isempty(&list))                                  \
493         {                                                             \
494             rt_list_for_each_entry_safe(iter, next, &list, list_node) \
495             {                                                         \
496                 iter->handler argv;                                   \
497             }                                                         \
498         }                                                             \
499         level = rt_spin_lock_irqsave(&lock);                          \
500         nested -= 1;                                                  \
501         rt_spin_unlock_irqrestore(&lock, level);                      \
502     } while (0)
503 #define RT_OBJECT_HOOKLIST_CALL(name, argv)                        \
504     _RT_OBJECT_HOOKLIST_CALL(name##_hooklistnode_t, name##_nested, \
505                              name##_hooklist, name##lock, argv)
506 
507 #else
508 
509 #define RT_OBJECT_HOOKLIST_DECLARE(handler_type, name)
510 #define RT_OBJECT_HOOKLIST_DEFINE_NODE(hookname, nodename, hooker_handler)
511 #define RT_OBJECT_HOOKLIST_DEFINE(name)
512 #define RT_OBJECT_HOOKLIST_CALL(name, argv)
513 #endif /* RT_USING_HOOKLIST */
514 
515 /**@}*/
516 
517 /**
518  * @addtogroup group_clock_management
519  */
520 
521 /**@{*/
522 
523 /**
524  * clock & timer macros
525  */
526 #define RT_TIMER_FLAG_DEACTIVATED       0x0             /**< timer is deactive */
527 #define RT_TIMER_FLAG_ACTIVATED         0x1             /**< timer is active */
528 #define RT_TIMER_FLAG_ONE_SHOT          0x0             /**< one shot timer */
529 #define RT_TIMER_FLAG_PERIODIC          0x2             /**< periodic timer */
530 
531 #define RT_TIMER_FLAG_HARD_TIMER        0x0             /**< hard timer,the timer's callback function will be called in tick isr. */
532 #define RT_TIMER_FLAG_SOFT_TIMER        0x4             /**< soft timer,the timer's callback function will be called in timer thread. */
533 #define RT_TIMER_FLAG_THREAD_TIMER \
534     (0x8 | RT_TIMER_FLAG_HARD_TIMER)                    /**< thread timer that cooperates with scheduler directly */
535 
536 #define RT_TIMER_CTRL_SET_TIME          0x0             /**< set timer control command */
537 #define RT_TIMER_CTRL_GET_TIME          0x1             /**< get timer control command */
538 #define RT_TIMER_CTRL_SET_ONESHOT       0x2             /**< change timer to one shot */
539 #define RT_TIMER_CTRL_SET_PERIODIC      0x3             /**< change timer to periodic */
540 #define RT_TIMER_CTRL_GET_STATE         0x4             /**< get timer run state active or deactive*/
541 #define RT_TIMER_CTRL_GET_REMAIN_TIME   0x5             /**< get the remaining hang time */
542 #define RT_TIMER_CTRL_GET_FUNC          0x6             /**< get timer timeout func  */
543 #define RT_TIMER_CTRL_SET_FUNC          0x7             /**< set timer timeout func  */
544 #define RT_TIMER_CTRL_GET_PARM          0x8             /**< get timer parameter  */
545 #define RT_TIMER_CTRL_SET_PARM          0x9             /**< set timer parameter  */
546 
547 #ifndef RT_TIMER_SKIP_LIST_LEVEL
548 #define RT_TIMER_SKIP_LIST_LEVEL          1
549 #endif
550 
551 /* 1 or 3 */
552 #ifndef RT_TIMER_SKIP_LIST_MASK
553 #define RT_TIMER_SKIP_LIST_MASK         0x3             /**< Timer skips the list mask */
554 #endif
555 
556 /**
557  * timeout handler of rt_timer
558  */
559 typedef void (*rt_timer_func_t)(void *parameter);
560 
561 /**
562  * timer structure
563  */
564 struct rt_timer
565 {
566     struct rt_object parent;                            /**< inherit from rt_object */
567 
568     rt_list_t        row[RT_TIMER_SKIP_LIST_LEVEL];
569 
570     rt_timer_func_t  timeout_func;                      /**< timeout function */
571     void             *parameter;                        /**< timeout function's parameter */
572 
573     rt_tick_t        init_tick;                         /**< timer timeout tick */
574     rt_tick_t        timeout_tick;                      /**< timeout tick */
575 };
576 typedef struct rt_timer *rt_timer_t;
577 
578 /**@}*/
579 
580 /**
581  * @addtogroup group_signal
582  */
583 /**@{*/
584 
585 #ifdef RT_USING_SIGNALS
586 #define RT_SIG_MAX          32
587 typedef unsigned long rt_sigset_t;
588 typedef siginfo_t rt_siginfo_t;
589 typedef void (*rt_sighandler_t)(int signo);
590 #endif /* RT_USING_SIGNALS */
591 /**@}*/
592 
593 /**
594  * @addtogroup group_thread_management
595  */
596 
597 /**@{*/
598 
599 /*
600  * Thread
601  */
602 
603 /*
604  * thread state definitions
605  */
606 #define RT_THREAD_INIT                       0x00                /**< Initialized status */
607 #define RT_THREAD_CLOSE                      0x01                /**< Closed status */
608 #define RT_THREAD_READY                      0x02                /**< Ready status */
609 #define RT_THREAD_RUNNING                    0x03                /**< Running status */
610 
611 /*
612  * for rt_thread_suspend_with_flag()
613  */
614 enum
615 {
616     RT_INTERRUPTIBLE = 0,
617     RT_KILLABLE,
618     RT_UNINTERRUPTIBLE,
619 };
620 
621 #define RT_THREAD_SUSPEND_MASK               0x04
622 #define RT_SIGNAL_COMMON_WAKEUP_MASK         0x02
623 #define RT_SIGNAL_KILL_WAKEUP_MASK           0x01
624 
625 #define RT_THREAD_SUSPEND_INTERRUPTIBLE      (RT_THREAD_SUSPEND_MASK)                                                             /**< Suspend interruptable 0x4 */
626 #define RT_THREAD_SUSPEND                    RT_THREAD_SUSPEND_INTERRUPTIBLE
627 #define RT_THREAD_SUSPEND_KILLABLE           (RT_THREAD_SUSPEND_MASK | RT_SIGNAL_COMMON_WAKEUP_MASK)                              /**< Suspend with killable 0x6 */
628 #define RT_THREAD_SUSPEND_UNINTERRUPTIBLE    (RT_THREAD_SUSPEND_MASK | RT_SIGNAL_COMMON_WAKEUP_MASK | RT_SIGNAL_KILL_WAKEUP_MASK) /**< Suspend with uninterruptable 0x7 */
629 #define RT_THREAD_STAT_MASK                  0x07
630 
631 #define RT_THREAD_STAT_YIELD            0x08                /**< indicate whether remaining_tick has been reloaded since last schedule */
632 #define RT_THREAD_STAT_YIELD_MASK       RT_THREAD_STAT_YIELD
633 
634 #define RT_THREAD_STAT_SIGNAL           0x10                /**< task hold signals */
635 #define RT_THREAD_STAT_SIGNAL_READY     (RT_THREAD_STAT_SIGNAL | RT_THREAD_READY)
636 #define RT_THREAD_STAT_SIGNAL_WAIT      0x20                /**< task is waiting for signals */
637 #define RT_THREAD_STAT_SIGNAL_PENDING   0x40                /**< signals is held and it has not been procressed */
638 #define RT_THREAD_STAT_SIGNAL_MASK      0xf0
639 
640 /**
641  * thread control command definitions
642  */
643 #define RT_THREAD_CTRL_STARTUP          0x00                /**< Startup thread. */
644 #define RT_THREAD_CTRL_CLOSE            0x01                /**< Close thread. */
645 #define RT_THREAD_CTRL_CHANGE_PRIORITY  0x02                /**< Change thread priority. */
646 #define RT_THREAD_CTRL_INFO             0x03                /**< Get thread information. */
647 #define RT_THREAD_CTRL_BIND_CPU         0x04                /**< Set thread bind cpu. */
648 #define RT_THREAD_CTRL_RESET_PRIORITY   0x05                /**< Reset thread priority. */
649 
650 /**
651  * CPU usage statistics data
652  */
653 struct rt_cpu_usage_stats
654 {
655     rt_ubase_t user;
656     rt_ubase_t system;
657     rt_ubase_t irq;
658     rt_ubase_t idle;
659 };
660 typedef struct rt_cpu_usage_stats *rt_cpu_usage_stats_t;
661 
662 #ifdef RT_USING_SMP
663 
664 #define RT_CPU_DETACHED                 RT_CPUS_NR          /**< The thread not running on cpu. */
665 #define RT_CPU_MASK                     ((1 << RT_CPUS_NR) - 1) /**< All CPUs mask bit. */
666 
667 #ifndef RT_SCHEDULE_IPI
668 #define RT_SCHEDULE_IPI                 0
669 #endif /* RT_SCHEDULE_IPI */
670 
671 #ifndef RT_STOP_IPI
672 #define RT_STOP_IPI                     1
673 #endif /* RT_STOP_IPI */
674 
675 #ifndef RT_SMP_CALL_IPI
676 #define RT_SMP_CALL_IPI                 2
677 #endif
678 
679 #define RT_MAX_IPI                      3
680 
681 #define _SCHEDULER_CONTEXT(fileds) fileds
682 
683 /**
684  * CPUs definitions
685  *
686  */
687 struct rt_cpu
688 {
689     /**
690      * protected by:
691      *   - other cores: accessing from other coress is undefined behaviour
692      *   - local core: rt_enter_critical()/rt_exit_critical()
693      */
694     _SCHEDULER_CONTEXT(
695         struct rt_thread        *current_thread;
696 
697         rt_uint8_t              irq_switch_flag:1;
698         rt_uint8_t              sched_lock_flag:1;
699 #ifndef ARCH_USING_HW_THREAD_SELF
700         rt_uint8_t              critical_switch_flag:1;
701 #endif /* ARCH_USING_HW_THREAD_SELF */
702 
703         rt_uint8_t              current_priority;
704         rt_list_t               priority_table[RT_THREAD_PRIORITY_MAX];
705     #if RT_THREAD_PRIORITY_MAX > 32
706         rt_uint32_t             priority_group;
707         rt_uint8_t              ready_table[32];
708     #else
709         rt_uint32_t             priority_group;
710     #endif /* RT_THREAD_PRIORITY_MAX > 32 */
711 
712         rt_atomic_t             tick;   /**< Passing tickes on this core */
713     );
714 
715     struct rt_thread            *idle_thread;
716     rt_atomic_t                 irq_nest;
717 
718 #ifdef RT_USING_SMART
719     struct rt_spinlock          spinlock;
720 #endif /* RT_USING_SMART */
721 #ifdef RT_USING_CPU_USAGE_TRACER
722     struct rt_cpu_usage_stats   cpu_stat;
723 #endif /* RT_USING_CPU_USAGE_TRACER */
724 #ifdef ARCH_USING_IRQ_CTX_LIST
725     rt_slist_t                  irq_ctx_head;
726 #endif /* ARCH_USING_IRQ_CTX_LIST */
727 };
728 
729 #else /* !RT_USING_SMP */
730 struct rt_cpu
731 {
732     struct rt_thread            *current_thread;
733     struct rt_thread            *idle_thread;
734 
735 #ifdef RT_USING_CPU_USAGE_TRACER
736     struct rt_cpu_usage_stats   cpu_stat;
737 #endif /* RT_USING_CPU_USAGE_TRACER */
738 #ifdef ARCH_USING_IRQ_CTX_LIST
739     rt_slist_t                  irq_ctx_head;
740 #endif /* ARCH_USING_IRQ_CTX_LIST */
741 };
742 
743 #endif /* RT_USING_SMP */
744 
745 typedef struct rt_cpu *rt_cpu_t;
746 /* Noted: As API to reject writing to this variable from application codes */
747 #define rt_current_thread rt_thread_self()
748 
749 struct rt_thread;
750 
751 /**
752  * interrupt/exception frame handling
753  *
754  */
755 
756 typedef struct rt_interrupt_context {
757     void *context;      /**< arch specific context */
758     rt_slist_t node;    /**< node for nested interrupt */
759 } *rt_interrupt_context_t;
760 
761 #ifdef RT_USING_SMART
762 typedef rt_err_t (*rt_wakeup_func_t)(void *object, struct rt_thread *thread);
763 
764 struct rt_wakeup
765 {
766     rt_wakeup_func_t func;
767     void *user_data;
768 };
769 
770 #define _LWP_NSIG       64
771 
772 #ifdef ARCH_CPU_64BIT
773 #define _LWP_NSIG_BPW   64
774 #else
775 #define _LWP_NSIG_BPW   32
776 #endif
777 
778 #define _LWP_NSIG_WORDS (RT_ALIGN(_LWP_NSIG, _LWP_NSIG_BPW) / _LWP_NSIG_BPW)
779 
780 typedef void (*lwp_sighandler_t)(int);
781 typedef void (*lwp_sigaction_t)(int signo, siginfo_t *info, void *context);
782 
783 typedef struct {
784     unsigned long sig[_LWP_NSIG_WORDS];
785 } lwp_sigset_t;
786 
787 #if _LWP_NSIG <= 64
788 #define lwp_sigmask(signo)      ((lwp_sigset_t){.sig = {[0] = ((long)(1u << ((signo)-1)))}})
789 #define lwp_sigset_init(mask)   ((lwp_sigset_t){.sig = {[0] = (long)(mask)}})
790 #endif /* _LWP_NSIG <= 64 */
791 
792 struct lwp_sigaction {
793     union {
794         void (*_sa_handler)(int);
795         void (*_sa_sigaction)(int, siginfo_t *, void *);
796     } __sa_handler;
797     lwp_sigset_t sa_mask;
798     int sa_flags;
799     void (*sa_restorer)(void);
800 };
801 
802 typedef struct lwp_siginfo_ext {
803     union {
804         /* for SIGCHLD */
805         struct {
806             int status;
807             clock_t utime;
808             clock_t stime;
809         } sigchld;
810     };
811 } *lwp_siginfo_ext_t;
812 
813 typedef struct lwp_siginfo {
814     rt_list_t node;
815 
816     struct {
817         int signo;
818         int code;
819 
820         int from_tid;
821         pid_t from_pid;
822     } ksiginfo;
823 
824     /* the signal specified extension field */
825     struct lwp_siginfo_ext *ext;
826 } *lwp_siginfo_t;
827 
828 typedef struct lwp_sigqueue {
829     rt_list_t siginfo_list;
830     lwp_sigset_t sigset_pending;
831 } *lwp_sigqueue_t;
832 
833 struct lwp_thread_signal {
834     lwp_sigset_t sigset_mask;
835     struct lwp_sigqueue sig_queue;
836 };
837 
838 struct rt_user_context
839 {
840     void *sp;
841     void *pc;
842     void *flag;
843 
844     void *ctx;
845 };
846 #endif /* RT_USING_SMART */
847 
848 typedef void (*rt_thread_cleanup_t)(struct rt_thread *tid);
849 
850 /**
851  * Thread structure
852  */
853 
854 struct rt_thread
855 {
856     struct rt_object            parent;
857 
858     /* stack point and entry */
859     void                        *sp;                    /**< stack point */
860     void                        *entry;                 /**< entry */
861     void                        *parameter;             /**< parameter */
862     void                        *stack_addr;            /**< stack address */
863     rt_uint32_t                 stack_size;             /**< stack size */
864 
865     /* error code */
866     rt_err_t                    error;                  /**< error code */
867 
868 #ifdef RT_USING_SMP
869     rt_atomic_t                 cpus_lock_nest;         /**< cpus lock count */
870 #endif
871 
872     RT_SCHED_THREAD_CTX
873     struct rt_timer             thread_timer;           /**< built-in thread timer */
874     rt_thread_cleanup_t         cleanup;                /**< cleanup function when thread exit */
875 
876 #ifdef RT_USING_MUTEX
877     /* object for IPC */
878     rt_list_t                   taken_object_list;
879     rt_object_t                 pending_object;
880 #endif /* RT_USING_MUTEX */
881 
882 #ifdef RT_USING_EVENT
883     /* thread event */
884     rt_uint32_t                 event_set;
885     rt_uint8_t                  event_info;
886 #endif /* RT_USING_EVENT */
887 
888 #ifdef RT_USING_SIGNALS
889     rt_sigset_t                 sig_pending;            /**< the pending signals */
890     rt_sigset_t                 sig_mask;               /**< the mask bits of signal */
891 
892 #ifndef RT_USING_SMP
893     void                        *sig_ret;               /**< the return stack pointer from signal */
894 #endif /* RT_USING_SMP */
895     rt_sighandler_t             *sig_vectors;           /**< vectors of signal handler */
896     void                        *si_list;               /**< the signal infor list */
897 #endif /* RT_USING_SIGNALS */
898 
899 #ifdef RT_USING_CPU_USAGE
900     rt_uint64_t                 duration_tick;          /**< cpu usage tick */
901 #endif /* RT_USING_CPU_USAGE */
902 
903 #ifdef RT_USING_PTHREADS
904     void                        *pthread_data;          /**< the handle of pthread data, adapt 32/64bit */
905 #endif /* RT_USING_PTHREADS */
906 
907     /* light weight process if present */
908 #ifdef RT_USING_SMART
909     void                        *msg_ret;               /**< the return msg */
910 
911     void                        *lwp;                   /**< the lwp reference */
912     /* for user create */
913     void                        *user_entry;
914     void                        *user_stack;
915     rt_uint32_t                 user_stack_size;
916     rt_uint32_t                 *kernel_sp;             /**< kernel stack point */
917     rt_list_t                   sibling;                /**< next thread of same process */
918 
919     struct lwp_thread_signal    signal;                 /**< lwp signal for user-space thread */
920     struct rt_user_context      user_ctx;               /**< user space context */
921     struct rt_wakeup            wakeup_handle;          /**< wakeup handle for IPC */
922     rt_atomic_t                 exit_request;           /**< pending exit request of thread */
923     int                         tid;                    /**< thread ID used by process */
924     int                         tid_ref_count;          /**< reference of tid */
925     void                        *susp_recycler;         /**< suspended recycler on this thread */
926     void                        *robust_list;           /**< pi lock, very carefully, it's a userspace list!*/
927 
928 #ifndef ARCH_MM_MMU
929     lwp_sighandler_t            signal_handler[32];
930 #else
931     int                         step_exec;
932     int                         debug_attach_req;
933     int                         debug_ret_user;
934     int                         debug_suspend;
935     struct rt_hw_exp_stack      *regs;
936     void                        *thread_idr;            /** lwp thread indicator */
937     int                         *clear_child_tid;
938 #endif /* ARCH_MM_MMU */
939 #endif /* RT_USING_SMART */
940 
941 #ifdef RT_USING_CPU_USAGE_TRACER
942     rt_ubase_t                  user_time;              /**< Ticks on user */
943     rt_ubase_t                  system_time;            /**< Ticks on system */
944 #endif /* RT_USING_CPU_USAGE_TRACER */
945 
946 #ifdef RT_USING_MEM_PROTECTION
947     void *mem_regions;
948 #ifdef RT_USING_HW_STACK_GUARD
949     void *stack_buf;
950 #endif /* RT_USING_HW_STACK_GUARD */
951 #endif /* RT_USING_MEM_PROTECTION */
952 
953     struct rt_spinlock          spinlock;
954     rt_ubase_t                  user_data;              /**< private user data beyond this thread */
955 };
956 typedef struct rt_thread *rt_thread_t;
957 
958 #ifdef RT_USING_SMART
959 #define LWP_IS_USER_MODE(t) ((t)->user_ctx.ctx == RT_NULL)
960 #else
961 #define LWP_IS_USER_MODE(t) (0)
962 #endif /* RT_USING_SMART */
963 
964 /**@}*/
965 
966 /**
967  * @addtogroup group_thread_comm
968  */
969 
970 /**@{*/
971 
972 /**
973  * IPC flags and control command definitions
974  */
975 #define RT_IPC_FLAG_FIFO                0x00            /**< FIFOed IPC. @ref group_thread_comm. */
976 #define RT_IPC_FLAG_PRIO                0x01            /**< PRIOed IPC. @ref group_thread_comm. */
977 
978 #define RT_IPC_CMD_UNKNOWN              0x00            /**< unknown IPC command */
979 #define RT_IPC_CMD_RESET                0x01            /**< reset IPC object */
980 #define RT_IPC_CMD_GET_STATE            0x02            /**< get the state of IPC object */
981 #define RT_IPC_CMD_SET_VLIMIT           0x03            /**< set max limit value of IPC value */
982 
983 #define RT_WAITING_FOREVER              -1              /**< Block forever until get resource. */
984 #define RT_WAITING_NO                   0               /**< Non-block. */
985 
986 /**
987  * Base structure of IPC object
988  */
989 struct rt_ipc_object
990 {
991     struct rt_object parent;                            /**< inherit from rt_object */
992 
993     rt_list_t suspend_thread;                 /**< threads pended on this resource */
994 };
995 
996 /**
997  * @addtogroup group_semaphore Semaphore
998  * @{
999  */
1000 
1001 #ifdef RT_USING_SEMAPHORE
1002 /**
1003  * Semaphore structure
1004  */
1005 struct rt_semaphore
1006 {
1007     struct rt_ipc_object parent;                        /**< inherit from ipc_object */
1008 
1009     rt_uint16_t          value;                         /**< value of semaphore. */
1010     rt_uint16_t          max_value;
1011     struct rt_spinlock   spinlock;
1012 };
1013 typedef struct rt_semaphore *rt_sem_t;
1014 #endif /* RT_USING_SEMAPHORE */
1015 
1016 /**@}*/
1017 
1018 /**
1019  * @addtogroup group_mutex Mutex
1020  * @{
1021  */
1022 
1023 #ifdef RT_USING_MUTEX
1024 /**
1025  * Mutual exclusion (mutex) structure
1026  */
1027 struct rt_mutex
1028 {
1029     struct rt_ipc_object parent;                        /**< inherit from ipc_object */
1030 
1031     rt_uint8_t           ceiling_priority;              /**< the priority ceiling of mutexe */
1032     rt_uint8_t           priority;                      /**< the maximal priority for pending thread */
1033     rt_uint8_t           hold;                          /**< numbers of thread hold the mutex */
1034     rt_uint8_t           reserved;                      /**< reserved field */
1035 
1036     struct rt_thread    *owner;                         /**< current owner of mutex */
1037     rt_list_t            taken_list;                    /**< the object list taken by thread */
1038     struct rt_spinlock   spinlock;
1039 };
1040 typedef struct rt_mutex *rt_mutex_t;
1041 #endif /* RT_USING_MUTEX */
1042 
1043 /**@}*/
1044 
1045 /**
1046  * @addtogroup group_event Event
1047  * @{
1048  */
1049 
1050 #ifdef RT_USING_EVENT
1051 /**
1052  * flag definitions in event
1053  */
1054 #define RT_EVENT_FLAG_AND               0x01            /**< logic and */
1055 #define RT_EVENT_FLAG_OR                0x02            /**< logic or */
1056 #define RT_EVENT_FLAG_CLEAR             0x04            /**< clear flag */
1057 
1058 /*
1059  * event structure
1060  */
1061 struct rt_event
1062 {
1063     struct rt_ipc_object parent;                        /**< inherit from ipc_object */
1064 
1065     rt_uint32_t          set;                           /**< event set */
1066     struct rt_spinlock   spinlock;
1067 };
1068 typedef struct rt_event *rt_event_t;
1069 #endif /* RT_USING_EVENT */
1070 
1071 /**@}*/
1072 
1073 /**
1074  * @addtogroup group_mailbox MailBox
1075  * @{
1076  */
1077 
1078 #ifdef RT_USING_MAILBOX
1079 /**
1080  * mailbox structure
1081  */
1082 struct rt_mailbox
1083 {
1084     struct rt_ipc_object parent;                        /**< inherit from ipc_object */
1085 
1086     rt_ubase_t          *msg_pool;                      /**< start address of message buffer */
1087 
1088     rt_uint16_t          size;                          /**< size of message pool */
1089 
1090     rt_uint16_t          entry;                         /**< index of messages in msg_pool */
1091     rt_uint16_t          in_offset;                     /**< input offset of the message buffer */
1092     rt_uint16_t          out_offset;                    /**< output offset of the message buffer */
1093 
1094     rt_list_t            suspend_sender_thread;         /**< sender thread suspended on this mailbox */
1095     struct rt_spinlock   spinlock;
1096 };
1097 typedef struct rt_mailbox *rt_mailbox_t;
1098 #endif /* RT_USING_MAILBOX */
1099 
1100 /**@}*/
1101 
1102 /**
1103  * @addtogroup group_messagequeue Message Queue
1104  * @{
1105  */
1106 
1107 #ifdef RT_USING_MESSAGEQUEUE
1108 /**
1109  * message queue structure
1110  */
1111 struct rt_messagequeue
1112 {
1113     struct rt_ipc_object parent;                        /**< inherit from ipc_object */
1114 
1115     void                *msg_pool;                      /**< start address of message queue */
1116 
1117     rt_uint16_t          msg_size;                      /**< message size of each message */
1118     rt_uint16_t          max_msgs;                      /**< max number of messages */
1119 
1120     rt_uint16_t          entry;                         /**< index of messages in the queue */
1121 
1122     void                *msg_queue_head;                /**< list head */
1123     void                *msg_queue_tail;                /**< list tail */
1124     void                *msg_queue_free;                /**< pointer indicated the free node of queue */
1125 
1126     rt_list_t            suspend_sender_thread;         /**< sender thread suspended on this message queue */
1127     struct rt_spinlock   spinlock;
1128 };
1129 typedef struct rt_messagequeue *rt_mq_t;
1130 #endif /* RT_USING_MESSAGEQUEUE */
1131 
1132 /**@}*/
1133 
1134 /**@}*/
1135 
1136 /**
1137  * @addtogroup group_memory_management
1138  */
1139 
1140 /**@{*/
1141 
1142 #ifdef RT_USING_HEAP
1143 /*
1144  * memory structure
1145  */
1146 struct rt_memory
1147 {
1148     struct rt_object        parent;                 /**< inherit from rt_object */
1149     const char *            algorithm;              /**< Memory management algorithm name */
1150     rt_ubase_t              address;                /**< memory start address */
1151     rt_size_t               total;                  /**< memory size */
1152     rt_size_t               used;                   /**< size used */
1153     rt_size_t               max;                    /**< maximum usage */
1154 };
1155 typedef struct rt_memory *rt_mem_t;
1156 #endif /* RT_USING_HEAP */
1157 
1158 /*
1159  * memory management
1160  * heap & partition
1161  */
1162 
1163 #ifdef RT_USING_SMALL_MEM
1164 typedef rt_mem_t rt_smem_t;
1165 #endif /* RT_USING_SMALL_MEM */
1166 
1167 #ifdef RT_USING_SLAB
1168 typedef rt_mem_t rt_slab_t;
1169 #endif /* RT_USING_SLAB */
1170 
1171 #ifdef RT_USING_MEMHEAP
1172 /**
1173  * memory item on the heap
1174  */
1175 struct rt_memheap_item
1176 {
1177     rt_uint32_t             magic;                      /**< magic number for memheap */
1178     struct rt_memheap      *pool_ptr;                   /**< point of pool */
1179 
1180     struct rt_memheap_item *next;                       /**< next memheap item */
1181     struct rt_memheap_item *prev;                       /**< prev memheap item */
1182 
1183     struct rt_memheap_item *next_free;                  /**< next free memheap item */
1184     struct rt_memheap_item *prev_free;                  /**< prev free memheap item */
1185 #ifdef RT_USING_MEMTRACE
1186     rt_uint8_t              owner_thread_name[4];       /**< owner thread name */
1187 #endif /* RT_USING_MEMTRACE */
1188 };
1189 
1190 /**
1191  * Base structure of memory heap object
1192  */
1193 struct rt_memheap
1194 {
1195     struct rt_object        parent;                     /**< inherit from rt_object */
1196 
1197     void                   *start_addr;                 /**< pool start address and size */
1198 
1199     rt_size_t               pool_size;                  /**< pool size */
1200     rt_size_t               available_size;             /**< available size */
1201     rt_size_t               max_used_size;              /**< maximum allocated size */
1202 
1203     struct rt_memheap_item *block_list;                 /**< used block list */
1204 
1205     struct rt_memheap_item *free_list;                  /**< free block list */
1206     struct rt_memheap_item  free_header;                /**< free block list header */
1207 
1208     struct rt_semaphore     lock;                       /**< semaphore lock */
1209     rt_bool_t               locked;                     /**< External lock mark */
1210 };
1211 #endif /* RT_USING_MEMHEAP */
1212 
1213 #ifdef RT_USING_MEMPOOL
1214 /**
1215  * Base structure of Memory pool object
1216  */
1217 struct rt_mempool
1218 {
1219     struct rt_object    parent;                            /**< inherit from rt_object */
1220 
1221     void                *start_address;                     /**< memory pool start */
1222     rt_size_t           size;                              /**< size of memory pool */
1223 
1224     rt_size_t           block_size;                        /**< size of memory blocks */
1225     rt_uint8_t          *block_list;                        /**< memory blocks list */
1226 
1227     rt_size_t           block_total_count;                 /**< numbers of memory block */
1228     rt_size_t           block_free_count;                  /**< numbers of free memory block */
1229 
1230     rt_list_t           suspend_thread;                    /**< threads pended on this resource */
1231     struct rt_spinlock  spinlock;
1232 };
1233 typedef struct rt_mempool *rt_mp_t;
1234 #endif /* RT_USING_MEMPOOL */
1235 
1236 /**@}*/
1237 
1238 #ifdef RT_USING_DEVICE
1239 /**
1240  * @addtogroup group_device_driver
1241  */
1242 
1243 /**@{*/
1244 
1245 /**
1246  * device (I/O) class type
1247  */
1248 enum rt_device_class_type
1249 {
1250     RT_Device_Class_Char = 0,                           /**< character device */
1251     RT_Device_Class_Block,                              /**< block device */
1252     RT_Device_Class_NetIf,                              /**< net interface */
1253     RT_Device_Class_MTD,                                /**< memory device */
1254     RT_Device_Class_CAN,                                /**< CAN device */
1255     RT_Device_Class_RTC,                                /**< RTC device */
1256     RT_Device_Class_Sound,                              /**< Sound device */
1257     RT_Device_Class_Graphic,                            /**< Graphic device */
1258     RT_Device_Class_I2CBUS,                             /**< I2C bus device */
1259     RT_Device_Class_USBDevice,                          /**< USB slave device */
1260     RT_Device_Class_USBHost,                            /**< USB host bus */
1261     RT_Device_Class_USBOTG,                             /**< USB OTG bus */
1262     RT_Device_Class_SPIBUS,                             /**< SPI bus device */
1263     RT_Device_Class_SPIDevice,                          /**< SPI device */
1264     RT_Device_Class_SDIO,                               /**< SDIO bus device */
1265     RT_Device_Class_PM,                                 /**< PM pseudo device */
1266     RT_Device_Class_Pipe,                               /**< Pipe device */
1267     RT_Device_Class_Portal,                             /**< Portal device */
1268     RT_Device_Class_Timer,                              /**< Timer device */
1269     RT_Device_Class_Miscellaneous,                      /**< Miscellaneous device */
1270     RT_Device_Class_Sensor,                             /**< Sensor device */
1271     RT_Device_Class_Touch,                              /**< Touch device */
1272     RT_Device_Class_PHY,                                /**< PHY device */
1273     RT_Device_Class_Security,                           /**< Security device */
1274     RT_Device_Class_WLAN,                               /**< WLAN device */
1275     RT_Device_Class_Pin,                                /**< Pin device */
1276     RT_Device_Class_ADC,                                /**< ADC device */
1277     RT_Device_Class_DAC,                                /**< DAC device */
1278     RT_Device_Class_WDT,                                /**< WDT device */
1279     RT_Device_Class_PWM,                                /**< PWM device */
1280     RT_Device_Class_Bus,                                /**< Bus device */
1281     RT_Device_Class_Unknown                             /**< unknown device */
1282 };
1283 
1284 /**
1285  * device flags definitions
1286  */
1287 #define RT_DEVICE_FLAG_DEACTIVATE       0x000           /**< device is not not initialized */
1288 
1289 #define RT_DEVICE_FLAG_RDONLY           0x001           /**< read only */
1290 #define RT_DEVICE_FLAG_WRONLY           0x002           /**< write only */
1291 #define RT_DEVICE_FLAG_RDWR             0x003           /**< read and write */
1292 
1293 #define RT_DEVICE_FLAG_REMOVABLE        0x004           /**< removable device */
1294 #define RT_DEVICE_FLAG_STANDALONE       0x008           /**< standalone device */
1295 #define RT_DEVICE_FLAG_ACTIVATED        0x010           /**< device is activated */
1296 #define RT_DEVICE_FLAG_SUSPENDED        0x020           /**< device is suspended */
1297 #define RT_DEVICE_FLAG_STREAM           0x040           /**< stream mode */
1298 #define RT_DEVICE_FLAG_DYNAMIC          0x080           /**< device is determined when open() */
1299 
1300 #define RT_DEVICE_FLAG_INT_RX           0x100           /**< INT mode on Rx */
1301 #define RT_DEVICE_FLAG_DMA_RX           0x200           /**< DMA mode on Rx */
1302 #define RT_DEVICE_FLAG_INT_TX           0x400           /**< INT mode on Tx */
1303 #define RT_DEVICE_FLAG_DMA_TX           0x800           /**< DMA mode on Tx */
1304 
1305 #define RT_DEVICE_OFLAG_CLOSE           0x000           /**< device is closed */
1306 #define RT_DEVICE_OFLAG_RDONLY          0x001           /**< read only access */
1307 #define RT_DEVICE_OFLAG_WRONLY          0x002           /**< write only access */
1308 #define RT_DEVICE_OFLAG_RDWR            0x003           /**< read and write */
1309 #define RT_DEVICE_OFLAG_OPEN            0x008           /**< device is opened */
1310 #define RT_DEVICE_OFLAG_MASK            0xf0f           /**< mask of open flag */
1311 
1312 /**
1313  * general device commands
1314  * 0x01 - 0x1F general device control commands
1315  * 0x20 - 0x3F udevice control commands
1316  * 0x40 -      special device control commands
1317  */
1318 #define RT_DEVICE_CTRL_RESUME           0x01            /**< resume device */
1319 #define RT_DEVICE_CTRL_SUSPEND          0x02            /**< suspend device */
1320 #define RT_DEVICE_CTRL_CONFIG           0x03            /**< configure device */
1321 #define RT_DEVICE_CTRL_CLOSE            0x04            /**< close device */
1322 #define RT_DEVICE_CTRL_NOTIFY_SET       0x05            /**< set notify func */
1323 #define RT_DEVICE_CTRL_SET_INT          0x06            /**< set interrupt */
1324 #define RT_DEVICE_CTRL_CLR_INT          0x07            /**< clear interrupt */
1325 #define RT_DEVICE_CTRL_GET_INT          0x08            /**< get interrupt status */
1326 #define RT_DEVICE_CTRL_CONSOLE_OFLAG    0x09            /**< get console open flag */
1327 #define RT_DEVICE_CTRL_MASK             0x1f            /**< mask for contrl commands */
1328 
1329 /**
1330  * device control
1331  */
1332 #define RT_DEVICE_CTRL_BASE(Type)        ((RT_Device_Class_##Type + 1) * 0x100)
1333 
1334 typedef struct rt_driver *rt_driver_t;
1335 typedef struct rt_device *rt_device_t;
1336 
1337 #ifdef RT_USING_DEVICE_OPS
1338 /**
1339  * operations set for device object
1340  */
1341 struct rt_device_ops
1342 {
1343     /* common device interface */
1344     rt_err_t  (*init)   (rt_device_t dev);
1345     rt_err_t  (*open)   (rt_device_t dev, rt_uint16_t oflag);
1346     rt_err_t  (*close)  (rt_device_t dev);
1347     rt_ssize_t (*read)  (rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size);
1348     rt_ssize_t (*write) (rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size);
1349     rt_err_t  (*control)(rt_device_t dev, int cmd, void *args);
1350 };
1351 #endif /* RT_USING_DEVICE_OPS */
1352 
1353 /**
1354  * WaitQueue structure
1355  */
1356 struct rt_wqueue
1357 {
1358     rt_uint32_t flag;
1359     rt_list_t waiting_list;
1360     struct rt_spinlock spinlock;
1361 };
1362 typedef struct rt_wqueue rt_wqueue_t;
1363 
1364 #ifdef RT_USING_DM
1365 struct rt_driver;
1366 struct rt_bus;
1367 #endif /* RT_USING_DM */
1368 
1369 /**
1370  * Device structure
1371  */
1372 struct rt_device
1373 {
1374     struct rt_object          parent;                   /**< inherit from rt_object */
1375 
1376 #ifdef RT_USING_DM
1377     struct rt_bus *bus;                                 /**< the bus mounting to */
1378     rt_list_t node;                                     /**< to mount on bus */
1379     struct rt_driver *drv;                              /**< driver for powering the device */
1380 #ifdef RT_USING_OFW
1381     void *ofw_node;                                     /**< ofw node get from device tree */
1382 #endif /* RT_USING_OFW */
1383     void *power_domain_unit;
1384 #ifdef RT_USING_DMA
1385     const void *dma_ops;
1386 #endif
1387 #endif /* RT_USING_DM */
1388 
1389     enum rt_device_class_type type;                     /**< device type */
1390     rt_uint16_t               flag;                     /**< device flag */
1391     rt_uint16_t               open_flag;                /**< device open flag */
1392 
1393     rt_uint8_t                ref_count;                /**< reference count */
1394 #ifdef RT_USING_DM
1395     rt_uint8_t                master_id;                /**< 0 - 255 */
1396 #endif
1397     rt_uint8_t                device_id;                /**< 0 - 255 */
1398 
1399     /* device call back */
1400     rt_err_t (*rx_indicate)(rt_device_t dev, rt_size_t size);
1401     rt_err_t (*tx_complete)(rt_device_t dev, void *buffer);
1402 
1403 #ifdef RT_USING_DEVICE_OPS
1404     const struct rt_device_ops *ops;
1405 #else
1406     /* common device interface */
1407     rt_err_t  (*init)   (rt_device_t dev);
1408     rt_err_t  (*open)   (rt_device_t dev, rt_uint16_t oflag);
1409     rt_err_t  (*close)  (rt_device_t dev);
1410     rt_ssize_t (*read)  (rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size);
1411     rt_ssize_t (*write) (rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size);
1412     rt_err_t  (*control)(rt_device_t dev, int cmd, void *args);
1413 #endif /* RT_USING_DEVICE_OPS */
1414 
1415 #ifdef RT_USING_POSIX_DEVIO
1416     const struct dfs_file_ops *fops;
1417     struct rt_wqueue wait_queue;
1418 #endif /* RT_USING_POSIX_DEVIO */
1419 
1420     rt_err_t (*readlink)
1421         (rt_device_t dev, char *buf, int len);          /**< for dynamic device */
1422 
1423     void                     *user_data;                /**< device private data */
1424 };
1425 
1426 /**
1427  * Notify structure
1428  */
1429 struct rt_device_notify
1430 {
1431     void (*notify)(rt_device_t dev);
1432     struct rt_device *dev;
1433 };
1434 
1435 #ifdef RT_USING_SMART
1436 struct rt_channel
1437 {
1438     struct rt_ipc_object parent;                        /**< inherit from object */
1439     struct rt_thread *reply;                            /**< the thread will be reply */
1440     struct rt_spinlock slock;                           /**< spinlock of this channel */
1441     rt_list_t wait_msg;                                 /**< the wait queue of sender msg */
1442     rt_list_t wait_thread;                              /**< the wait queue of sender thread */
1443     rt_wqueue_t reader_queue;                           /**< channel poll queue */
1444     rt_uint8_t  stat;                                   /**< the status of this channel */
1445     rt_ubase_t  ref;
1446 };
1447 typedef struct rt_channel *rt_channel_t;
1448 #endif /* RT_USING_SMART */
1449 
1450 /**@}*/
1451 #endif /* RT_USING_DEVICE */
1452 
1453 #ifdef __cplusplus
1454 }
1455 #endif
1456 
1457 #ifdef __cplusplus
1458 /* RT-Thread definitions for C++ */
1459 namespace rtthread {
1460 
1461 enum TICK_WAIT {
1462     WAIT_NONE = 0,
1463     WAIT_FOREVER = -1,
1464 };
1465 
1466 }
1467 
1468 #endif /* __cplusplus */
1469 
1470 #endif /* __RT_DEF_H__ */
1471