-
BasicRF
简析(四:
appSwitc
h()
简析)
appSwitch(
)
在
SI
中的函数关系如图
1
所示,其中
basicRfInit()
和
basicRfSendPacket()
两个函数比较有内容的,本文主要针对这两个函数进行展
开。
图
1
开始之前先介绍三个比较重要的结构体:
basicRfRxInfo_t
、
basicRfTxS
tate_t
和
basicRfPktHdr_t
//
接收帧信息
typedef struct {
uint8 seqNumber;
//
帧序号;
uint16 srcAddr;
//
源地址;
uint16 srcPanId; <
/p>
//
源节点的
PANID
;
int8
length;
//
帧长度;
uint8* pPayload; <
/p>
//
该指针指向帧数据即:净载荷数据;
uint8 ackRequest;
//
帧控制域的应答位信息;
int8 rssi;
//
接收信号强度指示;
volatile uint8 isReady;
//
通过
CRC
校验,
数据接收完成,
该标志位进行后续
读取操作;
uint8
status;
//
待定????
} basicRfRxInfo_t;
//
发送状态信息
typedef struct {
uint8 txSeqNumber;
//
帧序号;
volatile uint8
ackReceived;
//ACK
是否接收完成;
uint8 receiveOn;
//
是否处于接收状态;
uint32 frameCounter;
//
发送帧计数;
} basicRfTxState_t;
//BasicRf
帧头
(IEEE
802.15.4)
typedef struct {
uint8
packetLength;
//
帧长度;
uint8
fcf0;
// Frame control field LSB
uint8
fcf1;
// Frame control field MSB
uint8
seqNumber;
//
帧序号;
uint16
panId;
//PANID
;
uint16
destAddr;
//
目的地址;
uint16
srcAddr;
//
源地址;
#ifdef SECURITY_CCM
//
安全选项;
uint8
securityControl;
uint8
frameCounter[4];
#endif
}
basicRfPktHdr_t;
(
一
)
关于
basicRfInit()
/
**************************************************
*********************************
* @fn
basicRfInit
*
*
@brief
Initialise basic RF
datastructures. Sets channel, short address
and
*
PAN id in the chip and configures
interrupt on packet reception
*
初始化
BasicRF
数据结构
,
如:通道选择、短地址、
PANID
及接收中
断的配置;
* @param
pRfConfig -
pointer to BASIC_RF_CONFIG struct.
*
This struct must be allocated by higher
layer
*
txState
- file scope variable that keeps tx state info
//
发送状态信
息;
< br>
*
rxi -
file scope variable info extracted from the last
incoming
*
frame
//
最新的所接
收帧信息;
*
* @return
none
*/
uint8
basicRfInit(basicRfCfg_t* pRfConfig)
{
if (halRfInit()==FAILED)
//Rf
初始化,
启用
Rf
的推荐简单配置,
可选的
PA
模块配置,始终返回
Success
;
return
FAILED;
halIntOff();
//
关闭总中断;
// Set the protocol configuration
pConfig = pRfConfig;
//
指向相关配置信息;
ad
= NULL;
//
清空本节点的接收载荷数据;
eOn = TRUE;
//halRfInit()
中开启接收;
ounter = 0;
//
发送帧计数值;
umber = 0x88;
//
自行修改第一个发送帧序号初始值;
// Set channel
halRfSetChannel(pConfig->channel);
//
将定义的通道号写入相关寄存器;
// Write the short
address and the PAN ID to the CC2520 RAM
halRfSetShortAddr(pConfig->myAddr);
p>
//
将定义的本节点地址写入相关寄
存器;
//#define
SHORT_ADDR0
XREG( 0x6174 )
//#define
SHORT_ADDR1
XREG( 0x6175 )
halRfSetPanId(pConfig->panId);
//
将定义的
PANID
写入相关寄存
器;
//#define
PAN_ID0
XREG( 0x6172 )
//#define
PAN_ID1
XREG( 0x6173 )
// if security is enabled, write key
and nonce
#ifdef
SECURITY_CCM
basicRfSecurityInit(pConfig);
#endif
// Set up receive interrupt (received
data or acknowlegment)
h
alRfRxInterruptConfig(basicRfRxFrmDoneIsr);
//
对函数指针进行赋值,关
联相应的中断函数,
即:声明中断程序;
halIntOn();
//
开启总中断;
//
为什么要开闭总中断一
次????
先启用发送节点后启用接收节点时,意外的接收中断?
return SUCCESS;
}
basicRfInit()
< br>如上代码所示,该函数仅对
RF
做简单初始化、通道选择
、
PANID
、本节点地址进行配置,最后为
< br>RF
接收中断
声明一个函数指
针
basicRfRxFrmDoneIsr
;
/*********************************
**************************************************
* @fn
halRfRxInterruptConfig
*
* @brief
Configure RX
interrupt.
*
//
配置接收中断,将
RX
中断
指向
一段可执行程序;
*
@param
none
*
*
@return
none
*/
void
halRfRxInterruptConfig(ISR_FUNC_PTR pf)
{
uint8 x;
HAL_INT_LOCK(x);
p>
//
保存
EA
并将
其清零;
pfISR=
pf;
//
将函
数指针赋值,
而
pfISR
将在
RX
中断时被执行;
HAL_INT_UNLOCK(x);
p>
//
恢复之前
EA
的值;
}
/*********************************************** ************************************
*
* @fn
rfIsr
*
* @brief
Interrupt service routine that handles
RFPKTDONE interrupt.
*
//RX
中断服务程序;
* @param
none
*
* @return
none
*/
HAL_ISR_FUNCTION( rfIsr, RF_VECTOR )
{
uint8 x;
HAL_INT_LOCK(x);
if( RFIRQF0 &
IRQ_RXPKTDONE )
{
if(pfISR){
(*pfISR)();
// Execute the custom ISR
//
如果
pfISR
不为空则将调用<
/p>
函数指针所指向
的函数
basicRfRxFrmDoneIsr
();
}
S1CON= 0;
// Clear general RF interrupt flag
RFIRQF0&=
~IRQ_RXPKTDONE;
// Clear RXPKTDONE
interrupt
}
HAL_INT_UNLOCK(x);
}
RF
中断采用了宏声明的方式
(协议栈中多采用宏来声明中断,
而非常
规
C
语言函数),其声明语句如下:
#define HAL_ISR_FUNC_DECLARATION(f,v)
_PRAGMA(vector=v)
__near_func __interrupt void f(void)
//
中断函数声明的宏;
#define HAL_ISR_FUNC_PROTOTYPE(f,v)
_PRAGMA(vector=v)
__near_func __interrupt void f(void)
//
中断函数原型的宏;
#define HAL_ISR_FUNCTION(f,v)
HAL_ISR_FUNC_PROTOTYPE(f,v);
HAL_ISR_FUNC_DECLARATION(f,v)
//
中断函数定义宏,包括
//
原型和声明;
其中
rfIsr
对应于宏中的
f(void)
,类似于指向其自身
HAL_ISR_FUNC
TION()
。
(二)关于
basicRfSendPacket()
/*****************************************
******************************************
* @fn basicRfSendPacket
*
* @brief Send packet
*
* @param destAddr - destination short
address //
目的地址;
*
pPayload - pointer to payload buffer. This buffer
must be
* allocated by higher layer. //
需要
MAC
层以上产生要发送的数据<
/p>
(指针或数组)
;
* length - length of payload
//
要发送数据的长度;
*
txState - file scope variable that keeps tx state
info //
发送状态信息;
*
mpdu - file scope variable. Buffer for the frame
to send //
对数据进行封包为物
理层协议数据单元;
*
* @return
basicRFStatus_t - SUCCESS or FAILED
*/
uint8 basicRfSendPacket(uint16
destAddr, uint8* pPayload, uint8 length)
{
uint8 mpduLength;
uint8 status;
// Turn on
receiver if its not on
//
保证设
备处于接收状态,其初始值在
halRfInit()
中开启接
收并在
basicRfInit()
中被赋值为
TRUE
;
if(!eOn) {
halRfReceiveOn();
}
// Check
packet length
//
取最小的有效数据长度,<
/p>
类似与可变长度域,
可变长度值是很有用的例如:
串口透传的数据长度;
//
最大数据载荷为
//#define BASIC_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);
// Wait until the
transceiver is idle
//
根据
SFD
和
TX_Active
状态位来判定设备是否处于空闲状态;
//SFD
状态位为
0
说明设备目前
无发送无接收;
-
-
-
-
-
-
-
-
-
上一篇:niosii的UART串口通信
下一篇:中断控制