ESB是
ESB 支持双向数据包通信的基本协议包括数据包缓冲,数据包确认和丢失数据包的自动重传。
ESB特性:
- 支持星型网络拓扑结构,典型的是一路主接收,多达八路的发送。
- 传统模式下支持1到32字节的动态payload(数据传输宽度)
- NRF5系列之间支持1-252字节的静态的payload(数据传输宽度)
- 每个PTX和PRX节点都支持双工数据发送接收
- 数据包确认和自动数据包重传功能
- 每个管道都有独立的发送和接收FIFO
- 后向兼容NRF2401的增强型ESB。
资源:
ESB使用一组固定的资源,并要求对它们进行独占访问以确保正确操作。
- 射频(NRF_RADIO)
- 定时器:NRF_TIMER2,NRF_TIMER3:
- PPI(可编程外围互联)通道7,8,9,10,11,12,13
- 软件中断0
注意:没有MPU强制执行此独占访问,因此操纵这些资源会产生未定义的行为。(即最好避免操作这些资源)
另外:射频和定时器中断处理运行在0优先级(即最高优先级),ESB回调功能函数运行在1优先级。因此在应用程序中使用的其他中断应当运行在2-7优先级以确保正确操作。
向后兼容特性
即ESB支持NRF2401的一些说明,在此不赘述。
包事务
ESB数据包事务由PTX的数据包传输启动,并在PTX收到PRX的确认数据包(ACK数据包)时即为成功。
为了启用双向数据链路,PRX可以将数据有效载荷附加到ACK分组(即在回复PTX端ACK时可以夹带“其他信息”)。具体操作是PRX将一个数据包添加到其自身的TX FIFO,该FIFO将作为下一个ACK数据包中的有效负载发送(PTX和PRX双方都既有TX FIFO又有RX FIFO)
示意图:
如果PTX没有收到ACK包,将会尝试再次发送数据包直到收到ACK,允许的重新传输尝试的最大次数和每次尝试之间的延迟由最近一次调用nrf_esb_init指定(其中nrf_esb_config_t结构中nrf_esb_config_t :: retransmit_count和nrf_esb_config_t :: retransmit_delay的值分别指定重发尝试次数和它们之间的延迟)或者函数 nrf_esb_set_retransmit_count and nrf_esb_set_retransmit_delay。重传延迟定义为两次传输尝试开始之间的持续时间,注意这个间隔不同于NRF2401,2401中的重传间隔的延迟定义为从分组传输结束到重传开始的持续时间。
如果从PRX发送到PTX的ACK数据包丢失,但是PRX成功接收到初始数据包和后续重传尝试,重复的数据包将被PRX丢弃,这可以防止PRX应用程序接收重复的数据包。 但是,重复的数据包将始终由PRX回复ACK,即使它们被丢弃。
示意图:
PTX可以选择发送到PRX的个别包不需要从PRX返回ACK,当使用传递给nrf_esb_write_payload函数的p_payload参数为nrf_esb_payload_t :: noack字段将数据包上传到TX FIFO时,应用程序会做出此决定。
当PRX接收到不需要ACK的分组时,它不向PTX发送ACK分组,因此PTX将继续重传该分组,直到达到允许的最大重传次数。
配置ESB应用程序:
1、初始化ESB:nrf_esb_init.
2、如果必要的话,使用以下函数更新地址,前缀地址,信道,和比特率;
- nrf_esb_set_base_address_0
- nrf_esb_set_base_address_1
- nrf_esb_set_prefixes
- nrf_esb_set_rf_channel
- nrf_esb_set_bitrate
3、确保高频时钟正在运行:
4、开始发送或接收包:
(1)如果节点是PTX:
a.通过调用 nrf_esb_write_payload.将发送包添加到TX FIFO;
b.根据最近调用nrf_esb_init时使用的nrf_esb_config_t :: tx_mode的值,您可能必须调用nrf_esb_start_tx来启动传输
c.频率收到确认或超时后,处理NRF_ESB_EVENT_TX_SUCCESS,NRF_ESB_EVENT_TX_FAILED和NRF_ESB_EVENT_RX_RECEIVED事件。
(2)如果节点是PRX:
a.当数据包进入时处理NRF_ESB_EVENT_RX_RECEIVED事件。多个数据包可能在每个事件之间到达RX FIFO。
b.要将有效负载附加到确认数据包,请使用nrf_esb_write_payload将它们添加到TX FIFO。 在收到数据包之前,
必须对有效负载进行排队。 在通过确认发送排队的有效负载之后,假设它到达另一个设备。 因此, NRF_ESB_EVENT_TX_SUCCESS事件排队
注意:要停止ESB模式,可调用nrf_esb_disable,但要注意,当数据传输还在进行时,这种停止不会生效,因此在停止ESB模式之前必须检查设备是否处于空闲状态。
频率选择(切换):
ESB可以使用nRF5芯片可以使用的任何通道发送或接收数据包。 通过调用nrf_esb_set_rf_channel函数选择通道。 PTX和PRX必须使用相同的频率来交换数据。
管道和地址:
节点上的每个逻辑地址称为管道。每个管道映射一个空中地址以发送或接收数据。
空中地址由前缀一个字节的地址和2-4个字节的长的基地址组成(???)nRF5无线电使用0和1的交替序列作为分组的前导码。因此,对于要正确接收的数据包,基地址的最高有效字节不能是0和1的交替序列,也就是说,它不能是0x55或0xAA。
管道0具有其自己唯一的基址(基址0),而管道1-7使用相同的基址(基址1)。 8个管道中的每一个都具有唯一的字节长前缀地址。
在广播中,首先发送每个地址字节的最高有效位。 2-4字节长基址的最高有效字节是第一个发送的地址字节,而前缀字节是最后发送的。
地址不能包含0x00前缀和格式为0x00XXXXXX(长度4)/ 0x0000XXXX(长度5)的地址。 这样的零地址将导致返回错误代码NRF_ERROR_INVALID_PARAM。
注意:ESB中的字节排序和nRF5无线电外设不一样,因为地址字节在ESB中重新排列以匹配nRF24L无线电
示意图:
包识别:
从PTX发送到PRX的任何包由包头中的两比特分组ID字段(PID)以及分组的循环冗余校验(CRC)字段唯一地标识。该ID用于甄别与前一个包是否为不同的包
在接收端PRX,重发包会被丢弃且不会加入到RX FIFO中,因此NRF_ESB_EVENT_RX_RECEIVED事件不会被调用。
除了PID之外还使用CRC来识别唯一的分组。这降低了分组被错误地识别为重传尝试的可能性,并且当发生几个连续的失败分组传输尝试时由PRX丢弃。
FIFOs
在每个节点都有一个发送FIFO和接收FIFO,FIFO是被所有的管道所共享的,而nrf_esb_payload_t::pipe指定了每个包的管道,接收包时,此字段指定数据包来自哪个管道,在发送段,它指定了包所要被发送的管道;
当多个数据包排队时,它们以FIFO方式处理,忽略管道
PTX FIFO处理
在PTX模式下启用ESB时,上传到TX FIFO的任何数据包将在下次机会传输
当PTX从PRX成功接收到ACK时,PTX假定有效载荷已成功接收并添加到PRX的RX FIFO。 成功传输的数据包将从TX FIFO中删除,以便可以传输FIFO中的下一个数据包。
如果PTX接收的ACK包含有效载荷,则该有效载荷将被添加到PTX的RX FIFO。
PRX FIFO处理
当在PTX模式中使能ESB中时,PTX将会监视所有已启用的管道(地址)的传入数据包
如果接收到之前未添加到PRX的RX FIFO的新数据包,并且RX FIFO具有该数据包的可用空间,则将数据包添加到RX FIFO并发送ACK返回给PTX,如果PRX的TX FIFO包含任何数据包,则TX FIFO中的下一个可维护数据包作为有效负载附加在ACK数据包中。 请注意,在收到数据包之前,必须已将此TX数据包上载到TX FIFO。
Event处理
当频率上有一个事件时,ESB模块会分析其原因,且如果有必要的话,会将该事件排入应用程序,这个事件指示的可能时成功或者失败的操作或者在RX FIFO中有新的数据可以获得。
事件是作为一个flag排队的,且在第一次触发软件中断时被读出。因此,在发送给应用程序的每个事件可能包含多个频率的中断。例如NRF_ESB_EVENT_TX_SUCCESS 和NRF_ESB_EVENT_TX_FAILED事件可能分别指示着多个成功或者失败,NRF_ESB_EVENT_RX_RECEIVED事件表示RX FIFO中至少有一个新数据包;事件处理程序应确保在适当情况下完全清空RX FIFO