305 lines
8.0 KiB
C
305 lines
8.0 KiB
C
/*
|
||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
||
* All rights reserved.
|
||
*
|
||
* Redistribution and use in source and binary forms, with or without modification,
|
||
* are permitted provided that the following conditions are met:
|
||
*
|
||
* 1. Redistributions of source code must retain the above copyright notice,
|
||
* this list of conditions and the following disclaimer.
|
||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||
* this list of conditions and the following disclaimer in the documentation
|
||
* and/or other materials provided with the distribution.
|
||
* 3. The name of the author may not be used to endorse or promote products
|
||
* derived from this software without specific prior written permission.
|
||
*
|
||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||
* OF SUCH DAMAGE.
|
||
*
|
||
* This file is part of the lwIP TCP/IP stack.
|
||
*
|
||
* Author: Adam Dunkels <adam@sics.se>
|
||
*
|
||
*/
|
||
/* lwIP includes. */
|
||
#include "lwip/debug.h"
|
||
#include "lwip/def.h"
|
||
#include "lwip/sys.h"
|
||
#include "lwip/mem.h"
|
||
#include "pdebug.h"
|
||
#include <stdint.h>
|
||
#include "comm_types.h"
|
||
|
||
#ifdef USE_RTOS
|
||
|
||
|
||
|
||
//当消息指针为空时,指向一个常量pvNullPointer所指向的值.
|
||
//在UCOS中如果OSQPost()中的msg==NULL会返回一条OS_ERR_POST_NULL
|
||
//错误,而在lwip中会调用sys_mbox_post(mbox,NULL)发送一条空消息,我们
|
||
//在本函数中把NULL变成一个常量指针0Xffffffff
|
||
const void * const pvNullPointer = (mem_ptr_t*)0xffffffff;
|
||
|
||
|
||
err_t sys_mbox_new( sys_mbox_t *mbox, int size)
|
||
{
|
||
(*mbox) = mem_malloc(sizeof(TQ_DESCR));
|
||
memset((*mbox),0,sizeof(TQ_DESCR));
|
||
|
||
if(*mbox)
|
||
{
|
||
if(size > MAX_QUEUE_ENTRIES)
|
||
{
|
||
size=MAX_QUEUE_ENTRIES;
|
||
}
|
||
(*mbox)->pQ = OSQCreate(&((*mbox)->pvQEntries[0]), size); //使用UCOS创建一个消息队列
|
||
LWIP_ASSERT("OSQCreate",(*mbox)->pQ!=NULL);
|
||
if((*mbox)->pQ != NULL)
|
||
{
|
||
return ERR_OK;
|
||
}
|
||
else
|
||
{
|
||
mem_free((*mbox));
|
||
return ERR_MEM;
|
||
}
|
||
}
|
||
else return ERR_MEM;
|
||
}
|
||
|
||
void sys_mbox_free(sys_mbox_t * mbox)
|
||
{
|
||
u8_t ucErr;
|
||
(void)OSQDel((*mbox)->pQ, OS_DEL_ALWAYS, &ucErr);
|
||
LWIP_ASSERT( "OSQDel ",ucErr == OS_ERR_NONE );
|
||
mem_free((*mbox));
|
||
*mbox=NULL;
|
||
}
|
||
|
||
void sys_mbox_post(sys_mbox_t *mbox,void *msg)
|
||
{
|
||
if(msg == NULL)
|
||
{
|
||
msg=(void*)&pvNullPointer;//当msg为空时 msg等于pvNullPointer指向的值
|
||
}
|
||
while(OSQPost((*mbox)->pQ,msg) != OS_ERR_NONE);
|
||
}
|
||
//尝试向一个消息邮箱发送消息
|
||
//此函数相对于sys_mbox_post函数只发送一次消息,
|
||
//发送失败后不会尝试第二次发送
|
||
//*mbox:消息邮箱
|
||
//*msg:要发送的消息
|
||
//返回值:ERR_OK,发送OK
|
||
// ERR_MEM,发送失败
|
||
err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg)
|
||
{
|
||
if(msg == NULL)
|
||
{
|
||
msg=(void*)&pvNullPointer;//当msg为空时 msg等于pvNullPointer指向的值
|
||
}
|
||
if((OSQPost((*mbox)->pQ, msg)) != OS_ERR_NONE)
|
||
{
|
||
return ERR_MEM;
|
||
}
|
||
return ERR_OK;
|
||
}
|
||
|
||
//等待邮箱中的消息
|
||
//*mbox:消息邮箱
|
||
//*msg:消息
|
||
//timeout:超时时间,如果timeout为0的话,就一直等待
|
||
//返回值:当timeout不为0时如果成功的话就返回等待的时间,
|
||
// 失败的话就返回超时SYS_ARCH_TIMEOUT
|
||
u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout)
|
||
{
|
||
u8_t ucErr;
|
||
u32_t ucos_timeout,timeout_new;
|
||
void *temp;
|
||
sys_mbox_t m_box=*mbox;
|
||
if(timeout!=0)
|
||
{
|
||
ucos_timeout=(timeout*OS_TICKS_PER_SEC)/1000; //转换为节拍数,因为UCOS延时使用的是节拍数,而LWIP是用ms
|
||
if(ucos_timeout<1)ucos_timeout=1;//至少1个节拍
|
||
}else ucos_timeout = 0;
|
||
timeout = OSTimeGet(); //获取系统时间
|
||
temp=OSQPend(m_box->pQ,(u16_t)ucos_timeout,&ucErr); //请求消息队列,等待时限为ucos_timeout
|
||
if(msg!=NULL)
|
||
{
|
||
if(temp==(void*)&pvNullPointer)*msg = NULL; //因为lwip发送空消息的时候我们使用了pvNullPointer指针,所以判断pvNullPointer指向的值
|
||
else *msg=temp; //就可知道请求到的消息是否有效
|
||
}
|
||
if(ucErr==OS_ERR_TIMEOUT)timeout=SYS_ARCH_TIMEOUT; //请求超时
|
||
else
|
||
{
|
||
LWIP_ASSERT("OSQPend ",ucErr==OS_ERR_NONE);
|
||
timeout_new=OSTimeGet();
|
||
if (timeout_new>timeout) timeout_new = timeout_new - timeout;//算出请求消息或使用的时间
|
||
else timeout_new = 0xffffffff - timeout + timeout_new;
|
||
timeout=timeout_new*1000/OS_TICKS_PER_SEC + 1;
|
||
}
|
||
return timeout;
|
||
}
|
||
|
||
u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg)
|
||
{
|
||
return sys_arch_mbox_fetch(mbox, msg, 1);
|
||
}
|
||
|
||
int sys_mbox_valid(sys_mbox_t *mbox)
|
||
{
|
||
u8_t ucErr;
|
||
int ret;
|
||
OS_Q_DATA q_data;
|
||
memset(&q_data, 0, sizeof(OS_Q_DATA));
|
||
ucErr = OSQQuery ((*mbox)->pQ,&q_data);
|
||
ret=(ucErr<2 && (q_data.OSNMsgs<q_data.OSQSize))?1:0;
|
||
return ret;
|
||
}
|
||
|
||
void sys_mbox_set_invalid(sys_mbox_t *mbox)
|
||
{
|
||
*mbox = NULL;
|
||
}
|
||
|
||
err_t sys_sem_new(sys_sem_t * sem, u8_t count)
|
||
{
|
||
*sem = OSSemCreate((u16_t)count);
|
||
if(*sem == NULL)
|
||
{
|
||
return ERR_MEM;
|
||
}
|
||
return ERR_OK;
|
||
}
|
||
//等待一个信号量
|
||
//*sem:要等待的信号量
|
||
//timeout:超时时间
|
||
//返回值:当timeout不为0时如果成功的话就返回等待的时间,
|
||
// 失败的话就返回超时SYS_ARCH_TIMEOUT
|
||
u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout)
|
||
{
|
||
u8_t ucErr;
|
||
u32_t ucos_timeout, timeout_new;
|
||
if( timeout!=0)
|
||
{
|
||
ucos_timeout = (timeout * OS_TICKS_PER_SEC) / 1000;//转换为节拍数,因为UCOS延时使用的是节拍数,而LWIP是用ms
|
||
if(ucos_timeout < 1)
|
||
ucos_timeout = 1;
|
||
}else ucos_timeout = 0;
|
||
timeout = OSTimeGet();
|
||
OSSemPend (*sem,(u16_t)ucos_timeout, (u8_t *)&ucErr);
|
||
if(ucErr == OS_ERR_TIMEOUT)timeout=SYS_ARCH_TIMEOUT;//请求超时
|
||
else
|
||
{
|
||
timeout_new = OSTimeGet();
|
||
if (timeout_new>=timeout) timeout_new = timeout_new - timeout;
|
||
else timeout_new = 0xffffffff - timeout + timeout_new;
|
||
timeout = (timeout_new*1000/OS_TICKS_PER_SEC + 1);//算出请求消息或使用的时间(ms)
|
||
}
|
||
return timeout;
|
||
}
|
||
|
||
void sys_sem_signal(sys_sem_t *sem)
|
||
{
|
||
OSSemPost(*sem);
|
||
}
|
||
|
||
void sys_sem_free(sys_sem_t *sem)
|
||
{
|
||
u8_t ucErr;
|
||
(void)OSSemDel(*sem,OS_DEL_ALWAYS,&ucErr);
|
||
if(ucErr != OS_ERR_NONE)
|
||
{
|
||
LWIP_ASSERT("OSSemDel ",ucErr==OS_ERR_NONE);
|
||
}
|
||
*sem = NULL;
|
||
}
|
||
|
||
int sys_sem_valid(sys_sem_t *sem)
|
||
{
|
||
OS_SEM_DATA sem_data;
|
||
return (OSSemQuery (*sem,&sem_data) == OS_ERR_NONE )? 1:0;
|
||
}
|
||
|
||
void sys_sem_set_invalid(sys_sem_t *sem)
|
||
{
|
||
*sem = NULL;
|
||
}
|
||
|
||
void sys_init(void)
|
||
{
|
||
|
||
}
|
||
|
||
OS_STK TCPIP_THREAD_TASK_STK[TASK_TCPIP_THREAD_STK_SIZE];
|
||
sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, int stacksize, int prio)
|
||
{
|
||
CPU_INT08U task_err;
|
||
CPU_INT08U name_err;
|
||
|
||
//OSTaskCreate(thread,arg, &TCPIP_THREAD_TASK_STK[stacksize-1], prio);
|
||
task_err = OSTaskCreateExt((void (*)(void *)) thread,
|
||
(void *) 0,
|
||
(OS_STK *)&TCPIP_THREAD_TASK_STK[stacksize - 1],
|
||
(INT8U ) prio,
|
||
(INT16U ) prio,
|
||
(OS_STK *)&TCPIP_THREAD_TASK_STK[0],
|
||
(INT32U ) stacksize,
|
||
(void *) 0,
|
||
(INT16U )(OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR));
|
||
|
||
#if (OS_TASK_NAME_EN > 0)
|
||
OSTaskNameSet(prio, (u_int8_t *)name, &name_err);
|
||
#endif
|
||
|
||
// if ((task_err == OS_ERR_NONE) && (name_err == OS_ERR_NONE)) {
|
||
// pdebug(DEBUG_LEVEL_INFO,"create %s success...\n\r",(u_int8_t *)name);
|
||
// } else {
|
||
// pdebug(DEBUG_LEVEL_FATAL,"create %s failed...\n\r",(u_int8_t *)name);
|
||
// }
|
||
|
||
return 0;
|
||
}
|
||
|
||
|
||
u32_t sys_now(void)
|
||
{
|
||
return (OSTimeGet()*1000/OS_TICKS_PER_SEC+1);
|
||
}
|
||
|
||
#else
|
||
|
||
static uint32_t lwip_timer;//lwip本地时间计数器,单位:ms
|
||
|
||
void PIT_ISR(void)
|
||
{
|
||
lwip_timer++;
|
||
}
|
||
|
||
u32_t sys_now(void)
|
||
{
|
||
return lwip_timer*10;
|
||
}
|
||
|
||
u8_t timer_expired(u32_t *last_time,u32_t tmr_interval)
|
||
{
|
||
u32_t time;
|
||
time = *last_time;
|
||
if((lwip_timer-time)>=tmr_interval){
|
||
*last_time = lwip_timer;
|
||
return 1;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
#endif
|
||
|
||
|