写得不错,顶下
点赞  2011-7-28 16:51

怎样才算通讯稳定呢?

我用了楼主的tcp例子,在接收的函数里加了把收到的数据再发送回去的语句,与ZLG提供的“TCP&UDP测试工具”通讯。,开发板做服务器,“TCP&UDP测试工具”做客户端用发送间隔300ms的速度给开发板发数据,开发板接到数据后,把原数据返回给客户端。发现运行不到10分钟,就不通讯了,开发板无反应,连接不上,但能PING的通。试了几次都这样。这是什么原因呢?是不是程序里还需要加些什么措施?怎样才算通讯稳定呢? 修改的函数如下: static err_t APP_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) { unsigned int i; char *q; struct pbuf *pcopy=p; tAPPState *pState; pState = arg; if((err == ERR_OK) && (p != NULL)) { tcp_recved(pcb, p->tot_len); if(strncmp(p->payload, "LED ON", 6) == 0) { GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_4, GPIO_PIN_4); //pbuf_free(p); //tcp_sent(pcb, App_sent); } if(strncmp(p->payload, "LED OFF", 7) == 0) { GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_4, 0); //pbuf_free(p); //tcp_sent(pcb, App_sent); }  //处理接收部分

 while(pcopy) { tcp_write(pcb,pcopy->payload,pcopy->len,TCP_WRITE_FLAG_COPY); pcopy=pcopy->next; } 。 //发送数据 // send_data(); pbuf_free(p); pbuf_free(pcopy); } if((err == ERR_OK) && (p == NULL)) { // // Close the connection. // tcp_arg(pcb, NULL); tcp_sent(pcb, NULL); tcp_recv(pcb, NULL); mem_free(pState); tcp_close(pcb); } return ERR_OK; } 请高手解答一下,谢谢

[ 本帖最后由 boyong 于 2011-9-8 08:44 编辑 ]
点赞  2011-9-8 08:42
你的中断函数写了吗?怎么没看到,你发的工程里面也没有的啊,有时间的话,速回我。
点赞  2011-9-8 16:32

回复 62楼 boyong 的帖子

我把 pbuf_free(p);注释了,应该是一段时间后分配的内存用完了。
点赞  2011-9-8 17:39

回复 63楼 suguoliu 的帖子

写了,这个里边有两个中断:
    EXTERN  lwIPEthernetIntHandler
        EXTERN  SysTickIntHandler
点赞  2011-9-8 17:42

回复 65楼 academic 的帖子

lwIPEthernetIntHandler这个原函数没看到,在startup.s里面你是定义了,但是没看着原函数,中断能进哪了?
点赞  2011-9-9 08:36

回复 66楼 suguoliu 的帖子

这个函数在 lwiplib.c 里边。
点赞  2011-9-9 08:41
所说的内存用完释放,我这有个问题
while(1)
{
p = pbuf_alloc(PBUF_RAW,sizeof(UDPData),PBUF_RAM);
  p->payload=(void *)UDPData;
  udp_send(Pcb1,p);  
   pbuf_free(p);
  SysCtlDelay(SysCtlClockGet()/3);
}
我这样安排,按理说会一直的发送函数,但是只发了那么一会,在TCP&UDP测试工具上就没有显示了,也就是停止了发送,这怎么解释?
点赞  2011-9-9 08:44

回复 67楼 academic 的帖子

麻烦上传一下lwIPEthernetIntHandler这个中断原函数,你上传的工程里面是没有的,lwiplib.c里边怎么改动了你也没说。
点赞  2011-9-9 08:48

回复 69楼 suguoliu 的帖子

void
lwIPEthernetIntHandler(void)
{
    unsigned long ulStatus;
#if !NO_SYS
    portBASE_TYPE xWake;
#endif

    //
    // Read and Clear the interrupt.
    //
    ulStatus = EthernetIntStatus(ETH_BASE, false);
    EthernetIntClear(ETH_BASE, ulStatus);

    //
    // The handling of the interrupt is different based on the use of a RTOS.
    //
#if NO_SYS
    //
    // No RTOS is being used.  If a transmit/receive interrupt was active,
    // run the low-level interrupt handler.
    //
    if(ulStatus)
    {
        stellarisif_interrupt(&g_sNetIF);
    }

    //
    // Service the lwIP timers.
    //
    lwIPServiceTimers();
#else
    //
    // A RTOS is being used.  Signal the Ethernet interrupt task.
    //
    xQueueSendFromISR(g_pInterrupt, (void *)&ulStatus, &xWake);

    //
    // Disable the Ethernet interrupts.  Since the interrupts have not been
    // handled, they are not asserted.  Once they are handled by the Ethernet
    // interrupt task, it will re-enable the interrupts.
    //
    EthernetIntDisable(ETH_BASE, ETH_INT_RX | ETH_INT_TX);

    //
    // Potentially task switch as a result of the above queue write.
    //
    taskYIELD_FROM_ISR(xWake);
#endif
}
先不需要改lwiplib.c
点赞  2011-9-9 09:13

引用: 原帖由 suguoliu 于 2011-9-9 08:44 发表 所说的内存用完释放,我这有个问题 while(1) { p = pbuf_alloc(PBUF_RAW,sizeof(UDPData),PBUF_RAM); p->payload=(void *)UDPData; udp_send(Pcb1,p); pbuf_free(p); SysCtlDelay(SysCtlClockGe ...

 

这个我需要测试一下才知道。

点赞  2011-9-9 09:16

回复 70楼 academic 的帖子

你再看看这个不是你例子中的中断函数,要是这个的话,你的数据怎么接收的,udp_recv,APP_recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p,
              struct ip_addr *addr, u16_t port),这些都没看到调用。要不你把你的这个工程都传上来吧,我还能自己思考。把上面的UDP和TCP整个用到的全部都传上来岂不快乎
点赞  2011-9-9 09:28

回复 72楼 suguoliu 的帖子

该传的都传了,要不我把 StellarisWare 也传上来。
点赞  2011-9-9 09:30
你再看看,你的目标也是让人看懂让人学会,这一点是毋庸置疑的,现在是这一个函数,那一个函数,调来调去的,你自己的东西当然能懂,但传给别人并不一定能接受,所以说我也只是按你的实践了一遍发现有问题才提出来的,你能把整个工程都传的话,就无需那么多解释了。
点赞  2011-9-9 09:39

回复 74楼 suguoliu 的帖子

关于 TCP 和 UDP 简单的通信这两个例子,是整个工程都传上来了,放到 StellarisWare 下编译就可以通过。其它涉及到的部分,不是这一个例程就可以都展现出来的,怎么觉得我还有东西不传上来呢?
这两个例程已经是我精简了的,如果要看更复杂一点的,建议参考 TI Enet_lwip,Enet_io,S2E,Enet_uip 等例程。
点赞  2011-9-9 10:06

回复 10楼 academic 的帖子

Systick这个中断不是必须的,我把它删掉后,同样可以发送接收。为何要呢?请解释。
点赞  2011-9-9 14:24

回复 academic 的帖子

对i的例子可以调出来了,虽然是出来了,但看了中断程序,我一直不解。中断函数里只有stellarisif_interrupt(&lwip_netif);
我继续往下找stellarisif_interrupt里面的函数,里面有接收有传输的函数,我是大概了解意思了。但跟udp_recv之间的联系在哪里,或者在哪调用到了,都没发现。还有自己编写的那个函数APP_recv_udp,我知道肯定是被用到了,是用在udp_recv被指定数据接收。但都跟中断函数没有关联,这句好话说的有点生硬,我是没找出破绽,你可以解释一下。
点赞  2011-9-9 16:22

回复 11楼 academic 的帖子

//当数据被正确发送到远程主机后(收到ACK),该函数会被调用。
static err_t
App_sent(void *arg, struct tcp_pcb *pcb, u16_t len)
{
LWIP_UNUSED_ARG(len);

if(!arg) {
return ERR_OK;
}
tcp_arg(pcb, NULL);
tcp_sent(pcb, NULL);
tcp_recv(pcb, NULL);
mem_free(arg);
tcp_close(pcb);


return ERR_OK;

}


在这中,我有个问题。为什么发送到远程主机后,要关掉连接tcp_close(pcb);这样子的话只能发送一次,再发送的话,还得重新建立。为何要关掉?
点赞  2011-9-15 15:33
我发现没人来解答了。。。
点赞  2011-9-15 15:34

回复 78楼 suguoliu 的帖子

可以不关掉,关掉应该是为了释放资源。
点赞  2011-9-15 18:44
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复