- 简述
- UDP概述之前已经写过,请参阅:https://blog.csdn.net/Linux_ARM9/article/details/106008881
- 此处只写实验例程
- UDP层函数关系
- RAW 中与UDP相关的函数
- udp_new(); 新建一个UDP的PCB块
- udp_remove(); 将一个PCB控制块从链表中删除,并且释放这个控制块的内存
- udp_bind(); 为udp的PCB控制块绑定一个IP地址和端口号
- udp_connect(); 连接到指定IP地址主机的指定端口上,其它就是设置PCB控制块的remote_ip和remote_port
- udp_disconnect(); 断开链接,将控制块设置为非连接状态,其实就是清除remote_ip和remote_port字段
- udp_send(); 通过一个PCB控制块发送数据
- udp_recv(); 需要创建一一个回调函数,当接收到数据的时候被调用
- 复制例程中的udp_demo.c和udp_demo.h两个文件
- udp_demo.c函数详解
- udp_demo_set_remoteip();设置远端IP地址,UDP连接的时候要用到这个地址
- udp_demo_test(); UDP实验测试函数
- udp_demo_recv(); UDP接收数据回调函数
- udp_demo_senddata(); 发送数据
- udp_demo_connection_close(); 关闭UDP连接
- 软件设计
- 创建一个UDP的控制块
- 连接到指定IP地址和端口号
- 绑定IP地址和端口号
- 注册接收回调函数
- 回调函数内接收数据
- 发送数据
- 断开连接,并释放内存
- 在接收/发送数据的循环中需要调用lwip_periodic_handle()函数,否则网络无法运行
- 例程代码
-
//UDP测试
void udp_demo_test(void)
{
err_t err;
struct udp_pcb *udppcb; //定义一个TCP服务器控制块
struct ip_addr rmtipaddr; //远端ip地址
u8 *tbuf;
u8 key;
u8 res=0;
u16 t=0;
udp_demo_set_remoteip();//先选择IP
BSP_LCD_Clear(WHITE); //清屏
POINT_COLOR=RED; //红色字体
BSP_LCD_ShowString(30,30,200,16,16,"Apollo STM32F4&F7");
BSP_LCD_ShowString(30,50,200,16,16,"RAW UDP Test");
BSP_LCD_ShowString(30,70,200,16,16,"ATOM@ALIENTEK");
BSP_LCD_ShowString(30,90,200,16,16,"KEY0:Send data");
BSP_LCD_ShowString(30,110,200,16,16,"KEY_UP:Quit");
BSP_LCD_ShowString(30,130,200,16,16,"KEY1:Connect");
tbuf=mymalloc(SRAMIN,200); //申请内存
if(tbuf==NULL)return ; //内存申请失败了,直接退出
sprintf((char*)tbuf,"Local IP:%d.%d.%d.%d",lwipdev.ip[0],lwipdev.ip[1],lwipdev.ip[2],lwipdev.ip[3]);//服务器IP
BSP_LCD_ShowString(30,150,210,16,16,tbuf);
sprintf((char*)tbuf,"Remote IP:%d.%d.%d.%d",lwipdev.remoteip[0],lwipdev.remoteip[1],lwipdev.remoteip[2],lwipdev.remoteip[3]);//远端IP
BSP_LCD_ShowString(30,170,210,16,16,tbuf);
sprintf((char*)tbuf,"Remote Port:%d",UDP_DEMO_PORT);//客户端端口号
BSP_LCD_ShowString(30,190,210,16,16,tbuf);
POINT_COLOR=BLUE;
BSP_LCD_ShowString(30,210,210,16,16,"STATUS:Disconnected");
udppcb=udp_new();
if(udppcb)//创建成功
{
IP4_ADDR(&rmtipaddr,lwipdev.remoteip[0],lwipdev.remoteip[1],lwipdev.remoteip[2],lwipdev.remoteip[3]);
err=udp_connect(udppcb,&rmtipaddr,UDP_DEMO_PORT);//UDP客户端连接到指定IP地址和端口号的服务器
if(err==ERR_OK)
{
err=udp_bind(udppcb,IP_ADDR_ANY,UDP_DEMO_PORT);//绑定本地IP地址与端口号
if(err==ERR_OK) //绑定完成
{
udp_recv(udppcb,udp_demo_recv,NULL);//注册接收回调函数
BSP_LCD_ShowString(30,210,210,16,16,"STATUS:Connected ");//标记连接上了(UDP是非可靠连接,这里仅仅表示本地UDP已经准备好)
udp_demo_flag |= 1<<5; //标记已经连接上
POINT_COLOR=RED;
BSP_LCD_ShowString(30,230,BSP_LCD_InitStructure.width-30,BSP_LCD_InitStructure.height-190,16,"Receive Data:");//提示消息
POINT_COLOR=BLUE;//蓝色字体
}
else
res=1;
}
else
res=1;
}
else
res=1;
while(res==0)
{
key=BSP_KEY_Scan(0);
if(key==Key_WkUP_PA0_Value)break;
if(key==Key0_PH3_Value)//KEY0按下了,发送数据
{
udp_demo_senddata(udppcb);
}
if(udp_demo_flag&1<<6)//是否收到数据?
{
BSP_LCD_Fill(30,250,BSP_LCD_InitStructure.width-1,BSP_LCD_InitStructure.height-1,WHITE);//清上一次数据
BSP_LCD_ShowString(30,250,BSP_LCD_InitStructure.width-30,BSP_LCD_InitStructure.height-230,16,udp_demo_recvbuf);//显示接收到的数据
udp_demo_flag&=~(1<<6);//标记数据已经被处理了.
}
lwip_periodic_handle();
delay_us(100);
t++;
if(t==2000)
{
t=0;
LED0_Toggle;
}
}
udp_demo_connection_close(udppcb);
myfree(SRAMIN,tbuf);
}
- 总结
- 无
- 参考资料:
- 正点原子《STM32F767开发指南(HAL库版)》
- 正点原子《STM32F767 LWIP手册》
- 野火《STM32 HAL库开发实战指南》
- 野火《LWIP应用开发实战指南》
- 官方源码
- 硬件平台:
- 正点原子阿波罗F767
- 软件平台:
- MDK5.2.5
- 库版本:
- TM32Cube_FW_F7_V1.4.0
- LWIP版本
- lwip-1.4.1
- contrib-1.4.1
|
|