【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 ...
随机推荐
- [Lua] IT技术熟练度生成器 | 根据IT活动记录生成md表格 | 自创
IT技术熟练度 v1.0 为衡量个人能力水平自创的一套评分机制,根据时间.代码行数.基础理论三个变量生成.最近在学lua,正好练下基本功.效果可见 个人介绍 | 代码统计 - 小能日记 - 博客园 ( ...
- 地表最帅缓存Caffeine
简介 缓存是程序员们绕不开的话题,像是常用的本地缓存Guava,分布式缓存Redis等,是提供高性能服务的基础.今天敬姐带大家一起认识一个更高效的本地缓存--Caffeine. Caffeine Ca ...
- DeferredResult异步处理spring mvc Demo
一.概述 spring mvc同步接口在请求处理过程中一直处于阻塞状态,而异步接口可以启用后台线程去处理耗时任务.简单来说适用场景: 1.高并发: 2.高IO耗时操作. 二.Demo Spring M ...
- Win10 误删winsock注册表修复。 winsock.reg
手贱删除了注册表的winsock项, 导致无法上网. 导入后需要重启电脑才能上网, 这个文件是我在别人电脑里导出来的. 下载地址: https://pan.baidu.com/s/1wH8SdeWsx ...
- Binary String Copying
Smiling & Weeping ----第一次见你的时候, 在我的心里已经炸成了烟花, 需要用一生来打扫灰炉. 题目链接:Problem - C - Codeforces 题目大意不难,就 ...
- numpy_tricks
Numpy Tricks 这篇文章不定期更新,主要是记录在使用numpy过程中一些有效的tricks(或者重要的API) import numpy as np numpy.where() numpy. ...
- GIS中的ROI文件可否由.xml格式转为.roi格式?
本文介绍在ENVI软件中,将用户自行绘制的.xml格式的感兴趣区(ROI)文件转换为.roi格式的方法. 对于ENVI软件,其在早期版本中,默认将用户所绘制的感兴趣区文件保存为.roi格式:而 ...
- 「Tricks」整体DP
不太了解这个东西的具体定义是什么,总之应该是一个用数据结构维护 DP 状态的某几个维度的 trick 吧. 事实上你可以把这篇 post 理解为三个题的解集. 先直接来看 noi2020 - Dest ...
- Python 实现Word转PDF
通过将 Word 文档转换为 PDF,您可以确保文档在不同设备上呈现一致,并防止其他人对文档内容进行非授权修改.此外,在你需要打印文档时,转换为PDF还能确保打印输出的准确性.本文将介绍如何使用Pyt ...
- Linux挂载新磁盘
Linux挂载新磁盘 1. 查看磁盘 # df -lh # 查看磁盘占用情况,同时可以查看已挂载的磁盘及其挂载位置 # fdisk -l # 查看所有的磁盘分区 图中 /dev/sdb 下无分区信息, ...