1 |
786 |
skrzyp |
//==========================================================================
|
2 |
|
|
//
|
3 |
|
|
// sys_arch.c
|
4 |
|
|
//
|
5 |
|
|
// lwIP system architecture support.
|
6 |
|
|
//
|
7 |
|
|
//==========================================================================
|
8 |
|
|
//####ECOSGPLCOPYRIGHTBEGIN####
|
9 |
|
|
// -------------------------------------------
|
10 |
|
|
// This file is part of eCos, the Embedded Configurable Operating System.
|
11 |
|
|
// Copyright (C) 2008, 2009 Free Software Foundation
|
12 |
|
|
//
|
13 |
|
|
// eCos is free software; you can redistribute it and/or modify it under
|
14 |
|
|
// the terms of the GNU General Public License as published by the Free
|
15 |
|
|
// Software Foundation; either version 2 or (at your option) any later version.
|
16 |
|
|
//
|
17 |
|
|
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
|
18 |
|
|
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
19 |
|
|
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
20 |
|
|
// for more details.
|
21 |
|
|
//
|
22 |
|
|
// You should have received a copy of the GNU General Public License along
|
23 |
|
|
// with eCos; if not, write to the Free Software Foundation, Inc.,
|
24 |
|
|
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
|
25 |
|
|
//
|
26 |
|
|
// As a special exception, if other files instantiate templates or use macros
|
27 |
|
|
// or inline functions from this file, or you compile this file and link it
|
28 |
|
|
// with other works to produce a work based on this file, this file does not
|
29 |
|
|
// by itself cause the resulting work to be covered by the GNU General Public
|
30 |
|
|
// License. However the source code for this file must still be made available
|
31 |
|
|
// in accordance with section (3) of the GNU General Public License.
|
32 |
|
|
//
|
33 |
|
|
// This exception does not invalidate any other reasons why a work based on
|
34 |
|
|
// this file might be covered by the GNU General Public License.
|
35 |
|
|
// -------------------------------------------
|
36 |
|
|
//####ECOSGPLCOPYRIGHTEND####
|
37 |
|
|
//==========================================================================
|
38 |
|
|
//#####DESCRIPTIONBEGIN####
|
39 |
|
|
//
|
40 |
|
|
// Author(s): Simon Kallweit
|
41 |
|
|
// Contributors:
|
42 |
|
|
// Date: 2008-12-02
|
43 |
|
|
// Purpose:
|
44 |
|
|
// Description: Provides the system architecture support for lwIP.
|
45 |
|
|
//
|
46 |
|
|
//####DESCRIPTIONEND####
|
47 |
|
|
//
|
48 |
|
|
//==========================================================================
|
49 |
|
|
|
50 |
|
|
#include <pkgconf/hal.h>
|
51 |
|
|
|
52 |
|
|
#include <cyg/hal/hal_arch.h>
|
53 |
|
|
#include <cyg/kernel/kapi.h>
|
54 |
|
|
|
55 |
|
|
#include <lwip.h>
|
56 |
|
|
|
57 |
|
|
#include "lwip/opt.h"
|
58 |
|
|
#include "arch/sys_arch.h"
|
59 |
|
|
#include "lwip/sys.h"
|
60 |
|
|
#include "lwip/def.h"
|
61 |
|
|
#include "lwip/stats.h"
|
62 |
|
|
#include "lwip/debug.h"
|
63 |
|
|
|
64 |
|
|
// Milliseconds per system tick
|
65 |
|
|
#define MS_PER_TICK ((u32_t) (CYGNUM_HAL_RTC_NUMERATOR / \
|
66 |
|
|
(CYGNUM_HAL_RTC_DENOMINATOR * 1000000LL)))
|
67 |
|
|
|
68 |
|
|
// Macros to convert between ticks and milliseconds
|
69 |
|
|
#define TICKS_TO_MS(_ticks_) ((u16_t) ((_ticks_) * MS_PER_TICK + 1))
|
70 |
|
|
#define MS_TO_TICKS(_ms_) ((cyg_tick_count_t) (((_ms_) + \
|
71 |
|
|
(MS_PER_TICK - 1)) / MS_PER_TICK))
|
72 |
|
|
|
73 |
|
|
#if !NO_SYS
|
74 |
|
|
|
75 |
|
|
// Thread structure
|
76 |
|
|
struct lwip_thread {
|
77 |
|
|
struct lwip_thread *next; // Next thread in linked list
|
78 |
|
|
struct sys_timeouts to; // List of timeouts
|
79 |
|
|
cyg_handle_t handle; // Thread handle
|
80 |
|
|
cyg_thread thread; // Thread store
|
81 |
|
|
};
|
82 |
|
|
|
83 |
|
|
// A var memory pool is used for allocating semaphores, mboxes and threads
|
84 |
|
|
static char var_data[CYGNUM_LWIP_VARMEMPOOL_SIZE];
|
85 |
|
|
static cyg_mempool_var var_mempool;
|
86 |
|
|
static cyg_handle_t var_handle;
|
87 |
|
|
|
88 |
|
|
// Internal lwip thread stacks are statically allocated
|
89 |
|
|
#define TOTAL_STACKSIZE (TCPIP_THREAD_STACKSIZE + \
|
90 |
|
|
SLIPIF_THREAD_STACKSIZE + \
|
91 |
|
|
PPP_THREAD_STACKSIZE + \
|
92 |
|
|
ETH_THREAD_STACKSIZE)
|
93 |
|
|
|
94 |
|
|
static cyg_mutex_t stack_mutex;
|
95 |
|
|
static char stack_data[TOTAL_STACKSIZE];
|
96 |
|
|
static char *stack_pos = stack_data;
|
97 |
|
|
|
98 |
|
|
// Timeout for threads which were not created by sys_thread_new()
|
99 |
|
|
static struct sys_timeouts to;
|
100 |
|
|
|
101 |
|
|
// List of threads
|
102 |
|
|
static struct lwip_thread *threads;
|
103 |
|
|
|
104 |
|
|
//
|
105 |
|
|
// Is called to initialize the sys_arch layer.
|
106 |
|
|
//
|
107 |
|
|
void
|
108 |
|
|
sys_init(void)
|
109 |
|
|
{
|
110 |
|
|
cyg_mempool_var_create(
|
111 |
|
|
var_data,
|
112 |
|
|
sizeof(var_data),
|
113 |
|
|
&var_handle,
|
114 |
|
|
&var_mempool
|
115 |
|
|
);
|
116 |
|
|
|
117 |
|
|
threads = NULL;
|
118 |
|
|
to.next = NULL;
|
119 |
|
|
|
120 |
|
|
cyg_mutex_init(&stack_mutex);
|
121 |
|
|
}
|
122 |
|
|
|
123 |
|
|
//
|
124 |
|
|
// Creates and returns a new semaphore. The "count" argument specifies the
|
125 |
|
|
// initial state of the semaphore.
|
126 |
|
|
//
|
127 |
|
|
sys_sem_t
|
128 |
|
|
sys_sem_new(u8_t count)
|
129 |
|
|
{
|
130 |
|
|
sys_sem_t sem;
|
131 |
|
|
|
132 |
|
|
// Allocate semaphore
|
133 |
|
|
sem = (cyg_sem_t *) cyg_mempool_var_try_alloc(var_handle, sizeof(cyg_sem_t));
|
134 |
|
|
if (!sem)
|
135 |
|
|
return SYS_SEM_NULL;
|
136 |
|
|
cyg_semaphore_init(sem, count);
|
137 |
|
|
|
138 |
|
|
#if SYS_STATS
|
139 |
|
|
lwip_stats.sys.sem.used++;
|
140 |
|
|
if (lwip_stats.sys.sem.used > lwip_stats.sys.sem.max)
|
141 |
|
|
lwip_stats.sys.sem.max = lwip_stats.sys.sem.used;
|
142 |
|
|
#endif
|
143 |
|
|
|
144 |
|
|
return sem;
|
145 |
|
|
}
|
146 |
|
|
|
147 |
|
|
//
|
148 |
|
|
// Deallocates a semaphore.
|
149 |
|
|
//
|
150 |
|
|
void
|
151 |
|
|
sys_sem_free(sys_sem_t sem)
|
152 |
|
|
{
|
153 |
|
|
if (!sem)
|
154 |
|
|
return;
|
155 |
|
|
|
156 |
|
|
cyg_semaphore_destroy(sem);
|
157 |
|
|
cyg_mempool_var_free(var_handle, (void *) sem);
|
158 |
|
|
|
159 |
|
|
#if SYS_STATS
|
160 |
|
|
lwip_stats.sys.sem.used--;
|
161 |
|
|
#endif
|
162 |
|
|
}
|
163 |
|
|
|
164 |
|
|
//
|
165 |
|
|
// Signals a semaphore.
|
166 |
|
|
//
|
167 |
|
|
void
|
168 |
|
|
sys_sem_signal(sys_sem_t sem)
|
169 |
|
|
{
|
170 |
|
|
cyg_semaphore_post(sem);
|
171 |
|
|
}
|
172 |
|
|
|
173 |
|
|
//
|
174 |
|
|
// Blocks the thread while waiting for the semaphore to be signaled. If the
|
175 |
|
|
// "timeout" argument is non-zero, the thread should only be blocked for the
|
176 |
|
|
// specified time (measured in milliseconds). If the "timeout" argument is
|
177 |
|
|
// zero, the thread should be blocked until the semaphore is signalled.
|
178 |
|
|
//
|
179 |
|
|
// If the timeout argument is non-zero, the return value is the number of
|
180 |
|
|
// milliseconds spent waiting for the semaphore to be signaled. If the
|
181 |
|
|
// semaphore wasn't signaled within the specified time, the return value is
|
182 |
|
|
// SYS_ARCH_TIMEOUT. If the thread didn't have to wait for the semaphore
|
183 |
|
|
// (i.e., it was already signaled), the function may return zero.
|
184 |
|
|
//
|
185 |
|
|
// Notice that lwIP implements a function with a similar name, sys_sem_wait(),
|
186 |
|
|
// that uses the sys_arch_sem_wait() function.
|
187 |
|
|
//
|
188 |
|
|
u32_t
|
189 |
|
|
sys_arch_sem_wait(sys_sem_t sem, u32_t timeout)
|
190 |
|
|
{
|
191 |
|
|
if (timeout) {
|
192 |
|
|
cyg_tick_count_t start_time = cyg_current_time();
|
193 |
|
|
|
194 |
|
|
// Wait for semaphore with timeout
|
195 |
|
|
if (!cyg_semaphore_timed_wait(sem, start_time + MS_TO_TICKS(timeout)))
|
196 |
|
|
return SYS_ARCH_TIMEOUT;
|
197 |
|
|
// Return elapsed time
|
198 |
|
|
return TICKS_TO_MS(cyg_current_time() - start_time);
|
199 |
|
|
} else {
|
200 |
|
|
// Wait for semaphore indefinitely
|
201 |
|
|
cyg_semaphore_wait(sem);
|
202 |
|
|
return 0;
|
203 |
|
|
}
|
204 |
|
|
}
|
205 |
|
|
|
206 |
|
|
//
|
207 |
|
|
// Creates an empty mailbox for maximum "size" elements. Elements stored in
|
208 |
|
|
// mailboxes are pointers. You have to define macros "_MBOX_SIZE" in your
|
209 |
|
|
// lwipopts.h, or ignore this parameter in your implementation and use a
|
210 |
|
|
// default size.
|
211 |
|
|
//
|
212 |
|
|
sys_mbox_t
|
213 |
|
|
sys_mbox_new(int size)
|
214 |
|
|
{
|
215 |
|
|
cyg_mbox *mbox;
|
216 |
|
|
cyg_handle_t handle;
|
217 |
|
|
|
218 |
|
|
LWIP_UNUSED_ARG(size);
|
219 |
|
|
|
220 |
|
|
mbox = (cyg_mbox *) cyg_mempool_var_try_alloc(var_handle, sizeof(cyg_mbox));
|
221 |
|
|
if (!mbox)
|
222 |
|
|
return SYS_MBOX_NULL;
|
223 |
|
|
cyg_mbox_create(&handle, mbox);
|
224 |
|
|
|
225 |
|
|
#if SYS_STATS
|
226 |
|
|
lwip_stats.sys.mbox.used++;
|
227 |
|
|
if (lwip_stats.sys.mbox.used > lwip_stats.sys.mbox.max)
|
228 |
|
|
lwip_stats.sys.mbox.max = lwip_stats.sys.mbox.used;
|
229 |
|
|
#endif
|
230 |
|
|
|
231 |
|
|
return handle;
|
232 |
|
|
}
|
233 |
|
|
|
234 |
|
|
//
|
235 |
|
|
// Deallocates a mailbox. If there are messages still present in the mailbox
|
236 |
|
|
// when the mailbox is deallocated, it is an indication of a programming error
|
237 |
|
|
// in lwIP and the developer should be notified.
|
238 |
|
|
//
|
239 |
|
|
void
|
240 |
|
|
sys_mbox_free(sys_mbox_t mbox)
|
241 |
|
|
{
|
242 |
|
|
if (!mbox)
|
243 |
|
|
return;
|
244 |
|
|
|
245 |
|
|
if (cyg_mbox_peek(mbox))
|
246 |
|
|
LWIP_DEBUGF(SYS_DEBUG | LWIP_DBG_LEVEL_WARNING,
|
247 |
|
|
("sys_mbox_free: mbox not empty\n"));
|
248 |
|
|
|
249 |
|
|
cyg_mbox_delete(mbox);
|
250 |
|
|
cyg_mempool_var_free(var_handle, (void *) mbox);
|
251 |
|
|
|
252 |
|
|
#if SYS_STATS
|
253 |
|
|
lwip_stats.sys.mbox.used--;
|
254 |
|
|
#endif
|
255 |
|
|
}
|
256 |
|
|
|
257 |
|
|
//
|
258 |
|
|
// cyg_mbox_put() should not be passed a NULL, otherwise the cyg_mbox_get()
|
259 |
|
|
// will not know if it's real data or an error condition. But lwIP does pass
|
260 |
|
|
// NULL on occasion, in cases when maybe using a semaphore would be better. So
|
261 |
|
|
// this null_msg replaces NULL data.
|
262 |
|
|
//
|
263 |
|
|
static int null_msg;
|
264 |
|
|
|
265 |
|
|
//
|
266 |
|
|
// Posts the "msg" to the mailbox. This function have to block until the "msg"
|
267 |
|
|
// is really posted.
|
268 |
|
|
//
|
269 |
|
|
void
|
270 |
|
|
sys_mbox_post(sys_mbox_t mbox, void *msg)
|
271 |
|
|
{
|
272 |
|
|
// Map NULL messages
|
273 |
|
|
if (!msg)
|
274 |
|
|
msg = &null_msg;
|
275 |
|
|
while (cyg_mbox_put(mbox, msg) == false);
|
276 |
|
|
}
|
277 |
|
|
|
278 |
|
|
//
|
279 |
|
|
// Try to post the "msg" to the mailbox. Returns ERR_MEM if this one is full,
|
280 |
|
|
// else, ERR_OK if the "msg" is posted.
|
281 |
|
|
//
|
282 |
|
|
err_t
|
283 |
|
|
sys_mbox_trypost(sys_mbox_t mbox, void *msg)
|
284 |
|
|
{
|
285 |
|
|
// Map NULL messages
|
286 |
|
|
if (!msg)
|
287 |
|
|
msg = &null_msg;
|
288 |
|
|
return cyg_mbox_tryput(mbox, msg) ? ERR_OK : ERR_MEM;
|
289 |
|
|
}
|
290 |
|
|
|
291 |
|
|
//
|
292 |
|
|
// Blocks the thread until a message arrives in the mailbox, but does not block
|
293 |
|
|
// the thread longer than "timeout" milliseconds (similar to the
|
294 |
|
|
// sys_arch_sem_wait() function). If "timeout" is 0, the thread should be
|
295 |
|
|
// blocked until a message arrives. The "msg" argument is a result parameter
|
296 |
|
|
// that is set by the function (i.e., by doing "*msg = ptr"). The "msg"
|
297 |
|
|
// parameter maybe NULL to indicate that the message should be dropped.
|
298 |
|
|
//
|
299 |
|
|
// The return values are the same as for the sys_arch_sem_wait() function:
|
300 |
|
|
// Number of milliseconds spent waiting or SYS_ARCH_TIMEOUT if there was a
|
301 |
|
|
// timeout.
|
302 |
|
|
//
|
303 |
|
|
// Note that a function with a similar name, sys_mbox_fetch(), is implemented
|
304 |
|
|
// by lwIP.
|
305 |
|
|
//
|
306 |
|
|
u32_t
|
307 |
|
|
sys_arch_mbox_fetch(sys_mbox_t mbox, void **msg, u32_t timeout)
|
308 |
|
|
{
|
309 |
|
|
void *m;
|
310 |
|
|
|
311 |
|
|
if (timeout) {
|
312 |
|
|
cyg_tick_count_t start_time = cyg_current_time();
|
313 |
|
|
|
314 |
|
|
// Wait for mailbox with timeout
|
315 |
|
|
if (!(m = cyg_mbox_timed_get(mbox, start_time + MS_TO_TICKS(timeout))))
|
316 |
|
|
return SYS_ARCH_TIMEOUT;
|
317 |
|
|
// Map NULL messages
|
318 |
|
|
if (m == &null_msg)
|
319 |
|
|
m = NULL;
|
320 |
|
|
*msg = m;
|
321 |
|
|
// Return elapsed time
|
322 |
|
|
return TICKS_TO_MS(cyg_current_time() - start_time);
|
323 |
|
|
} else {
|
324 |
|
|
// Wait for semaphore indefinitely
|
325 |
|
|
m = cyg_mbox_get(mbox);
|
326 |
|
|
// Map NULL messages
|
327 |
|
|
if (m == &null_msg)
|
328 |
|
|
m = NULL;
|
329 |
|
|
*msg = m;
|
330 |
|
|
return 0;
|
331 |
|
|
}
|
332 |
|
|
}
|
333 |
|
|
|
334 |
|
|
//
|
335 |
|
|
// This is similar to sys_arch_mbox_fetch, however if a message is not present
|
336 |
|
|
// in the mailbox, it immediately returns with the code SYS_MBOX_EMPTY. On
|
337 |
|
|
// success 0 is returned.
|
338 |
|
|
//
|
339 |
|
|
// To allow for efficient implementations, this can be defined as a
|
340 |
|
|
// function-like macro in sys_arch.h instead of a normal function. For example,
|
341 |
|
|
// a naive implementation could be:
|
342 |
|
|
//
|
343 |
|
|
// #define sys_arch_mbox_tryfetch(mbox,msg) sys_arch_mbox_fetch(mbox,msg,1)
|
344 |
|
|
//
|
345 |
|
|
// although this would introduce unnecessary delays.
|
346 |
|
|
//
|
347 |
|
|
u32_t
|
348 |
|
|
sys_arch_mbox_tryfetch(sys_mbox_t mbox, void **msg)
|
349 |
|
|
{
|
350 |
|
|
void *m;
|
351 |
|
|
|
352 |
|
|
m = cyg_mbox_tryget(mbox);
|
353 |
|
|
if (!m)
|
354 |
|
|
return SYS_MBOX_EMPTY;
|
355 |
|
|
|
356 |
|
|
if (m == &null_msg)
|
357 |
|
|
m = NULL;
|
358 |
|
|
*msg = m;
|
359 |
|
|
|
360 |
|
|
return 0;
|
361 |
|
|
}
|
362 |
|
|
|
363 |
|
|
//
|
364 |
|
|
// Returns a pointer to the per-thread sys_timeouts structure. In lwIP, each
|
365 |
|
|
// thread has a list of timeouts which is repressented as a linked list of
|
366 |
|
|
// sys_timeout structures. The sys_timeouts structure holds a pointer to a
|
367 |
|
|
// linked list of timeouts. This function is called by the lwIP timeout
|
368 |
|
|
// scheduler and must not return a NULL value.
|
369 |
|
|
//
|
370 |
|
|
// In a single thread sys_arch implementation, this function will simply return
|
371 |
|
|
// a pointer to a global sys_timeouts variable stored in the sys_arch module.
|
372 |
|
|
//
|
373 |
|
|
struct sys_timeouts *
|
374 |
|
|
sys_arch_timeouts(void)
|
375 |
|
|
{
|
376 |
|
|
cyg_handle_t handle;
|
377 |
|
|
struct lwip_thread *t;
|
378 |
|
|
|
379 |
|
|
handle = cyg_thread_self();
|
380 |
|
|
for (t = threads; t; t = t->next)
|
381 |
|
|
if (t->handle == handle)
|
382 |
|
|
return &(t->to);
|
383 |
|
|
|
384 |
|
|
return &to;
|
385 |
|
|
}
|
386 |
|
|
|
387 |
|
|
//
|
388 |
|
|
// Starts a new thread named "name" with priority "prio" that will begin its
|
389 |
|
|
// execution in the function "thread()". The "arg" argument will be passed as
|
390 |
|
|
// an argument to the thread() function. The stack size to used for this thread
|
391 |
|
|
// is the "stacksize" parameter. The id of the new thread is returned. Both the
|
392 |
|
|
// id and the priority are system dependent.
|
393 |
|
|
//
|
394 |
|
|
sys_thread_t
|
395 |
|
|
sys_thread_new(char *name, void (* thread)(void *arg), void *arg,
|
396 |
|
|
int stacksize, int prio)
|
397 |
|
|
{
|
398 |
|
|
void *stack;
|
399 |
|
|
|
400 |
|
|
cyg_mutex_lock(&stack_mutex);
|
401 |
|
|
stack = stack_pos;
|
402 |
|
|
stack_pos += stacksize;
|
403 |
|
|
cyg_mutex_unlock(&stack_mutex);
|
404 |
|
|
|
405 |
|
|
if (stack_pos > stack_data + TOTAL_STACKSIZE)
|
406 |
|
|
CYG_FAIL("Not enough memory to allocate the thread's stack. You may "
|
407 |
|
|
"want to use cyg_lwip_thread_new() instead of "
|
408 |
|
|
"sys_thread_new() so you can provide external stack memory.");
|
409 |
|
|
|
410 |
|
|
return cyg_lwip_thread_new(name, thread, arg, stack, stacksize, prio);
|
411 |
|
|
}
|
412 |
|
|
|
413 |
|
|
//
|
414 |
|
|
// Basically implements the sys_thread_new() call, but adds a "stack" parameter,
|
415 |
|
|
// allowing clients to provide their own stack buffers.
|
416 |
|
|
//
|
417 |
|
|
sys_thread_t
|
418 |
|
|
cyg_lwip_thread_new(char *name, void (* thread)(void *arg), void *arg,
|
419 |
|
|
void *stack, int stacksize, int prio)
|
420 |
|
|
{
|
421 |
|
|
struct lwip_thread *t;
|
422 |
|
|
|
423 |
|
|
t = (struct lwip_thread *) cyg_mempool_var_alloc(
|
424 |
|
|
var_handle, sizeof(struct lwip_thread));
|
425 |
|
|
|
426 |
|
|
t->next = threads;
|
427 |
|
|
t->to.next = NULL;
|
428 |
|
|
|
429 |
|
|
threads = t;
|
430 |
|
|
|
431 |
|
|
cyg_thread_create(
|
432 |
|
|
prio,
|
433 |
|
|
(cyg_thread_entry_t *) thread,
|
434 |
|
|
(cyg_addrword_t) arg,
|
435 |
|
|
name,
|
436 |
|
|
stack,
|
437 |
|
|
stacksize,
|
438 |
|
|
&t->handle,
|
439 |
|
|
&t->thread
|
440 |
|
|
);
|
441 |
|
|
cyg_thread_resume(t->handle);
|
442 |
|
|
|
443 |
|
|
return t->handle;
|
444 |
|
|
}
|
445 |
|
|
|
446 |
|
|
#endif // !NO_SYS
|
447 |
|
|
|
448 |
|
|
//
|
449 |
|
|
// Returns the current time in milliseconds.
|
450 |
|
|
//
|
451 |
|
|
u32_t
|
452 |
|
|
sys_now(void)
|
453 |
|
|
{
|
454 |
|
|
return cyg_current_time() * MS_PER_TICK;
|
455 |
|
|
}
|
456 |
|
|
|
457 |
|
|
//
|
458 |
|
|
// This optional function does a "fast" critical region protection and returns
|
459 |
|
|
// the previous protection level. This function is only called during very short
|
460 |
|
|
// critical regions. An embedded system which supports ISR-based drivers might
|
461 |
|
|
// want to implement this function by disabling interrupts. Task-based systems
|
462 |
|
|
// might want to implement this by using a mutex or disabling tasking. This
|
463 |
|
|
// function should support recursive calls from the same task or interrupt. In
|
464 |
|
|
// other words, sys_arch_protect() could be called while already protected. In
|
465 |
|
|
// that case the return value indicates that it is already protected.
|
466 |
|
|
//
|
467 |
|
|
// sys_arch_protect() is only required if your port is supporting an operating
|
468 |
|
|
// system.
|
469 |
|
|
//
|
470 |
|
|
sys_prot_t
|
471 |
|
|
sys_arch_protect(void)
|
472 |
|
|
{
|
473 |
|
|
cyg_scheduler_lock();
|
474 |
|
|
|
475 |
|
|
return 0;
|
476 |
|
|
}
|
477 |
|
|
|
478 |
|
|
//
|
479 |
|
|
// This optional function does a "fast" set of critical region protection to the
|
480 |
|
|
// value specified by pval. See the documentation for sys_arch_protect() for
|
481 |
|
|
// more information. This function is only required if your port is supporting
|
482 |
|
|
// an operating system.
|
483 |
|
|
//
|
484 |
|
|
void
|
485 |
|
|
sys_arch_unprotect(sys_prot_t pval)
|
486 |
|
|
{
|
487 |
|
|
LWIP_UNUSED_ARG(pval);
|
488 |
|
|
|
489 |
|
|
cyg_scheduler_unlock();
|
490 |
|
|
}
|