1. 问题
整车测试时发现,MCU收到SoC发送的组播以太网帧,导致片间通信数据丢帧;
2. 分析
组播以太网帧数据量大,时间间隔短且一直在外发。询问得知该以太网帧为某算法模块计算结果,需要组播发送给上位机查看。
图1:组播以太网帧
该外发以太网帧的源MAC与源IP和片间通信时SoC发送给MCU的MAC和IP一致,且组播的目的IP和目的MAC无法更改,这就导致MCU在接收片间通信数据外,组播以太网帧也会被接收进来,并且到TcpIp_Udp_RxIndication后,找不到对应的socket然后帧被丢掉(图2),以太网接收中断处理函数的时间被拉长到50ms(图3)。
图2:TcpIp_Udp_RxIndication函数
图3:以太网接收中断时长
3. 解决
本着算法不改代码和模型的原则,先从MCU自身着手,否可以过滤以太网帧。
3.1 查看TC397 user manual
3.1.1 MAC接收特性
灵活的地址过滤方式:
- 多达31个额外的48位完美目的地址过滤器,每个字节带有掩码
- 最多31个48位源地址比较检查,每个字节带有掩码
- 选项性通过所有组播寻址数据包
- 混杂模式:所有报文不经过过滤直接通过,用于网络监控
- 通过状态报告传递所有传入数据包(根据过滤器)
3.1.2 帧过滤
3.1.3 源地址或者目的地址过滤
- 单播目的地址过滤
MAC支持128个MAC地址实现单播精准过滤。MAC将收到的所有48位单播地址与编程的MAC地址进行匹配。默认的MacAddr0总是使能。MacAddr1到MacAddr127地址通过单独的使能位来选择。对于MacAddr1到MacAddr31地址,通过在寄存器中设置相应的掩码字节控制位,将接收到的目的地址与之相比较,从而过滤每一个字节。MacAddr31到MacAddr127没有掩码控制,所有6字节MAC地址斗鱼收到的6字节目的地址进行比较。
查看寄存器:
- 组播目的地址过滤
要是MAC通过所有组播数据包,在MAC_Packet_Filter寄存器中设置PM位。
组播地址与已编程的MAC目的地址寄存器(1-31)比较。还支持组地址过滤。
- 广播地址过滤
默认情况下,MAC不过滤任何广播报文。设置MAC_Packet_Filter寄存器中的DBF位,使MAC拒绝所有广播报文。
- 单播源地址过滤
MAC可以根据收到的豹纹的源地址字段进行精准的过滤。默认情况下,MAC将源地址字段与源地址寄存器中编程的值进行比较。通过设置MAC地址寄存器[1-31]对应寄存器的第30位,可以将其配置为使用SA而不是DA进行比较。
MAC还支持SA组过滤。可以通过屏蔽地址的一个或者多个字节来过滤一组地址。如果在MAC_Packet_Filter寄存器中设置了SAF位,则MAC将丢弃未通过SA过滤的报文。否则,SA过滤器的结果将作为接收状态位给出。当设置了SAF位,需要根据SA过滤器和DA过滤器的结果进行&运算,以决定是否转发该报文。这意味着如果一个过滤器失败,数据包将被丢弃。只有当数据包一次通过两个过滤器时,数据包才会被转发到应用程序。
- 翻转过滤
对于DA和SA过滤,可以通过设置MAC_Packet_Filter寄存器的DAIF和SAIF位来翻转最终输出的过滤器匹配结果。DAIF位及时用于单播DA报文,也适用于组播DA报文。单播和组播目的地址过滤的结果被翻转。类似的,当设置了SAIF时,单播SA过滤器的结果也会反转。
3.1.4 具体寄存器
- MAC_PACKET_FILTER寄存器
Field | Bits | Type | Description |
PR | 0 | rw | Promiscuous Mode 当设置此位时,地址过滤模块通过所有传入的数据包,而不考虑目的地址或源地址。设置PR时,总是清除Rx状态字的SA或DA Filter Fails状态位。 复位后值:0x0 |
RES 2_1 | 2:1 | r | Reserved |
DAIF | 3 | rw | DA Inverse Filtering 当设置此位时,地址检查块以反转过滤方式对单播和组播报文的 DA地址进行比较。当该位复位时,对报文进行正常过滤。 复位后值:0x0 |
PM | 4 | rw | Pass All Multicast 当设置此位时,表示所有接收到的具有组播目的地址(目的地址字段的第一位为'1')的报文都将通过。 复位后值:0x0 |
DBF | 5 | rw | Disable Broadcast Packets 当设置此位时,AFM模块将阻塞所有传入的广播报文。此外,它覆盖所有其他过滤器设置。当此位被重置时,AFM模块将通过接收到的所有广播报文。 复位后值:0x0 |
PCF | 7:6 | rw | Pass Control Packets 这些位控制所有控制包(control packet)的转发(包括单播和多播暂停帧)。 复位后值:0x0 00b MAC过滤所有到达应用程序的控制包(control packet)。 01b 除了Pause packet以外的所有控制报文,即使没有通过地址过滤,MAC也会将这些控制报文转发给应用。 10b MAC将所有控制报文转发给应用程序,即使它们没有通过地址过滤。 11b MAC转发通过地址过滤器的控制报文。 |
SAIF | 8 | rw | SA Inverse Filtering 设置此位后,地址检查以反转过滤方式进行SA地址比较。如果数据包的SA与SA寄存器中编程的值匹配,则将其标记为未通过SA地址过滤器。当此位被重置时,如果数据包的SA与SA寄存器中编程的值不匹配,则将其标记为未通过SA地址过滤器。 复位后值:0x0 |
SAF | 9 | rw | Source Address Filter Enable 当设置此位时,MAC将收到的数据包中的SA字段与已启用的SA寄存器中编程的值进行比较。如果比较失败,则丢弃报文。当此位被重置时,MAC将收到的数据包转发给应用程序,并根据SA地址比较更新Rx状态的SAF位。 注:根据IEEE规范,SA的47位是保留的。然而,在DWC_ether_qos中,MAC比较所有48位。软件驱动程序在为设置SA的MAC地址寄存器时应该考虑到这一点。 复位后值:0x0 |
RES_10 | 10 | r | Reserved |
RES_15_11 | 15:11 | r | Reserved 复位后值:0x0 |
VTFE | 16 | rw | VLAN Tag Filter Enable 设置此位后,不匹配VLAN Tag的报文将被丢弃。当此位被重置时,MAC将转发所有报文,而不管VLAN Tag的匹配状态如何。 复位后值:0x0 |
RES19_17 | 19:17 | r | Reserved 复位后值:0x0 |
RES_21_20 | 21:20 | r | Reserved |
RES 30 22 | 30:22 | r | Reserved 复位后值:0x0 |
RA | 31 | rw | Receive All 当设置此位时,MAC Receiver模块将接收到的所有数据包传递给应用程序,而不管它们是否通过地址过滤器。SA或DA过滤的结果在Rx状态字的相应位更新(通过或失败)。当此位被重置时,接收器模块只将那些通过SA或DA地址过滤器的数据包传递给应用程序。 复位后值:0x0 |
- MAC_ADDRESS0_HIGH+MAC_ADDRESS0_LOW
HIGH和LOW组合一起,进行DA地址过滤;
- MAC_ADDRESSi_HIGH寄存器:
- MAC_ADDRESSi_LOW寄存器:
3.1.5 过滤器总结
依据接收到的数据包类型,DA和SA过滤器总结如下:
Packet Type | PR | DAIF | PM | DBF | DA Filter Operation |
Broadcas | 1 | X | X | X | Pass |
0 | X | X | 0 | Pass | |
0 | X | X | 1 | Fail | |
Unicast | 1 | X | X | X | Pass all packets |
0 | 0 | X | X | Pass on Perfect/Group filter match | |
0 | 1 | X | X | Fail on Perfect/Group filter match | |
Multicast | 1 | X | X | X | Pass all packets |
X | X | 1 | X | Pass all packets | |
0 | 0 | 0 | X | Pass on Perfect/Group filter match and drop Pause packets if PCF = 0x | |
0 | 1 | 0 | X | Fail on Perfec t/Gro up filter match and drop Pause packets if PCF = 0x |
Packet Type | PR | SAIF | SAF | DA Filter Operation |
Unicast | 1 | X | X | Pass all packets |
0 | 0 | 0 | Pass status on Perfect or Group filter match but do not drop packets that fail | |
0 | 1 | 0 | Fail status on Perfect or Group filter match but do not drop packet | |
0 | 0 | 1 | Pass on Perfect or Group filter match and drop packets that fail | |
0 | 1 | 1 | Fail on Perfect or Group filter match and drop packets that fail |
3.2 实验
目标:过滤组播以太网帧,保留偏见通信单播以太网帧核广播帧。
突破口:组播的目的MAC不是MCU的MAC,可以设置DA过滤器,DA必须是MCU的MAC才可以通过。因此MAC_PACKET_FILTER寄存器设置如下,MAC_PACKET_FILTER寄存器值为0:
PR | DAIF | PM | DBF | SAIF | SAF | DA Filter Operation |
0 | 0 | 0 | 0 | 0 | 0 | 1. 所有广播报文可以通过; 2. 和过滤器比较通过的单播报文可以通过; 3. 和过滤器比较通过的组播报文可以通过; 4. 不适用SA过滤; |
MAC_ADDRESS0_HIGH+MAC_ADDRESS0_LOW寄存器在初始化时会根据设置的MCU MAC地址写入该寄存器。
3.3 代码
# define ETH_30_TC3XX_REG_MAC_HIGH_AE (0x80000000u)
# define ETH_30_TC3XX_REG_OFFS_ADDR0_HIGH (0x0300u)
# define ETH_30_TC3XX_REG_OFFS_ADDR0_LOW (0x0304u)
# define ETH_30_TC3XX_REG_OFFS_ADDR1_HIGH (0x0308u)
# define ETH_30_TC3XX_REG_OFFS_ADDR1_LOW (0x030Cu)
Eth_30_Tc3xx_RegPtrType reg = Eth_30_Tc3xx_GetRegBaseAddrOfEthCtrlState(0u) + ETH_30_TC3XX_REG_OFFS_MAC_PACKET_FILTER;
/*Disable Promiscuous Mode*/
if((*reg) & ETH_30_TC3XX_REG_PACKET_FILTER_PR)
{
(*reg) = (*reg) & ~ETH_30_TC3XX_REG_PACKET_FILTER_PR;
}
/*does not Pass All Multicast*/
if((*reg) & ETH_30_TC3XX_REG_PACKET_FILTER_PM)
{
(*reg) = (*reg) & ~ETH_30_TC3XX_REG_PACKET_FILTER_PM;
}
/*------------------------------------------------------*/
Eth_30_Tc3xx_RegPtrType reg;
uint8 PdelayMultiCastAddr[6u] = {0x01u,0x80u,0xC2u,0x00u,0x00u,0x0E};
/*pass muilticast--pdelay in EthTsync*/
reg = Eth_30_Tc3xx_GetRegBaseAddrOfEthCtrlState(0u) + ETH_30_TC3XX_REG_OFFS_ADDR1_HIGH;
(*reg) = (uint32)(((uint32)PdelayMultiCastAddr[5] << 8u) | ((uint32)PdelayMultiCastAddr[4]) | (uint32)ETH_30_TC3XX_REG_MAC_HIGH_AE) ;
reg = Eth_30_Tc3xx_GetRegBaseAddrOfEthCtrlState(0u) + ETH_30_TC3XX_REG_OFFS_ADDR1_LOW;
(*reg) = (uint32)((uint32)PdelayMultiCastAddr[3] << 24u) |
((uint32)PdelayMultiCastAddr[2] << 16u) |
((uint32)PdelayMultiCastAddr[1] << 8u) | ((uint32)PdelayMultiCastAddr[0]);
3.4 测试
1. 使用canoe模拟回灌组播报文;
2. 使用capl脚本同时模拟片间UDP报文;
includes
{
}
variables
{
UdpSocket gSocket;
byte data[15] = {0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; //payload data
}
on key 'a'
{
gSocket = UdpSocket::Open(IP_Endpoint(0.0.0.0:51000)); // simulated is listen the port.
gSocket.sendto(IP_Endpoint(192.168.30.66:51000), data, elCount(data)); // send message to ECU
}
3. 查看以太网接收中断时间长度,仅100us。且IpV4_Arp_RxIndication接收正常(广播)。
4. 模拟片间通信发送UDP报文:
可以成功接收到片间通信数据(单播);
5. 实车验证
片间组播报文:
中断时间长度:
只有Arp_RxIndication产生中断;开启片间通信正常。