CMSIS2000  0.0.7
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
context.h
Go to the documentation of this file.
1 /*
2  * CMSIS2000
3  * CMSIS-like sources for LPC2xxx series MCUs
4  *
5  * (C) Copyright 2011-2012, Dmitriy Cherepanov, All Rights Reserved
6  *
7  * Version: 0.0.7
8  * Date of the Last Update: 2013-03-04
9  *
10  * Permission is hereby granted, free of charge, to any person obtaining a copy
11  * of this software and associated documentation files (the "Software"), to
12  * deal in the Software without restriction, including without limitation the
13  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
14  * sell copies of the Software, and to permit persons to whom the Software is
15  * furnished to do so, subject to the following conditions:
16  *
17  * The above copyright notice and this permission notice shall be included in
18  * all copies or substantial portions of the Software.
19  *
20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
26  * IN THE SOFTWARE.
27  *
28  * Do not be lasy! For the latest version see http://irtos.sourceforge.net .
29  *
30  *
31 #*/
32 /* coroutine.h
33  *
34  * Coroutine mechanics, implemented on top of standard ANSI C. See
35  * http://www.chiark.greenend.org.uk/~sgtatham/coroutines.html for
36  * a full discussion of the theory behind this.
37  *
38  * To use these macros to define a coroutine, you need to write a
39  * function that looks something like this.
40  *
41  * [Simple version using static variables (scr macros)]
42  * int ascending (void) {
43  * static int i;
44  *
45  * scrBegin;
46  * for (i=0; i<10; i++) {
47  * scrReturn(i);
48  * }
49  * scrFinish(-1);
50  * }
51  *
52  * [Re-entrant version using an explicit context structure (ccr macros)]
53  * int ascending (ccrContParam) {
54  * ccrBeginContext;
55  * int i;
56  * ccrEndContext(foo);
57  *
58  * ccrBegin(foo);
59  * for (foo->i=0; foo->i<10; foo->i++) {
60  * ccrReturn(foo->i);
61  * }
62  * ccrFinish(-1);
63  * }
64  *
65  * In the static version, you need only surround the function body
66  * with `scrBegin' and `scrFinish', and then you can do `scrReturn'
67  * within the function and on the next call control will resume
68  * just after the scrReturn statement. Any local variables you need
69  * to be persistent across an `scrReturn' must be declared static.
70  *
71  * In the re-entrant version, you need to declare your persistent
72  * variables between `ccrBeginContext' and `ccrEndContext'. These
73  * will be members of a structure whose name you specify in the
74  * parameter to `ccrEndContext'.
75  *
76  * The re-entrant macros will malloc() the state structure on first
77  * call, and free() it when `ccrFinish' is reached. If you want to
78  * abort in the middle, you can use `ccrStop' to free the state
79  * structure immediately (equivalent to an explicit return() in a
80  * caller-type routine).
81  *
82  * A coroutine returning void type may call `ccrReturnV',
83  * `ccrFinishV' and `ccrStopV', or `scrReturnV', to avoid having to
84  * specify an empty parameter to the ordinary return macros.
85  *
86  * Ground rules:
87  * - never put `ccrReturn' or `scrReturn' within an explicit `switch'.
88  * - never put two `ccrReturn' or `scrReturn' statements on the same
89  * source line.
90  *
91  * The caller of a static coroutine calls it just as if it were an
92  * ordinary function:
93  *
94  * void main(void) {
95  * int i;
96  * do {
97  * i = ascending();
98  * printf("got number %d\n", i);
99  * } while (i != -1);
100  * }
101  *
102  * The caller of a re-entrant coroutine must provide a context
103  * variable:
104  *
105  * void main(void) {
106  * ccrContext z = 0;
107  * do {
108  * printf("got number %d\n", ascending (&z));
109  * } while (z);
110  * }
111  *
112  * Note that the context variable is set back to zero when the
113  * coroutine terminates (by crStop, or by control reaching
114  * crFinish). This can make the re-entrant coroutines more useful
115  * than the static ones, because you can tell when they have
116  * finished.
117  *
118  * If you need to dispose of a crContext when it is non-zero (that
119  * is, if you want to stop calling a coroutine without suffering a
120  * memory leak), the caller should call `ccrAbort(ctx)' where `ctx'
121  * is the context variable.
122  *
123  * This mechanism could have been better implemented using GNU C
124  * and its ability to store pointers to labels, but sadly this is
125  * not part of the ANSI C standard and so the mechanism is done by
126  * case statements instead. That's why you can't put a crReturn()
127  * inside a switch() statement.
128  */
129 
130 
131 /* coroutine.h is copyright 2011 Cherepanov Dmitriy.
132  * coroutine.h is copyright 1995,2000 Simon Tatham.
133  *
134  * Permission is hereby granted, free of charge, to any person
135  * obtaining a copy of this software and associated documentation
136  * files (the "Software"), to deal in the Software without
137  * restriction, including without limitation the rights to use,
138  * copy, modify, merge, publish, distribute, sublicense, and/or
139  * sell copies of the Software, and to permit persons to whom the
140  * Software is furnished to do so, subject to the following
141  * conditions:
142  *
143  * The above copyright notice and this permission notice shall be
144  * included in all copies or substantial portions of the Software.
145  *
146  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
147  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
148  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
149  * NONINFRINGEMENT. IN NO EVENT SHALL SIMON TATHAM BE LIABLE FOR
150  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
151  * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
152  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
153  * SOFTWARE.
154  *
155  */
156 
157 #ifndef _CR_CONTEXT_H_
158 #define _CR_CONTEXT_H_ 1
159 
160 #ifdef _CR_CONTEXT_H_SCHEME /* if another non portable realization*/
161  #include _CR_CONTEXT_H_SCHEME
162 #else
163 typedef signed int cr_cntx_t;
164 #define CR_CONTEXT_INIT_VALUE 0
165 
166 #define CR_EXECUTING(context) (context > 0)
167 #define CR_EXITED(context) (context == 0)
168 #define CR_ERROR(context) (context < 0)
169 
170 /*
171  advantage of static coroutines -- can return usual values
172  disadvantage of static coroutines -- can not be run two examples on the same code
173 */
174 /*
175  * `scr' macros for static coroutines.
176  */
177  /*
178 #define CR_CONTEXT_RESTORE(cntx) switch(cntx) { case 0:;
179 #define CR_CONTEXT_SAVE_AND_RETURN(cntx) do {\
180  return (cntx = (cr_cntx_t)CR_CONTEXT_INIT_VALUE);\
181  case __LINE__:;\
182  } while (0)
183 #define CR_CONTEXT_RESET_AND_RETURN(cntx) do {\
184  return (cntx = (cr_cntx_t)CR_CONTEXT_INIT_VALUE);\
185  } while (0)
186 
187 #define CR_CONTEXT_ERROR(cr,error) do {\
188  cntx = (cr_cntx_t)CR_CONTEXT_INIT_VALUE; \
189  return (error);\
190  } while (0)
191 #define CR_CONTEXT_END(cntx) }
192 
193 
194 
195 #define CR_WAIT(cr,condition) do { \
196  \
197  if (!(condition)) { \
198  CR_CONTEXT_RETURN \
199  } \
200  \
201  } while (0)
202 */
203 /*
204  * `ccr' macros for re-entrant coroutines.
205  */
206 #define CR_CONTEXT_RESTORE(cntx) switch(cntx) { case 0:
207 #define CR_CONTEXT_SAVE_AND_RETURN(cntx) do {\
208  return (cntx = (cr_cntx_t)__LINE__);\
209  case __LINE__:;\
210  } while (0)
211 #define CR_CONTEXT_RESET_AND_RETURN(cntx) do {\
212  return (cntx = (cr_cntx_t)CR_CONTEXT_INIT_VALUE);\
213  } while (0)
214 
215 #define CR_CONTEXT_ERROR(cr,error) do {\
216  cr = (cr_cntx_t)CR_CONTEXT_INIT_VALUE; \
217  return (error);\
218  } while (0)
219 #define CR_CONTEXT_END(cntx) }
220 
221 
222 
223 #define CR_WAIT(cr,condition) do { \
224  \
225  if (!(condition)) { \
226  CR_CONTEXT_RETURN \
227  } \
228  \
229  } while (0)
230 
231 #endif /* _CR_CONTEXT_H_SCHEME */
232 #endif /* _CR_CONTEXT_H_ */