TNeoKernel  v1.04
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
tn_arch.h
Go to the documentation of this file.
1 /*******************************************************************************
2  *
3  * TNeoKernel: 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  * TNeoKernel: copyright © 2014 Dmitry Frank.
8  *
9  * TNeoKernel 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: TNeoKernel.
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  * Architecture-dependent routines declaration.
41  */
42 
43 #ifndef _TN_ARCH_H
44 #define _TN_ARCH_H
45 
46 
47 /*******************************************************************************
48  * INCLUDED FILES
49  ******************************************************************************/
50 
51 #include "../core/tn_common.h"
52 
53 
54 
55 /*******************************************************************************
56  * ACTUAL PORT IMPLEMENTATION
57  ******************************************************************************/
58 
59 #if defined(__TN_ARCH_PIC32MX__)
60 # include "pic32/tn_arch_pic32.h"
61 #elif defined(__TN_ARCH_PIC24_DSPIC__)
63 #else
64 # error "unknown platform"
65 #endif
66 
67 
68 
69 #ifdef __cplusplus
70 extern "C" { /*}*/
71 #endif
72 
73 /*******************************************************************************
74  * PUBLIC FUNCTION PROTOTYPES
75  ******************************************************************************/
76 
77 
78 /**
79  * Unconditionally disable <i>system interrupts</i>.
80  *
81  * Refer to the section \ref interrupt_types for details on what is <i>system
82  * interrupt</i>.
83  */
84 void tn_arch_int_dis(void);
85 
86 /**
87  * Unconditionally enable interrupts
88  *
89  * Refer to the section \ref interrupt_types for details on what is <i>system
90  * interrupt</i>.
91  */
92 void tn_arch_int_en(void);
93 
94 /**
95  * Disable <i>system interrupts</i> and return previous value of status
96  * register, atomically.
97  *
98  * Refer to the section \ref interrupt_types for details on what is <i>system
99  * interrupt</i>.
100  *
101  * @see `tn_arch_sr_restore()`
102  */
104 
105 /**
106  * Restore previously saved status register.
107  *
108  * @param sr status register value previously from
109  * `tn_arch_sr_save_int_dis()`
110  *
111  * @see `tn_arch_sr_save_int_dis()`
112  */
114 
115 /**
116  * Architecture-dependent system startup routine. Called from `tn_sys_start()`.
117  */
118 void _tn_arch_sys_init(
119  TN_UWord *int_stack,
120  unsigned int int_stack_size
121  );
122 
123 
124 /**
125  * Should return top of the stack, which may be:
126  *
127  * - `(stack_low_address - 1)`
128  * - `(stack_low_address + stack_size)`
129  * - `(stack_low_address)`
130  * - `(stack_low_address + stack_size - 1)`
131  *
132  * (depending on the architecture)
133  *
134  * @param stack_low_address
135  * Start address of the stack array.
136  * @param stack_size
137  * Size of the stack in `#TN_UWord`-s, not in bytes.
138  */
140  TN_UWord *stack_low_address,
141  int stack_size
142  );
143 
144 /**
145  * Should put initial CPU context to the provided stack pointer for new task
146  * and return current stack pointer.
147  *
148  * When resulting context gets restored by
149  * `_tn_arch_context_switch_now_nosave()` or `_tn_arch_context_switch_pend()`,
150  * the following conditions should be met:
151  *
152  * - Interrupts are enabled;
153  * - Return address is set to `tn_task_exit()`, so that when task body function
154  * returns, `tn_task_exit()` gets automatially called;
155  * - Argument 0 contains `param` pointer
156  *
157  * @param task_func
158  * Pointer to task body function.
159  * @param stack_top
160  * Top of the stack, returned by `_tn_arch_stack_top_get()`.
161  * @param stack_size
162  * Size of the stack in `#TN_UWord`-s, not in bytes.
163  * @param param
164  * User-provided parameter for task body function.
165  *
166  * @return current stack pointer (top of the stack)
167  */
169  TN_TaskBody *task_func,
170  TN_UWord *stack_top,
171  int stack_size,
172  void *param
173  );
174 
175 /**
176  * Should return 1 if <i>system ISR</i> is currently running, 0 otherwise.
177  *
178  * Refer to the section \ref interrupt_types for details on what is <i>system
179  * ISR</i>.
180  */
181 int _tn_arch_inside_isr(void);
182 
183 /**
184  * Should return 1 if <i>system interrupts</i> are currently disabled, 0
185  * otherwise.
186  *
187  * Refer to the section \ref interrupt_types for details on what is <i>system
188  * interrupt</i>.
189  */
190 int _tn_arch_is_int_disabled(void);
191 
192 /**
193  * Called whenever we need to switch context from one task to another.
194  *
195  * This function typically does NOT switch context; it merely pends it,
196  * that is, it sets appropriate interrupt flag. If current level is an
197  * application level, interrupt is fired immediately, and context gets
198  * switched.
199  *
200  * But, if it's hard or impossible on particular platform to use dedicated
201  * interrupt flag, this function may just switch the context on its own.
202  *
203  * **Preconditions:**
204  *
205  * - interrupts are enabled;
206  * - `tn_curr_run_task` points to currently running (preempted) task;
207  * - `tn_next_task_to_run` points to new task to run.
208  *
209  * **Actions to perform in actual context switching routine:**
210  *
211  * - save context of the preempted task to its stack;
212  * - set `tn_curr_run_task` to `tn_next_task_to_run`;
213  * - restore context of the newly activated task from its stack.
214  *
215  * @see `tn_curr_run_task`
216  * @see `tn_next_task_to_run`
217  */
219 
220 /**
221  * Called whenever we need to switch context to new task, but don't save
222  * current context. This happens:
223  * - At system start, inside `tn_sys_start()`;
224  * - At task exit, inside `tn_task_exit()`
225  *
226  * This function doesn't pend context switch, it switches context immediately.
227  *
228  * **Preconditions:**
229  *
230  * - interrupts are disabled;
231  * - `tn_next_task_to_run` is already set to needed task.
232  *
233  * **Actions to perform:**
234  *
235  * - set `tn_curr_run_task` to `tn_next_task_to_run`;
236  * - restore context of the newly activated task from its stack.
237  *
238  * @see `tn_curr_run_task`
239  * @see `tn_next_task_to_run`
240  */
242 
243 #ifdef __cplusplus
244 } /* extern "C" */
245 #endif
246 
247 
248 
249 
250 
251 
252 
253 
254 
255 #endif /* _TN_ARCH_H */
256 
TN_UWord * _tn_arch_stack_init(TN_TaskBody *task_func, TN_UWord *stack_top, int stack_size, void *param)
Should put initial CPU context to the provided stack pointer for new task and return current stack po...
PIC32 architecture-dependent routines.
int _tn_arch_is_int_disabled(void)
Should return 1 if system interrupts are currently disabled, 0 otherwise.
void _tn_arch_context_switch_pend(void)
Called whenever we need to switch context from one task to another.
TN_UWord * _tn_arch_stack_top_get(TN_UWord *stack_low_address, int stack_size)
Should return top of the stack, which may be:
void tn_arch_int_en(void)
Unconditionally enable interrupts.
void tn_arch_int_dis(void)
Unconditionally disable system interrupts.
PIC24/dsPIC architecture-dependent routines.
int _tn_arch_inside_isr(void)
Should return 1 if system ISR is currently running, 0 otherwise.
void( TN_TaskBody)(void *param)
Prototype for task body function.
Definition: tn_common.h:144
TN_UWord tn_arch_sr_save_int_dis(void)
Disable system interrupts and return previous value of status register, atomically.
void _tn_arch_context_switch_now_nosave(void)
Called whenever we need to switch context to new task, but don't save current context.
void tn_arch_sr_restore(TN_UWord sr)
Restore previously saved status register.
unsigned int TN_UWord
Unsigned integer type whose size is equal to the size of CPU register.
void _tn_arch_sys_init(TN_UWord *int_stack, unsigned int int_stack_size)
Architecture-dependent system startup routine.