<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
This chapter describes the MAC/PHY interface for FDD, RFD, and their derivatives.
2.1General MAC/Network Interface Information
The interface between the Network Layer (NWK) and the MAC Logical Management Entity Layer (MLME) is based on service primitives passed from one layer to the other through a layer Service Access Point (SAP). Two SAPs must be implemented as functions in the application:
1.zbErrorCode_t MLME_NWK_SapHandler(void *msg); MLME to NWK SAP
MLME_NWK_SapHandler() function passes primitives from the MLME to the NWK)
2.zbErrorCode_t MCPS_NWK_SapHandler(void *msg); MCPS to NWK SAP
MCPS_NWK_SapHandler() function passes primitives from the MCPS to the NWK)
NOTE:the two fuctions locate in: \BeeApps\BeeAppinit.c
Two SAP handlers are likewise implemented in the MAC. They accept messages in the opposite direction from the NWK to the MLME, and MCPS.
The SAP handler functions should not be called directly, but through the available MSG_Send(SAP msg) macro. The identifier ‘SAP’ will be concatenated with _SapHandler, so the MSG_Send(NWK_MLME msg) will be translated to NWK_MLME_SapHandler(msg), where msg is some message that must be sent from the NWK to the MLME. Both MLME and MCPS service primitives use the same type of messages as defined in the NwkMacInterface.h interface header file. The macros are defined in the MsgSystem.h header file.
The NWK_MLME_SapHandler() and NWK_MCPS_SapHandler() functions may place a message in a queue. In order to process queued messages, the Mlme_Main() function must be polled from the NWK or from the users application.
bool_t Mlme_Main(void);
The function returns TRUE if it has more to process (that is, it must be called again) and returns FALSE if it does not have more to process. The CPU sleep mode can be entered by the NWK or the application.
Because the NWK and MLME/MCPS interfaces are based on messages being passed to a few SAPs, each message needs to have an identifier. These identifiers are shown in the following four tables. Some of the identifiers are unsupported for some of the Device Types. For example, the MLME-GTS.request primitive is available for the FFDNGTS but the functionality is not supported.
Table 2-1 lists all the message identifiers in the MLME to NWK direction. They cover all the MLME confirm and indication primitives.
Table 2-1. Primitives In The MLME to NWK Direction
Message Identifier (primMlmeToNwk_t) | 802.15.4 MLME to NWK Primitives |
gNwkAssociateInd_c | MLME-ASSOCIATE.Indication |
gNwkAssociateCnf_c | MLME-ASSOCIATE.Confirm |
gNwkDisassociateInd_c | MLME-DISASSOCIATE.Indication |
gNwkDisassociateCnf_c | MLME-DISASSOCIATE.Confirm |
gNwkBeaconNotifyInd_c | MLME-BEACON-NOTIFY.Indication |
gNwkGetCnf_c | N/A |
gNwkGtsInd_c | MLME-GTS.Indication |
gNwkGtsCnf_c | MLME-GTS.Confirm |
gNwkOrphanInd_c | MLME-RESET.Confirm |
gNwkResetCnf_c | N/A |
gNwkRxEnableCnf_c | MLME-RX-ENABLE.Confirm |
gNwkScanCnf_c | MLME-SCAN.Confirm |
gNwkCommStatusInd_c | MLME-COMM-STATUS.Indication |
gNwkSetCnf_c | N/A |
gNwkStartCnf_c | MLME-START.Confirm |
gNwkSyncLossInd_c | MLME-SYNC-LOSS.Indication |
gNwkPollCnf_c | MLME-POLL.Confirm |
Table 2-2 lists all the message identifiers in the MCPS to NWK direction. They cover all the MCPS confirm and indication primitives.
Table 2-2. Primitives in the MCPS to NWK Direction
Message Identifier (primMcpsToNwk_t) | 802.15.4 MCPS to NWK Primitives |
gMcpsDataCnf_c | MCPS-DATA.Confirm |
gMcpsDataInd_c | MCPS-DATA.Confirm |
gMcpsPurgeCnf_c | MCPS-PURGE.Confirm |
Table 2-3 lists all the message identifiers in the NWK to the MLME direction. They cover all the MLME request and response primitives.
Table 2-3. Primitives in the NWK to MLME Direction
Message Identifier (primNwkToMlme_t) | 802.15.4 NWK to MLME Primitives |
gMlmeAssociateReq_c | MLME-ASSOCIATE.Request |
gMlmeAssociateRes_c | MLME-ASSOCIATE.Response |
gMlmeDisassociateReq_c | MLME-DISASSOCIATE.Request |
gMlmeGetReq_c | MLME-GET.Request |
gMlmeGtsReq_c | MLME-GTS.Request |
gMlmeOrphanRes_c | MLME-ORPHAN.Response |
gMlmeResetReq_c | MLME-RESET.Request |
gMlmeRxEnableReq_c | MLME-RX-ENABLE.Request |
gMlmeScanReq_c | MLME-SCAN.Request |
gMlmeSetReq_c | MLME-SET.Request |
gMlmeStartReq_c | MLME-START.Request |
gMlmeSyncReq_c | MLME-SYNC.Request |
gMlmePollReq_c | MLME-POLL.Request |
Table 2-4 provides a list of all the message identifiers in the NWK to the MCPS direction. They cover all the MCPS request and response primitives.
Table 2-4. Primitives in the NWK to MCPS Direction
Message Identifier (primNwkToMcps_t) | 802.15.4 NWK to MCPS Primitives |
gMcpsDataReq_c | MCPS-DATA.Request |
gMcpsPurgeReq_c | MCPS-PURGE.Request |
2.2 Data Types
This section describes the main C-structures and data types used by the MAC/NWK interface.
A common feature of all the interface structures, with the exception of the pointer type, is that all elements of a size greater than 1 byte are little endian, and declared as byte arrays. That is, a 16 bit short must be stored as shown in the following code example:
short panId = 0x1234;
associateReq->coordPanId[0] = panId & 0xFF; // 0x34
associateReq->coordPanId[1] = panId >> 8; // 0x12
The pointer type is the exception from the little endian notation. The pointer type may be aligned to a suitable boundary and have the endianess of the CPU in question.
Values for the various structure elements are defined by the 802.15.4 Standard. For example, Address Mode can take on the values 0 (No), 2 (Short), and 3 (Extended).
The structures described in Section 4.1.2.1, “Reset Request” through Section 4.10.4.3, “GTS Indication” have been collected in single message type as unions, plus a message type that corresponds to the enumeration of the primitives. These are the structures which transport messages across the interface.
For messages from the MLME to the NWK the following structure/union is used.
// MLME to NWK message
typedef struct nwkMessage_tag {
primMlmeToNwk_t msgType;
union {
nwkAssociateInd_t associateInd;
nwkAssociateCnf_t associateCnf;
nwkDisassociateInd_t disassociateInd;
nwkDisassociateCnf_t disassociateCnf;
nwkBeaconNotifyInd_t beaconNotifyInd;
nwkGetCnf_t getCnf;// Not used
nwkGtsInd_t gtsInd;
nwkGtsCnf_t gtsCnf;
nwkOrphanInd_t orphanInd;
nwkResetCnf_t resetCnf; // Not used
nwkRxEnableCnf_t rxEnableCnf;
nwkScanCnf_t scanCnf;
nwkCommStatusInd_t commStatusInd;
nwkSetCnf_t setCnf;// Not used
nwkStartCnf_t startCnf;
nwkSyncLossInd_t syncLossInd;
nwkPollCnf_t pollCnf;
} msgData;
} nwkMessage_t;
For messages from the MCPS to the NWK the following structure/union is used:
// MCPS to NWK message
typedef struct mcpsToNwkMessage_tag {
primMcpsToNwk_t msgType;
union {
mcpsDataCnf_t dataCnf;
mcpsDataInd_t dataInd;
mcpsPurgeCnf_t purgeCnf;
} msgData;
} mcpsToNwkMessage_t;
The following structure/union is used for messages that must be sent from the NWK to the MLME. An MLME message must be allocated using MSG_AllocType(mlmeMessage_t). The macro returns a pointer to a memory location with a sufficient number of bytes, or NULL if the memory pools are exhausted. The NULL pointer should be handled in the same way as a confirm message with a status code of TRANSACTION_OVERFLOW.
An allocated message that is sent to the MLME will be freed automatically. Pay attention to the comments regarding allocation for the Set, Get, and Reset requests described in Section 4.1.2, “Configuration Primitives”.
// NWK to MLME message
typedef struct mlmeMessage_tag {
primNwkToMlme_t msgType;
union {
mlmeAssociateReq_t associateReq;
mlmeAssociateRes_t associateRes;
mlmeDisassociateReq_t disassociateReq;
mlmeGetReq_t getReq;
mlmeGtsReq_t gtsReq;
mlmeOrphanRes_t orphanRes;
mlmeResetReq_t resetReq;
mlmeRxEnableReq_t rxEnableReq;
mlmeScanReq_t scanReq;
mlmeSetReq_t setReq;
mlmeStartReq_t startReq;
mlmeSyncReq_t syncReq;
mlmePollReq_t pollReq;
} msgData;
} mlmeMessage_t;
The following structure/union is used for messages that must be sent from the NWK to the MCPS. An MCPS-PURGE.request must be allocated using MSG_AllocType(nwkToMcpsMessage_t), while an MCPS-DATA.request message must be allocated using
MSG_Alloc((sizeof( nwkToMcpsMessage_t)-1)+size). Both allocation macros return a pointer to a memory location with a sufficient number of bytes, or NULL if the memory pools are exhausted. The NULL pointer should be handled in the same way as a confirm message with a status code of TRANSACTION_OVERFLOW.
An allocated message that is sent to the MCPS will be freed automatically.
// NWK to MCPS message
typedef struct nwkToMcpsMessage_tag {
primNwkToMcps_t msgType;
union {
mcpsDataReq_t dataReq;
mcpsPurgeReq_t purgeReq;
} msgData;
} nwkToMcpsMessage_t;
2.3 Message Buffer Configuration
The message system, which is an integral part of the MAC and the interface to the MAC, relies on a pool of message buffers. Depending on the Device Type and selected feature set the buffer pool varies in size. Typically, a coordinator can have 5 small messages of 22 bytes each and 5 large messages of 134 bytes each. The number of buffers is defined in the FunctionalityDefines.h header file in the Ghdr folder. Specifically, the gTotalSmallMsgs_d, and gBigMsgsExtraOverhead_d constant definitions can be used to configure the number of message buffers.
NOTE
Freescale strongly recommends to only increase the number of message buffers because MAC functionality may be adversely affected by a reduction in the number of message buffers. If users are absolutely required to reduce the number of message buffers, then extensive testing must be performed to ensure that the MAC is not influenced by the reduced buffer count.
When building applications incorporating the Freescale MAC, the GlobalVars.c source file must be included because it contains the instantiation of the MAC message pools.
An application is allowed to add message buffers to the pools as well as use the extra buffers for both MAC messages and non-MAC related memory allocations. However, if using the buffers for private allocations, the application must take care to not allocate more buffers than was added. For example, if gTotalSmallMsgs_d is changed from 5 to 12, then the application should only use the extra 7 buffers for private allocations. Otherwise, the MAC may fail to function properly.
Instead of adding application specific buffers to the MAC buffer pool, the application can create its own private pool. The following example shows how to accomplish this using the data types and macros from the MsgSystem.h file. The example defines four pools configured as shown in Table 2-5.
Table 2-5. Pool ConfigurationPool ID | Number of buffers | Size of each buffer in bytes |
0 | mMyAppNumBuf0 = 8 | mMyAppBufSize0 = 16 |
1 | mMyAppNumBuf1 = 4 | mMyAppBufSize1 = 32 |
2 | mMyAppNumBuf2 = 2 | mMyAppBufSize2 = 50 |
3 | mMyAppNumBuf3 = 1 | mMyAppBufSize3 = 128 |
1.The message system header file is included and then the APP_Alloc*** macros are defined to access the application specific pool (myAppPools).
#include “MsgSystem.h”
#define APP_Alloc(size) MM_AllocPool(myAppPools, numBytes)
#define APP_AllocType(type) MM_AllocPool(myAppPools, sizeof(type))
2.The pool layout is defined using the poolInfo_t type.
NOTE
It is important that the buffer sizes are sorted in ascending order. The sequence in this example must be as follows:
16, 32, 50, 128
#define mMyAppNumBuf0 8 // Pool0 has 8 buffers of
#define mMyAppBufSize0 16 // 16 bytes each
#define mMyAppNumBuf1 4 // Pool1 has 4 buffers of
#define mMyAppBufSize1 32 // 32 bytes each
#define mMyAppNumBuf2 2 // Pool2 has 2 buffers of
#define mMyAppBufSize2 50 // 50 bytes each
#define mMyAppNumBuf3 1 // Pool3 has 1 buffer of
#define mMyAppBufSize3 128 // 128 bytes
const poolInfo_t myAppPoolInfo[4] = {
mMyAppNumBuf0, mMyAppBufSize0, mMyAppBufSize1,
mMyAppNumBuf1, mMyAppBufSize1, mMyAppBufSize2,
mMyAppNumBuf2, mMyAppBufSize2, mMyAppBufSize3,
mMyAppNumBuf3, mMyAppBufSize3, 0
};
In order to allocate the heap for the pools, the total size of the pools must be known. The following code snippet shows how to calculate the total heap size and then allocate it. Extra space (sizeof listHeader_t) is added to each buffer for storing two pointers related to linked list operations.
#define mMyAppHeapSize (\
mMyAppNumBuf0*(mMyAppBufSize0+sizeof(listHeader_t)) + \
mMyAppNumBuf1*(mMyAppBufSize1+sizeof(listHeader_t)) + \
mMyAppNumBuf2*(mMyAppBufSize2+sizeof(listHeader_t)) + \
mMyAppNumBuf3*(mMyAppBufSize3+sizeof(listHeader_t)) )
uint8_t myAppHeap[mMyAppHeapSize];
NOTE
Depending on machine architecture, it may be required to restrict the buffer sizes to values divisible by sizeof(void *). Otherwise, bus access violations may occur.
For example, a buffer size of 50 can cause problems on 32 bit architectures. To avoid potential issues, the size should be defined as 32.
When initializing the pools the myAppPools array is filled with information about each pool. This array is used as the handle to the application’s private pool when allocating a buffer.
pools_t myAppPools[4];
// Initialize application pools
MM_Init(myAppHeap, myAppPoolInfo, myAppPools);
When allocating buffers from the application pool, use the APP_Alloc(size) and APP_AllocType(type) macros. They will translate to MM_Alloc(myAppPools, size), and MM_Alloc(myAppPools, sizeof(type)) respectively. MSG_Free can be used on all buffers regardless of the pool they originate from. This implies that the application private buffers can be sent to the MAC as long as the message sizes expected by the MAC are complied with (a minimum of 22 bytes for small non-data messages and a minimum of 134 bytes for data packets and command frames). When freed by the MAC, the application buffers are returned to the applications private pool.
2.4Message System API
This section describes the macros and functions available in the Message System API. In order to use the API, the MsgSystem.h header file must be included in the relevant source code files. The GlobalVars.c file is also a requirement in the build.
2.4.1MM_Init
Prototype
void MM_Init(uint8_t *pHeap, const poolInfo_t *pPoolInfo, pools_t *pPools);
Arguments
None
pHeap
Points to a contiguous memory block with space for the complete memory pool including space for linked list housekeeping. The number of bytes required in the heap can be calculated using the following equation:
<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" />
Where:
M is the number of pools of different buffer sizes.
Nm is the number of buffers in pool m.
Sm is the number of bytes in each buffer in pool m.
For example, if M="2", pools are defined with N0=3 buffers of S0=16 bytes, and N1=2 buffers of S1=64 bytes, then the amount of heap memory must be: 3*(16+4) + 2*(64+4) = 196 bytes, assuming that sizeof(listHeader_t) is 4. The heap can be created as follows:
uint8_t myHeap[196];
pPoolInformation
Points to an array of data structures which define the memory pool layout. The array is not altered by this function and may be placed in read only memory. The format of the pool info array is shown in Table 2-6.
Table 2-6. Pool Info ArrayN0 | S0 | S1 |
N1 | S1 | S2 |
N2 | S2 | SM-1 |
NM-1 | SM-1 | 0 (Termination) |
An important restriction to the buffer sizes is shown in the following formula:
For example, the pools must be defined with ascending buffer sizes. An equally important restriction is that the buffer size must be a modulus of the pointer size of the machine architecture. For example, on 32 bit MCUs the buffer size must be divisible by 4. Otherwise, bus access violations occur when accessing misaligned buffers.
Using the previous example, a pool can be constructed by defining the following structure:
const poolInfo_t myPoolInfo[2] = {
3, 16, 64,
2, 64, 0 };
pPools
Points to an array of c-structures which will receive the initialized memory pool handle. The handle is used when allocating memory from the pool. If M pools have been defined in the pool info array, then the output array also needs to reserve space for M number of pools_t structures. For example, continuing with the current example, the array is defined as:
pools_t myPools[2];
To fill in the array the MM_Init function is called as follows:
MM_Init(myHeap, myPoolInfo, myPools);
Now allocation and deallocation is possible using the application specific allocation function and the standard free function:
myDataType_t *pBuffer = MM_AllocPool(myPools, 12);
MSG_Free(pBuffer);
Functional Description
The MM_Init function is used whenever a new set of memory pools must be created. It is used by the MAC during initialization and soft reset (MLME-RESET.request) to configure the MAC message pool. However, applications may also use the function for creating their own private pools.
The array of poolInfo_t structures is used for segmenting the supplied heap into buffers, and organizing them in pools. All buffers are assigned a header with a pointer to the original pool, and a next pointer for linked list operations. The pool information, including anchors for each buffer pool, is stored in the output pools_t array.
2.4.2MSG_Alloc
Macro Definition
#define MSG_Alloc(size) MM_Alloc(size)
Arguments
None
Size
Specifies the size of the requested buffer, which must be less than 256 bytes.
Functional Description
The macro is typically translated directly to MM_Alloc(size). See Section 2.4.4, “MM_Alloc” for more information.
Example
uint8_t *pMsg = MSG_Alloc(10);
2.4.3MSG_AllocType
Macro Definition
#define MSG_AllocType(type) MM_Alloc(sizeof(type))
Arguments
None
Type
Specifies the type of the requested buffer. The type is translated to a size which must be less than 256 bytes.
Functional Description
The macro is typically translated directly to MM_Alloc(sizeof(type)). See Section 2.4.5, “MM_AllocPool” for more information.
Example
mlmeMessage_t *pMsg = MSG_AllocType(mlmeMessage_t);
2.4.4MM_Alloc
Prototype
void *MM_Alloc(uint8_t size);
Arguments
None
Size
Specifies the size of the requested buffer, which must be less than 256 bytes.
Returns
Pointer to allocated buffer, or NULL if no buffers were available.
Functional Description
This function is solely for allocating buffers from the MAC pools. Otherwise, the functionality is identical to MM_AllocPool. See Section 2.4.5, “MM_AllocPool” for more information. Freescale recommends using the MSG_Alloc and MSG_AllocType macros instead of the direct function call.
Example
nwkToMcpsMessage_t *pMsg = MM_Alloc(sizeof(nwkToMcpsMessage_t));
2.4.5 MM_AllocPool
Prototype
void *MM_AllocPool(pools_t *pPool, uint8_t size);
Arguments
None
pPool
The pool to allocate a buffer from. pPool must have been initialized by MM_Init.
Size
Specifies the size of the requested buffer, which must be less than 256 bytes.
Returns
Pointer to allocated buffer, or NULL if no buffers were available.
Functional Description
This function searches in the memory pool specified by the pPool argument for a buffer of at least the number of bytes given by the size argument. The search starts at the smallest buffer size and ends at the largest buffer size.
For example, assume a memory pool with 3 buffers of 16 bytes and 2 buffers of 64 bytes. If the size argument is 10, a buffer from the 16 byte pool will be allocated. After allocating two additional buffers of size 10, the 16 bytes buffer pool is exhausted. If allocating the fourth 10 bytes buffer, it will be allocated from the pool with the 64 bytes buffers. The next time that the function is called when all buffers of all sizes in the pool have been allocated, the function returns the value NULL to signify that no memory is available. The function also returns NULL if no buffers of the requested buffer size exists in the pools. For example, if the size argument is 70, then none of the pools in the example will match the request and the return value is NULL.
Example
myTypeA_t *pMsg = MM_AllocPool(myPools, sizeof(myTypeA_t));
2.4.6MSG_Free
Macro Definition
#define MSG_Free(buffer) MM_Free(buffer)
Arguments
None
Buffer
Specifies the buffer to be returned to the memory pool.
Functional Description
The macro is typically translated directly to MM_Free(size). See Section 2.4.7, “MM_Free” for more information.
2.4.7 MM_Free
Prototype
void MM_Free(void *pBuffer);
Arguments
None
pBuffer
The buffer to be returned to the memory pool from which it was allocated.
Functional Description
The pBuffer argument points at a memory buffer allocated by the MSG_Alloc and MSG_AllocType macros, or the MM_Alloc and MM_AllocPool functions. It is important that the value of the pBuffer pointer is the same as the value returned by any of the four allocation methods. Otherwise, the memory pool will be invalidated.
Example
uint8_t *pMsg = MM_Alloc(14);
/* Important: Do not modify the value returned by any allocation function. E.g. pMsg++, or pMsg += startOfDataIndex etc. will cause the MM_Free function to invalidate the memory pool. */
MM_Free(pMsg);
2.4.8MSG_Send
Macro Definition
#define MSG_Send(sap, msg) (sap##_SapHandler((void *)(msg)))
Arguments
None
SAP
Specifies the name of the service access point to which the message is sent.
Message
Specifies the message to be send to the service access point.
Functional Description
The macro translates into a function with the name of the specified SAP concatenated with the extension “_SapHandler”. For example, a network layer or application must implement a function called MLME_NWK_SapHandler. The 802.15.4 MAC will call that function when sending messages to the network layer or application.
The following SAPs must be defined by the upper layer:
MLME_NWK_SapHandler()
MCPS_NWK_SapHandler()
ASP_APP_SapHandler()
See Section 2.1, “General MAC/Network Interface Information”, and Section 5.1, “General APP/ASP Interface Information” for more information about the service access points.
Example
mlmeMessage_t *pMsg = MSG_AllocType(mlmeMessage_t);
PrepareAssociateMessage(pMsg); // Pseudo code.
// Call NWK_MLME_SapHandler(pMsg);
MSG_Send(NWK_MLME, pMsg);
2.4.9 MSG_InitQueue
Macro Definition
#define MSG_InitQueue(anchor) List_ClearAnchor(anchor)
Arguments
None
Anchor
Specifies a pointer to the queue anchor that must be initialized.
Functional Description
This macro translates to a function which clears the head and tail pointers of the queue anchor. All anchors must be cleared during system initialization before they are used for queuing messages.
Example
anchor_t myNwkQueue;
void MyApp_Init(void)
{
MSG_InitQueue(&myNwkQueue);
}
2.4.10MSG_Queue
Macro Definition
#define MSG_Queue(anchor, msg) List_AddTail((anchor), (msg))
Arguments
None
Anchor
Specifies a pointer to the queue anchor which will receive the message.
Message
Specifies a pointer to the message being queued.
Functional Description
The macro translates to a function which adds the message to the tail of the queue. There is no limit imposed on the number of messages that can be stored in the queue. When combined with the MSG_DeQueue macro, a FIFO queue is realized.
Example
anchor_t myMlmeNwkQueue;
void MLME_NWK_SapHandler(nwkMessage_t *pMsg)
{ // Queue up messages from the MLME.
MSG_Queue(&myMlmeNwkQueue, pMsg);
}
2.4.11 MSG_QueueHead
Macro Definition
#define MSG_QueueHead(anchor, msg) List_AddHead((anchor), (msg))
Arguments
None
Anchor
Specifies a pointer to the queue anchor which will receive the message.
Message
Specifies a pointer to the message being queued.
Functional Description
This macro translates to a function which adds the message to the head of the queue. There is no limit imposed on the number of messages that can be stored in the queue. When combined with the MSG_DeQueue macro a LIFO queue, or stack, is realized because messages are always de-queued from the head of the queue. See Section 2.4.12, “MSG_DeQueue”.
Example
anchor_t myStackQueue;
void AddToStack(myDataType_t *pMsg)
{ // Put the message on the stack-like queue
MSG_QueueHead(&myStackQueue, pMsg);
}
2.4.12MSG_DeQueue
Macro Definition
#define MSG_DeQueue(anchor) List_RemoveHead(anchor)
Arguments
None
Anchor
Specifies a pointer to the queue anchor.
Returns
Pointer to de-queued message or NULL if queue is empty.
Functional Description
The macro translates to a function which removes a message from the head of the specified queue.
Example
anchor_t myMcpsNwkQueue;
void ProcessMcpsMessage(void)
{
mcpsToNwkMessage_t *pMsg = MSG_DeQueue(&myMcpsNwkQueue);
// Do something with the message.
...
// ALWAYS free message when done with it.
MSG_Free(pMsg);
}
2.4.13 MSG_Pending
Macro Definition
#define MSG_Pending(anchor) ((anchor)->pHead != 0)
Arguments
None
Anchor
Specifies a pointer to the queue anchor.
Returns
TRUE if one or more messages in queue, or FALSE if queue is empty.
Functional Description
This macro checks if there are any messages in the specified queue. This is accomplished without disabling interrupts, and it is the recommended method for checking queues for messages. The MSG_DeQueue macro translates to a function which disables interrupts for a few micro seconds. Thus, if checking the queues in a tight loop, it is preferred to use MSG_Pending so as not to interfere with the real-time functionality of the MAC.
Example
anchor_t myMcpsNwkQueue;
while(running) {
if(MSG_Pending(&myMcpsNwkQueue)) {
// Function uses MSG_DeQueue to obtain queued message.
ProcessMcpsMessage();
}
}
文章评论(0条评论)
登录后参与讨论