TI SimpleLink Wi-Fi接收过滤器:实现物联网设备低功耗与高效数据处理
2026/7/29 12:58:47 网站建设 项目流程

1. 项目概述:为什么我们需要Wi-Fi接收过滤器?

在嵌入式Wi-Fi设备开发中,尤其是那些对功耗、响应速度和网络流量极为敏感的物联网终端,一个常见且棘手的问题是:如何让设备只处理它真正关心的数据?想象一下,你的设备连接在一个繁忙的Wi-Fi网络中,周围充斥着大量的广播包、组播包、其他设备的ARP请求、无关的TCP握手包等等。如果主处理器(MCU)需要逐一接收并处理所有这些数据包,其CPU负载将不堪重负,宝贵的电池电量也会被迅速耗尽,更不用说那些需要被快速响应的关键数据包可能会被淹没在“噪音”中。

这就是接收过滤器(Rx Filter)登场的场景。它本质上是一个部署在Wi-Fi网络处理器(如TI SimpleLink系列芯片)硬件或底层固件中的“智能哨兵”。它的职责是在数据包到达主机应用层之前,根据开发者预设的一系列规则,进行高速、低功耗的筛选。只有匹配规则的数据包才会被递交给主机处理,不匹配的则可能被直接丢弃或触发特定动作,从而极大地减轻了主机的负担。

本次我们将深入解析德州仪器(TI)SimpleLink Wi-Fi平台中接收过滤器的核心机制,特别是其触发条件(Trigger)执行动作(Action)以及全生命周期的配置管理。理解这些概念,你就能像给设备编写“条件反射”一样,让它变得既聪明又高效。无论你是想实现超低功耗的“Wake on Wireless LAN”(无线唤醒),还是构建一个只对特定协议(如MQTT over TLS)响应的安全终端,亦或是进行网络诊断和流量嗅探,Rx Filter都是你必须掌握的核心工具。

2. 接收过滤器核心架构与设计哲学

在深入代码之前,我们必须先建立起对Rx Filter系统架构的宏观认知。SimpleLink的Rx Filter并非一个简单的“if-else”判断,而是一个设计精巧、层次分明的规则引擎。

2.1 过滤器规则的三要素:触发、匹配与动作

一个完整的过滤器规则由三个核心部分组成,它们像一条流水线一样协同工作:

  1. 触发器(Trigger):这是规则的“上岗条件”。它定义了在何种环境状态下,这条规则才需要被评估。例如,只有当设备处于STA(站点)模式且已成功获取IP地址时,某条针对HTTP流量的过滤规则才生效。如果触发条件不满足,规则直接跳过,匹配结果视为FALSE。这避免了在不必要的场景下进行无谓的规则匹配计算。

  2. 匹配器(Matcher/Rule):这是规则的“核心判断逻辑”。它定义了需要检查数据包的哪些头部字段(如MAC地址、IP地址、端口号、协议类型等),以及匹配的数值或范围。这部分是过滤器进行数据包分类的核心。

  3. 动作(Action):这是规则的“执行结果”。当触发器条件满足且匹配器成功匹配后,系统将执行预设的动作。最典型的动作包括:将数据包丢弃(DROP)、传递给主机(PASS,通常为默认或NULL动作)、或者向主机发送一个事件通知(EVENT_TO_HOST)。

这种“条件-判断-执行”的分离设计,赋予了过滤器极大的灵活性和效率。你可以为不同网络状态(如未连接、已连接、已获IP)定义完全不同的过滤策略集。

2.2 规则的树状层次结构与层间依赖

SimpleLink的过滤器支持以树状结构进行组织,这是其强大功能的关键。每个过滤器都可以指定一个父过滤器ID(Parent Filter ID)

  • 根过滤器(Root Filter):将ParentFilterId设置为0的过滤器即为根过滤器。它没有父节点,可以独立存在并被评估。
  • 子过滤器(Child Filter):拥有非零父过滤器ID的过滤器。一个子过滤器只有当其父过滤器的匹配结果为TRUE时,才会被评估。这创建了一种逻辑上的“与(AND)”关系。例如,你可以创建一个根过滤器来匹配所有TCP流量(父过滤器),然后创建多个子过滤器来分别匹配目的端口为80、443、1883等(子过滤器)。只有当数据包是TCP包时,才会进一步检查它是否去往这些特定端口。

然而,这种树状结构并非任意组合,它必须遵循网络协议栈的分层原则。规则被分为四个逻辑组(A, B, C, D),对应从底层到高层的协议头:

组别规则字段示例可成为哪些组的父节点对应协议层
AFRAME_TYPE,MAC_SRC_ADDRESS,BSSIDA, B, C, D数据链路层 (MAC层)
BETHER_TYPE,IP_VERSION,L1_PAYLOADB, C, D网络层 (IP层)
CSource IP,Destination IP,IP_PROTOCOLC, D传输层 (TCP/UDP/ICMP)
DSource Port,Destination Port,L4_PAYLOADD应用层(基于端口)

关键限制:一个过滤器只能成为同层或更高层(编号更大)过滤器的父节点。例如,一个基于IP协议(组C)的过滤器可以作为一个基于端口(组D)的过滤器的父节点,但不能反过来成为一个基于MAC地址(组A)的过滤器的父节点。这完全符合数据包处理流程:必须先识别出IP包,才能去检查它的端口。

重要经验:在设计复杂过滤规则树时,务必从底层(组A)向高层(组D)构建。将最通用、最底层的条件(如“仅处理来自某BSSID的数据”)设为根过滤器或高层父节点,可以提前过滤掉大量无关数据包,显著提升过滤效率。同时,如果一个过滤器的动作为DROP,它绝对不能作为任何其他过滤器的父节点,因为数据包一旦被丢弃,后续的树遍历就会立即终止。

3. 触发器(Trigger)的深度解析与实战配置

触发器是过滤规则的“开关”,它确保了规则只在正确的上下文环境中被激活。SimpleLink提供了两类触发器:基于连接状态的触发器和基于计数器的触发器。

3.1 连接状态与设备角色触发器

这是最常用的触发器类型,它由两个维度构成:Role(角色)和ConnectionState(连接状态)。

支持的角色(Role):

  • SL_WLAN_RX_FILTER_ROLE_STA:设备作为Wi-Fi客户端(站点)时。
  • SL_WLAN_RX_FILTER_ROLE_AP:设备作为Wi-Fi接入点时。
  • SL_WLAN_RX_FILTER_ROLE_PROMISCUOUS:设备处于混杂模式(常用于嗅探器)时。
  • SL_WLAN_RX_FILTER_ROLE_NULL:通常表示不限制角色,或用于特殊状态。

支持的连接状态(ConnectionState):

  • SL_WLAN_RX_FILTER_STATE_STA_CONNECTED:STA角色下,已连接到AP。
  • SL_WLAN_RX_FILTER_STATE_STA_NOT_CONNECTED:STA角色下,未连接。
  • SL_WLAN_RX_FILTER_STATE_STA_HAS_IP:STA角色下,已连接已通过DHCP或静态配置获得IP地址。
  • SL_WLAN_RX_FILTER_STATE_STA_HAS_NO_IP:STA角色下,已连接但未获得IP地址。

实战配置示例:

假设我们要创建一个过滤器,仅在设备作为STA且成功获取IP地址后才生效,用于监听特定的MQTT服务器(例如,目的端口1883)流量。

SlWlanRxFilterTrigger_t trigger; /* 1. 设置父过滤器ID,假设我们这是一个根过滤器 */ trigger.ParentFilterID = 0; /* 2. 不使用计数器触发器 */ trigger.Counter = SL_WLAN_RX_FILTER_NO_TRIGGER_COUNTER; /* 注意:Counter val和Compare function在不使用计数器时可忽略或设默认值 */ /* 3. 配置角色和连接状态触发器 */ trigger.Role = SL_WLAN_RX_FILTER_ROLE_STA; // 仅当设备是STA时生效 trigger.ConnectionState = SL_WLAN_RX_FILTER_STATE_STA_HAS_IP; // 仅当STA已获得IP时生效 /* 接下来可以定义匹配规则(Rule)和动作(Action)... */

另一个例子:创建一个在混杂模式(嗅探模式)下始终生效的过滤器,用于捕获所有802.11管理帧。

trigger.ParentFilterID = 0; trigger.Counter = SL_WLAN_RX_FILTER_NO_TRIGGER_COUNTER; trigger.Role = SL_WLAN_RX_FILTER_ROLE_PROMISCUOUS; // 关键:角色设为混杂模式 /* 在混杂模式下,ConnectionState参数通常被忽略,但按API要求仍需提供一个值 */ trigger.ConnectionState = SL_WLAN_RX_FILTER_STATE_STA_CONNECTED; // 此值在混杂模式下无实际作用

避坑指南ConnectionState的选项是位掩码(bitmask),理论上可以通过“或”操作组合多个状态。例如,STA_CONNECTED | STA_HAS_IP。但在实际使用中,尤其是与STA_HAS_IP组合时,需要仔细理解其逻辑。STA_HAS_IP本身隐含了已连接的状态。最稳妥的做法是,根据你的业务逻辑精确选择单一状态,避免产生歧义。例如,如果你只想在“已连接但IP未就绪”时过滤ARP包,就明确使用STA_HAS_NO_IP

3.2 计数器触发器(Counter Trigger)——高级用法

计数器触发器提供了一种基于“事件发生次数”的动态触发机制。你可以定义一个计数器(共8个,RX_FILTER_COUNTER1-8),并设置一个比较函数(如大于、等于、小于)和阈值。当与该计数器关联的规则匹配次数满足比较条件时,触发器才为真。

计数器与规则组的绑定关系

  • RX_FILTER_COUNTER1RX_FILTER_COUNTER4:只能与组C和组D的规则(IP层及以上)关联使用。
  • RX_FILTER_COUNTER5RX_FILTER_COUNTER8:只能与组A和组B的规则(MAC层和网络层)关联使用。

应用场景:例如,你可以创建一个规则,用于丢弃来自某个异常IP的前10个数据包(使用计数器),但在第11个包到来时,不再丢弃,而是触发一个事件通知主机,提示“检测到疑似攻击源,已拦截10次”。这实现了简单的基于次数的速率限制或异常检测。

SlWlanRxFilterTrigger_t trigger; trigger.ParentFilterID = 0; trigger.Role = SL_WLAN_RX_FILTER_ROLE_STA; trigger.ConnectionState = SL_WLAN_RX_FILTER_STATE_STA_CONNECTED; /* 启用计数器触发器 */ trigger.Counter = RX_FILTER_COUNTER1; // 使用计数器1 trigger.CounterVal = 10; // 阈值设为10 trigger.CompareFunc = SL_WLAN_RX_FILTER_CMP_GREATER_OR_EQUAL; // 比较函数:大于或等于 /* 当与此触发器关联的规则匹配次数 >= 10 时,此触发器才返回TRUE */

实操心得:计数器触发器功能强大,但相对复杂,会占用额外的芯片资源。在常见的流量过滤场景中,基于连接状态的触发器已足够。除非你有明确的“第N次匹配时执行特殊动作”的需求,否则建议优先使用简单的状态触发器。

3.3 混杂模式下的过滤注意事项

当设备角色设置为PROMISCUOUS时,设备处于射频收发器(Transceiver)模式。在此模式下:

  1. 数据接收:必须调用sl_Recv()函数来触发设备开始接收帧。在此之前,过滤器不会处理任何数据包。
  2. 过滤层级限制:在混杂模式下,TCP和UDP帧是承载在分片的IPv4或IPv6数据报中的。因此,无法在L4(传输层)基于端口(Port)或载荷(Payload)进行过滤。也就是说,组D的规则在混杂模式下是无效或受限的。你的过滤重点应放在MAC帧头(组A)和IP版本/地址(组B、C)上。

4. 过滤器动作(Action)详解与事件机制

当触发条件满足且规则匹配成功时,过滤器将执行一个或多个动作。动作是过滤规则的最终产出。

4.1 基本动作类型

  1. SL_WLAN_RX_FILTER_ACTION_NULL:无动作。数据包通常会继续传递给主机(除非被其他规则丢弃)。这常用于“仅记录”或作为更复杂规则树的中间节点。
  2. SL_WLAN_RX_FILTER_ACTION_DROP:丢弃数据包。这是实现流量控制、安全屏蔽和节省功耗的最直接方式。再次强调,带DROP动作的过滤器不能作为父过滤器。
  3. SL_WLAN_RX_FILTER_ACTION_EVENT_TO_HOST:向主机发送一个事件。这是实现无线唤醒(Wake on WLAN)等高级功能的关键。数据包本身可能被丢弃也可能被传递(取决于是否有其他动作),但主机会收到一个异步事件通知。

4.2 事件动作与主机事件聚合

事件动作允许过滤器在匹配时“悄悄”通知主机,而不一定需要传递数据包本身。每个事件动作都有一个UserId参数,范围是0-63,它定义了在触发的事件中设置哪个位(bit)。

关键在于主机事件的聚合机制:为了减少事件数量,SimpleLink会对单个数据包触发的事件进行聚合。

  • 同一规则组内聚合:如果多个匹配的过滤器属于同一个规则组(A/B/C/D),且都设置了事件动作,那么它们触发的事件会被合并成一个主机事件,该事件的位图中会同时设置这些过滤器对应的UserId位。
    • 示例:规则1(源IP匹配)和规则2(目的IP匹配)都属于组C,且分别设置UserId为2和3。当一个数据包同时匹配这两条规则时,主机只会收到一个事件,其事件位图的第2位和第3位被置1。
  • 不同规则组分别发送:如果匹配的过滤器来自不同的规则组,则会产生多个独立的主机事件。
    • 示例:规则1(源MAC地址,组A)设置UserId为1,规则2(目的端口,组D)设置UserId为4。一个数据包同时匹配两者,主机会收到两个独立的事件,一个指示位1被置位,另一个指示位4被置位。

4.3 事件处理代码实战

下面是一个完整的添加带事件动作的过滤器,并在主机侧处理事件的示例:

// 添加过滤器的函数片段 void AddFilterWithEvent(SlWlanRxFilterID_t parentFilterId) { SlWlanRxFilterID_t newFilterId; SlWlanRxFilterRuleType_t ruleType; SlWlanRxFilterTrigger_t trigger; SlWlanRxFilterAction_t action; SlWlanRxFilterRuleHeader_t rule; _i16 retVal; // 1. 设置规则类型和具体规则(例如,匹配目的端口1883) ruleType = SL_WLAN_RX_FILTER_RULE_DST_PORT; rule.Port = 1883; // MQTT默认端口 // 2. 配置触发器(例如,仅在STA有IP时生效) trigger.ParentFilterID = parentFilterId; trigger.Counter = SL_WLAN_RX_FILTER_NO_TRIGGER_COUNTER; trigger.Role = SL_WLAN_RX_FILTER_ROLE_STA; trigger.ConnectionState = SL_WLAN_RX_FILTER_STATE_STA_HAS_IP; // 3. 配置动作 - 发送事件到主机,并指定事件ID(例如,使用位2) action.Type = SL_WLAN_RX_FILTER_ACTION_EVENT_TO_HOST; action.UserId = 2; // 当此过滤器匹配时,主机事件位图的第2位将被置1 // 4. 添加过滤器 retVal = sl_WlanRxFilterAdd( ruleType, 0, // FilterFlags,通常为0或按需设置 (const SlWlanRxFilterRule_u* const)&rule, (const SlWlanRxFilterTrigger_t* const)&trigger, (const SlWlanRxFilterAction_t* const)&action, &newFilterId // 返回新创建的过滤器ID ); if (retVal < 0) { // 处理错误 printf("Failed to add Rx Filter, error: %d\n", retVal); } else { printf("Rx Filter added successfully, ID: %u\n", newFilterId); } } // 在主事件处理循环中处理WLAN事件 void SimpleLinkWlanEventHandler(SlWlanEvent_t *pSlWlanEvent) { switch(pSlWlanEvent->Id) { case SL_WLAN_EVENT_CONNECT: // 处理连接事件... break; case SL_WLAN_EVENT_DISCONNECT: // 处理断开事件... break; case SL_WLAN_EVENT_RXFILTER: // <-- 接收过滤器事件! { SlWlanEventRxFilterInfo_t *pEventData = (SlWlanEventRxFilterInfo_t *)&pSlWlanEvent->Data; // 遍历64个可能的事件位,检查哪些被触发了 for(int i = 0; i < 64; i++) { if(SL_WLAN_ISBITSET8(pEventData->UserActionIdBitmap, i)) { // 根据i的值,执行相应的处理逻辑 switch(i) { case 2: printf("[RxFilter Event] Filter with UserId 2 triggered! (MQTT port detected)\n"); // 例如,可以在这里唤醒主处理器,或者设置一个标志位 break; // 可以处理其他UserId... default: printf("[RxFilter Event] Unknown filter event with UserId: %d\n", i); break; } } } } break; default: break; } }

注意事项:事件处理是异步的。确保你的SimpleLinkWlanEventHandler被正确挂接到SimpleLink的非阻塞任务或中断上下文中。处理事件时应尽量快速,避免长时间阻塞,以免影响其他网络事件的处理。

5. 过滤器的全生命周期管理

创建过滤器只是第一步,如何启用、禁用、批量操作、持久化存储乃至动态更新,是工程实践中更重要的环节。SimpleLink提供了一套基于sl_WlanSetsl_WlanGetAPI的完整管理方案。

5.1 核心管理操作概览

所有过滤器管理操作都通过向sl_WlanSetsl_WlanGet传递特定的ConfigId(SL_WLAN_RX_FILTERS_ID) 和ConfigOpt来实现。操作的目标过滤器通过一个128位的位域(Bit Field)来指定,每位对应一个过滤器ID(0-127)。

设置位域的宏

SL_WLAN_SETBIT8(BitField.FilterIdMask, FilterId); // 将指定位置1 SL_WLAN_CLEARBIT8(BitField.FilterIdMask, FilterId); // 将指定位清0

5.2 启用与禁用过滤器

强烈建议在创建过滤器时将其置于禁用状态,待所有相关过滤器都配置完成后,再一次性批量启用。这可以避免在配置过程中出现不可预知的过滤行为。

启用/禁用API

  • ConfigOpt:SL_WLAN_RX_FILTER_STATE
  • 位域含义:位域中为1的位对应的过滤器将被启用,为0的位对应的过滤器将被禁用。不存在的过滤器ID会被忽略。
SlWlanRxFilterOperationCommandBuff_t filterOpBuff; _u16 retVal; // 1. 首先,获取当前所有过滤器的启用状态(可选,用于修改) _u16 opt = SL_WLAN_RX_FILTER_STATE; _u16 size = sizeof(SlWlanRxFilterRetrieveStateBuff_t); SlWlanRxFilterRetrieveStateBuff_t currentState; retVal = sl_WlanGet(SL_WLAN_RX_FILTERS_ID, &opt, &size, (_u8*)&currentState); if(retVal == 0) { // currentState.FilterIdMask 包含了当前启用状态的位图 } // 2. 准备要设置的位图:假设我们要启用ID为1和35的过滤器,禁用其他。 memset(&filterOpBuff, 0, sizeof(filterOpBuff)); SL_WLAN_SETBIT8(filterOpBuff.FilterIdMask, 1); SL_WLAN_SETBIT8(filterOpBuff.FilterIdMask, 35); // 注意:未设置的位默认为0,意味着禁用。如果你想保持其他过滤器状态不变,需要先获取当前状态再修改。 // 3. 执行设置 retVal = sl_WlanSet(SL_WLAN_RX_FILTERS_ID, SL_WLAN_RX_FILTER_STATE, sizeof(SlWlanRxFilterOperationCommandBuff_t), (unsigned char*)&filterOpBuff); if (retVal != 0) { // 处理错误 }

5.3 获取过滤器状态

用于查询哪些过滤器当前处于启用状态。

_u16 size = sizeof(SlWlanRxFilterRetrieveStateBuff_t); _u16 opt = SL_WLAN_RX_FILTER_STATE; SlWlanRxFilterRetrieveStateBuff_t stateBuff; retVal = sl_WlanGet(SL_WLAN_RX_FILTERS_ID, &opt, (_u16*)&size, (_u8*)&stateBuff); // 成功返回后,stateBuff.FilterIdMask 的位图指示了已启用过滤器的ID。

5.4 删除过滤器

将过滤器从活动列表中移除。如果过滤器被标记为“持久化”(persistent),仅删除操作还不够,必须配合STORE操作(见下文)才能将其从闪存中彻底清除。

删除API

  • ConfigOpt:SL_WLAN_RX_FILTER_REMOVE
  • 位域含义:位域中为1的位对应的过滤器将被删除。
SlWlanRxFilterOperationCommandBuff_t removeBuff; memset(&removeBuff, 0, sizeof(removeBuff)); SL_WLAN_SETBIT8(removeBuff.FilterIdMask, 10); // 删除ID为10的过滤器 retVal = sl_WlanSet(SL_WLAN_RX_FILTERS_ID, SL_WLAN_RX_FILTER_REMOVE, sizeof(SlWlanRxFilterOperationCommandBuff_t), (unsigned char*)&removeBuff);

5.5 持久化存储过滤器

默认情况下,过滤器仅存在于设备RAM中,断电即丢失。通过STORE操作,可以将当前活动的、标记为持久的过滤器保存到外部串行闪存(SFLASH)中。设备下次启动时,会自动加载这些过滤器。

存储API

  • ConfigOpt:SL_WLAN_RX_FILTER_STORE
  • 注意:此操作没有位域参数,它会存储所有当前已配置的过滤器。通常在执行一系列ADDSET操作后调用一次。
// 保存所有当前过滤器到闪存 retVal = sl_WlanSet(SL_WLAN_RX_FILTERS_ID, SL_WLAN_RX_FILTER_STORE, 0, NULL); if (retVal != 0) { printf("Failed to store filters to flash: %d\n", retVal); }

关键建议:TI官方强烈建议在所有Socket都关闭的情况下进行过滤器的更新、删除和存储操作。这是因为活跃的Socket可能会持有对过滤器的引用,在操作过程中更改过滤器可能导致不可预测的行为或数据包丢失。

5.6 动态更新过滤器参数

有时你可能需要在不删除重建过滤器的情况下,修改其规则参数(如更新要匹配的IP地址或端口)。这可以通过UPDATE_ARGS操作实现。

更新API

  • ConfigOpt:SL_WLAN_RX_FILTER_UPDATE_ARGS
  • 需要传递一个包含目标过滤器ID和新参数的结构体。
SlWlanRxFilterUpdateArgsCommandBuff_t updateBuff; unsigned char newBssid[6] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF}; // 新的BSSID unsigned char mask[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; // 全匹配掩码 updateBuff.FilterId = targetFilterId; // 要更新的过滤器ID updateBuff.BinaryOrAscii = 1; // 1表示参数是二进制值 memcpy(updateBuff.Args.Value.Bssid[0], newBssid, 6); // 设置新的BSSID值 memcpy(updateBuff.Args.Mask, mask, 6); // 设置掩码 retVal = sl_WlanSet(SL_WLAN_RX_FILTERS_ID, SL_WLAN_RX_FILTER_UPDATE_ARGS, sizeof(SlWlanRxFilterUpdateArgsCommandBuff_t), (unsigned char*)&updateBuff);

6. 实战:构建一个完整的低功耗数据采集终端方案

让我们结合以上所有知识,设计一个典型的物联网边缘设备场景:一个电池供电的传感器节点,通过Wi-Fi定期向云服务器上报数据。为了最大化电池寿命,我们需要:

  1. 深度睡眠:大部分时间处于低功耗休眠状态。
  2. 无线唤醒:仅当收到来自特定服务器的“数据请求”指令包时,才唤醒主处理器并上传数据。
  3. 流量净化:忽略所有其他网络噪音,包括广播、组播和无关的单播数据。

实现步骤:

步骤1:设备启动与初始化设备上电,初始化SimpleLink驱动,连接到指定的AP并获取IP地址。

步骤2:创建并配置唤醒过滤器在进入深度睡眠前,我们需要配置一个高优先级的Rx Filter。

  • 触发器Role = STA,ConnectionState = STA_HAS_IP。确保只在联网状态下监听。
  • 匹配规则
    • 规则A(根过滤器):匹配目标MAC地址为本设备MAC。ParentFilterId = 0,Rule = DST_MAC_ADDRESS。这是第一道关卡,过滤掉所有不是发给本机的数据包。
    • 规则B(子过滤器):匹配目标IP地址为云服务器IP。ParentFilterId = A的ID,Rule = DST_IP_ADDRESS。只有发给本机且目的地是服务器的包才进一步检查。
    • 规则C(子过滤器):匹配目标端口为我们的自定义控制端口(例如9999)。ParentFilterId = B的ID,Rule = DST_PORT = 9999。这是最具体的业务规则。
  • 动作:在规则C上设置动作ACTION_EVENT_TO_HOST,并分配一个唯一的UserId(例如0)。
  • 启用过滤器:将这三个过滤器一次性启用。

步骤3:进入深度睡眠并等待唤醒主机MCU调用进入深度睡眠的函数。此时,Wi-Fi网络处理器(NWP)仍然保持供电和基本运行,并持续运行我们刚才配置的Rx Filter。

步骤4:被无线唤醒当云服务器向该设备的IP:9999发送一个特定的UDP或TCP数据包时,数据包流经网络:

  1. 匹配规则A(目标MAC):通过。
  2. 匹配规则B(目标IP):通过。
  3. 匹配规则C(目标端口):通过。
  4. 触发动作:由于规则C匹配成功,且动作为EVENT_TO_HOST,NWP会生成一个主机事件,事件位图的第0位被置1。这个事件足以将主机MCU从深度睡眠中唤醒。

步骤5:主机处理事件并响应主机MCU被唤醒后,SimpleLink的事件处理机制会递送SL_WLAN_EVENT_RXFILTER事件。在事件处理函数中,我们检查到位0被置位,就知道是“数据请求”指令到了。

  • 主机可以立即读取这个数据包(如果动作也包含传递包的话),或者根据事件直接执行预设操作(如读取传感器数据)。
  • 主机通过Wi-Fi将传感器数据发送回服务器。
  • 数据发送完毕后,主机可以重新配置过滤器(如果需要),然后再次进入深度睡眠,等待下一次唤醒。

步骤6:过滤器管理优化

  • 持久化:在初次配置好这套完美的唤醒过滤器后,执行一次SL_WLAN_RX_FILTER_STORE操作,将其保存到闪存。这样,设备即使完全断电重启,也无需主机MCU干预,NWP在初始化后会自动加载这些过滤器,立即具备唤醒能力。
  • 动态更新:如果服务器的IP地址变更,主机在唤醒后,可以使用SL_WLAN_RX_FILTER_UPDATE_ARGS动态更新规则B中的IP地址,然后再次存储,使新配置持久化。

通过这样一套组合拳,设备99%的时间都在深度睡眠,功耗极低,只有在收到精确指令时才全功率工作片刻,实现了电池寿命的极大延长。这正是SimpleLink Rx Filter在物联网设备设计中价值的完美体现。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询