【STM32F407+CUBEMX+FreeRTOS+lwIP之UDP记录】

STM32F407+CUBEMX+FreeRTOS+lwIP之UDP记录

  • 基本信息
  • cubemx配置
    • GPIO
    • NVIC
    • RCC
    • SYS
    • ETH
    • FREERTOS
    • lwIP
  • UDP(SOCKET)
    • 效果
  • UDP广播(SOCKET)
    • 效果
  • UDP组播(SOCKET)
    • cubemx注意以下
    • ethernetif.c
    • 效果
  • 可参考正点原子和野火的手册

基本信息

正点原子F407探索者开发板
cubemx v6.10.0
STM32Cube FM_f4 v1.28.0
8720A

cubemx配置

GPIO

在这里插入图片描述

NVIC

在这里插入图片描述
在这里插入图片描述

RCC

在这里插入图片描述

SYS

在这里插入图片描述

ETH

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

FREERTOS

这个按需配置
在这里插入图片描述

lwIP

这个按需配置

8720A可以选下图中这个,其他为适配的可以生成代码后自己修改

UDP(SOCKET)

本地端口是本地对外开放的端口
远程端口目标IP的端口

一些定义

#include <lwip/sockets.h>
#include "lwip/opt.h"
#include "lwip/sys.h"
#include "lwip/api.h"
#include "lwip/udp.h"
#include "queue.h"

osThreadId_t led_TaskHandle;
const osThreadAttr_t led_Task_attributes = {
  .name = "led_Task",
  .stack_size = 128 * 4,
  .priority = (osPriority_t) (osPriorityNormal-10),
};
void Start_led_Task(void *argument);


#ifdef lwip_socket_udp_base
osThreadId_t socket_udp_TaskHandle;
const osThreadAttr_t socket_udp_Task_attributes = {
  .name = "socket_udp_Task",
  .stack_size = 128 * 8,
  .priority = (osPriority_t) (osPriorityNormal-9),
};
void Start_socket_udp_Task(void *argument);
#define LWIP_DEMO_PORT 8081
#define LWIP_DEMO_RX_BUFSIZE         200    /* 最大接收数据长度 */
//#define IP_ADDR   "192.168.123.92"		/* 单播 一对一*/
socklen_t sock_fd;                     /* 定义一个Socket接口 */
struct sockaddr_in local_info;         /* 定义Socket地址信息结构体 */
/* 接收数据缓冲区 */
uint8_t g_lwip_demo_recvbuf[LWIP_DEMO_RX_BUFSIZE];

osThreadId_t lwip_recv_TaskHandle;
const osThreadAttr_t lwip_recv_Task_attributes = {
  .name = "lwip_recv_Task",
  .stack_size = 128 * 4,
  .priority = (osPriority_t) (osPriorityNormal-9),
};
/* 显示消息队列的数量 */
#define DISPLAYMSG_Q_NUM    20              /* 显示消息队列的数量 */
QueueHandle_t g_display_queue;              /* 显示消息队列句柄 */

创建led任务

led_TaskHandle = osThreadNew(Start_led_Task, NULL, &led_Task_attributes);

lwIP初始化后UDP、接收、队列

void StartDefaultTask(void *argument)
{
  /* init code for LWIP */
  MX_LWIP_Init();
  /* USER CODE BEGIN StartDefaultTask */
	taskENTER_CRITICAL();           /* 进入临界区 */
	socket_udp_TaskHandle = osThreadNew(Start_socket_udp_Task, NULL, &socket_udp_Task_attributes);
	lwip_recv_TaskHandle = osThreadNew(lwip_recv_Task, NULL, &lwip_recv_Task_attributes);
	g_display_queue = xQueueCreate(DISPLAYMSG_Q_NUM,200);/* 创建消息Message_Queue,队列项长度是200长度 */
	taskEXIT_CRITICAL();            /* 退出临界区 */
  /* Infinite loop */
  for(;;)
  {
    osDelay(1);	//ticks
  }
  /* USER CODE END StartDefaultTask */
}

udp配置

void Start_socket_udp_Task(void *argument){

	/* 发送数据内容 */
	char g_lwip_demo_sendbuf[] = "ALIENTEK DATA \r\n";
	memset(&local_info, 0, sizeof(struct sockaddr_in)); /* 将服务器地址清空 */
    local_info.sin_len = sizeof(local_info);
    local_info.sin_family = AF_INET;                    /* IPv4地址 */
    local_info.sin_port = htons(LWIP_DEMO_PORT);        /* 设置端口号 */
    local_info.sin_addr.s_addr = htons(INADDR_ANY);     /* 设置本地IP地址 */
	
	
	sock_fd = socket(AF_INET,SOCK_DGRAM,0);/* 建立一个新的socket连接 */
	if (sock_fd < 0)
    {
        printf("socket failed!\n");
    }
	int ret = bind(sock_fd,(struct sockaddr *)&local_info, sizeof(struct sockaddr_in));/* 建立绑定 */
	if (ret < 0)
    {
        printf(" bind error!\n ");
    }
	while(1){
		local_info.sin_addr.s_addr = inet_addr(IP_ADDR);                /* 需要发送的远程IP地址 */
		sendto(sock_fd,                                         /* scoket */
                  (char *)g_lwip_demo_sendbuf,                        /* 发送的数据 */
                  sizeof(g_lwip_demo_sendbuf), 0,                     /* 发送的数据大小 */
                  (struct sockaddr *)&local_info,                   /* 接收端地址信息 */ 
                  sizeof(local_info));                              /* 接收端地址信息大小 */
		vTaskDelay(400);
		LL_GPIO_TogglePin(LED1_GPIO_Port,LED1_Pin);
	}
}

将从队列收到的消息打印出来

void Start_led_Task(void *argument){
	uint8_t buffer[200];
	while(1){
		LL_GPIO_TogglePin(LED0_GPIO_Port,LED0_Pin);
		vTaskDelay(500);
		if (xQueueReceive(g_display_queue,&buffer,portMAX_DELAY))
		{
			printf("%s\n",buffer);
			memset(buffer,0,200);       /* 清除缓冲区 */
		}
	}
}
void lwip_recv_Task(void *argument){
	BaseType_t lwip_err;
	
	struct sockaddr_in sender;/*存放发送方信息*/
    int sender_len = sizeof(sender);/*发送方信息长度*/
	
	while(1){
		memset(g_lwip_demo_recvbuf, 0, sizeof(g_lwip_demo_recvbuf));
//		recv(sock_fd, (void *)g_lwip_demo_recvbuf, sizeof(g_lwip_demo_recvbuf), 0);/*这个只有通信数据*/
		recvfrom(sock_fd, (void *)g_lwip_demo_recvbuf, sizeof(g_lwip_demo_recvbuf), 0,(struct sockaddr*)&sender,(socklen_t *)&sender_len);/*这个只有通信数据、还有发送方信息*/
		lwip_err = xQueueSend(g_display_queue,&g_lwip_demo_recvbuf,0);
		if (lwip_err == errQUEUE_FULL)
		{
			printf("队列Key_Queue已满,数据发送失败!\r\n");
		}else{
			/*IP*/
			printf("%s %d \n", inet_ntoa(sender.sin_addr), ntohs(sender.sin_port));/*打印发送放IP和端口*/
		}
		vTaskDelay(10);
	}
}

效果

在这里插入图片描述

UDP广播(SOCKET)

#define IP_ADDR   "192.168.123.255"		/* 广播所有设备255.255.255.255 通常只在本地网络中使用*/

效果

在这里插入图片描述
在这里插入图片描述

UDP组播(SOCKET)

添加一些定义

/* 组播D类IP:224.0.0.0至239.255.255.255 */
/* 多播/组播 IP 地址 */
#define GROUP_IP "224.0.1.0"
/* 多播信息 */
struct ip_mreq_t
{
    struct ip_mreq mreq;            /* 多播信息控制块 */
    socklen_t mreq_len;             /* 多播信息长度 */
};
struct ip_mreq_t mreq_info;

bind后加这个

/*组播 LWIP_IGMP为1*/
	mreq_info.mreq.imr_multiaddr.s_addr = inet_addr(GROUP_IP);     /* 多播组 IP 地址设置 */
    mreq_info.mreq.imr_interface.s_addr = htonl(INADDR_ANY);       /* 待加入多播组的 IP 地址 */
    mreq_info.mreq_len = sizeof(struct ip_mreq);
	/* 添加多播组成员(该语句之前,socket 只与 某单播IP地址相关联 执行该语句后 将与多播地址相关联) */
    ret = setsockopt(sock_fd,IPPROTO_IP,IP_ADD_MEMBERSHIP,&mreq_info.mreq,mreq_info.mreq_len);
    if (ret < 0)
    {
        printf("setsockopt failed !");
    }
    else
    {
        printf("setsockopt success\n");
    }

切到组播IP,发送数据

local_info.sin_addr.s_addr = inet_addr(GROUP_IP); /* 组播ip */
sendto(sock_fd,                                         /* scoket */
                  (char *)g_lwip_demo_sendbuf,                        /* 发送的数据 */
                  sizeof(g_lwip_demo_sendbuf), 0,                     /* 发送的数据大小 */
                  (struct sockaddr *)&local_info,                   /* 接收端地址信息 */ 
                  sizeof(local_info));                              /* 接收端地址信息大小 */
		vTaskDelay(400);
		LL_GPIO_TogglePin(LED1_GPIO_Port,LED1_Pin);

cubemx注意以下

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

ethernetif.c

netif初始化前添加

netif->flags |=NETIF_FLAG_IGMP;/*组播*/

PHY初始化前添加

HAL_ETH_GetMACFilterConfig(&heth,&g_eth_macfilterconfig_handler);
	g_eth_macfilterconfig_handler.ReceiveAllMode = ENABLE;
	g_eth_macfilterconfig_handler.PassAllMulticast =ENABLE;
	HAL_ETH_SetMACFilterConfig(&heth,&g_eth_macfilterconfig_handler);

这个定义到外面

	ETH_MACFilterConfigTypeDef g_eth_macfilterconfig_handler;

效果

在这里插入图片描述

可参考正点原子和野火的手册

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/582314.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

深度学习论文:Local Feature Matching Using Deep Learning: A Survey

深度学习论文: Local Feature Matching Using Deep Learning: A Survey Local Feature Matching Using Deep Learning: A Survey PDF: https://arxiv.org/pdf/2401.17592 1 概述 近年来&#xff0c;深度学习模型的引入引发了对局部特征匹配技术的广泛探索。本文旨在全面概述局…

go语言实现简单ngnix样例

目录 1、代码实现样例&#xff1a; 2、postman调用ngnix&#xff0c;转发&#xff1a; 1、代码实现样例&#xff1a; package mainimport ("bytes""encoding/json""io""log""net/http""net/http/httputil""…

防止核心研发数据流失:管理者跳槽怎么办?

在高速发展的科技行业中&#xff0c;核心研发数据是企业最宝贵的资产之一。然而&#xff0c;当高层管理人员或核心技术人员因跳槽等原因离开公司时&#xff0c;他们可能会无意中或有意地携带走企业的核心研发数据&#xff0c;这对于任何企业来说都是一个巨大的风险。为了有效地…

Vue---组件

Vue—组件 目录 Vue---组件定义组件全局组件局部组件 组件通讯***重点***父子通信之父传子&#xff08;props&#xff09;父子通信之子传父&#xff08;$emit&#xff09;ref属性&#xff08;$refs&#xff09; 动态组件插槽命名插槽 定义组件 全局组件 vue2中template只能传…

ArcGIS小技巧—基于点数据的密度分析(含练习数据)

关于空间点数据的密度分析&#xff0c;Arcgis Map中提供了基础的点密度分析和核密度分析。核密度分析可以通过手动设置搜索半径&#xff0c;调整密度分布的合理性。 但有时由于实际工作的需要&#xff0c;我们需要对研究范围做特定划分&#xff0c;比如根据格网规则划分做密度…

Flask框架进阶-Flask流式输出和受访配置--纯净详解版

Flask流式输出&#x1f680; 在工作的项目当中遇到了一种情况&#xff0c;当前端页面需要对某个展示信息进行批量更新&#xff0c;如果直接将全部的数据算完之后&#xff0c;再返回更新&#xff0c;则会导致&#xff0c;前端点击刷新之后等待时间过长&#xff0c;开始考虑到用进…

电脑录制视频快捷键,一键开启录屏新时代(干货)

“最近尝试录制一些电脑上的操作视频&#xff0c;用来制作教学教程。不过&#xff0c;每次录制都要通过菜单或搜索来打开录屏软件&#xff0c;实在是有些繁琐。有没有人知道哪些电脑录制视频的快捷键呀&#xff1f;或者有没有通用的快捷键设置方法&#xff1f;” 在当今数字时…

CMake+qt+Visual Studio

#使用qt Creator 创建Cmake 项目,使用Cmake Gui 生成sln 工程&#xff0c;使用Visual Studio 开发 ##使用qt Creator 创建CMake项目 和创建pro工程的步骤一致&#xff0c;只是在选择构建系统的步骤上选择CMake,接下来步骤完全相同 工程新建完成之后&#xff0c;构建cmake 项…

PE文件(三)节表作业

本次作业以notepad进行演示&#xff0c;如下是其在硬盘上的内存 1.手动解析节表 由标准pe头可知&#xff0c;一共由7个节也就是7个节表&#xff0c;可选pe头的大小是0X00F0&#xff0c;即240字节大小 根据上述我们所获取的信息&#xff0c;找到节表的首地址为0x01F8 .text …

微服务:Nacos注册中心

个人简介&#xff1a;Java领域新星创作者&#xff1b;阿里云技术博主、星级博主、专家博主&#xff1b;正在Java学习的路上摸爬滚打&#xff0c;记录学习的过程~ 个人主页&#xff1a;.29.的博客 学习社区&#xff1a;进去逛一逛~ Nacos注册中心 一、服务注册与发现1.启动Nacos…

Vite proxy-rewrite 属性详解

在前端开发中&#xff0c;为了避免跨域问题&#xff0c;我们会在vite.config.ts 中配置如下问题 rewrite: 由于不了解Nginx的知识&#xff0c;这个属性一直困扰着我&#xff0c;这个重写有啥用&#xff0c;加和不加有啥影响 server: {host: 0.0.0.0,proxy: {/api: {target: ht…

手机通讯录删除了怎么恢复?这里几个方法超快找回!

当我们不小心删除了手机通讯录中的联系人&#xff0c;或者手机丢失导致通讯录信息丢失&#xff0c;恢复通讯录就变得非常重要了。手机通讯录删除了怎么恢复&#xff1f;我们该如何快速找回这些重要的联系人信息呢&#xff1f;下面我们将介绍2种简单易行的方法&#xff0c;帮助您…

Spark核心名词解释与编程

Spark核心概念 名词解释 1)ClusterManager&#xff1a;在Standalone(上述安装的模式&#xff0c;也就是依托于spark集群本身)模式中即为Master&#xff08;主节点&#xff09;&#xff0c;控制整个集群&#xff0c;监控Worker。在YARN模式中为资源管理器ResourceManager(国内…

树莓集团整合行业资源 优化数字产业生态圈

树莓集团&#xff0c;作为国际数字影像产业园的运营方以及链主企业&#xff0c;自创立以来&#xff0c;一直致力于整合行业优质资源&#xff0c;为数字科技领域的优秀企业提供一片肥沃的创新土壤。随着信息技术的迅猛发展和数字经济的深入推进&#xff0c;树莓集团深知自身的责…

七彩虹(Colorful)隐星P16 2023款笔记本电脑原装出厂Win11系统镜像下载 带建Recovery一键还原功能

七彩虹原厂Windows预装OEM专用系统&#xff0c;恢复出厂开箱状态一模一样 适用型号&#xff1a;隐星P16 23 链接&#xff1a;https://pan.baidu.com/s/1Ig5MQMiC8k4VSuCOZRQHUw?pwdak5l 提取码&#xff1a;ak5l 原厂W11系统自带所有驱动、出厂时自带的主题与专用壁纸、系…

机器学习在医疗行业的应用:颠覆传统诊疗模式,开启智慧医疗新时代

文章目录 一、精准诊断的突破二、药物研发的革新三、患者管理的智能化四、智能辅助决策系统五、机器学习在医疗行业的前景 随着科技的飞速发展&#xff0c;机器学习作为人工智能的核心技术&#xff0c;正逐渐渗透到各个行业中&#xff0c;其中在医疗行业的应用尤为引人瞩目。机…

Strassen矩阵乘法——C++

【题目描述】 根据课本“Strassen矩阵乘法”的基本原理&#xff0c;设计并实现一个矩阵快速乘法的工具。并演示至少10000维的矩阵快速乘法对比样例。 【功能要求】 实现普通矩阵乘法算法和“Strassen矩阵乘法”算法对相同的矩阵&#xff0c;分别用普通矩阵乘法算法&#xff…

电机控制系列模块解析(11)—— 电流采样

一、电流采样分类 由下图可知&#xff0c;采样电阻的位置不同&#xff0c;电流采样分为输出电流采样、下桥电流采样、母线电流采样。 输出电流采样 定义&#xff1a;输出电流采样是指对电机定子绕组或转子绕组&#xff08;对于内转子永磁同步电机&#xff09;输出的电流进行测…

什么是区块链?智能合约有什么用?

一、什么是区块链&#xff1f; 区块链是一种去中心化的分布式账本技术&#xff0c;通过加密和共识机制确保数据的安全和透明。它将交易数据按照时间顺序记录在区块中&#xff0c;并通过链式链接保证了数据的不可篡改性。 二、什么是智能合约&#xff1f; 智能合约是运行在区…