请选择 进入手机版 | 继续访问电脑版

你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

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

[复制链接]
风子 提问时间:2016-12-11 20:02 /
  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

        先简单介绍一下这个例子的代码结构,有利于自己移植的时候修改
image74.png
main函数:
  -使能CPUICACHEDCACHE
  -HAL 库初始化
  -配置系统时钟
  -定义和创建一个线程作为启动线程
  -启动FreeRTOS内核,将CPU控制权交给内核
  -进入死循环,CPU已经由内核控制,不会再运行到这里


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


   再接下来,内核已经有多个线程在运行,此处只关心服务器线程,也就是由http_server_socket_init函数创建的http_server_socket_thread线程,在之后的修改中,这两个函数都将会被替换为我们自己写的函数
image76.png
image77.png
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,具体功能实现

        三个函数主要部分代码如下:

  1. void my_server_init(void)
  2. {
  3.     sys_thread_new("MY_SERVER", my_server_thread, NULL, DEFAULT_THREAD_STACKSIZE * 2, TCPIP_THREAD_PRIO);
  4. }
复制代码
创建新线程,运行my_server_thread函数
  1. void my_server_thread(void *arg)
  2. {
  3.     int listenfd,connectfd;
  4.     struct sockaddr_in server,client;
  5.     socklen_t addrlen;

  6.     if((listenfd = socket(AF_INET,SOCK_STREAM,0)) == -1)
  7.     {
  8.         return ;
  9.     }

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

  13.     if(bind(listenfd,(struct sockaddr *)&server,sizeof(server)) == -1)
  14.     {
  15.         return;
  16.     }
  17.     if(listen(listenfd,BACKLOG) == -1)
  18.     {
  19.         return;
  20.     }
  21.     addrlen = sizeof(client);

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

  25.         my_server_echo(connectfd);
  26.     }

  27.     close(listenfd);
  28. }
复制代码

一旦有客户端链接,就调用my_server_echo函数

  1. void my_server_echo(int connfd)
  2. {
  3.     int rxsize;
  4. while(1)
  5.     {
  6.         if((rxsize = read(connfd, recvbuf, MAX_BUFF_SIZE)) == -1)
  7.         {
  8.             continue;
  9.         }
  10.         else
  11.         {
  12.                   recvbuf[rxsize - 1] = '\0';
  13.                
  14.                 if(strncmp(recvbuf,LED1_ON,sizeof(LED1_ON)) == 0)
  15.                         BSP_LED_On(LED1);
  16.                 else if(strncmp(recvbuf,LED1_OFF,sizeof(LED1_OFF)) == 0)
  17.                         BSP_LED_Off(LED1);
  18.                 else if(strncmp(recvbuf,LED2_ON,sizeof(LED2_ON)) == 0)
  19.                         BSP_LED_On(LED2);
  20.                 else if(strncmp(recvbuf,LED2_OFF,sizeof(LED2_OFF)) == 0)
  21.                         BSP_LED_Off(LED2);
  22.   LCD_UsrLog("%s\n",recvbuf);
  23.                 write(connfd, recvbuf, rxsize);
  24.         }
  25.         osDelay(10);
  26.     }
复制代码
    由于客户端输入命令以回车键结束,所以接收到的最后一个字符recvbuf[rxsize- 1]原本应该是'\n',应该执行recvbuf[rxsize]= '\0';作为字符串结束,不过为了和设置的宏定义比较,直接把接收到的最后一个字符recvbuf[rxsize- 1]换成字符串结束符,以便strncmp能获得正确的结果

    现在服务器有了,还需要客户端,客户端运行在linux系统,这里就不贴代码了,有需要的在文末链接去找。
代码写好了接下来编译运行,看看效果
image78.png

复位运行,没有客户端链接
image79.png
有一个客户端链接上了,
ip地址 192.168.1.149 (我的电脑)
port  59614  (分配的临时端口,每次连接不一定一样)
此时led1onled2off状态
image80.png
输入led1off,led2on
此时led1被关闭,led2打开
image81.png

输入led1on,两个led都打开
image82.png

输入led1off,led2off,连个led都关闭
image83.png
  测试一下回显功能,就是服务器发回客户端发送的命令,其实前面已经可以看到,电脑上的窗口中,输入的命令显示了两次,一次为输入,一次为从服务器读取的回显

这个小程序就完成了,再次感谢ST中文网http://www.stmcu.com.cn/提供试用

需要完整代码的可以去下面链接下载:


评分

参与人数 1 ST金币 +30 收起 理由
zero99 + 30

查看全部评分

收藏 7 评论24 发布时间:2016-12-11 20:02

举报

24个回答
风子 回答时间:2016-12-13 09:21:21
shuolang126 发表于 2016-12-13 07:23
最近STM32F769比较火爆啊,支持原创!谢谢楼主分享!

主要是社区和官方提供的资源搞活动,谢谢支持
jackten 回答时间:2016-12-11 23:07:48
谢谢分享                     
望-尘 回答时间:2016-12-12 15:33:01
大神,关于CubeMX的问题,https://www.stmcu.org.cn/module/forum/thread-609696-1-1.html
请您帮助看一下吧。
Paderboy 回答时间:2016-12-11 20:10:12
赞,支持支持。。。
netlhx 回答时间:2016-12-11 20:38:18
赞一个,严重支持
leo121_3006061 回答时间:2016-12-11 21:13:44
写的非常好,谢谢分享:
无薪税绵 回答时间:2016-12-11 21:42:49
谢谢楼主整理资源。
5265325 回答时间:2016-12-11 22:10:29
creep 回答时间:2016-12-11 22:33:27
厉害                     
wolfgang 回答时间:2016-12-11 22:47:10
不错,赞一个
左岸右岸 回答时间:2016-12-12 08:51:43
顶           
andypanfan 回答时间:2016-12-12 09:00:08
写的非常好,谢谢分享
anobodykey 回答时间:2016-12-12 09:08:37
谢谢分享
斜阳 回答时间:2016-12-12 09:11:33
高阶技术贴,支持支持
风子 回答时间:2016-12-12 09:22:35
leo121_3006061 发表于 2016-12-11 21:13
写的非常好,谢谢分享:

谢谢支持
风子 回答时间:2016-12-12 09:28:37

感谢支持
12下一页

所属标签

相似问题

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版