TNeo  v1.08
tn_cfg_default.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  * TNeo default configuration file, to be copied as `tn_cfg.h`.
41  *
42  * This project is intended to be built as a library, separately from main
43  * project (although nothing prevents you from bundling things together, if you
44  * want to).
45  *
46  * There are various options available which affects API and behavior of the
47  * kernel. But these options are specific for particular project, and aren't
48  * related to the kernel itself, so we need to keep them separately.
49  *
50  * To this end, file `tn.h` (the main kernel header file) includes `tn_cfg.h`,
51  * which isn't included in the repository (even more, it is added to
52  * `.hgignore` list actually). Instead, default configuration file
53  * `tn_cfg_default.h` is provided, and when you just cloned the repository, you
54  * might want to copy it as `tn_cfg.h`. Or even better, if your filesystem
55  * supports symbolic links, copy it somewhere to your main project's directory
56  * (so that you can add it to your VCS there), and create symlink to it named
57  * `tn_cfg.h` in the TNeo source directory, like this:
58  *
59  * $ cd /path/to/tneo/src
60  * $ cp ./tn_cfg_default.h /path/to/main/project/lib_cfg/tn_cfg.h
61  * $ ln -s /path/to/main/project/lib_cfg/tn_cfg.h ./tn_cfg.h
62  *
63  * Default configuration file contains detailed comments, so you can read them
64  * and configure behavior as you like.
65  */
66 
67 #ifndef _TN_CFG_DEFAULT_H
68 #define _TN_CFG_DEFAULT_H
69 
70 
71 /*******************************************************************************
72  * INCLUDED FILES
73  ******************************************************************************/
74 
75 //-- some defaults depend on architecture, so we should include
76 // `tn_arch_detect.h`
77 #include "arch/tn_arch_detect.h"
78 
79 
80 /*******************************************************************************
81  * USER-DEFINED OPTIONS
82  ******************************************************************************/
83 
84 /**
85  * This option enables run-time check which ensures that build-time options for
86  * the kernel match ones for the application.
87  *
88  * Without this check, it is possible that you change your `tn_cfg.h` file, and
89  * just rebuild your application without rebuilding the kernel. Then,
90  * application would assume that kernel behaves accordingly to `tn_cfg.h` which
91  * was included in the application, but this is actually not true: you need to
92  * rebuild the kernel for changes to take effect.
93  *
94  * With this option turned on, if build-time configurations don't match, you
95  * will get run-time error (`_TN_FATAL_ERROR()`) inside `tn_sys_start()`, which
96  * is much more informative than weird bugs caused by configuration mismatch.
97  *
98  * <b>Note</b>: turning this option on makes sense if only you use TNeo
99  * as a separate library. If you build TNeo together with the
100  * application, both the kernel and the application always use the same
101  * `tn_cfg.h` file, therefore this option is useless.
102  *
103  * \attention If this option is on, your application must include the file
104  * `tn_app_check.c`.
105  */
106 #ifndef TN_CHECK_BUILD_CFG
107 # define TN_CHECK_BUILD_CFG 1
108 #endif
109 
110 
111 /**
112  * Number of priorities that can be used by application, plus one for idle task
113  * (which has the lowest priority). This value can't be higher than
114  * architecture-dependent value `#TN_PRIORITIES_MAX_CNT`, which typically
115  * equals to width of `int` type. So, for 32-bit systems, max number of
116  * priorities is 32.
117  *
118  * But usually, application needs much less: I can imagine **at most** 4-5
119  * different priorities, plus one for the idle task.
120  *
121  * Do note also that each possible priority level takes RAM: two pointers for
122  * linked list and one `short` for time slice value, so on 32-bit system it
123  * takes 10 bytes. So, with default value of 32 priorities available, it takes
124  * 320 bytes. If you set it, say, to 5, you save `270` bytes, which might be
125  * notable.
126  *
127  * Default: `#TN_PRIORITIES_MAX_CNT`.
128  */
129 #ifndef TN_PRIORITIES_CNT
130 # define TN_PRIORITIES_CNT TN_PRIORITIES_MAX_CNT
131 #endif
132 
133 /**
134  * Enables additional param checking for most of the system functions.
135  * It's surely useful for debug, but probably better to remove in release.
136  * If it is set, most of the system functions are able to return two additional
137  * codes:
138  *
139  * * `#TN_RC_WPARAM` if wrong params were given;
140  * * `#TN_RC_INVALID_OBJ` if given pointer doesn't point to a valid object.
141  * Object validity is checked by means of the special ID field of type
142  * `enum #TN_ObjId`.
143  *
144  * @see `enum #TN_ObjId`
145  */
146 #ifndef TN_CHECK_PARAM
147 # define TN_CHECK_PARAM 1
148 #endif
149 
150 /**
151  * Allows additional internal self-checking, useful to catch internal
152  * TNeo bugs as well as illegal kernel usage (e.g. sleeping in the idle
153  * task callback). Produces a couple of extra instructions which usually just
154  * causes debugger to stop if something goes wrong.
155  */
156 #ifndef TN_DEBUG
157 # define TN_DEBUG 0
158 #endif
159 
160 /**
161  * Whether old TNKernel names (definitions, functions, etc) should be
162  * available. If you're porting your existing application written for
163  * TNKernel, it is definitely worth enabling. If you start new project with
164  * TNeo from scratch, it's better to avoid old names.
165  */
166 #ifndef TN_OLD_TNKERNEL_NAMES
167 # define TN_OLD_TNKERNEL_NAMES 1
168 #endif
169 
170 /**
171  * Whether mutexes API should be available
172  */
173 #ifndef TN_USE_MUTEXES
174 # define TN_USE_MUTEXES 1
175 #endif
176 
177 /**
178  * Whether mutexes should allow recursive locking/unlocking
179  */
180 #ifndef TN_MUTEX_REC
181 # define TN_MUTEX_REC 1
182 #endif
183 
184 /**
185  * Whether RTOS should detect deadlocks and notify user about them
186  * via callback
187  *
188  * @see see `tn_callback_deadlock_set()`
189  * @see see `#TN_CBDeadlock`
190  */
191 #ifndef TN_MUTEX_DEADLOCK_DETECT
192 # define TN_MUTEX_DEADLOCK_DETECT 1
193 #endif
194 
195 /**
196  *
197  * <i>Takes effect if only `#TN_DYNAMIC_TICK` is <B>not set</B></i>.
198  *
199  * Number of "tick" lists of timers, must be a power or two; minimum value:
200  * `2`; typical values: `4`, `8` or `16`.
201  *
202  * Refer to the \ref timers_static_implementation for details.
203  *
204  * Shortly: this value represents number of elements in the array of
205  * `struct TN_ListItem`, on 32-bit system each element takes 8 bytes.
206  *
207  * The larger value, the more memory is needed, and the faster
208  * $(TN_SYS_TIMER_LINK) ISR works. If your application has a lot of timers
209  * and/or sleeping tasks, consider incrementing this value; otherwise,
210  * default value should work for you.
211  */
212 #ifndef TN_TICK_LISTS_CNT
213 # define TN_TICK_LISTS_CNT 8
214 #endif
215 
216 
217 /**
218  * API option for `MAKE_ALIG()` macro.
219  *
220  * There is a terrible mess with `MAKE_ALIG()` macro: original TNKernel docs
221  * specify that the argument of it should be the size to align, but almost all
222  * ports, including "original" one, defined it so that it takes type, not size.
223  *
224  * But the port by AlexB implemented it differently
225  * (i.e. accordingly to the docs)
226  *
227  * When I was moving from the port by AlexB to another one, do you have any
228  * idea how much time it took me to figure out why do I have rare weird bug? :)
229  *
230  * So, available options:
231  *
232  * * `#TN_API_MAKE_ALIG_ARG__TYPE`:
233  * In this case, you should use macro like this:
234  * `TN_MAKE_ALIG(struct my_struct)`
235  * This way is used in the majority of TNKernel ports.
236  * (actually, in all ports except the one by AlexB)
237  *
238  * * `#TN_API_MAKE_ALIG_ARG__SIZE`:
239  * In this case, you should use macro like this:
240  * `TN_MAKE_ALIG(sizeof(struct my_struct))`
241  * This way is stated in TNKernel docs
242  * and used in the port for dsPIC/PIC24/PIC32 by AlexB.
243  */
244 #ifndef TN_API_MAKE_ALIG_ARG
245 # define TN_API_MAKE_ALIG_ARG TN_API_MAKE_ALIG_ARG__SIZE
246 #endif
247 
248 
249 /**
250  * Whether profiler functionality should be enabled.
251  * Enabling this option adds overhead to context switching and increases
252  * the size of `#TN_Task` structure by about 20 bytes.
253  *
254  * @see `#TN_PROFILER_WAIT_TIME`
255  * @see `#tn_task_profiler_timing_get()`
256  * @see `struct #TN_TaskTiming`
257  */
258 #ifndef TN_PROFILER
259 # define TN_PROFILER 0
260 #endif
261 
262 /**
263  * Whether profiler should store wait time for each wait reason. Enabling this
264  * option bumps the size of `#TN_Task` structure by more than 100 bytes,
265  * see `struct #TN_TaskTiming`.
266  *
267  * Relevant if only `#TN_PROFILER` is non-zero.
268  */
269 #ifndef TN_PROFILER_WAIT_TIME
270 # define TN_PROFILER_WAIT_TIME 0
271 #endif
272 
273 /**
274  * Whether interrupt stack space should be initialized with
275  * `#TN_FILL_STACK_VAL` on system start. It is useful to disable this option if
276  * you don't want to allocate separate array for interrupt stack, but use
277  * initialization stack for it.
278  */
279 #ifndef TN_INIT_INTERRUPT_STACK_SPACE
280 # define TN_INIT_INTERRUPT_STACK_SPACE 1
281 #endif
282 
283 /**
284  * Whether software stack overflow check is enabled.
285  *
286  * Enabling this option adds small overhead to context switching and system
287  * tick processing (`#tn_tick_int_processing()`), it also reduces the payload
288  * of task stacks by just one word (`#TN_UWord`) for each stack.
289  *
290  * When stack overflow happens, the kernel calls user-provided callback (see
291  * `#tn_callback_stack_overflow_set()`); if this callback is undefined, the
292  * kernel calls `#_TN_FATAL_ERROR()`.
293  *
294  * This option is on by default for all architectures except PIC24/dsPIC,
295  * since this architecture has hardware stack pointer limit, unlike the others.
296  *
297  * \attention
298  * It is not an absolute guarantee that the kernel will detect any stack
299  * overflow. The kernel tries to detect stack overflow by checking the latest
300  * address of stack, which should have special value `#TN_FILL_STACK_VAL`.
301  *
302  * \attention
303  * So stack overflow is detected if only the overflow caused this value to
304  * corrupt, which isn't always the case.
305  *
306  * \attention
307  * More, the check is performed only at context switch and timer tick
308  * processing, which may be too late.
309  *
310  * Nevertheless, from my personal experience, it helps to catch stack overflow
311  * bugs a lot.
312  */
313 #ifndef TN_STACK_OVERFLOW_CHECK
314 # if defined(__TN_ARCH_PIC24_DSPIC__)
315 /*
316  * On PIC24/dsPIC, we have hardware stack pointer limit, so, no need for
317  * software check
318  */
319 # define TN_STACK_OVERFLOW_CHECK 0
320 # else
321 /*
322  * On all other architectures, software stack overflow check is ON by default
323  */
324 # define TN_STACK_OVERFLOW_CHECK 1
325 # endif
326 #endif
327 
328 
329 /**
330  * Whether the kernel should use \ref time_ticks__dynamic_tick scheme instead of
331  * \ref time_ticks__static_tick.
332  */
333 #ifndef TN_DYNAMIC_TICK
334 # define TN_DYNAMIC_TICK 0
335 #endif
336 
337 
338 /**
339  * Whether the old TNKernel events API compatibility mode is active.
340  *
341  * \warning Use it if only you're porting your existing TNKernel project on
342  * TNeo. Otherwise, usage of this option is strongly discouraged.
343  *
344  * Actually, events are the most incompatible thing between TNeo and
345  * TNKernel (for some details, refer to the section \ref tnkernel_diff_event)
346  *
347  * This option is quite useful when you're porting your existing TNKernel app
348  * to TNeo. When it is non-zero, old events symbols are available and
349  * behave just like they do in TNKernel.
350  *
351  * The full list of what becomes available:
352  *
353  * - Event group attributes:
354  * - `#TN_EVENT_ATTR_SINGLE`
355  * - `#TN_EVENT_ATTR_MULTI`
356  * - `#TN_EVENT_ATTR_CLR`
357  *
358  * - Functions:
359  * - `#tn_event_create()`
360  * - `#tn_event_delete()`
361  * - `#tn_event_wait()`
362  * - `#tn_event_wait_polling()`
363  * - `#tn_event_iwait()`
364  * - `#tn_event_set()`
365  * - `#tn_event_iset()`
366  * - `#tn_event_clear()`
367  * - `#tn_event_iclear()`
368  */
369 #ifndef TN_OLD_EVENT_API
370 # define TN_OLD_EVENT_API 0
371 #endif
372 
373 
374 /**
375  * Whether the kernel should use compiler-specific forced inline qualifiers (if
376  * possible) instead of "usual" `inline`, which is just a hint for the
377  * compiler.
378  */
379 #ifndef TN_FORCED_INLINE
380 # define TN_FORCED_INLINE 1
381 #endif
382 
383 /**
384  * Whether a maximum of reasonable functions should be inlined. Depending of the
385  * configuration this may increase the size of the kernel, but it will also
386  * improve the performance.
387  */
388 #ifndef TN_MAX_INLINE
389 # define TN_MAX_INLINE 0
390 #endif
391 
392 
393 
394 /*******************************************************************************
395  * PIC24/dsPIC-specific configuration
396  ******************************************************************************/
397 
398 
399 /**
400  * Maximum system interrupt priority. For details on system interrupts on
401  * PIC24/dsPIC, refer to the section \ref pic24_interrupts
402  * "PIC24/dsPIC interrupts".
403  *
404  * Should be >= 1 and <= 6. Default: 4.
405  */
406 
407 #ifndef TN_P24_SYS_IPL
408 # define TN_P24_SYS_IPL 4
409 #endif
410 
411 #endif // _TN_CFG_DEFAULT_H
412 
413