风子 发表于 2016-12-11 20:02:44

【F769IDISCOVERY评测】LwIP TCP编程之LED远程控制

STM32F769IDISCOVERY开发板(STM32官网)集成了有线网络接口和WIFI接口,在上一篇帖子中介绍了一个网口应用实力,演示一个HTTPServer的demo,本文介绍自己开发一个简单的TCPServer,实现以下功能:
1.开发板作为服务器,等待客户端链接2.客户端链接成功后,向服务器发送字符串或命令3.开发板收到客户端的命令后,将收到的命令显示在LCD屏幕上4.将收到的命令发送回客户端,客户端显示出来5.几个特殊命令,控制开发板上两个LED的亮和灭
本文的程序基于上一篇帖子介绍的例子https://www.stmcu.org.cn/module/forum/thread-609498-1-1.html移植而来,该例子库STM32CubeF7中STM32Cube_FW_F7_V1.5.0\Projects\STM32F769I-Discovery\Applications\LwIP\LwIP_HTTP_Server_Socket_RTOS
      先简单介绍一下这个例子的代码结构,有利于自己移植的时候修改main函数:-使能CPU的ICACHE和DCACHE-HAL 库初始化-配置系统时钟-定义和创建一个线程作为启动线程-启动FreeRTOS内核,将CPU控制权交给内核-进入死循环,CPU已经由内核控制,不会再运行到这里

接下来,FreeRTOS内核控制CPU后会执行启动线程StartThread:-BSP初始化,主要是初始化了开发板上的LED和LCD,用来显示-初始化TCP/IP协议栈-网口配置,配置网口参数,MCU底层网口初始化,创建和配置网络状态改变,接收发送等相关回调函数,创建数据接收线程-初始化httpserver,这就是修改的地方,将替换成我们自己的server相关函数,该函数里将会创建一个线程,用于运行我们自己的服务器代码-在LCD显示前面初始化是否成功的状态-如果使用DHCP,创建DHCP线程-删除本线程,即删除启动线程

   再接下来,内核已经有多个线程在运行,此处只关心服务器线程,也就是由http_server_socket_init函数创建的http_server_socket_thread线程,在之后的修改中,这两个函数都将会被替换为我们自己写的函数http_server_socket_thread:-创建socket-绑定socket监听地址和端口-设置监听socket-调用accept等待链接,该函数将会阻塞,线程挂起,直到有客户端链接才会返回-一旦有了链接,就转入具体服务函数http_server_serve,就是发送和接收数据,这个函数也会被替换成自己的服务函数
讲完了例子的代码结构,总结起来需要修改的地方也不多,就3个:1.http_server_socket_init换成my_server_init,完成初始化2.http_server_socket_thread换成my_server_thread,服务器端代码3.http_server_serve换成my_server_echo,具体功能实现
      三个函数主要部分代码如下:
void my_server_init(void)
{
    sys_thread_new("MY_SERVER", my_server_thread, NULL, DEFAULT_THREAD_STACKSIZE * 2, TCPIP_THREAD_PRIO);
}创建新线程,运行my_server_thread函数void my_server_thread(void *arg)
{
    int listenfd,connectfd;
    struct sockaddr_in server,client;
    socklen_t addrlen;

    if((listenfd = socket(AF_INET,SOCK_STREAM,0)) == -1)
    {
      return ;
    }

    server.sin_family = AF_INET;
    server.sin_port = htons(PORT);
    server.sin_addr.s_addr = htonl(INADDR_ANY);

    if(bind(listenfd,(struct sockaddr *)&server,sizeof(server)) == -1)
    {
      return;
    }
    if(listen(listenfd,BACKLOG) == -1)
    {
      return;
    }
    addrlen = sizeof(client);

    while(1)
    {
      connectfd = accept(listenfd,(struct sockaddr*)&client,&addrlen);

      my_server_echo(connectfd);
    }

    close(listenfd);
}
一旦有客户端链接,就调用my_server_echo函数
void my_server_echo(int connfd)
{
    int rxsize;
while(1)
    {
      if((rxsize = read(connfd, recvbuf, MAX_BUFF_SIZE)) == -1)
      {
            continue;
      }
      else
      {
                  recvbuf = '\0';
               
                if(strncmp(recvbuf,LED1_ON,sizeof(LED1_ON)) == 0)
                        BSP_LED_On(LED1);
                else if(strncmp(recvbuf,LED1_OFF,sizeof(LED1_OFF)) == 0)
                        BSP_LED_Off(LED1);
                else if(strncmp(recvbuf,LED2_ON,sizeof(LED2_ON)) == 0)
                        BSP_LED_On(LED2);
                else if(strncmp(recvbuf,LED2_OFF,sizeof(LED2_OFF)) == 0)
                        BSP_LED_Off(LED2);
LCD_UsrLog("%s\n",recvbuf);
                write(connfd, recvbuf, rxsize);
      }
      osDelay(10);
    }    由于客户端输入命令以回车键结束,所以接收到的最后一个字符recvbuf原本应该是'\n',应该执行recvbuf= '\0';作为字符串结束,不过为了和设置的宏定义比较,直接把接收到的最后一个字符recvbuf换成字符串结束符,以便strncmp能获得正确的结果
    现在服务器有了,还需要客户端,客户端运行在linux系统,这里就不贴代码了,有需要的在文末链接去找。代码写好了接下来编译运行,看看效果
复位运行,没有客户端链接有一个客户端链接上了,ip地址 192.168.1.149 (我的电脑),port59614(分配的临时端口,每次连接不一定一样)此时led1on,led2off状态输入led1off,led2on此时led1被关闭,led2打开

输入led1on,两个led都打开
输入led1off,led2off,连个led都关闭测试一下回显功能,就是服务器发回客户端发送的命令,其实前面已经可以看到,电脑上的窗口中,输入的命令显示了两次,一次为输入,一次为从服务器读取的回显
这个小程序就完成了,再次感谢ST中文网http://www.stmcu.com.cn/提供试用
需要完整代码的可以去下面链接下载:http://github.com/wlhe/stm32f769/tree/lwip-tcp-server

Paderboy 发表于 2016-12-11 20:10:12

:loveliness:赞,支持支持。。。

netlhx 发表于 2016-12-11 20:38:18

赞一个,严重支持:lol

leo121_3006061 发表于 2016-12-11 21:13:44

写的非常好,谢谢分享::)

无薪税绵 发表于 2016-12-11 21:42:49

谢谢楼主整理资源。

5265325 发表于 2016-12-11 22:10:29

:lol:lol:lol:lol

creep 发表于 2016-12-11 22:33:27

厉害                     

wolfgang2015 发表于 2016-12-11 22:47:10

不错,赞一个

jackten 发表于 2016-12-11 23:07:48

谢谢分享                     

左岸右岸 发表于 2016-12-12 08:51:43

顶         
页: [1] 2 3
查看完整版本: 【F769IDISCOVERY评测】LwIP TCP编程之LED远程控制