[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[lwip-users] question about sys_mbox_fetch() which is called in netconn_
From: |
tao meng |
Subject: |
[lwip-users] question about sys_mbox_fetch() which is called in netconn_recv! |
Date: |
Fri, 17 Sep 2004 10:45:22 +0800 |
Dear lwip users:
I use two different communication mechanism between NE2000 NIC receive
packet interrupt and my own read packet task:one is using a
global variable,the other is using Semaphore,that is after create a
semaphore, I will call OSSemPend(my_sem,0,&err) in my read packet task, and
call OSSemPost() in NE2000 NIC receive packet interrupt.
1.First communication machanism
Now I can make lwip0.7.2+ucos_ii2.70 run stable on my ADI-BF532 board
if I use a global Flag"Global_Flag" in small packet size.If NE2000 receive
packet interrupt is coming then I will set "Global_Flag = 1",then In one of
my task,which is use to read packet from the NIC,I just test
"Global_Flag",given as follows:
////////////////////////////////
(1)void ne2k_isr(void)
{
//other code is omitted
if (isr & ISR_PRX)
{
//* pNE_ISR = ISR_PRX; // clear interrupt
Global_Flag = 1;
}
}
(2)void ReadPacketTask(void *param)
{
INT8U err;
param = param;
while(1)
{
while(rtl8019as_input(rtl8019as_netif));
OSTimeDly(1);
}
}
(3)bool Global_Flag = 0;
int rtl8019as_input(struct netif *my_netif)
{
u8_t curr,bnry;
if(Global_Flag == 0)
return 1;
Global_Flag = 0;
* pNE_CR = CMD_PAGE1 | CMD_NODMA | CMD_RUN;
curr =* pNE_CURR;
* pNE_CR = CMD_PAGE0 | CMD_NODMA | CMD_RUN;
bnry =* pNE_BNRY;
if(curr == bnry)
return 1;
//get more than one packet until receive buffer is empty
while(curr != bnry )
{
ne2k_input(my_netif);//
//get curr and bnry again
* pNE_CR=CMD_PAGE1 | CMD_NODMA | CMD_RUN;
curr =* pNE_CURR;
* pNE_CR=CMD_PAGE0 | CMD_NODMA | CMD_RUN;
bnry =* pNE_BNRY;
}
* pNE_CR = CMD_PAGE0 | CMD_NODMA | CMD_RUN;
* pNE_ISR |= ISR_PRX; // clear interrupt
return 0;
}
////////////////////////////////
To the above code, I still have two questions:
(a).Since I should call at least a ucos_ii service in ucos_ii task,so I
just call OSTimeDly(1) in ReadPacketTask,but I think it will result in low
efficiency,and is there any other method to avoid making my task wait a
fixed period of time???(The method of using semaphore I will talk about
later!)
(b)If I use the above code, I found that data throughput is very limited in
both tcp and udp, even though they can work very stable in small packet
size!So I want to know how I can enlarge the throughput both in tcp and
udp!
2.Second communication machnism
(1)void main(void)
{
HardWareInit();
OSInit(); // Initialize uC/OS
//++9-10
rtl8019as_Sem = OSSemCreate(0);
CreateTasks();
// Start Multitasking
OSStart();
}
(2)void ne2k_isr(void)
{
//other code is omitted
//got packet with no errors
if (isr & ISR_PRX)
{
//* pNE_ISR = ISR_PRX; // clear interrupt
err = OSSemPost(rtl8019as_Sem);
}
}
(3)void ReadPacketTask(void *param)
{
INT8U err;
param = param;
while(1)
{
OSSemPend(rtl8019as_Sem,0,&err);
if(err != OS_NO_ERR)
{
printf("OSSemPend() error,err = %d\n",err);
OSTaskSuspend(OS_PRIO_SELF);
}
rtl8019as_service(rtl8019as_netif);
}
}
(4)void rtl8019as_service(struct netif *netif)
{
u8_t curr,bnry;
* pNE_CR = CMD_PAGE1 | CMD_NODMA | CMD_RUN;
curr =* pNE_CURR;
* pNE_CR = CMD_PAGE0 | CMD_NODMA | CMD_RUN;
bnry =* pNE_BNRY;
//get more than one packet until receive buffer is empty
while(curr != bnry )
{
ne2k_input(netif);
//get curr and bnry again
* pNE_CR=CMD_PAGE1 | CMD_NODMA | CMD_RUN;
curr =* pNE_CURR;
* pNE_CR=CMD_PAGE0 | CMD_NODMA | CMD_RUN;
bnry =* pNE_BNRY;
}
* pNE_CR = CMD_PAGE0 | CMD_NODMA | CMD_RUN;
* pNE_ISR |= ISR_PRX;
}
In this communication mechanism I still have the following questions:
(1)sometimes it shows that "sys_mbox_fetch(conn->recvmbox, (void **)&p);"
(which is called in netconn_recv() ) return "p == NULL",that is the
following branch will be enter in netconn_recv():
/////////////////
/* If we are closed, we indicate that we no longer wish to receive
data by setting conn->recvmbox to SYS_MBOX_NULL. */
if (p == NULL)
{
memp_free(MEMP_NETBUF, buf);
sys_mbox_free(conn->recvmbox);
conn->recvmbox = SYS_MBOX_NULL;
DEBUGU(1,("In netconn_recv(),p == NULL\n\r"));
return NULL;
}
/////////////////
So I cannot transfer data anymore!The following is the "sys_mbox_fetch()"
and "sys_arch_mbox_fetch" that I use:
/////////////////////
(1)void
sys_mbox_fetch(sys_mbox_t mbox, void **msg)
{
u32_t time;
struct sys_timeouts *timeouts;
struct sys_timeout *tmptimeout;
sys_timeout_handler h;
void *arg;
again:
timeouts = sys_arch_timeouts();
if (!timeouts || !timeouts->next)
{
//
//DEBUGU(1,("In sys_mbox_fetch(),before1111\n\r"));
sys_arch_mbox_fetch(mbox, msg, 0);
}
else
{
if (timeouts->next->time > 0)
{
//
//DEBUGU(1,("In sys_mbox_fetch(),before2222\n\r"));
time = sys_arch_mbox_fetch(mbox, msg, timeouts->next->time);
}
else
{
time = SYS_ARCH_TIMEOUT;
}
if (time == SYS_ARCH_TIMEOUT)
{
/* If time == SYS_ARCH_TIMEOUT, a timeout occured before a message
could be fetched. We should now call the timeout handler and
deallocate the memory allocated for the timeout. */
tmptimeout = timeouts->next;
timeouts->next = tmptimeout->next;
h = tmptimeout->h;
arg = tmptimeout->arg;
memp_free(MEMP_SYS_TIMEOUT, tmptimeout);
if (h != NULL)
{
LWIP_DEBUGF(SYS_DEBUG, ("smf calling h=%p(%p)\n", (void *)h, (void
*)arg));
h(arg);
}
/* We try again to fetch a message from the mbox. */
goto again;
}
else
{
/* If time != SYS_ARCH_TIMEOUT, a message was received before the
timeout
occured. The time variable is set to the number of
milliseconds we waited for the message. */
if (time <= timeouts->next->time)
{
timeouts->next->time -= time;
}
else
{
timeouts->next->time = 0;
}
}
}
}
(2)
u32_t sys_arch_mbox_fetch(sys_mbox_t mbox, void **data, u32_t timeout)
{
u8_t ucErr;
u32_t ucos_timeout;
void *temp;
if(timeout)
{
ucos_timeout = (timeout * OS_TICKS_PER_SEC)/1000;
if(ucos_timeout < 1)
ucos_timeout = 1;
else if(ucos_timeout > 65535)
ucos_timeout = 65535;
}
else
{
ucos_timeout = 0;
}
temp = OSQPend( mbox->pQ, ucos_timeout, &ucErr );
if(data)
{
if( temp == (void*)&pvNullPointer )
{
*data = NULL;
}
else
{
*data = temp;
}
}
if( ucErr == OS_TIMEOUT )
{
timeout = SYS_ARCH_TIMEOUT;
}
else
{
LWIP_ASSERT( "OSQPend ", ucErr == OS_NO_ERR );
/* Calculate time we waited for the message to arrive. */
/* XXX: we cheat and just pretend that we waited for long! */
timeout = 1;
}
return timeout;
}
/////////////////////
The following is my tcpecho test code:
////////////////////////
/*-----------------------------------------------------------------------------------*/
static void
tcpecho_thread(void *arg)
{
struct netconn *conn, *newconn;
err_t err;
// Create a new connection identifier.
conn = netconn_new(NETCONN_TCP);
// Bind connection to well known port number 7.
netconn_bind(conn, NULL, 7);
// Tell connection to go into listening mode.
netconn_listen(conn);
DEBUGU(TCPECHO_DEBUG,("TcpEcho.c: listen!\n\r"));
//sys_timeout(TCP_TMR_INTERVAL, (sys_timeout_handler)tcpip_tcp_timer,
NULL);
while(1)
{
// Grab new connection.
newconn = netconn_accept(conn);
// Process the new connection.
if(newconn != NULL)
{
struct netbuf * buf;
void * data;
u16_t len;
u32_t i;
while((buf = netconn_recv(newconn)) != NULL)
{
do
{
netbuf_data( buf, & data, & len);
err = netconn_write(newconn, data, len, NETCONN_COPY);
if(err != ERR_OK)
{
//printf("tcpecho: netconn_write: error \"%s\"\n",
lwip_strerr(err));
DEBUGU(1,("Tcpecho.c: netconn_write error!\n\r"));
}
} while(netbuf_next(buf) >= 0);
netbuf_delete(buf);
//OSTimeDly(1);
}
printf("Got EOF, looping\n");
// Close connection and discard connection identifier.
netconn_delete(newconn);
}
}
}
/*-----------------------------------------------------------------------------------*/
void
tcpecho_init(void)
{
sys_thread_new(tcpecho_thread, NULL,8);
}
/*-----------------------------------------------------------------------------------*/
////////////////////////
I am looking forward to hearing your opinion to my problems,Thanks In
advance!
Meng Tao
Nanjing University of Posts and Telecommunications
_________________________________________________________________
与联机的朋友进行交流,请使用 MSN Messenger: http://messenger.msn.com/cn
- [lwip-users] question about sys_mbox_fetch() which is called in netconn_recv!,
tao meng <=