打印

求在STM32上裸机移植LWIP,STM32做CLIENT,CLIENT简单地发送数据

[复制链接]
14490|20
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
can123dao|  楼主 | 2013-7-18 22:00 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
求在STM32上裸机移植LWIP,STM32做TCP CLIENT,CLIENT简单地发送数据
沙发
openrd| | 2013-7-23 21:49 | 只看该作者
哈哈,楼主别求了,我最近也在做这个,还是动手做吧。TCP做server刚做了一点,可以发送数据,但是不太正常有问题
客户端的还没搞定,我也是需要做一个客户端的,纠结了很久,动手做就会有发现的,多交流

使用特权

评论回复
板凳
haibian826| | 2013-7-23 23:39 | 只看该作者
uIP-1.0就行吧??
代码有一个,仅供参考

芯嵌STM32_网口驱动_串口_OK.rar (4.11 MB)

使用特权

评论回复
地板
can123dao|  楼主 | 2013-7-27 09:36 | 只看该作者
openrd 发表于 2013-7-23 21:49
哈哈,楼主别求了,我最近也在做这个,还是动手做吧。TCP做server刚做了一点,可以发送数据,但是不太正常 ...

这个差不多了,想加上DHCP,还有问题

使用特权

评论回复
5
openrd| | 2013-7-29 12:19 | 只看该作者
can123dao 发表于 2013-7-27 09:36
这个差不多了,想加上DHCP,还有问题

发送和接收都有吗?

使用特权

评论回复
6
can123dao|  楼主 | 2013-7-29 15:17 | 只看该作者
openrd 发表于 2013-7-29 12:19
发送和接收都有吗?

使用特权

评论回复
7
openrd| | 2013-7-29 21:04 | 只看该作者
can123dao 发表于 2013-7-29 15:17

udp_connect(uclient_pcb,IP_ADDR_BROADCAST, UDP_CLIENT_PORT);
udp_send(uclient_pcb, p);
我做了udp客户端数据发送之后,就是上面的过程,发送数据时没有问题的,紧接着
udp_recv(uclient_pcb, myudp_client_callback, NULL);接收数据,回调函数myudp_client_callback内对接收的数据进行处理,可是接收不到,请问,可是在发送之后这样接收吗?

使用特权

评论回复
8
bencn| | 2013-7-30 00:58 | 只看该作者
好高深,看不懂

使用特权

评论回复
9
can123dao|  楼主 | 2013-7-30 16:00 | 只看该作者
openrd 发表于 2013-7-29 21:04
udp_connect(uclient_pcb,IP_ADDR_BROADCAST, UDP_CLIENT_PORT);
udp_send(uclient_pcb, p);
我做了udp ...

给你我的做CLIENT的代码吧,是TCP的,
#include "lwip/tcp.h"
#include "lwip/err.h"
#include "stm32f10x.h"
#include <string.h>
#include <stdio.h>
extern struct netif *enc28j60;
enum tcp_client_state{
        CLIENT_CONNECTED = 0x00U,
        CLIENT_WAITING_FOR_CMD,
        CLIENT_BUSY,
        CLIENT_SENT,
        CLIENT_ERROR,
        CLIENT_CLOSE,
        CLIENT_WAITING_FOR_CONNECTION
};

struct tcp_client_app_arg{
        uint8_t app_state;
        uint8_t textlen;
        uint8_t* dataptr;
};

static struct ip_addr destip;

void tcp_client_errf(void *arg, err_t err)
{
        struct tcp_client_app_arg* pro_arg = (struct tcp_client_app_arg*)arg;

        printf("tcp client err\n");
       
        pro_arg->app_state = CLIENT_ERROR;

        switch(err){
                case ERR_MEM: printf("Out of memory error\n"); break;
                case ERR_BUF: printf("Buffer error\n"); break;
                case ERR_TIMEOUT: printf("Timeout\n"); break;
                case ERR_RTE: printf("Routing problem\n"); break;
                case ERR_ABRT: printf("Connection aborted\n"); break;
                case ERR_RST: printf("Connection reset\n"); break;
                case ERR_CLSD: printf("Connection closed\n"); break;
                case ERR_CONN: printf("Not connected\n"); break;
                case ERR_VAL: printf("Illegal value\n"); break;
                case ERR_ARG: printf("Illegal argument\n"); break;
                case ERR_USE: printf("Address in use\n"); break;
                case ERR_IF: printf("Low-level netif error\n"); break;
                case ERR_ISCONN: printf("Already connected\n"); break;
                case ERR_INPROGRESS: printf("Operation in progress\n"); break;
                default: printf("Unknown error\n");
        }
}
err_t tcp_client_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
{
        struct pbuf *q;
        struct tcp_client_app_arg *appcmd = (struct tcp_client_app_arg *)arg;
        uint16_t i = 0;
        uint8_t ip[4];
        uint8_t* str;

        const char* cmd1 = "hello";
        const char* cmd2 = "LEDON";
        const char* cmd3 = "LEDOFF";
        const char* cmd4 = "echo IP";
        const char* cmd5 = "bye";

        printf("tcp client recieve\n");
               
        /* We perform here any necessary processing on the pbuf */
        if (p != NULL)
        {        
                /* We call this function to tell the LwIp that we have processed the data */
                /* This lets the stack advertise a larger window, so more data can be received*/
                tcp_recved(pcb, p->tot_len);
               
                /* Check the name if NULL, no data passed, return withh illegal argument error */
                if(appcmd == NULL)
                {
                  pbuf_free(p);
                  return ERR_ARG;
                }
                appcmd->dataptr = (uint8_t*)mem_calloc(sizeof(uint8_t), p->tot_len);
                if(appcmd->dataptr == NULL){
                        printf("Memory error\n");
                        return ERR_MEM;
                }
                appcmd->textlen = p->tot_len;
                for(q=p; q!=NULL; q=q->next){
                        memcpy((uint8_t*)&appcmd->dataptr[i], q->payload, q->len);  //同一个数据包会存在一个pbuf链表中
                        i = i + q->len;
                }
                //应用层代码
                switch(appcmd->app_state){
                        case CLIENT_CONNECTED:
                        case CLIENT_WAITING_FOR_CMD: {
                                if(memcmp(appcmd->dataptr, cmd1, strlen(cmd1)) == 0)
                                {
                                        str = "hello\n";
//                                        tcp_write(pcb, (uint8_t*)str, strlen(str), 1);
                                }
                                else if(memcmp(appcmd->dataptr, cmd2, strlen(cmd2)) == 0)
                                {
                                        GPIO_ResetBits(GPIOF,GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9);
                                        str="LEDON\n";
                                        //还可以加上这样
                                        /*if(GPIO_ReadInputDataBit(GPIOF,GPIO_Pin_6) == RESET)str="LEDON\n";*/
                                }
                                else if(memcmp(appcmd->dataptr, cmd3, strlen(cmd3)) == 0)
                                {
                                        GPIO_SetBits(GPIOF,GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9);
                                        str="LEDOFF\n";
                                }
                                else if(memcmp(appcmd->dataptr, cmd4, strlen(cmd4)) == 0)
                                {
                                        ip[0] = 192;  
                                        ip[1] = 168;  
                                        ip[2] = 0;   
                                        ip[3] = 16;
//                                        ip[0] = enc28j60->ip_addr.addr>>24;         //打出来有点不对         
//                                        ip[1] = enc28j60->ip_addr.addr>>16;
//                                        ip[2] = enc28j60->ip_addr.addr>>8;   
//                                        ip[3] = enc28j60->ip_addr.addr;
//                                        ip[0] = pcb->remote_ip.addr>>24;                 
//                                        ip[1] = pcb->remote_ip.addr>>16;
//                                        ip[2] = pcb->remote_ip.addr>>8;   
//                                        ip[3] = pcb->remote_ip.addr;
                                        str = mem_calloc(sizeof(uint8_t), 30);
                                        sprintf((char*)str, "ipaddr:%d,%d,%d,%d\n", ip[3], ip[2], ip[1], ip[0]);
                                        tcp_write(pcb, (const char *)str, strlen(str), 1);
                                        mem_free(str);
                                        break;
                                }
                                else if(memcmp(appcmd->dataptr, cmd5, strlen(cmd5)) == 0)
                                {
                                        appcmd->app_state = CLIENT_CLOSE;
                                       
                                        break;
                                }
                                else
                                {
                                        str = "unknown cmd\n";
//                                        tcp_write(pcb, (uint8_t*)str, strlen(str), 1);
                                }
                                tcp_write(pcb, (const char *)str, strlen(str), 1);
                                break;
                        }
                        default:
                        {
                                str = "lwip down\n";
                                tcp_write(pcb, (const char *)str, strlen(str), 1);
                                break;
                        }
                }
                mem_free(appcmd->dataptr);
                //取得应用层数据后,先释放pbuf队列相应数据链,再对数据进行解析与执行操作
                /* End of processing, we free the pbuf */
                pbuf_free(p);
        }  
        else if (err == ERR_OK)
        {
                /* When the pbuf is NULL and the err is ERR_OK, the remote end
                                                    is closing the connection. */
                /* We free the allocated memory and we close the connection */
                mem_free(appcmd);
                return tcp_close(pcb);
        }
        return ERR_OK;
}
err_t tcp_client_sent(void *arg, struct tcp_pcb *pcb, u16_t len)
{
        struct tcp_client_app_arg* pro_arg = (struct tcp_client_app_arg*)arg;

        printf("tcp client sent\n");

        switch(pro_arg->app_state){
                case CLIENT_WAITING_FOR_CMD:{
                        printf("acked!\n");
                        break;
                }
                case CLIENT_CLOSE:{
                        mem_free(pro_arg);
                        return tcp_close(pcb);
                }
                default:{}
        }

        return ERR_OK;
}

err_t tcp_client_poll(void *arg, struct tcp_pcb *pcb)
{
        const char* str = "The data come from the stm32 client\n";

        printf("tcp client poll\n");

        tcp_write(pcb, (const char*)str, strlen(str), 1);

        return ERR_OK;
}
err_t tcp_client_connected(void *arg, struct tcp_pcb *pcb, err_t err)
{
        struct tcp_client_app_arg* app_arg = (struct tcp_client_app_arg*)arg;
        uint8_t* str = "Welcome to the client\n";
       
        printf("tcp client connected\n");

        tcp_err(pcb, tcp_client_errf);                 //指定出错时的回调函数
          tcp_recv(pcb, tcp_client_recv);                 //指定接收到新数据时的回调函数
        tcp_sent(pcb, tcp_client_sent);                 //指定远程主机成功接收到数据的回调函数
        tcp_poll(pcb, tcp_client_poll, 4);         //指定轮询的时间间隔和回调函数(*250ms)

        tcp_write(pcb, (const char *)str, strlen(str), 1);
        app_arg->app_state = CLIENT_WAITING_FOR_CMD;

        return ERR_OK;
}

void tcp_client_init(void)
{
        struct tcp_pcb* client_pcb;
        struct tcp_client_app_arg* app_arg;

        printf("tcp client inti\n");

        destip.addr = (uint32_t)192+(168<<8)+(0<<16)+(105<<24);

        client_pcb = tcp_new();
        if(client_pcb != NULL)
        {
//                tcp_bind(client_pcb,IP_ADDR_ANY,2200);
                tcp_arg(client_pcb, mem_calloc(sizeof(struct tcp_client_app_arg), 1));   
                app_arg = client_pcb->callback_arg;
                app_arg->app_state = CLIENT_WAITING_FOR_CONNECTION;          
                tcp_connect(client_pcb, &destip, 2200, tcp_client_connected);         //按需求连接,加上条件
        }
        else
        {

                printf("tcp alloc failed\n");
        }
}


使用特权

评论回复
10
outstanding| | 2013-7-30 16:12 | 只看该作者

使用特权

评论回复
11
openrd| | 2013-7-30 16:37 | 只看该作者
can123dao 发表于 2013-7-30 16:00
给你我的做CLIENT的代码吧,是TCP的,

TCP面向连接,过程虽然复杂些,但是感觉靠谱点。请问你有做个UDP接收吗?我觉得我的是回调函数部分有点问题。不过很感谢

使用特权

评论回复
12
can123dao|  楼主 | 2013-7-30 16:50 | 只看该作者
openrd 发表于 2013-7-30 16:37
TCP面向连接,过程虽然复杂些,但是感觉靠谱点。请问你有做个UDP接收吗?我觉得我的是回调函数部分有点问 ...

我也是这段时间才在弄LWIP以前没学过TCP/IP,UDP还没做过呢,这在弄DHCP,这里面有UDP的,现在有问题,源码里面有行代码
udp_recv(dhcp->pcb, dhcp_recv, netif);
执行时发现并没有调用dhcp_recv。好多东西不懂。

使用特权

评论回复
13
openrd| | 2013-7-30 17:32 | 只看该作者
can123dao 发表于 2013-7-30 16:50
我也是这段时间才在弄LWIP以前没学过TCP/IP,UDP还没做过呢,这在弄DHCP,这里面有UDP的,现在有问题,源 ...

哦,这样,共同学习,我只是做了简单的发送信息和接收信息,现在分开是可以的。但是还是很多东西不懂,下一步是结合起来,发送特定的数据,然后接收应答。
之前是因为工具问题,换了个工具可以接收了。

使用特权

评论回复
14
hkcj| | 2013-7-30 18:56 | 只看该作者
问题解决了就好  帮你顶一个   呵呵  很好

使用特权

评论回复
15
can123dao|  楼主 | 2013-7-31 18:12 | 只看该作者
加上DHCP功能,分配IP成功后,SERVER功能能实现,但作为CLIENT连不上PC,是怎么回事呢

使用特权

评论回复
16
openrd| | 2013-8-1 11:15 | 只看该作者
UDP收到数据后使用udp_sendto回显,使用UDP测试工具可以看到发送的数据,问题是怎么把数据提取出来?memcpy(Recvdata,p->payload,p->len);貌似不太对啊,Recvdata数组内的数据并不是发送的数据,请教高人解答

使用特权

评论回复
17
likfire| | 2013-8-17 21:10 | 只看该作者
can123dao 发表于 2013-7-30 16:00
给你我的做CLIENT的代码吧,是TCP的,

您好,我是一名stm32的初学者,现在在做stm32 client上遇到了困难,您可以提供这个工程的源码吗?我的邮箱likfire@qq.com,如果不方便的话也没关系,谢谢!

使用特权

评论回复
18
tao122188| | 2014-5-30 01:25 | 只看该作者
正在做LWIP 求交流!!!

使用特权

评论回复
19
xinyunliushui| | 2014-7-9 16:04 | 只看该作者
tao122188 发表于 2014-5-30 01:25
正在做LWIP 求交流!!!

我也是啊,求交流,我的qq412492751,求加上能交流下

使用特权

评论回复
20
gjianw217| | 2015-7-13 15:54 | 只看该作者
去正点原子论坛看看

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

36

主题

114

帖子

2

粉丝