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  * 2024-01-18     Shell        Separate the basic types from rtdef.h
9  */
10 
11 #ifndef __RT_TYPES_H__
12 #define __RT_TYPES_H__
13 
14 #include <rtconfig.h>
15 
16 #include <stdint.h>
17 #include <stddef.h>
18 #include <stdarg.h>
19 #ifndef RT_USING_NANO
20 #include <sys/types.h>
21 #include <sys/errno.h>
22 #if defined(RT_USING_SIGNALS) || defined(RT_USING_SMART)
23 #include <sys/signal.h>
24 #endif /* defined(RT_USING_SIGNALS) || defined(RT_USING_SMART) */
25 #endif /* RT_USING_NANO */
26 
27 #ifdef __cplusplus
28 extern "C" {
29 #endif
30 
31 /**
32  * RT-Thread basic data types definition
33  */
34 
35 #if defined(_WIN64) || defined(__x86_64__)
36 #ifndef ARCH_CPU_64BIT
37 #define ARCH_CPU_64BIT
38 #endif // ARCH_CPU_64BIT
39 #endif // defined(_WIN64) || defined(__x86_64__)
40 
41 typedef int                             rt_bool_t;      /**< boolean type */
42 
43 #ifndef RT_USING_ARCH_DATA_TYPE
44 #ifdef RT_USING_LIBC
45 typedef int8_t                          rt_int8_t;      /**<  8bit integer type */
46 typedef int16_t                         rt_int16_t;     /**< 16bit integer type */
47 typedef int32_t                         rt_int32_t;     /**< 32bit integer type */
48 typedef uint8_t                         rt_uint8_t;     /**<  8bit unsigned integer type */
49 typedef uint16_t                        rt_uint16_t;    /**< 16bit unsigned integer type */
50 typedef uint32_t                        rt_uint32_t;    /**< 32bit unsigned integer type */
51 typedef int64_t                         rt_int64_t;     /**< 64bit integer type */
52 typedef uint64_t                        rt_uint64_t;    /**< 64bit unsigned integer type */
53 #else
54 typedef signed   char                   rt_int8_t;      /**<  8bit integer type */
55 typedef signed   short                  rt_int16_t;     /**< 16bit integer type */
56 typedef signed   int                    rt_int32_t;     /**< 32bit integer type */
57 typedef unsigned char                   rt_uint8_t;     /**<  8bit unsigned integer type */
58 typedef unsigned short                  rt_uint16_t;    /**< 16bit unsigned integer type */
59 typedef unsigned int                    rt_uint32_t;    /**< 32bit unsigned integer type */
60 #ifdef ARCH_CPU_64BIT
61 typedef signed long                     rt_int64_t;     /**< 64bit integer type */
62 typedef unsigned long                   rt_uint64_t;    /**< 64bit unsigned integer type */
63 #else
64 typedef signed long long                rt_int64_t;     /**< 64bit integer type */
65 typedef unsigned long long              rt_uint64_t;    /**< 64bit unsigned integer type */
66 #endif /* ARCH_CPU_64BIT */
67 #endif /* RT_USING_LIBC */
68 #endif /* RT_USING_ARCH_DATA_TYPE */
69 
70 #ifdef ARCH_CPU_64BIT
71 typedef rt_int64_t                      rt_base_t;      /**< Nbit CPU related data type */
72 typedef rt_uint64_t                     rt_ubase_t;     /**< Nbit unsigned CPU related data type */
73 #else
74 typedef rt_int32_t                      rt_base_t;      /**< Nbit CPU related data type */
75 typedef rt_uint32_t                     rt_ubase_t;     /**< Nbit unsigned CPU related data type */
76 #endif
77 
78 #if defined(RT_USING_LIBC) && !defined(RT_USING_NANO)
79 typedef size_t                          rt_size_t;      /**< Type for size number */
80 typedef ssize_t                         rt_ssize_t;     /**< Used for a count of bytes or an error indication */
81 typedef intptr_t                        rt_intptr_t;    /**< Type for signed pointer length integer */
82 typedef uintptr_t                       rt_uintptr_t;   /**< Type for unsigned pointer length integer */
83 #else
84 typedef rt_ubase_t                      rt_size_t;      /**< Type for size number */
85 typedef rt_base_t                       rt_ssize_t;     /**< Used for a count of bytes or an error indication */
86 typedef rt_base_t                      rt_intptr_t;    /**< Type for signed pointer length integer */
87 typedef rt_ubase_t                       rt_uintptr_t;   /**< Type for unsigned pointer length integer */
88 #endif /* defined(RT_USING_LIBC) && !defined(RT_USING_NANO) */
89 
90 typedef rt_base_t                       rt_err_t;       /**< Type for error number */
91 typedef rt_uint32_t                     rt_time_t;      /**< Type for time stamp */
92 typedef rt_uint32_t                     rt_tick_t;      /**< Type for tick count */
93 typedef rt_base_t                       rt_flag_t;      /**< Type for flags */
94 typedef rt_ubase_t                      rt_dev_t;       /**< Type for device */
95 typedef rt_base_t                       rt_off_t;       /**< Type for offset */
96 
97 #if defined(RT_USING_STDC_ATOMIC) && __STDC_VERSION__ < 201112L
98 #undef RT_USING_STDC_ATOMIC
99 #warning Not using C11 or beyond! Maybe you should change the -std option on your compiler
100 #endif
101 
102 #ifdef __cplusplus
103     typedef rt_base_t rt_atomic_t;
104 #else
105     #if defined(RT_USING_STDC_ATOMIC)
106         #include <stdatomic.h>
107         typedef _Atomic(rt_base_t) rt_atomic_t;
108     #elif defined(RT_USING_HW_ATOMIC)
109         typedef rt_base_t rt_atomic_t;
110     #else
111         typedef rt_base_t rt_atomic_t;
112     #endif /* RT_USING_STDC_ATOMIC */
113 #endif /* __cplusplus */
114 
115 /* boolean type definitions */
116 #define RT_TRUE                         1               /**< boolean true  */
117 #define RT_FALSE                        0               /**< boolean fails */
118 
119 /* null pointer definition */
120 #define RT_NULL                         0
121 
122 /**
123  * Double List structure
124  */
125 struct rt_list_node
126 {
127     struct rt_list_node *next;                          /**< point to next node. */
128     struct rt_list_node *prev;                          /**< point to prev node. */
129 };
130 typedef struct rt_list_node rt_list_t;                  /**< Type for lists. */
131 
132 /**
133  * Single List structure
134  */
135 struct rt_slist_node
136 {
137     struct rt_slist_node *next;                         /**< point to next node. */
138 };
139 typedef struct rt_slist_node rt_slist_t;                /**< Type for single list. */
140 
141 /**
142  * Lock-less Single List structure
143  */
144 struct rt_lockless_slist_node
145 {
146     rt_atomic_t next;                                   /**< point to next node. */
147 };
148 typedef struct rt_lockless_slist_node rt_ll_slist_t;    /**< Type for lock-les single list. */
149 
150 /**
151  * Spinlock
152  */
153 #ifdef RT_USING_SMP
154 #include <cpuport.h> /* for spinlock from arch */
155 
156 struct rt_spinlock
157 {
158     rt_hw_spinlock_t lock;
159 #ifdef RT_USING_DEBUG
160     rt_uint32_t critical_level;
161 #endif /* RT_USING_DEBUG */
162 #if defined(RT_DEBUGING_SPINLOCK)
163     void *owner;
164     void *pc;
165 #endif /* RT_DEBUGING_SPINLOCK */
166 };
167 
168 #ifndef RT_SPINLOCK_INIT
169 #define RT_SPINLOCK_INIT {{0}} /* can be overridden by cpuport.h */
170 #endif /* RT_SPINLOCK_INIT */
171 
172 #else /* !RT_USING_SMP */
173 
174 struct rt_spinlock
175 {
176 #ifdef RT_USING_DEBUG
177     rt_uint32_t critical_level;
178 #endif /* RT_USING_DEBUG */
179     rt_ubase_t lock;
180 };
181 #define RT_SPINLOCK_INIT {0}
182 #endif /* RT_USING_SMP */
183 #if defined(RT_DEBUGING_SPINLOCK) && defined(RT_USING_SMP)
184 
185     #define __OWNER_MAGIC ((void *)0xdeadbeaf)
186 
187     #if defined(__GNUC__)
188     #define __GET_RETURN_ADDRESS __builtin_return_address(0)
189     #else /* !__GNUC__ */
190     #define __GET_RETURN_ADDRESS RT_NULL
191     #endif /* __GNUC__ */
192 
193     #define _SPIN_LOCK_DEBUG_OWNER(lock)                  \
194         do                                                \
195         {                                                 \
196             struct rt_thread *_curthr = rt_thread_self(); \
197             if (_curthr != RT_NULL)                       \
198             {                                             \
199                 (lock)->owner = _curthr;                  \
200                 (lock)->pc = __GET_RETURN_ADDRESS;        \
201             }                                             \
202         } while (0)
203 
204     #define _SPIN_UNLOCK_DEBUG_OWNER(lock) \
205         do                                 \
206         {                                  \
207             (lock)->owner = __OWNER_MAGIC; \
208             (lock)->pc = RT_NULL;          \
209         } while (0)
210 
211 #else /* !RT_DEBUGING_SPINLOCK */
212 
213     #define _SPIN_LOCK_DEBUG_OWNER(lock)    RT_UNUSED(lock)
214     #define _SPIN_UNLOCK_DEBUG_OWNER(lock)  RT_UNUSED(lock)
215 #endif /* RT_DEBUGING_SPINLOCK */
216 
217 #ifdef RT_DEBUGING_CRITICAL
218     #define _SPIN_LOCK_DEBUG_CRITICAL(lock)               \
219         do                                                \
220         {                                                 \
221             (lock)->critical_level = rt_critical_level(); \
222         } while (0)
223 
224     #define _SPIN_UNLOCK_DEBUG_CRITICAL(lock, critical) \
225         do                                              \
226         {                                               \
227             (critical) = (lock)->critical_level;        \
228         } while (0)
229 
230 #else /* !RT_DEBUGING_CRITICAL */
231     #define _SPIN_LOCK_DEBUG_CRITICAL(lock)             RT_UNUSED(lock)
232     #define _SPIN_UNLOCK_DEBUG_CRITICAL(lock, critical) do {critical = 0; RT_UNUSED(lock);} while (0)
233 
234 #endif /* RT_DEBUGING_CRITICAL */
235 
236 #define RT_SPIN_LOCK_DEBUG(lock)         \
237     do                                   \
238     {                                    \
239         _SPIN_LOCK_DEBUG_OWNER(lock);    \
240         _SPIN_LOCK_DEBUG_CRITICAL(lock); \
241     } while (0)
242 
243 #define RT_SPIN_UNLOCK_DEBUG(lock, critical)         \
244     do                                               \
245     {                                                \
246         _SPIN_UNLOCK_DEBUG_OWNER(lock);              \
247         _SPIN_UNLOCK_DEBUG_CRITICAL(lock, critical); \
248     } while (0)
249 
250 typedef struct rt_spinlock rt_spinlock_t;
251 
252 #define RT_DEFINE_SPINLOCK(x)  struct rt_spinlock x = RT_SPINLOCK_INIT
253 
254 #ifdef __cplusplus
255 }
256 #endif
257 
258 #endif /* __RT_TYPES_H__ */
259