Chinaunix首页 | 论坛 | 博客
  • 博客访问: 11955
  • 博文数量: 2
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 30
  • 用 户 组: 普通用户
  • 注册时间: 2012-08-17 12:22
文章分类

全部博文(2)

文章存档

2014年(2)

我的朋友
最近访客

分类: 嵌入式

2014-01-18 16:18:15

uIP主要用于8位或16位嵌入式系统中,以解决单片机在网络中的通信问题。本案例是uIP基于stm32下的移植,使之能在stm32平台下能进行网络通信。在uIP下一个IP包最大长度为1500 bytes,最小不能低于60。每0.5s读一个IP包,即一个IP包读取的速度为3kbytes/s,uIP的最大传输速度为24kbps
        

Net中主要做的是NetMSG Mannge的数据交互,NetPrv中的数据交互,Net又主要是通过Rj45或者是通过3G网连接到网络的。而在Net的一切的数据交互中,都是通过网络来控制完成。

Net uIP主要工作:

         Net中要做的事有:

1、  mac登陆,连通网络;

2、  查看Msg Manage的相关信息;由于查的命令是通过网络的,在得到数据这后还的在发到,网络上去。

Client  -> MSG -> NET-> MSG -> host

Client  <- MSG<- NET <-          MSG <-  host

3、  Prv中有实时数据(包括出错信息等)传出,在Net中要处理,可能会与MSG Manage 交互,flash交互,,在实时数据的读取上,要有时钟控制监听,在时钟内不断的去轮询是否有实时数据到达,有则优先处理实时数据。

4、  登陆后还可能要做些配置管理,如IPgateway, netmask,,或者是密码的修改等。

5、  命令下达管理。

6、  以后可能还要实现,软件的远程升级等。

 

 

 

在整个案例中所在解决的问题有:

1、  解决uIP下基于TCP协议的webserver服务,使之能实现服务器端与客户端的正常通信。

2、  定义集中器中uIP下的网络通信协议书。使各种要处理的事件数据能在网络中正常传输。

在移植中UIP_BUFSIZE d的最大长为1500(在驱动中可以一次收发的长为1500),而tcpbuf用来存收到的uip_len,tcpbuf最大限度长可以为1440(1500-60),60长为TCP+IP头。
--------------------------------------------------------------------------------------------------------------------
tcp_demoappcall.c
//TCP应用接口函数(UIP_APPCALL)
//完成TCP服务(包括server和client)和HTTP服务
void tcp_demo_appcall(void)
{    
      
    switch(uip_conn->lport)//本地监听端口80和1200
    {
        case HTONS(HTTPPORT):
            httpd_appcall();
            break;
        case HTONS(CLIENTPORT):
            tcp_server_demo_appcall();
            break;
        default:                          
            break;
    }            
    switch(uip_conn->rport)    //远程连接1400端口
    {
        case HTONS(SERVERPORT):
            tcp_client_demo_appcall();
           break;
        default:
           break;
    }   

------------------------------------------------------------------------------------------------------------------------------
tcp_client.c
#include "uip.h"
#include
#include    

u8 g_loginflag=1;
u32 g_logtime;
u32 g_relogtime;
u16 g_revnumb;

u8 pmac[4] = {0x11,0x10,0x3c,0x11};

u8 tcp_client_databuf[TCPLEN];       //发送数据缓存      
u8 tcp_client_sta;                //客户端状态
//[7]:0,无连接;1,已经连接;
//[6]:0,无数据;1,收到客户端数据
//[5]:0,无数据;1,有数据需要发送

//这是一个TCP 客户端应用回调函数。
//该函数通过UIP_APPCALL(tcp_demo_appcall)调用,实现Web Client的功能.
//当uip事件发生时,UIP_APPCALL函数会被调用,根据所属端口(1400),确定是否执行该函数。
//例如 : 当一个TCP连接被创建时、有新的数据到达、数据已经被应答、数据需要重发等事件
void tcp_client_demo_appcall(void)
{    
    u16 i;
    
    u16 mbuflen;
    u8 heattime;
     u32 heatlen;
    
     struct tcp_demo_appstate *s = (struct tcp_demo_appstate *)&uip_conn->appstate;
    if(uip_aborted())tcp_client_aborted();        //连接终止       
    if(uip_timedout())tcp_client_timedout();    //连接超时   
    if(uip_closed())tcp_client_closed();        //连接关闭       
     if(uip_connected())tcp_client_connected();    //连接成功        
    if(uip_acked())tcp_client_acked();            //发送的数据成功送达
     //接收到一个新的TCP数据包
     mbuflen = TCPLEN-1;
    if (uip_newdata())
    {
        if((tcp_client_sta&(1<<6))==0)//还未收到数据
        {
            if(uip_len>mbuflen)
            {           
                ((u8*)uip_appdata)[mbuflen]=0;
            }            
                //strcpy((char*)tcp_client_databuf,uip_appdata);    
            for(i = 0;i             {
                tcp_client_databuf[i] = ((u8*)uip_appdata)[i];
            }
            tcp_client_sta|=1<<6;//表示收到客户端数据
        }                  
    }else if(tcp_client_sta&(1<<5))//有数据需要发送
    {
        s->textptr=tcp_client_databuf;
        s->textlen=strlen((const char*)tcp_client_databuf);

        tcp_client_sta&=~(1<<5);//清除标记
    }  
    /*
    //当需要重发、新数据到达、数据包送达、连接建立时,通知uip发送数据
    if(uip_rexmit()||uip_newdata()||uip_acked()||uip_connected()||uip_poll())
    {
        tcp_client_senddata();
    }*/
    if(tcp_client_sta&(1<<7))   // 连接成功
    {
        if(g_loginflag)
        {
            g_revnumb = LogInToPc(CMD_LOGINPC, pmac);
                        
                       g_logtime = t1_unixTime;
            g_loginflag = 0;
        }
    
        if(g_heatflag)
        {
            g_heatnow = t1_unixTime;
            heattime = g_heatnow-g_heatbefor;
            if(heattime >= 60)
            {
                heatlen = heatbeat(CMD_HEARTBEATACK, pmac);
                //uip_send(s_RevPcBuf,heatlen+2);
                g_heatbefor=0;
                g_heatnow = 0;
                g_heatflag = 0;
            }
        }
               if(g_loginflag == 0)
               {
                     if(uip_rexmit())
                     {
                         AgainLogInToPc(CMD_LOGINPC, pmac, g_revnumb);
                     }
               }
        if(g_heatflag == 0)
        {
            if(uip_rexmit())
            {
                Againheatbeat(CMD_HEARTBEATACK, pmac, heatlen);
            }
        }
    }
}



//这里我们假定Server端的IP地址为:192.168.1.103
//这个IP必须根据Server端的IP修改.
//尝试重新连接

u8 host_ip_buff[4]={192,168,0,149};  //serv 121

void tcp_client_reconnect()
{
    uip_ipaddr_t ipaddr;
    uip_ipaddr(&ipaddr,host_ip_buff[0],host_ip_buff[1],host_ip_buff[2],host_ip_buff[3]);    //设置IP为192.168.1.103
    vTaskDelay(1);
    uip_connect(&ipaddr,htons(SERVERPORT));     //端口为1400
}


u8    Connect(u8 i1,u8 i2,u8 i3,u8 i4)
{
     uip_ipaddr_t ipaddr;
    host_ip_buff[0] = i1;
    host_ip_buff[1] = i2;
    host_ip_buff[2] = i3;
    host_ip_buff[3] = i4;

    uip_ipaddr(&ipaddr,host_ip_buff[0],host_ip_buff[1],host_ip_buff[2],host_ip_buff[3]);    //设置IP为192.168.1.103
    uip_connect(&ipaddr,htons(SERVERPORT));     //端口为1400
}



//终止连接                    
void tcp_client_aborted(void)
{
    tcp_client_sta&=~(1<<7);    //标志没有连接
#if UARTPRINT
    if(uip_aborted())
    {
        Uartprint(7,"\4aborted");
    }
#endif
    g_loginflag = 1;
    tcp_client_reconnect();        //尝试重新连接
    
    //uip_log("tcp_client aborted!\r\n");//打印log
}
//连接超时
void tcp_client_timedout(void)
{
    tcp_client_sta&=~(1<<7);    //标志没有连接
#if UARTPRINT
    if(uip_timedout())
    {
        Uartprint(7,"\4outtime");
    }
#endif
    g_loginflag = 1;
    tcp_client_reconnect();        //尝试重新连接
    
    //uip_log("tcp_client timeout!\r\n");//打印log
}
//连接关闭
void tcp_client_closed(void)
{
    tcp_client_sta&=~(1<<7);    //标志没有连接
#if UARTPRINT
    if(uip_closed())
    {
        Uartprint(6,"\4closed");
    }
#endif
    g_loginflag = 1;
    tcp_client_reconnect();        //尝试重新连接
    
    //uip_log("tcp_client closed!\r\n");//打印log
}    
//连接建立
void tcp_client_connected(void)
{
    struct tcp_demo_appstate *s=(struct tcp_demo_appstate *)&uip_conn->appstate;
     tcp_client_sta|=1<<7;        //标志连接成功
#if UARTPRINT
    if(uip_connected())
    {
        Uartprint(9,"\4connected");
    }
    #endif
      //uip_log("tcp_client connected!\r\n");//打印log
    s->state=STATE_CMD;         //指令状态
    s->textlen=0;
    #if 0
    s->textptr="ALIENTEK STM32 Board Connected Successfully!\r\n";//回应消息
    s->textlen=strlen((char *)s->textptr);    
    #endif
    //if(LogIn(uip_ethaddr.addr,(char *)scanf("%s", mPassWord)) == 0)
    //pritnf("log in is Successfull!\r\n");

}
//发送的数据成功送达
void tcp_client_acked(void)
{                                                
    struct tcp_demo_appstate *s=(struct tcp_demo_appstate *)&uip_conn->appstate;
    s->textlen=0;//发送清零
    //uip_log("tcp_client acked!\r\n");//表示成功发送        
}
//发送数据给服务端
void tcp_client_senddata(void)
{
    struct tcp_demo_appstate *s = (struct tcp_demo_appstate *)&uip_conn->appstate;
    //s->textptr:发送的数据包缓冲区指针
    //s->textlen:数据包的大小(单位字节)           
    if(s->textlen>0)uip_send(s->textptr, s->textlen);//发送TCP数据包    
}
------------------------------------------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////////////
                
u8 tcp_server_databuf[TCPLEN];       //发送数据缓存      
u8 tcp_server_sta;                //服务端状态
//[7]:0,无连接;1,已经连接;
//[6]:0,无数据;1,收到客户端数据
//[5]:0,无数据;1,有数据需要发送

        
//这是一个TCP 服务器应用回调函数。
//该函数通过UIP_APPCALL(tcp_demo_appcall)调用,实现Web Server的功能.
//当uip事件发生时,UIP_APPCALL函数会被调用,根据所属端口(1200),确定是否执行该函数。
//例如 : 当一个TCP连接被创建时、有新的数据到达、数据已经被应答、数据需要重发等事件
void tcp_server_demo_appcall(void)
{
    u16 mbuflen;
     struct tcp_demo_appstate *s = (struct tcp_demo_appstate *)&uip_conn->appstate;
    if(uip_aborted())tcp_server_aborted();        //连接终止
     if(uip_timedout())tcp_server_timedout();    //连接超时   
    if(uip_closed())tcp_server_closed();        //连接关闭       
     if(uip_connected())tcp_server_connected();    //连接成功        
    if(uip_acked())tcp_server_acked();            //发送的数据成功送达
    //接收到一个新的TCP数据包
    mbuflen = TCPLEN-1;
    if (uip_newdata())//收到客户端发过来的数据
    {
        if((tcp_server_sta&(1<<6))==0)//还未收到数据
        {
            if(uip_len>mbuflen)
            {           
                ((u8*)uip_appdata)[mbuflen]=0;
            }            
                strcpy((char*)tcp_server_databuf,uip_appdata);    
            //printf("ssss%d\n",tcp_server_databuf[0]);
            tcp_server_sta|=1<<6;//表示收到客户端数据
        }
    }else if(tcp_server_sta&(1<<5))//有数据需要发送
    {
        s->textptr=tcp_server_databuf;
        s->textlen=strlen((const char*)tcp_server_databuf);
        tcp_server_sta&=~(1<<5);//清除标记
    }   
    //当需要重发、新数据到达、数据包送达、连接建立时,通知uip发送数据
    if(uip_rexmit()||uip_newdata()||uip_acked()||uip_connected()||uip_poll())
    {
        tcp_server_senddata();
    }
}      
//终止连接                    
void tcp_server_aborted(void)
{
    tcp_server_sta&=~(1<<7);    //标志没有连接
    //uip_log("tcp_server aborted!\r\n");//打印log
}
//连接超时
void tcp_server_timedout(void)
{
    tcp_server_sta&=~(1<<7);    //标志没有连接
    //uip_log("tcp_server timeout!\r\n");//打印log
}
//连接关闭
void tcp_server_closed(void)
{
    tcp_server_sta&=~(1<<7);    //标志没有连接
    //uip_log("tcp_server closed!\r\n");//打印log
}
//连接建立
void tcp_server_connected(void)
{                                  
    struct tcp_demo_appstate *s = (struct tcp_demo_appstate *)&uip_conn->appstate;
    //uip_conn结构体有一个"appstate"字段指向应用程序自定义的结构体。
    //声明一个s指针,是为了便于使用。
     //不需要再单独为每个uip_conn分配内存,这个已经在uip中分配好了。
    //在uip.c 中 的相关代码如下:
    //        struct uip_conn *uip_conn;
    //        struct uip_conn uip_conns[UIP_CONNS]; //UIP_CONNS缺省=10
    //定义了1个连接的数组,支持同时创建几个连接。
    //uip_conn是一个全局的指针,指向当前的tcp或udp连接。
    tcp_server_sta|=1<<7;        //标志连接成功
      //uip_log("tcp_server connected!\r\n");//打印log
    s->state=STATE_CMD;         //指令状态
    s->textlen=0;
    s->textptr="Connect to ALIENTEK STM32 Board Successfully!\r\n";
    s->textlen=strlen((char *)s->textptr);
}
//发送的数据成功送达
void tcp_server_acked(void)
{                                
    struct tcp_demo_appstate *s=(struct tcp_demo_appstate *)&uip_conn->appstate;
    s->textlen=0;//发送清零
    //uip_log("tcp_server acked!\r\n");//表示成功发送        
}
//发送数据给客户端
void tcp_server_senddata(void)
{
    struct tcp_demo_appstate *s = (struct tcp_demo_appstate *)&uip_conn->appstate;
    //s->textptr : 发送的数据包缓冲区指针
    //s->textlen :数据包的大小(单位字节)           
    if(s->textlen>0)uip_send(s->textptr, s->textlen);//发送TCP数据包    
}







阅读(2248) | 评论(0) | 转发(0) |
0

上一篇:没有了

下一篇:STM32下uIP移植问题

给主人留下些什么吧!~~