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

  组播(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. uniapp APP微信登录、支付、分享以及支付宝支付 实战踩坑记录

    1.微信支付和支付宝支付   先上代码.封装好了的组件    html部分      <template> <view class="rows"> < ...

  2. 推荐一款免费好用的远程桌面:Getscreen

    因为平时有多台设备要用,所以远程桌面是我经常要使用的工具. 最近,正好看到一款不错的远程桌面软件,马上拿出来推荐给大家,如果有需要的可以看看. 今天要推荐的远程桌面软件就是这款叫Getscreen的软 ...

  3. Windows安装、配置、卸载MySQL教程

    MySQL是一个关系型数据库管理系统,目前为Oracle旗下产品,它具有开源.体积小.速度快的优点,许多网站使用的都是MySQL数据库. 简单而言,MySQL数据库核心功能就是用来存储数据的. MyS ...

  4. 解读Redis常见命令

    Redis数据结构介绍 Redis是一个key-value的数据库,key一般是String类型,不过value的类型多种多样: 贴心小建议:命令不要死记,学会查询就好啦 Redis为了方便我们学习, ...

  5. PivotGridControl自定义行数据的统计公式

    我们在使用PivotGridControl进行数据统计的时候,用时候需要在不同的行使用不同的汇总公式的情况,本文就是为了说明怎么实现此功能,如下图说明 数据源: 注意:此时数据列指定的SummaryT ...

  6. 「codeforces - 1633F」Perfect Matching

    link. 首先所有的 activated nodes 组合成了一棵以 \(1\) 为根的有根树.询问即求由 activated nodes 组成的树的最大匹配.对于树上最大匹配有一个贪心策略:自底向 ...

  7. Redis持久化 (RDB和AOF) 梳理

    Redis有两种持久化方案: RDB持久化 AOF持久化 RDB持久化 RDB全称Redis Database Backup file(Redis数据备份文件),也被叫做Redis数据快照.简单来说就 ...

  8. Fireboom on Sealos:半小时搞定一个月的接口工作

    后端日常开发工作中有 88% 的接口都是 CURD,占用了超过 6 成开发时间.这些工作枯燥乏味,且价值低下,不仅荒废了时间,还无法获得任何成就感.而 Fireboom 可在 2 分钟内,完成传统模式 ...

  9. jquery设置图片可手动拖拽

    JQuery是一款流行的JavaScript框架,可以轻松实现网页交互效果.而其中一种常见效果是图片手动拖拽.以下是设置图片手动拖拽的JQuery代码. 1 2 3 4 5 6 7 8 9 10 11 ...

  10. Python比较字符串格式类型时间大小

    已知的格式是 06/24/2021 15:47:01.491 时间比较的思路是,把数据转换成时间戳比较: 第一步是把 06/24/2021 15:47:01.491 格式转换称 2021-06-24 ...