STM32F4NETCONN编程接口UDP


  移植平台使用STM32F407为核心芯片的正点原子开发平台,网络芯片使用LAN8720。LWIP使用官方1.4.1版本。本文章只说移植,详细说明请参考正点原子《STM32F4 LWIP开发手册》。
  基础工程为UCOSII操作系统,使用LWIP网络协议栈。见上一章。代码参考自正点原子。
1、初始化

(1)头文件和宏定义

#include "mysys.h"
#include "includes.h"
#include "lwip_comm.h"
#include "lwip/api.h"
#include "lwip/lwip_sys.h"
#include "string.h"

#define UDP_DEMO_BUFSIZE	2000	//定义udp最大接收发送数据长度
#define UDP_DEMO_PORT		8001	//定义udp连接的本地端口号
#define LWIP_SEND_DATA		0X80	//定义有数据发送

u8 udp_sendbuf[UDP_DEMO_BUFSIZE];
u8 udp_recvbuf[UDP_DEMO_BUFSIZE];	//UDP接收数据缓冲区

//UDP数据标志位
//使用第七位作为发送标记为
u8 udp_flag;

//创建netconn描述符
struct netconn *udpconn;

(2)对UDP进行初始化、创建UDP进程

//TCP客户端任务
#define UDP_RECV_PRIO		7
//任务堆栈大小
#define UDP_RECV_STK_SIZE	300
//任务堆栈
OS_STK UDP_RECV_TASK_STK[UDP_RECV_STK_SIZE];

//创建UDP线程
//返回值:0 UDP创建成功
//其他 UDP创建失败
INT8U udp_demo_init(void)
{
	INT8U res;
	OS_CPU_SR cpu_sr;
	UDP_Config();
	OS_ENTER_CRITICAL();	//关中断	
	res = OSTaskCreate(udp_recv_thread,(void*)0,(OS_STK*)&UDP_RECV_TASK_STK[UDP_RECV_STK_SIZE-1],UDP_RECV_PRIO); //创建UDP线程
	OS_EXIT_CRITICAL();		//开中断
	
	return res;
}

(3)UDP初始化函数

err_t UDP_Config(void)
{
	err_t err;
	struct ip_addr destipaddr;
	udpconn = netconn_new(NETCONN_UDP);  //创建一个UDP链接
	udpconn->recv_timeout = 10;      //recv接受线程阻塞时间
	if(udpconn != NULL)  //创建UDP连接成功
	{
		//绑定IP地址和端口号  
		err = netconn_bind(udpconn,IP_ADDR_ANY,UDP_DEMO_PORT); 
		//构造目的IP地址
		IP4_ADDR(&destipaddr,lwipdev.remoteip[0],lwipdev.remoteip[1], lwipdev.remoteip[2],lwipdev.remoteip[3]);
		//连接到远端主机	
		netconn_connect(udpconn,&destipaddr,UDP_DEMO_PORT); 
		if(err != ERR_OK)//绑定完成
		  {printf("UDP绑定失败\r\n");return 1;}
	}
	else 
	 {printf("UDP连接创建失败\r\n");return 2;}
	return 0;
}

2、UDP接受发送
(1)接受进程

//udp任务函数
static void udp_recv_thread(void *arg)
{
	OS_CPU_SR cpu_sr;
	static struct netbuf  *recvbuf;	
	u32 data_len = 0;
	struct pbuf *q;
	err_t err;
	LWIP_UNUSED_ARG(arg);
	while(1)
	{		
		netconn_recv(udpconn,&recvbuf); //接收数据
		if(recvbuf != NULL)          //接收到数据
		{ 			
			OS_ENTER_CRITICAL(); //关中断
			memset(udp_recvbuf,0,UDP_DEMO_BUFSIZE);  //数据接收缓冲区清零
			for(q=recvbuf->p;q!=NULL;q=q->next)  //遍历完整个pbuf链表
			{
				//判断要拷贝到UDP_DEMO_RX_BUFSIZE中的数据是否大于UDP_DEMO_RX_BUFSIZE的剩余空间,如果大于
				//的话就只拷贝UDP_DEMO_RX_BUFSIZE中剩余长度的数据,否则的话就拷贝所有的数据
				if(q->len > (UDP_DEMO_BUFSIZE-data_len)) 
					memcpy(udp_recvbuf+data_len,q->payload,(UDP_DEMO_BUFSIZE-data_len));//拷贝数据
				else 
					memcpy(udp_recvbuf+data_len,q->payload,q->len);
				data_len += q->len;  	
				if(data_len > UDP_DEMO_BUFSIZE) break; //超出TCP客户端接收数组,跳出	
			}
			OS_EXIT_CRITICAL();  //开中断
			data_len=0;  //复制完成后data_len要清零。
			UDP_Receive_Handle();//对接受的数据进行处理-----自写
			netbuf_delete(recvbuf);      //删除buf
		}
		OSTimeDlyHMSM(0,0,0,5);  //延时5ms
	}
}

(2)UDP发送函数

void UDP_Send(void)
{
	err_t err;
	static struct netbuf  *sentbuf;
	if((udp_flag & LWIP_SEND_DATA) == LWIP_SEND_DATA) //有数据要发送
	{
		sentbuf = netbuf_new();
		netbuf_alloc(sentbuf,strlen((char *)udp_sendbuf));
		memcpy(sentbuf->p->payload,(void*)udp_sendbuf,strlen((char*)udp_sendbuf));
		err = netconn_send(udpconn,sentbuf);  	//将netbuf中的数据发送出去
		if(err != ERR_OK)
			printf("UDP发送失败\r\n");
		udp_flag &= ~LWIP_SEND_DATA;	//清除数据发送标志
		netbuf_delete(sentbuf);      	//删除buf
	}		
}

3、主函数
主函数中仅创建了入口函数,并无其他内容,硬件初始化在入口函数中进行,不在展示。
1、start入口函数

void start_task(void *pdata)
{
	OS_CPU_SR cpu_sr;
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);	//中断分组配置
	SysLED_Init();
	SysTick_init();
	USART_Config();
	FSMC_SRAM_Init();	//外部SRAM初始化
	mymem_init();  		//初始化存池
	lwip_comm_init();
	udp_demo_init();
	printf("初始化完成\r\n");
	OSStatInit();  			//初始化统计任务
	OS_ENTER_CRITICAL();  	//关中断	
	OSTaskCreate(led_task,(void*)0,(OS_STK*)&LED_TASK_STK[LED_STK_SIZE-1],LED_TASK_PRIO);//创建LED任务
	OSTaskSuspend(OS_PRIO_SELF); //挂起start_task任务
	OS_EXIT_CRITICAL();  		//开中断
}
  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值