TNeo  BETA v1.08-11-g97e5a6d
tn_common.h
Go to the documentation of this file.
1 /*******************************************************************************
2  *
3  * TNeo: real-time kernel initially based on TNKernel
4  *
5  * TNKernel: copyright 2004, 2013 Yuri Tiomkin.
6  * PIC32-specific routines: copyright 2013, 2014 Anders Montonen.
7  * TNeo: copyright 2014 Dmitry Frank.
8  *
9  * TNeo was born as a thorough review and re-implementation of
10  * TNKernel. The new kernel has well-formed code, inherited bugs are fixed
11  * as well as new features being added, and it is tested carefully with
12  * unit-tests.
13  *
14  * API is changed somewhat, so it's not 100% compatible with TNKernel,
15  * hence the new name: TNeo.
16  *
17  * Permission to use, copy, modify, and distribute this software in source
18  * and binary forms and its documentation for any purpose and without fee
19  * is hereby granted, provided that the above copyright notice appear
20  * in all copies and that both that copyright notice and this permission
21  * notice appear in supporting documentation.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE DMITRY FRANK AND CONTRIBUTORS "AS IS"
24  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
26  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DMITRY FRANK OR CONTRIBUTORS BE
27  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
33  * THE POSSIBILITY OF SUCH DAMAGE.
34  *
35  ******************************************************************************/
36 
37 /**
38  * \file
39  *
40  * Definitions used through the whole kernel.
41  */
42 
43 #ifndef _TN_COMMON_H
44 #define _TN_COMMON_H
45 
46 /*******************************************************************************
47  * INCLUDED FILES
48  ******************************************************************************/
49 
50 #include "../arch/tn_arch_detect.h"
51 #include "tn_cfg_dispatch.h"
52 
53 #ifdef __cplusplus
54 extern "C" { /*}*/
55 #endif
56 
57 /*******************************************************************************
58  * PUBLIC TYPES
59  ******************************************************************************/
60 
61 /**
62  * Magic number for object validity verification
63  */
64 // TODO: use TN_UWord here instead of unsigned int
65 enum TN_ObjId {
66  TN_ID_NONE = (int)0x0, //!< id for invalid object
67  TN_ID_TASK = (int)0x47ABCF69, //!< id for tasks
68  TN_ID_SEMAPHORE = (int)0x6FA173EB, //!< id for semaphores
69  TN_ID_EVENTGRP = (int)0x5E224F25, //!< id for event groups
70  TN_ID_DATAQUEUE = (int)0x0C8A6C89, //!< id for data queues
71  TN_ID_FSMEMORYPOOL = (int)0x26B7CE8B, //!< id for fixed memory pools
72  TN_ID_MUTEX = (int)0x17129E45, //!< id for mutexes
73  TN_ID_TIMER = (int)0x1A937FBC, //!< id for timers
74  TN_ID_EXCHANGE = (int)0x32b7c072, //!< id for exchange objects
75  TN_ID_EXCHANGE_LINK = (int)0x24d36f35, //!< id for exchange link
76 };
77 
78 /**
79  * Result code returned by kernel services.
80  */
81 enum TN_RCode {
82  ///
83  /// Successful operation
84  TN_RC_OK = 0,
85  ///
86  /// Timeout (consult `#TN_TickCnt` for details).
87  /// @see `#TN_TickCnt`
89  ///
90  /// This code is returned in the following cases:
91  /// * Trying to increment semaphore count more than its max count;
92  /// * Trying to return extra memory block to fixed memory pool.
93  /// @see tn_sem.h
94  /// @see tn_fmem.h
96  ///
97  /// Wrong context error: returned if function is called from
98  /// non-acceptable context. Required context suggested for every
99  /// function by badges:
100  ///
101  /// * $(TN_CALL_FROM_TASK) - function can be called from task;
102  /// * $(TN_CALL_FROM_ISR) - function can be called from ISR.
103  ///
104  /// @see `tn_sys_context_get()`
105  /// @see `enum #TN_Context`
107  ///
108  /// Wrong task state error: requested operation requires different
109  /// task state
111  ///
112  /// This code is returned by most of the kernel functions when
113  /// wrong params were given to function. This error code can be returned
114  /// if only build-time option `#TN_CHECK_PARAM` is non-zero
115  /// @see `#TN_CHECK_PARAM`
117  ///
118  /// Illegal usage. Returned in the following cases:
119  /// * task tries to unlock or delete the mutex that is locked by different
120  /// task,
121  /// * task tries to lock mutex with priority ceiling whose priority is
122  /// lower than task's priority
123  /// @see tn_mutex.h
125  ///
126  /// Returned when user tries to perform some operation on invalid object
127  /// (mutex, semaphore, etc).
128  /// Object validity is checked by comparing special `id_...` field value
129  /// with the value from `enum #TN_ObjId`
130  /// @see `#TN_CHECK_PARAM`
132  /// Object for whose event task was waiting is deleted.
134  /// Task was released from waiting forcibly because some other task
135  /// called `tn_task_release_wait()`
137  /// Internal kernel error, should never be returned by kernel services.
138  /// If it is returned, it's a bug in the kernel.
140 };
141 
142 /**
143  * Prototype for task body function.
144  */
145 typedef void (TN_TaskBody)(void *param);
146 
147 
148 /**
149  * Type for system tick count, it is used by the kernel to represent absolute
150  * tick count value as well as relative timeouts.
151  *
152  * When it is used as a timeout value, it represents the maximum number of
153  * system ticks to wait.
154  *
155  * Assume user called some system function, and it can't perform its job
156  * immediately (say, it needs to lock mutex but it is already locked, etc).
157  *
158  * So, function can wait or return an error. There are possible `timeout`
159  * values and appropriate behavior of the function:
160  *
161  * - `timeout` is set to `0`: function doesn't wait at all, no context switch
162  * is performed, `#TN_RC_TIMEOUT` is returned immediately.
163  * - `timeout` is set to `#TN_WAIT_INFINITE`: function waits until it
164  * eventually **can** perform its job. Timeout is not taken in account, so
165  * `#TN_RC_TIMEOUT` is never returned.
166  * - `timeout` is set to other value: function waits at most specified number
167  * of system ticks. Strictly speaking, it waits from `(timeout - 1)` to
168  * `timeout` ticks. So, if you specify that timeout is 1, be aware that it
169  * might actually don't wait at all: if $(TN_SYS_TIMER_LINK) interrupt
170  * happens just while function is putting task to wait (with interrupts
171  * disabled), then ISR will be executed right after function puts task to
172  * wait. Then `tn_tick_int_processing()` will immediately remove the task
173  * from wait queue and make it runnable again.
174  *
175  * So, to guarantee that task waits *at least* 1 system tick, you should
176  * specify timeout value of `2`.
177  *
178  * **Note** also that there are other possible ways to make task runnable:
179  *
180  * - if task waits because of call to `tn_task_sleep()`, it may be woken up by
181  * some other task, by means of `tn_task_wakeup()`. In this case,
182  * `tn_task_sleep()` returns `#TN_RC_OK`.
183  * - independently of the wait reason, task may be released from wait forcibly,
184  * by means of `tn_task_release_wait()`. It this case, `#TN_RC_FORCED` is
185  * returned by the waiting function. (the usage of the
186  * `tn_task_release_wait()` function is discouraged though)
187  */
188 typedef unsigned long TN_TickCnt;
189 
190 /*******************************************************************************
191  * PROTECTED GLOBAL DATA
192  ******************************************************************************/
193 
194 /*******************************************************************************
195  * DEFINITIONS
196  ******************************************************************************/
197 
198 
199 /// NULL pointer definition
200 #ifndef TN_NULL
201 # ifdef __cplusplus
202 # define TN_NULL 0
203 # else
204 # define TN_NULL ((void *)0)
205 # endif
206 #endif
207 
208 /// boolean type definition
209 #ifndef TN_BOOL
210 # ifdef __cplusplus
211 # define TN_BOOL bool
212 # else
213 # define TN_BOOL int
214 # endif
215 #endif
216 
217 /// `true` value definition for type `#TN_BOOL`
218 #ifndef TN_TRUE
219 # define TN_TRUE (1 == 1)
220 #endif
221 
222 /// `false` value definition for type `#TN_BOOL`
223 #ifndef TN_FALSE
224 # define TN_FALSE (1 == 0)
225 #endif
226 
227 /**
228  * Macro for making a number a multiple of `sizeof(#TN_UWord)`, should be used
229  * with fixed memory block pool. See `tn_fmem_create()` for usage example.
230  */
231 #define TN_MAKE_ALIG_SIZE(a) \
232  (((a) + (sizeof(TN_UWord) - 1)) & (~(sizeof(TN_UWord) - 1)))
233 
234 //-- self-checking
235 #if (!defined TN_API_MAKE_ALIG_ARG)
236 # error TN_API_MAKE_ALIG_ARG is not defined
237 #elif (!defined TN_API_MAKE_ALIG_ARG__TYPE)
238 # error TN_API_MAKE_ALIG_ARG__TYPE is not defined
239 #elif (!defined TN_API_MAKE_ALIG_ARG__SIZE)
240 # error TN_API_MAKE_ALIG_ARG__SIZE is not defined
241 #endif
242 
243 //-- define MAKE_ALIG accordingly to config
244 /**
245  * The same as `#TN_MAKE_ALIG_SIZE` but its behavior depends on the option
246  * `#TN_API_MAKE_ALIG_ARG`
247  *
248  * \attention it is recommended to use `#TN_MAKE_ALIG_SIZE` macro instead
249  * of this one, in order to avoid confusion caused by various
250  * TNKernel ports: refer to the section \ref tnkernel_diff_make_alig for details.
251  */
252 #if (TN_API_MAKE_ALIG_ARG == TN_API_MAKE_ALIG_ARG__TYPE)
253 # define TN_MAKE_ALIG(a) TN_MAKE_ALIG_SIZE(sizeof(a))
254 #elif (TN_API_MAKE_ALIG_ARG == TN_API_MAKE_ALIG_ARG__SIZE)
255 # define TN_MAKE_ALIG(a) TN_MAKE_ALIG_SIZE(a)
256 #else
257 # error wrong TN_API_MAKE_ALIG_ARG
258 #endif
259 
260 /**
261  * Suppresses "unused" compiler warning for some particular symbol
262  */
263 #define _TN_UNUSED(x) (void)(x)
264 
265 #define _TN_FATAL_ERROR(error_msg) _TN_FATAL_ERRORF(error_msg, NULL)
266 
267 /*******************************************************************************
268  * PUBLIC FUNCTION PROTOTYPES
269  ******************************************************************************/
270 
271 #ifdef __cplusplus
272 } /* extern "C" */
273 #endif
274 
275 #endif // _TN_COMMON_H
276 
277 /*******************************************************************************
278  * end of file
279  ******************************************************************************/
280 
281 
id for data queues
Definition: tn_common.h:70
Wrong context error: returned if function is called from non-acceptable context.
Definition: tn_common.h:106
id for exchange objects
Definition: tn_common.h:74
Returned when user tries to perform some operation on invalid object (mutex, semaphore, etc).
Definition: tn_common.h:131
Task was released from waiting forcibly because some other task called tn_task_release_wait() ...
Definition: tn_common.h:136
id for fixed memory pools
Definition: tn_common.h:71
TN_RCode
Result code returned by kernel services.
Definition: tn_common.h:81
TN_ObjId
Magic number for object validity verification.
Definition: tn_common.h:65
unsigned long TN_TickCnt
Type for system tick count, it is used by the kernel to represent absolute tick count value as well a...
Definition: tn_common.h:188
Successful operation.
Definition: tn_common.h:84
id for semaphores
Definition: tn_common.h:68
Illegal usage.
Definition: tn_common.h:124
This code is returned in the following cases:
Definition: tn_common.h:95
id for exchange link
Definition: tn_common.h:75
Dispatch configuration: set predefined options, include user-provided cfg file as well as default cfg...
Internal kernel error, should never be returned by kernel services.
Definition: tn_common.h:139
id for tasks
Definition: tn_common.h:67
id for event groups
Definition: tn_common.h:69
id for invalid object
Definition: tn_common.h:66
This code is returned by most of the kernel functions when wrong params were given to function...
Definition: tn_common.h:116
Wrong task state error: requested operation requires different task state.
Definition: tn_common.h:110
Object for whose event task was waiting is deleted.
Definition: tn_common.h:133
Timeout (consult TN_TickCnt for details).
Definition: tn_common.h:88
id for mutexes
Definition: tn_common.h:72
void() TN_TaskBody(void *param)
Prototype for task body function.
Definition: tn_common.h:145
id for timers
Definition: tn_common.h:73