mirror of
https://github.com/ep00ch/lwip-contrib-mac.git
synced 2024-06-12 01:29:28 +00:00
281 lines
7.0 KiB
C
281 lines
7.0 KiB
C
//==========================================================================
|
|
//####ECOSGPLCOPYRIGHTBEGIN####
|
|
// -------------------------------------------
|
|
// This file is part of eCos, the Embedded Configurable Operating System.
|
|
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
|
|
//
|
|
// eCos is free software; you can redistribute it and/or modify it under
|
|
// the terms of the GNU General Public License as published by the Free
|
|
// Software Foundation; either version 2 or (at your option) any later version.
|
|
//
|
|
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
// for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License along
|
|
// with eCos; if not, write to the Free Software Foundation, Inc.,
|
|
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
|
|
//
|
|
// As a special exception, if other files instantiate templates or use macros
|
|
// or inline functions from this file, or you compile this file and link it
|
|
// with other works to produce a work based on this file, this file does not
|
|
// by itself cause the resulting work to be covered by the GNU General Public
|
|
// License. However the source code for this file must still be made available
|
|
// in accordance with section (3) of the GNU General Public License.
|
|
//
|
|
// This exception does not invalidate any other reasons why a work based on
|
|
// this file might be covered by the GNU General Public License.
|
|
// -------------------------------------------
|
|
//####ECOSGPLCOPYRIGHTEND####
|
|
//==========================================================================
|
|
// Author: Jani Monoses
|
|
// Contributors: Claudio Leonel Salvadori
|
|
//
|
|
|
|
/*
|
|
* This file implements the eCos specific sys_arch functions used by lwIP
|
|
*/
|
|
|
|
#include "lwip/opt.h"
|
|
#include "arch/sys_arch.h"
|
|
#include "lwip/sys.h"
|
|
#include "lwip/def.h"
|
|
|
|
//FIXME use CYG_HWR_whatever for RTC
|
|
|
|
/* lwIp timeouts are milliseconds, eCos time unit is clock tick */
|
|
//1s = 1000ms = 100ticks (eCos default is 100 tick per second for most(all?) platforms)
|
|
#define tick_to_msec(tick) ((u16_t)((tick)*10+1))
|
|
#define msec_to_tick(msec) ((cyg_tick_count_t)(msec+9)/10)
|
|
|
|
/* We use a common var mempool for allocating semaphores, mboxes and threads... */
|
|
static char memvar[CYGNUM_LWIP_VARMEMPOOL_SIZE];
|
|
static cyg_mempool_var var_mempool;
|
|
static cyg_handle_t var_mempool_h;
|
|
|
|
|
|
#define SYS_THREADS 2 /* polling thread and tcpip_thread */
|
|
|
|
#define THREAD_COUNT (CYGNUM_LWIP_APP_THREADS + SYS_THREADS)
|
|
static char memfix[CYGNUM_LWIP_THREAD_STACK_SIZE * THREAD_COUNT];
|
|
|
|
/* List of threads: associate eCos thread info with lwIP timeout info */
|
|
struct lwip_thread {
|
|
struct lwip_thread * next;
|
|
struct sys_timeouts to;
|
|
cyg_handle_t th;
|
|
cyg_thread t;
|
|
} *threads;
|
|
|
|
/*
|
|
* Timeout for threads which were not created by sys_thread_new
|
|
* usually "main"
|
|
*/
|
|
struct sys_timeouts to;
|
|
|
|
/*
|
|
* Set up memory pools and threads
|
|
*/
|
|
void sys_init(void)
|
|
{
|
|
cyg_mempool_var_create(memvar, sizeof(memvar), &var_mempool_h, &var_mempool);
|
|
|
|
threads = NULL;
|
|
to.next = NULL;
|
|
}
|
|
|
|
/*
|
|
* Create a new mbox.If no memory is available return NULL
|
|
*/
|
|
sys_mbox_t sys_mbox_new(void)
|
|
{
|
|
cyg_mbox * mbox;
|
|
cyg_handle_t m;
|
|
mbox = (cyg_mbox *)cyg_mempool_var_try_alloc(var_mempool_h, sizeof(cyg_mbox));
|
|
|
|
/* out of memory? */
|
|
if(!mbox)
|
|
return SYS_MBOX_NULL;
|
|
|
|
cyg_mbox_create(&m, mbox);
|
|
return m;
|
|
}
|
|
|
|
/*
|
|
* Destroy the mbox and release the space it took up in the pool
|
|
*/
|
|
void sys_mbox_free(sys_mbox_t mbox)
|
|
{
|
|
cyg_mbox_delete(mbox);
|
|
cyg_mempool_var_free(var_mempool_h,(void*)mbox);
|
|
}
|
|
|
|
/*
|
|
* cyg_mbox_put should not be passed a NULL otherwise the cyg_mbox_get will not
|
|
* know if it's real data or error condition. But lwIP does pass NULL on occasion
|
|
* in cases when maybe using a semaphore would be better. So this dummy_msg replaces
|
|
* NULL data
|
|
*/
|
|
|
|
int dummy_msg = 1;
|
|
|
|
/*
|
|
* Post data to a mbox.
|
|
*/
|
|
void sys_mbox_post(sys_mbox_t mbox, void *data)
|
|
{
|
|
if (!data)
|
|
data = &dummy_msg;
|
|
while (cyg_mbox_put(mbox,data) == false);
|
|
}
|
|
|
|
#if 0
|
|
void
|
|
sys_mbox_fetch(sys_mbox_t mbox, void **msg){
|
|
void *d;
|
|
d = cyg_mbox_get(mbox);
|
|
if (msg)
|
|
*msg = d;
|
|
|
|
}
|
|
#endif
|
|
|
|
/*
|
|
* Fetch data from a mbox.Wait for at most timeout millisecs
|
|
* Return -1 if timed out otherwise time spent waiting.
|
|
*/
|
|
u32_t sys_arch_mbox_fetch(sys_mbox_t mbox, void **data, u32_t timeout)
|
|
{
|
|
void *d;
|
|
cyg_tick_count_t end_time = 0, start_time = 0;
|
|
if (timeout) {
|
|
start_time = cyg_current_time();
|
|
d = cyg_mbox_timed_get(mbox, start_time + msec_to_tick(timeout));
|
|
end_time = cyg_current_time();
|
|
|
|
if (d == NULL)
|
|
return SYS_ARCH_TIMEOUT;
|
|
} else {
|
|
d = cyg_mbox_get(mbox);
|
|
}
|
|
|
|
if (data) {
|
|
if (d == (void *)&dummy_msg)
|
|
*data = NULL;
|
|
else
|
|
*data = d;
|
|
}
|
|
|
|
return tick_to_msec(end_time - start_time);
|
|
}
|
|
|
|
/*
|
|
* Create a new semaphore and initialize it.
|
|
* If no memory is available return NULL
|
|
*/
|
|
sys_sem_t sys_sem_new(u8_t count)
|
|
{
|
|
sys_sem_t sem;
|
|
|
|
sem = (cyg_sem_t *)cyg_mempool_var_try_alloc(var_mempool_h, sizeof(cyg_sem_t));
|
|
/* out of memory? */
|
|
if(!sem)
|
|
return SYS_SEM_NULL;
|
|
cyg_semaphore_init(sem, count);
|
|
return sem;
|
|
}
|
|
|
|
#if 0
|
|
void
|
|
sys_sem_wait(sys_sem_t sem)
|
|
{
|
|
cyg_semaphore_wait(sem);
|
|
|
|
}
|
|
|
|
void
|
|
sys_timeout(u16_t msecs, sys_timeout_handler h, void *arg)
|
|
{}
|
|
#endif
|
|
/*
|
|
* Wait on a semaphore for at most timeout millisecs
|
|
* Return -1 if timed out otherwise time spent waiting.
|
|
*/
|
|
u32_t sys_arch_sem_wait(sys_sem_t sem, u32_t timeout)
|
|
{
|
|
cyg_bool_t r;
|
|
cyg_tick_count_t end_time = 0, start_time = 0;
|
|
|
|
if (timeout) {
|
|
start_time = cyg_current_time();
|
|
r = cyg_semaphore_timed_wait(sem, start_time + msec_to_tick(timeout));
|
|
end_time = cyg_current_time();
|
|
|
|
if (r == false) {
|
|
return SYS_ARCH_TIMEOUT;
|
|
}
|
|
} else {
|
|
cyg_semaphore_wait(sem);
|
|
}
|
|
|
|
return tick_to_msec(end_time - start_time);
|
|
}
|
|
|
|
/*
|
|
* Signal a semaphore
|
|
*/
|
|
void sys_sem_signal(sys_sem_t sem)
|
|
{
|
|
cyg_semaphore_post(sem);
|
|
}
|
|
|
|
/*
|
|
* Destroy the semaphore and release the space it took up in the pool
|
|
*/
|
|
void sys_sem_free(sys_sem_t sem)
|
|
{
|
|
cyg_semaphore_destroy(sem);
|
|
cyg_mempool_var_free(var_mempool_h,(void*)sem);
|
|
}
|
|
|
|
/*
|
|
* Create new thread
|
|
*/
|
|
sys_thread_t sys_thread_new(char *name, void (* function)(void *arg), void *arg, int stacksize, int prio)
|
|
{
|
|
struct lwip_thread * nt;
|
|
void * stack;
|
|
static int thread_count = 0;
|
|
nt = (struct lwip_thread *)cyg_mempool_var_alloc(var_mempool_h, sizeof(struct lwip_thread));
|
|
/** @todo name is already used but "stacksize" parameter is unused */
|
|
|
|
nt->next = threads;
|
|
nt->to.next = NULL;
|
|
|
|
threads = nt;
|
|
|
|
stack = (void *)(memfix+CYGNUM_LWIP_THREAD_STACK_SIZE*thread_count++);
|
|
cyg_thread_create(prio, (cyg_thread_entry_t *)function, (cyg_addrword_t)arg,
|
|
name, stack, CYGNUM_LWIP_THREAD_STACK_SIZE, &(nt->th), &(nt->t) );
|
|
|
|
cyg_thread_resume(nt->th);
|
|
return NULL;
|
|
}
|
|
|
|
/*
|
|
* Return current thread's timeout info
|
|
*/
|
|
struct sys_timeouts *sys_arch_timeouts(void)
|
|
{
|
|
cyg_handle_t ct;
|
|
struct lwip_thread *t;
|
|
|
|
ct = cyg_thread_self();
|
|
for(t = threads; t; t = t->next)
|
|
if (t->th == ct)
|
|
return &(t->to);
|
|
|
|
return &to;
|
|
}
|