TNeo  v1.06
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
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 /**
275  * Whether software stack overflow check is enabled. Enabling this option adds
276  * small overhead to context switching and system tick processing
277  * (`#tn_tick_int_processing()`). When stack overflow happens, the kernel calls
278  * user-provided callback (see `#tn_callback_stack_overflow_set()`); if this
279  * callback is undefined, the kernel calls `#_TN_FATAL_ERROR()`.
280  *
281  * This option is on by default for all architectures except PIC24/dsPIC,
282  * since this architecture has hardware stack pointer limit.
283  */
284 #ifndef TN_STACK_OVERFLOW_CHECK
285 # if defined(__TN_ARCH_PIC24_DSPIC__)
286 /*
287  * On PIC24/dsPIC, we have hardware stack pointer limit, so, no need for
288  * software check
289  */
290 # define TN_STACK_OVERFLOW_CHECK 0
291 # else
292 /*
293  * On all other architectures, software stack overflow check is ON by default
294  */
295 # define TN_STACK_OVERFLOW_CHECK 1
296 # endif
297 #endif
298 
299 
300 /**
301  * Whether the kernel should use \ref time_ticks__dynamic_tick scheme instead of
302  * \ref time_ticks__static_tick.
303  */
304 #ifndef TN_DYNAMIC_TICK
305 # define TN_DYNAMIC_TICK 0
306 #endif
307 
308 
309 /**
310  * Whether the old TNKernel events API compatibility mode is active.
311  *
312  * \warning Use it if only you're porting your existing TNKernel project on
313  * TNeo. Otherwise, usage of this option is strongly discouraged.
314  *
315  * Actually, events are the most incompatible thing between TNeo and
316  * TNKernel (for some details, refer to the section \ref tnkernel_diff_event)
317  *
318  * This option is quite useful when you're porting your existing TNKernel app
319  * to TNeo. When it is non-zero, old events symbols are available and
320  * behave just like they do in TNKernel.
321  *
322  * The full list of what becomes available:
323  *
324  * - Event group attributes:
325  * - `#TN_EVENT_ATTR_SINGLE`
326  * - `#TN_EVENT_ATTR_MULTI`
327  * - `#TN_EVENT_ATTR_CLR`
328  *
329  * - Functions:
330  * - `#tn_event_create()`
331  * - `#tn_event_delete()`
332  * - `#tn_event_wait()`
333  * - `#tn_event_wait_polling()`
334  * - `#tn_event_iwait()`
335  * - `#tn_event_set()`
336  * - `#tn_event_iset()`
337  * - `#tn_event_clear()`
338  * - `#tn_event_iclear()`
339  */
340 #ifndef TN_OLD_EVENT_API
341 # define TN_OLD_EVENT_API 0
342 #endif
343 
344 
345 
346 /*******************************************************************************
347  * PIC24/dsPIC-specific configuration
348  ******************************************************************************/
349 
350 
351 /**
352  * \def TN_P24_SYS_IPL
353  *
354  * Maximum system interrupt priority. For details on system interrupts on
355  * PIC24/dsPIC, refer to the section \ref pic24_interrupts
356  * "PIC24/dsPIC interrupts".
357  *
358  * \attention you should also set `#TN_P24_SYS_IPL_STR` to appropriate value.
359  *
360  * Should be >= 1 and <= 6. Default: 4.
361  *
362  */
363 
364 /**
365  * \def TN_P24_SYS_IPL_STR
366  *
367  * The same as `#TN_P24_SYS_IPL` but should be set as string, for example:
368  * \code{.c}
369  * #define TN_P24_SYS_IPL_STR "4"
370  * \endcode
371  *
372  * It is used in assembly for ISR macro `tn_p24_soft_isr()`.
373  * I don't like that we have to keep two macros instead of just one, so if
374  * anybody knows how to use integer value there, please let me know :)
375  */
376 
377 #ifndef TN_P24_SYS_IPL
378 //-- NOTE: the following two macros should correspond: they should specify
379 // the same number, but in one case it is an integer, and in the second case
380 // it is a string. If anyone knows how to write it so that we can specify
381 // just a single macro, please let me know. :)
382 # define TN_P24_SYS_IPL 4
383 # define TN_P24_SYS_IPL_STR "4"
384 #endif
385 
386 #endif // _TN_CFG_DEFAULT_H
387 
388