【WCH以太网接口系列芯片】基于CH395的组播应用
---------------------------------------------------------------------------------------------------------------------------------------------------
组播(Multicast)是一种在计算机网络中实现一对多通信的技术。在传统的单播(Unicast)通信中,一台计算机发送数据,只有特定的目标计算机可以接收到数据。而在组播中,一台计算机可以同时发送数据给一个组播组中的多个计算机,只有属于该组的计算机才能接收到数据。组播技术可以有效地减少数据在网络中的传输量,提高网络的效率。
CH395Q/L芯片是一款以太网协议栈芯片,它支持组播应用,同时可以通过MAC过滤模式来接受组播数据包。
本文通过使用沁恒CH32V307单片机SPI驱动CH395Q,编译软件为MRS。
首先,在主函数中对CH395进行初始化(注意主程序开始时先延时200ms时间以上和初始化延时),IP和网关及相关变量信息不在这边复述,程序代码见文章链接地址。
CH395CMDReset(); /* 复位CH395芯片 */
Delay_Ms(1000); /* 延时1000毫秒,要分开写,否则无效 */
Delay_Ms(1000);
i = CH395CMDGetVer(); /*获取芯片以及固件版本号 */
printf("CH395CMDGetVer:%x\n",i);
InitCH395InfParam(); /* 初始化CH395相关变量 */
i = CH395Init(); /* 初始化CH395芯片 ,200Ms以上*/
printf("CH395Init:%x\n",i);
mStopIfError(i); /*调试使用,显示错误代码,并停机*/
初始化完成后,根据CH395相关例程和手册(5.11节)描述,通过CMD_SET_MAC_FILT设置MAC过滤模式,该命令共9个字节数据。第一个字节用来设置过滤模式(图1示该字节的各位含义),芯片复位后默认是开启第0、3、4位的。程序中开启接收组播包,因此第一位写入0x1d。

图1 CH395MAC过滤模式第一字节各位含义
第 2 至第 5 字节为 HASH0(哈希表 0),第 6 至第 9 字节为 HASH1(哈希表 1),仅在多播开启有效。哈希表算法可以通过目的地址MAC地址计算出32位的CRC值,使用此 CRC 值的高 6 位作为索引值,将 HASH 表对应的位写 1。哈希算法可根据实际优化,通过该种算法可以过滤大部分无效帧,减少芯片处理负荷。
MacCrc32 = CH395CRCRet6Bit(MultiMac_1); //该命令详细内容可以参考官网提供的例程CH395CMD中
printf("MacCrc32 : %2x\n",(uint16_t)MacCrc32);
if(MacCrc32 > 31)
{
MacCrc32 -=32;
printf("MacCrc32_1 : %2x\n",(uint16_t)MacCrc32);
Hash1 = Hash1|((uint32_t)1<<MacCrc32);
}
else
{
Hash0 |= ((uint32_t)1<<MacCrc32);
}
printf("Hash0:%lx\r\n",(uint32_t)Hash0);
printf("Hash1:%lx\r\n",(uint32_t)Hash1);
CH395CMDSetMACFilt(0x1d, Hash0, Hash1);//开启接收多播包
MacCrc32 = CH395CRCRet6Bit(MultiMac_2);
printf("MacCrc32 : %2x\n",(uint16_t)MacCrc32);
if(MacCrc32 > 31)
{
MacCrc32 -=32;
printf("MacCrc32_2 : %2x\n",(uint16_t)MacCrc32);
Hash1 = Hash1|((uint32_t)1<<MacCrc32);
}
else
{
Hash0 |= ((uint32_t)1<<MacCrc32);
}
printf("Hash0:%lx\r\n",(uint32_t)Hash0);
printf("Hash1:%lx\r\n",(uint32_t)Hash1);
CH395CMDSetMACFilt(0x1d, Hash0, Hash1);
完成这些配置后,则对相应的scoket进行初始化和打开,注意socket要配置为UDP模式下。
void InitSocketParam(void)
{
memset(&sockinf[0],0,sizeof(sockinf[0])); /* 将SockInf[0]全部清零*/
memcpy(&sockinf[0].IPAddr, BroadcastIP,sizeof(BroadcastIP)); /* 如果启用UDP SERVER功能,需将目的IP设为广播地址255.255.255.255 */
// sockinf[0].DesPort = Socket0DesPort; /* 目的端口 */
sockinf[0].SourPort= Socket0SourPort; /* 源端口 */
sockinf[0].ProtoType=PROTO_TYPE_UDP; /* UDP模式 */
memset(&sockinf[1],0,sizeof(sockinf[1])); /* 将SockInf[0]全部清零*/
memcpy(&sockinf[1].IPAddr, BroadcastIP,sizeof(BroadcastIP)); /* 如果启用UDP SERVER功能,需将目的IP设为广播地址255.255.255.255 */
// sockinf[1].DesPort = Socket1DesPort; /* 目的端口 */
sockinf[1].SourPort= Socket1SourPort; /* 源端口 */
sockinf[1].ProtoType=PROTO_TYPE_UDP; /* UDP模式 */
}
void CH395SocketInitOpen(void)
{
UINT8 i;
/* socket 0为UDP模式 */
CH395SetSocketDesIP(0,sockinf[0].IPAddr); /* 设置socket 0目标IP地址 */
CH395SetSocketProtType(0,sockinf[0].ProtoType); /* 设置socket 0协议类型 */
// CH395SetSocketDesPort(0,sockinf[0].DesPort); /* 设置socket 0目的端口 */
CH395SetSocketSourPort(0,sockinf[0].SourPort); /* 设置socket 0源端口 */
i = CH395OpenSocket(0); /* 打开socket 0 */
mStopIfError(i);
CH395SetSocketDesIP(1,sockinf[1].IPAddr); /* 设置socket 0目标IP地址 */
CH395SetSocketProtType(1,sockinf[1].ProtoType); /* 设置socket 0协议类型 */
// CH395SetSocketDesPort(1,sockinf[1].DesPort); /* 设置socket 0目的端口 */
CH395SetSocketSourPort(1,sockinf[1].SourPort); /* 设置socket 0源端口 */
i = CH395OpenSocket(1); /* 打开socket 0 */
mStopIfError(i);
}
到这里的CH395的配置信息就满足组播应用需求了,注意使用时需要对CH395全局和Socket中断信息的读写,这里不再描述,可以参考例程代码。
---------------------------------------------------------------------------------------------------------------------------------------------------
配置完成后,我们可以通过网络测试工具和wireshark进行数据测试和抓包。
首先,通过网络测试工具建立一个UDP,目标IP为224.1.1.4,目标端口为6000,定时向224.1.1.4地址发送数据,图2示。

图2 网络测试工具配置
可以通过wireshark抓取网络数据包和单片机串口打印信息来判断CH395是否接受到该数据,图3示网络抓包和串口打印信息。

图3 数据监控
图中可以看出,电脑端192.168.1.21向224.1.1.4地址发送数据后,因程序里对socket的目的IP设置为广播地址,所以CH395接收到该数据包后会打印带有主机地址信息。其中len长为22的原因是程序设置socket为UDP Server模式,该模式下会带有信源的8个字节地址信息。为了更直观的判断CH395是否收到该数据,在该例程中调用了UDPSendto函数,CH395接受到该组播数据后会向原主机地址进行数据回传。可以在wires hark抓包图中第216行可以清晰看到CH395会向主机地址回传数据。
该例程测试是在直连电脑的情况下进行的,所以能够直观的接收到组播数据。但在更多的应用时,会发现我们电脑会时常发送一个组播请求的报文IGMP,而CH395并没有发送该报文,导致使用此例程可能无法在路由等网络环境对组播数据进行收发。
针对这个应用,我会在下一篇文章中做一个简单例程测试,让CH395在接入路由的环境下可以通过发送请求报文来加入组播段,解决无法接受组播数据的问题。
(测试例程)https://files.cnblogs.com/files/blogs/805237/Socket-UdpMulticast.rar?t=1700655709&download=true
【WCH以太网接口系列芯片】基于CH395的组播应用的更多相关文章
- 海思3516系列芯片SPI速率慢问题深入分析与优化(基于PL022 SPI 控制器)
海思3516系列芯片SPI速率慢问题深入分析与优化(基于PL022 SPI 控制器) 我在某个海思主控的项目中需要使用SPI接口来驱动一块液晶屏,液晶屏主控为 st7789,分辨率 240x240,图 ...
- nxp基于layerscape系列芯片的硬件型号解析
每一种layerscape系列芯片都有两种硬件型号: RDB 和QDS RDB: Refrence Design Board QDS: QorIQ Development system
- 以太网接口TCP/IP协议介绍,说的很容易懂了
以太网接口TCP/IP协议介绍,说的很容易懂了 TCP/IP协议,或称为TCP/IP协议栈,或互联网协议系列. TCP/IP协议栈(按TCP/IP参考模型划分) 应用层 FTP SMTP HTT ...
- [转帖]你不曾见过的国产CPU:可能是最全的龙芯系列芯片家谱(下)
你不曾见过的国产CPU:可能是最全的龙芯系列芯片家谱(下) https://www.ijiwei.com/html/news/newsdetail?source=pc&news_id=7177 ...
- Keil MDK STM32系列(九) 基于HAL和FatFs的FAT格式SD卡TF卡读写
Keil MDK STM32系列 Keil MDK STM32系列(一) 基于标准外设库SPL的STM32F103开发 Keil MDK STM32系列(二) 基于标准外设库SPL的STM32F401 ...
- Keil MDK STM32系列(一) 基于标准外设库SPL的STM32F103开发
Keil MDK STM32系列 Keil MDK STM32系列(一) 基于标准外设库SPL的STM32F103开发 Keil MDK STM32系列(二) 基于标准外设库SPL的STM32F401 ...
- Keil MDK STM32系列(二) 基于标准外设库SPL的STM32F401开发
Keil MDK STM32系列 Keil MDK STM32系列(一) 基于标准外设库SPL的STM32F103开发 Keil MDK STM32系列(二) 基于标准外设库SPL的STM32F401 ...
- Nacos系列:基于Nacos的配置中心
前言 在看正文之前,我想请你回顾一下自己待过的公司都是怎么管理配置的,我想应该会有以下几种方式: 1.硬编码 没有什么配置不配置的,直接写在代码里面,比如使用常量类 优势:对开发友好,开发清楚地知道代 ...
- STM32系列芯片命名规范
1.STM32的基础知识 STM32是意法半导体公司,基于ARM Cortex®-M0,M0+,M3, M4和M7内核生产的系列通用MCU.截止当前时间为止(20190515),STM32有STM32 ...
- Keil MDK STM32系列(三) 基于标准外设库SPL的STM32F407开发
Keil MDK STM32系列 Keil MDK STM32系列(一) 基于标准外设库SPL的STM32F103开发 Keil MDK STM32系列(二) 基于标准外设库SPL的STM32F401 ...
随机推荐
- 千万级数据深分页查询SQL性能优化实践
一.系统介绍和问题描述 如何在Mysql中实现上亿数据的遍历查询?先来介绍一下系统主角:关注系统,主要是维护京东用户和业务对象之前的关注关系:并对外提供各种关系查询,比如查询用户的关注商品或店铺列表, ...
- C++算法之旅、04 基础篇 | 第一章
常用代码模板1--基础算法 - AcWing ios::sync_with_stdio(false) 提高 cin 读取速度,副作用是不能使用 scanf 数据输入规模大于一百万建议用scanf 快速 ...
- MapReduce核心概念及架构
MapReduce简介 MapReduce常用于对大规模数据集(大于1TB)的并行运算,或对大数据进行加工.挖掘和优化等处理. MapReduce将并行计算过程高度抽象到了两个函数map和reduce ...
- 关于TCP 四次挥手过程中的reset包问题
数据包过程 TCP状态机转换过程 客户端在接受到第32个数据包之后,应该发送1个对FIN的ACK数据包,然而客户端缺直接连续发送了3个Rest数据包36~38,客户端并未进入time wait阶段,直 ...
- tcpdump后台不间断抓包
版本1的抓包命令 这两天排查一个小问题,需要在服务器上使用tcpdump24小时不间断抓包,这里简单记录下. 先看下tcpdump的语法: tcpdump [ -AbdDefhHIJKlLnNOpqS ...
- 常用设计模式(Java)
目录 设计模式引入 1. 什么是设计模式 2. 学习设计模式的意义 3. 设计模式的基本要素 4. OOP七大原则 1.单例模式 1. 饿汉式单例 2. 懒汉式单例 3. 内部类实现单例 4. 反射会 ...
- 彻底弄懂ip掩码中的网络地址、广播地址、主机地址
本文为博主原创,转载请注明出处: 概念理解: IP掩码(或子网掩码)用于确定一个IP地址的网络部分和主机部分.它是一个32位的二进制数字,与IP地址做逻辑与运算,将IP地址划分为网络地址和主机地址两部 ...
- 爬虫系列——Scrapy
文章目录 一 介绍 二 安装 三 命令行工具 四 项目结构以及爬虫应用简介 五 Spiders 六 Selectors 七 Items 八 Item Pipeline 九 Dowloader Midd ...
- 高效数据管理:Java助力实现Excel数据验证
摘要:本文由葡萄城技术团队原创并首发.转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 前言 在Java中,开发者可以使用一些开源的库(如Apache POI ...
- .netCore 图形验证码,非System.Drawing.Common
netcore需要跨平台,说白点就是放在windows服务器要能用,放在linux服务器上也能用,甚至macos上. 很多时候需要使用到图形验证码,这就有问题了. 旧方案1.引入包 <Packa ...