您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 招聘面试 > BasicRF 简析
BasicRF简析(四:appSwitch()简析)appSwitch()在SI中的函数关系如图1所示,其中basicRfInit()和basicRfSendPacket()两个函数比较有内容的,本文主要针对这两个函数进行展开。图1开始之前先介绍三个比较重要的结构体:basicRfRxInfo_t、basicRfTxState_t和basicRfPktHdr_t//接收帧信息typedefstruct{uint8seqNumber;//帧序号;uint16srcAddr;//源地址;uint16srcPanId;//源节点的PANID;int8length;//帧长度;uint8*pPayload;//该指针指向帧数据即:净载荷数据;uint8ackRequest;//帧控制域的应答位信息;int8rssi;//接收信号强度指示;volatileuint8isReady;//通过CRC校验,数据接收完成,该标志位进行后续读取操作;uint8status;//待定????}basicRfRxInfo_t;//发送状态信息typedefstruct{uint8txSeqNumber;//帧序号;volatileuint8ackReceived;//ACK是否接收完成;uint8receiveOn;//是否处于接收状态;uint32frameCounter;//发送帧计数;}basicRfTxState_t;//BasicRf帧头(IEEE802.15.4)typedefstruct{uint8packetLength;//帧长度;uint8fcf0;//FramecontrolfieldLSBuint8fcf1;//FramecontrolfieldMSBuint8seqNumber;//帧序号;uint16panId;//PANID;uint16destAddr;//目的地址;uint16srcAddr;//源地址;#ifdefSECURITY_CCM//安全选项;uint8securityControl;uint8frameCounter[4];#endif}basicRfPktHdr_t;(一)关于basicRfInit()/************************************************************************************@fnbasicRfInit**@briefInitialisebasicRFdatastructures.Setschannel,shortaddressand*PANidinthechipandconfiguresinterruptonpacketreception*初始化BasicRF数据结构,如:通道选择、短地址、PANID及接收中断的配置;*@parampRfConfig-pointertoBASIC_RF_CONFIGstruct.*Thisstructmustbeallocatedbyhigherlayer*txState-filescopevariablethatkeepstxstateinfo//发送状态信息;*rxi-filescopevariableinfoextractedfromthelastincoming*frame//最新的所接收帧信息;**@returnnone*/uint8basicRfInit(basicRfCfg_t*pRfConfig){if(halRfInit()==FAILED)//Rf初始化,启用Rf的推荐简单配置,可选的PA模块配置,始终返回Success;returnFAILED;halIntOff();//关闭总中断;//SettheprotocolconfigurationpConfig=pRfConfig;//指向相关配置信息;rxi.pPayload=NULL;//清空本节点的接收载荷数据;txState.receiveOn=TRUE;//halRfInit()中开启接收;txState.frameCounter=0;//发送帧计数值;txState.txSeqNumber=0x88;//自行修改第一个发送帧序号初始值;//SetchannelhalRfSetChannel(pConfig-channel);//将定义的通道号写入相关寄存器;//WritetheshortaddressandthePANIDtotheCC2520RAMhalRfSetShortAddr(pConfig-myAddr);//将定义的本节点地址写入相关寄存器;//#defineSHORT_ADDR0XREG(0x6174)//#defineSHORT_ADDR1XREG(0x6175)halRfSetPanId(pConfig-panId);//将定义的PANID写入相关寄存器;//#definePAN_ID0XREG(0x6172)//#definePAN_ID1XREG(0x6173)//ifsecurityisenabled,writekeyandnonce#ifdefSECURITY_CCMbasicRfSecurityInit(pConfig);#endif//Setupreceiveinterrupt(receiveddataoracknowlegment)halRfRxInterruptConfig(basicRfRxFrmDoneIsr);//对函数指针进行赋值,关联相应的中断函数,即:声明中断程序;halIntOn();//开启总中断;//为什么要开闭总中断一次????先启用发送节点后启用接收节点时,意外的接收中断?returnSUCCESS;}basicRfInit()如上代码所示,该函数仅对RF做简单初始化、通道选择、PANID、本节点地址进行配置,最后为RF接收中断声明一个函数指针basicRfRxFrmDoneIsr;/************************************************************************************@fnhalRfRxInterruptConfig**@briefConfigureRXinterrupt.*//配置接收中断,将RX中断指向一段可执行程序;*@paramnone**@returnnone*/voidhalRfRxInterruptConfig(ISR_FUNC_PTRpf){uint8x;HAL_INT_LOCK(x);//保存EA并将其清零;pfISR=pf;//将函数指针赋值,而pfISR将在RX中断时被执行;HAL_INT_UNLOCK(x);//恢复之前EA的值;}/*************************************************************************************@fnrfIsr**@briefInterruptserviceroutinethathandlesRFPKTDONEinterrupt.*//RX中断服务程序;*@paramnone**@returnnone*/HAL_ISR_FUNCTION(rfIsr,RF_VECTOR){uint8x;HAL_INT_LOCK(x);if(RFIRQF0&IRQ_RXPKTDONE){if(pfISR){(*pfISR)();//ExecutethecustomISR//如果pfISR不为空则将调用函数指针所指向的函数basicRfRxFrmDoneIsr();}S1CON=0;//CleargeneralRFinterruptflagRFIRQF0&=~IRQ_RXPKTDONE;//ClearRXPKTDONEinterrupt}HAL_INT_UNLOCK(x);}RF中断采用了宏声明的方式(协议栈中多采用宏来声明中断,而非常规C语言函数),其声明语句如下:#defineHAL_ISR_FUNC_DECLARATION(f,v)_PRAGMA(vector=v)__near_func__interruptvoidf(void)//中断函数声明的宏;#defineHAL_ISR_FUNC_PROTOTYPE(f,v)_PRAGMA(vector=v)__near_func__interruptvoidf(void)//中断函数原型的宏;#defineHAL_ISR_FUNCTION(f,v)HAL_ISR_FUNC_PROTOTYPE(f,v);HAL_ISR_FUNC_DECLARATION(f,v)//中断函数定义宏,包括//原型和声明;其中rfIsr对应于宏中的f(void),类似于指向其自身HAL_ISR_FUNCTION()。(二)关于basicRfSendPacket()/************************************************************************************@fnbasicRfSendPacket**@briefSendpacket**@paramdestAddr-destinationshortaddress//目的地址;*pPayload-pointertopayloadbuffer.Thisbuffermustbe*allocatedbyhigherlayer.//需要MAC层以上产生要发送的数据(指针或数组);*length-lengthofpayload//要发送数据的长度;*txState-filescopevariablethatkeepstxstateinfo//发送状态信息;*mpdu-filescopevariable.Bufferfortheframetosend//对数据进行封包为物理层协议数据单元;**@returnbasicRFStatus_t-SUCCESSorFAILED*/uint8basicRfSendPacket(uint16destAddr,uint8*pPayload,uint8length){uint8mpduLength;uint8status;//Turnonreceiverifitsnoton//保证设备处于接收状态,其初始值在halRfInit()中开启接收并在basicRfInit()中被赋值为TRUE;if(!txState.receiveOn){halRfReceiveOn();}//Checkpacketlength//取最小的有效数据长度,类似与可变长度域,可变长度值是很有用的例如:串口透传的数据长度;//最大数据载荷为//#defineBASIC_RF_MAX_PAYLOAD_SIZE(127-BASIC_RF_PACKET_OVERHEAD_SIZE-BASIC_RF_AUX_HDR_LENGTH-BASIC_RF_LEN_MIC)//后面两项为安全选项的附加信息,可根据需要自行调整;length=min(length,BASIC_RF_MAX_PAYLOAD_SIZE);//Waituntilthetransceiverisidle//根据SFD和TX_Active状态位来判定设备是否处于空闲状态;//SFD状态位为0说明设备目前无发送无接收;halRfWaitTransceiverReady();//TurnoffRXframedoneinterrupttoavoidinterferenceontheSPIinterface//防止2591冲突???halRfDisableRxInterrupt();mpduLength=basicRfBuildMpdu(destAddr,pPayload,length);//根据目的地址、载荷数据及长度信息进行封包;#ifdefSECURITY_CCMhalRfWriteTxBufSecure(txMpdu,mpduLen
本文标题:BasicRF 简析
链接地址:https://www.777doc.com/doc-3820873 .html