---------------------------------------------------------------------------------------------------------------------------------------------------

  组播(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的组播应用的更多相关文章

  1. 海思3516系列芯片SPI速率慢问题深入分析与优化(基于PL022 SPI 控制器)

    海思3516系列芯片SPI速率慢问题深入分析与优化(基于PL022 SPI 控制器) 我在某个海思主控的项目中需要使用SPI接口来驱动一块液晶屏,液晶屏主控为 st7789,分辨率 240x240,图 ...

  2. nxp基于layerscape系列芯片的硬件型号解析

    每一种layerscape系列芯片都有两种硬件型号: RDB 和QDS RDB: Refrence Design Board QDS: QorIQ Development system

  3. 以太网接口TCP/IP协议介绍,说的很容易懂了

      以太网接口TCP/IP协议介绍,说的很容易懂了  TCP/IP协议,或称为TCP/IP协议栈,或互联网协议系列. TCP/IP协议栈(按TCP/IP参考模型划分) 应用层 FTP SMTP HTT ...

  4. [转帖]你不曾见过的国产CPU:可能是最全的龙芯系列芯片家谱(下)

    你不曾见过的国产CPU:可能是最全的龙芯系列芯片家谱(下) https://www.ijiwei.com/html/news/newsdetail?source=pc&news_id=7177 ...

  5. Keil MDK STM32系列(九) 基于HAL和FatFs的FAT格式SD卡TF卡读写

    Keil MDK STM32系列 Keil MDK STM32系列(一) 基于标准外设库SPL的STM32F103开发 Keil MDK STM32系列(二) 基于标准外设库SPL的STM32F401 ...

  6. Keil MDK STM32系列(一) 基于标准外设库SPL的STM32F103开发

    Keil MDK STM32系列 Keil MDK STM32系列(一) 基于标准外设库SPL的STM32F103开发 Keil MDK STM32系列(二) 基于标准外设库SPL的STM32F401 ...

  7. Keil MDK STM32系列(二) 基于标准外设库SPL的STM32F401开发

    Keil MDK STM32系列 Keil MDK STM32系列(一) 基于标准外设库SPL的STM32F103开发 Keil MDK STM32系列(二) 基于标准外设库SPL的STM32F401 ...

  8. Nacos系列:基于Nacos的配置中心

    前言 在看正文之前,我想请你回顾一下自己待过的公司都是怎么管理配置的,我想应该会有以下几种方式: 1.硬编码 没有什么配置不配置的,直接写在代码里面,比如使用常量类 优势:对开发友好,开发清楚地知道代 ...

  9. STM32系列芯片命名规范

    1.STM32的基础知识 STM32是意法半导体公司,基于ARM Cortex®-M0,M0+,M3, M4和M7内核生产的系列通用MCU.截止当前时间为止(20190515),STM32有STM32 ...

  10. Keil MDK STM32系列(三) 基于标准外设库SPL的STM32F407开发

    Keil MDK STM32系列 Keil MDK STM32系列(一) 基于标准外设库SPL的STM32F103开发 Keil MDK STM32系列(二) 基于标准外设库SPL的STM32F401 ...

随机推荐

  1. API技术的使用场景

    ​ 互联网的发展和普及,API技术也变得越来越重要.API是应用程序接口,它是一种连接不同应用程序或系统之间数据交换和通信的方式.API技术不仅提高了不同应用程序之间的互操作性,还加速了应用程序的开发 ...

  2. 循序渐进介绍基于CommunityToolkit.Mvvm 和HandyControl的WPF应用端开发(1)

    在我们的SqlSugar的开发框架中,整合了Winform端.Vue3+ElementPlus的前端.以及基于UniApp+Vue+ThorUI的移动前端几个前端处理,基本上覆盖了我们日常的应用模式了 ...

  3. JAVA-Springboot实践项目-用户注册

    Smiling & Weeping ----我本没喜欢的人, 见你的次数多了, 也就有了. 1.创建数据表 1.1.选中数据表: use store 1.2.创建t_user表: 2创建用户实 ...

  4. 【krpano】图文案例

    KRPano图文案例可以展示图片和文字,并支持图片放大浏览,以及文本拖动等操作. 具体截图如下: 下载地址:http://pan.baidu.com/s/1qXQnPes 感谢群内小伙伴 快乐分享 本 ...

  5. 从DevOps实践落地的角度谈谈“流程”和“规范"的反模式

    最近在经历的一些事情,让我突发灵感,觉得要写点关于DevOps体系建设过程中的"流程规范",记录下来. 如何解读"流程规范" 谈到DevOps落地,无一例外都会 ...

  6. 小札 Combinatorics 2

    对于 Newton Expansion,式子本身的证明其实无甚可翻新的花样,但是题还是很有意思的.比如 codeforces - 1332E Height All the Same 这个. 首先给出几 ...

  7. 解锁Java面试中的锁:深入了解不同类型的锁和它们的用途

    简介 多线程编程在现代软件开发中扮演着至关重要的角色.它使我们能够有效地利用多核处理器和提高应用程序的性能.然而,多线程编程也伴随着一系列挑战,其中最重要的之一就是处理共享资源的线程安全性.在这个领域 ...

  8. .NET周刊【9月第3期 2023-09-17】

    国内文章 在.NET 8 RC1 版本中 MAUI.ASP.NET Core 和 EF8 的新特性 https://www.cnblogs.com/shanyou/p/17698428.html 从年 ...

  9. MySQL系列之主从复制进阶——延时从库、半同步、过滤复制、GTID复制

    目录 1. 延时从库 1.1介绍 1.2 为什么要有延时从 1.3 配置延时从库 1.4 延时从库应用 1.4.1 故障恢复思路 1.4.2 故障模拟及恢复 2. 半同步 *** 2.1 半同步复制工 ...

  10. 【译】为什么命名“它”为依赖属性(DependencyProperty)

    当我们创建新的类和成员时,我们花费了大量的时间和精力是它们尽可能的好用,好理解,好发现.通常我们会遵循.Net框架设计指南,尤其是会不断地研究这个新类与其他类,未来计划等内容之间的关系. 当命名依赖属 ...