如标题所示,移植在UCOSSIII系统下的LWIP性能好差,非常不稳定。打开原则的实验网页,有时候图片显示不了,控制LED 蜂鸣器的时候要点击发送好几次才可以.不够在原子哥的UCOSSII的性能好。[mw_shl_code=c,true]/* * 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>
*
*/
/* Porting by Michael Vysotsky <michaelvy@hotmail.com> August 2011 */
/*-----------------------------------------------------------------------------------*/
/*
Deallocates a mailbox. If there are messages still present in the如果当邮箱被释放 仍有消息存在邮箱中
mailbox when the mailbox is deallocated, it is an indication of a 将会有一个处理错误在LWIP中
programming error in lwIP and the developer should be notified. 开发者应该注意
*/
void sys_mbox_free(sys_mbox_t * mbox)
{
OS_ERR ucErr;
LWIP_ASSERT( "sys_mbox_free ", mbox != SYS_MBOX_NULL );
/*-----------------------------------------------------------------------------------
* Posts the "msg" to the mailbox.
*/
void sys_mbox_post(sys_mbox_t *mbox, void *msg)
{
OS_ERR ucErr;
CPU_INT08U i=0;
if( msg == NULL ) msg = (void*)&pvNullPointer;
/* try 10 times */
while(i<10){
OSQPost(mbox, msg,0,OS_OPT_POST_ALL,&ucErr);
if(ucErr == OS_ERR_NONE)
break;
i++;
OSTimeDly(5,OS_OPT_TIME_DLY,&ucErr);
}
LWIP_ASSERT( "sys_mbox_post error!\n", i !=10 );
}
/* Try to post the "msg" to the mailbox. */
err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg)
{
OS_ERR ucErr;
if(msg == NULL ) msg = (void*)&pvNullPointer;
OSQPost(mbox, msg,0,OS_OPT_POST_ALL,&ucErr);
if(ucErr != OS_ERR_NONE){
return ERR_MEM;
}
return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/
/*
Blocks the thread until a message arrives in the mailbox, but does
not block the thread longer than "timeout" milliseconds (similar to
the sys_arch_sem_wait() function). The "msg" argument is a result
parameter that is set by the function (i.e., by doing "*msg =
ptr"). The "msg" parameter maybe NULL to indicate that the message
should be dropped.
The return values are the same as for the sys_arch_sem_wait() function:
Number of milliseconds spent waiting or SYS_ARCH_TIMEOUT if there was a
timeout.
Note that a function with a similar name, sys_mbox_fetch(), is
implemented by lwIP. 等待消息达到邮箱
*/
//等待邮箱中的消息
//*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)
{
OS_ERR ucErr;
OS_MSG_SIZE msg_size;
CPU_TS ucos_timeout;
CPU_TS in_timeout = timeout/LWIP_ARCH_TICK_PER_MS;
if(timeout && in_timeout == 0)
in_timeout = 1;
*msg = OSQPend (mbox, //消息队列
in_timeout, //等待时间
OS_OPT_PEND_BLOCKING, //等待选项
&msg_size, //消息大小
&ucos_timeout, //获取时间戳
&ucErr); //错误代码
if ( ucErr == OS_ERR_TIMEOUT )
ucos_timeout = SYS_ARCH_TIMEOUT;
return ucos_timeout;
}
/**
* Check if an mbox is valid/allocated: 检查一个消息邮箱是否有效
* @param sys_mbox_t *mbox pointer mail box
* @return 1 for valid, 0 for invalid
*/
int sys_mbox_valid(sys_mbox_t *mbox)
{
if(mbox->NamePtr)
return (strcmp(mbox->NamePtr,"?Q"))? 1:0;
else
return 0;
}
/**
* Set an mbox invalid so that sys_mbox_valid returns 0
*/
void sys_mbox_set_invalid(sys_mbox_t *mbox)
{
if(sys_mbox_valid(mbox))
sys_mbox_free(mbox);
}
/* 创建一个信号量
* Creates and returns a new semaphore. The "count" argument specifies
* the initial state of the semaphore. TBD finish and test
*/
err_t sys_sem_new(sys_sem_t * sem, u8_t count)
{
OS_ERR ucErr;
OSSemCreate (sem,"LWIP Sem",count,&ucErr);
if(ucErr != OS_ERR_NONE ){
LWIP_ASSERT("OSSemCreate ",ucErr == OS_ERR_NONE );
return -1;
}
return 0;
}
/*
Blocks the thread while waiting for the semaphore to be
signaled. If the "timeout" argument is non-zero, the thread should
only be blocked for the specified time (measured in
milliseconds).
If the timeout argument is non-zero, the return value is the number of
milliseconds spent waiting for the semaphore to be signaled. If the
semaphore wasn't signaled within the specified time, the return value is
SYS_ARCH_TIMEOUT. If the thread didn't have to wait for the semaphore
(i.e., it was already signaled), the function may return zero.
Notice that lwIP implements a function with a similar name,
sys_sem_wait(), that uses the sys_arch_sem_wait() function. 等待一个信号量
*/
u32_t
sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout)
{
OS_ERR ucErr;
CPU_TS ucos_timeout;
CPU_TS in_timeout = timeout/LWIP_ARCH_TICK_PER_MS; //LWIP_ARCH_TICK_PER_MS=1000/OS_CFG_TICK_RATE_HZ=1
if(timeout && in_timeout == 0)
in_timeout = 1;
OSSemPend (sem, //信号量
in_timeout, //等待时间
OS_OPT_PEND_BLOCKING, //等待选项
&ucos_timeout, //获取时间戳
&ucErr); //错误代码
/* only when timeout! */
if(ucErr == OS_ERR_TIMEOUT)
ucos_timeout = SYS_ARCH_TIMEOUT;
return ucos_timeout;
}
/*-----------------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------------------*/
// TBD
/*-----------------------------------------------------------------------------------*/
/* 此函数的功能是创建一个新的进程并启动进程
Starts a new thread with priority "prio" that will begin its execution in the
function "thread()". The "arg" argument will be passed as an argument to the
thread() function. The id of the new thread is returned. Both the id and
the priority are system dependent.
*/
sys_thread_t sys_thread_new(const char *name, //进程名字 "tcpip_thread"
lwip_thread_fn thread, //进程任务 tcpip_thread
void *arg, //进程任务参数 NULL
int stacksize, //进程任务堆栈大小 1024
int prio) //进程任务优先级
{
int i;
OS_ERR ucErr; //返回的错误参数
CPU_INT08U ubPrio = LWIP_TASK_START_PRIO; //3
CPU_STK * task_stk ; //任务堆栈
int tsk_prio ; //任务优先级
arg = arg;
return ubPrio;
}
/**
* Sleep for some ms. Timeouts are NOT processed while sleeping.
*
* @param ms number of milliseconds to sleep
*/
void sys_msleep(u32_t ms)
{
delay_ms(ms);
}
//获取系统时间,LWIP1.4.1增加的函数
//返回值:当前系统时间(单位:毫秒)
u32_t sys_now(void)
{
OS_TICK os_tick_ctr;
CPU_SR_ALLOC();
/*
This optional function does a "fast" critical region protection and returns
the previous protection level. This function is only called during very short
critical regions. An embedded system which supports ISR-based drivers might
want to implement this function by disabling interrupts. Task-based systems
might want to implement this by using a mutex or disabling tasking. This
function should support recursive calls from the same task or interrupt. In
other words, sys_arch_protect() could be called while already protected. In
that case the return value indicates that it is already protected.
sys_arch_protect() is only required if your port is supporting an operating
system.
*/
sys_prot_t sys_arch_protect(void)
{
CPU_SR_ALLOC();
CPU_CRITICAL_ENTER();
return 1;
}
/*
This optional function does a "fast" set of critical region protection to the
value specified by pval. See the documentation for sys_arch_protect() for
more information. This function is only required if your port is supporting
an operating system.
*/
void sys_arch_unprotect(sys_prot_t pval)
{
CPU_SR_ALLOC();
/**
* SYS_LIGHTWEIGHT_PROT==1: if you want inter-task protection for certain
* critical regions during buffer allocation, deallocation and memory
* allocation and deallocation. 如果你想inter-task保护某些关键区域在缓冲区分配、回收和内存分配和重分配
*/
#define SYS_LIGHTWEIGHT_PROT 1 //为1时使用实时操作系统的轻量级保护,保护关键代码不被中断打断 【原为0】
/**
* NO_SYS==1: Provides VERY minimal functionality. Otherwise,
* use lwIP facilities.
*/
#define NO_SYS 0
/* ---------- Memory options ---------- */
/* MEM_ALIGNMENT: should be set to the alignment of the CPU for which
lwIP is compiled. 4 byte alignment -> define MEM_ALIGNMENT to 4, 2
byte alignment -> define MEM_ALIGNMENT to 2. */
#define MEM_ALIGNMENT 4 //字节对齐
/* MEM_SIZE: the size of the heap memory. If the application will send
a lot of data that needs to be copied, this should be set high. */
#define MEM_SIZE (16000) //【已修改:原为1024】
/* MEMP_NUM_PBUF: the number of memp struct pbufs. If the application
sends a lot of data out of ROM (or other static memory), this
should be set high. */
//原为10
#define MEMP_NUM_PBUF 100 //MEMP_NUM_PBUF:memp结构的pbuf数量,如果应用从ROM或者静态存储区发送大量数据时,这个值应该设置大一点
/* MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One
per active UDP "connection". */
#define MEMP_NUM_UDP_PCB 6
/* MEMP_NUM_TCP_PCB: the number of simulatenously active TCP
connections. */
#define MEMP_NUM_TCP_PCB 10
/* MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP
connections. */
#define MEMP_NUM_TCP_PCB_LISTEN 6
/* MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP
segments. */
#define MEMP_NUM_TCP_SEG 15
/* MEMP_NUM_SYS_TIMEOUT: the number of simulateously active
timeouts. */
#define MEMP_NUM_SYS_TIMEOUT 8
/* ---------- Pbuf options ---------- */
/* PBUF_POOL_SIZE: the number of buffers in the pbuf pool. */
/* Controls if TCP should queue segments that arrive out of
order. Define to 0 if your device is low on memory. */
#undef TCP_QUEUE_OOSEQ
#define TCP_QUEUE_OOSEQ 0 //当TCP的数据段超出队列时的控制位,当设备的内存过小的时候此项应为0
/**
* TCPIP_MBOX_SIZE: The mailbox size for the tcpip thread messages
* The queue size value itself is platform-dependent, but is passed to
* sys_mbox_new() when tcpip_init is called.
*/
#undef TCPIP_MBOX_SIZE
#define TCPIP_MBOX_SIZE MAX_QUEUE_ENTRIES
/**
* DEFAULT_TCP_RECVMBOX_SIZE: The mailbox size for the incoming packets on a
* NETCONN_TCP. The queue size value itself is platform-dependent, but is passed
* to sys_mbox_new() when the recvmbox is created.
*/
#undef DEFAULT_TCP_RECVMBOX_SIZE
#define DEFAULT_TCP_RECVMBOX_SIZE MAX_QUEUE_ENTRIES
/**
* DEFAULT_ACCEPTMBOX_SIZE: The mailbox size for the incoming connections.
* The queue size value itself is platform-dependent, but is passed to
* sys_mbox_new() when the acceptmbox is created.
*/
#undef DEFAULT_ACCEPTMBOX_SIZE
#define DEFAULT_ACCEPTMBOX_SIZE MAX_QUEUE_ENTRIES
/* TCP Maximum segment size. */
#define TCP_MSS (1500 - 40) /* TCP_MSS = (Ethernet MTU - IP header size - TCP header size) */
/* TCP sender buffer space (bytes). */
#define TCP_SND_BUF (4*TCP_MSS)
/* TCP sender buffer space (pbufs). This must be at least = 2 *
TCP_SND_BUF/TCP_MSS for things to work. */
/* ---------- DHCP options ---------- */
/* Define LWIP_DHCP to 1 if you want DHCP configuration of
interfaces. DHCP is not implemented in lwIP 0.5.1, however, so
turning this on does currently not work. */
#define LWIP_DHCP 0
/*
The STM32F107 allows computing and verifying the IP, UDP, TCP and ICMP checksums by hardware:
- To use this feature let the following define uncommented.
- To disable it and process by CPU comment the the checksum.
*/
#define CHECKSUM_BY_HARDWARE
#ifdef CHECKSUM_BY_HARDWARE
/* CHECKSUM_GEN_IP==0: Generate checksums by hardware for outgoing IP packets.*/
#define CHECKSUM_GEN_IP 0
/* CHECKSUM_GEN_UDP==0: Generate checksums by hardware for outgoing UDP packets.*/
#define CHECKSUM_GEN_UDP 0
/* CHECKSUM_GEN_TCP==0: Generate checksums by hardware for outgoing TCP packets.*/
#define CHECKSUM_GEN_TCP 0
/* CHECKSUM_CHECK_IP==0: Check checksums by hardware for incoming IP packets.*/
#define CHECKSUM_CHECK_IP 0
/* CHECKSUM_CHECK_UDP==0: Check checksums by hardware for incoming UDP packets.*/
#define CHECKSUM_CHECK_UDP 0
/* CHECKSUM_CHECK_TCP==0: Check checksums by hardware for incoming TCP packets.*/
#define CHECKSUM_CHECK_TCP 0
#else
/* CHECKSUM_GEN_IP==1: Generate checksums in software for outgoing IP packets.*/
#define CHECKSUM_GEN_IP 1
/* CHECKSUM_GEN_UDP==1: Generate checksums in software for outgoing UDP packets.*/
#define CHECKSUM_GEN_UDP 1
/* CHECKSUM_GEN_TCP==1: Generate checksums in software for outgoing TCP packets.*/
#define CHECKSUM_GEN_TCP 1
/* CHECKSUM_CHECK_IP==1: Check checksums in software for incoming IP packets.*/
#define CHECKSUM_CHECK_IP 1
/* CHECKSUM_CHECK_UDP==1: Check checksums in software for incoming UDP packets.*/
#define CHECKSUM_CHECK_UDP 1
/* CHECKSUM_CHECK_TCP==1: Check checksums in software for incoming TCP packets.*/
#define CHECKSUM_CHECK_TCP 1
#endif
/*
----------------------------------------------
---------- Sequential layer options ----------
----------------------------------------------
*/
/**
* LWIP_NETCONN==1: Enable Netconn API (require to use api_lib.c)
*/
#define LWIP_NETCONN 1
/*
------------------------------------
---------- Socket options ----------
------------------------------------
*/
/**
* LWIP_SOCKET==1: Enable Socket API (require to use sockets.c)
*/
#define LWIP_SOCKET 1