Marc Boscher

List_RemoveHead goes into infinite loop in simple 802.15.4 app

Discussion created by Marc Boscher on Apr 28, 2008
Latest reply on May 1, 2008 by Mads Westergreen
Hi,

I'm moving from an old version of the 802.15.4 MAC library (1.063) to the most recent in the BeeStack. I've coded a simple transmit test that continuously sends a short broadcast message (1 at a time). The app is based on MyWirelessApp framework project. Strangely, after around 76 packets sent, the application hangs by infinitely calling Default_Dummy_ISR().

Here's the call stack:

- Default_Dummy_ISR()
- List_RemoveHeade (pAnchor=0x43f)  (always the same address)
- Mlme_Main (events=2)
- TS_Scheduler()
- MemCtrlNonBCoord

Here's the hardware:
- MC13213
- Custom PCB with mappings updated in PortConfig.h
- Working with legacy 802.15.4 lib version 1.063

I'm suspecting from kind of memory allocation problem but can't figure it out. I've adjusted the pool size without results.

Any help would be greatly appreciated!
Cheers!
Marc

Here's my MApp.c code:

Code:
/***************************************************************************** * MyWirelessApp Demo Framework * * (c) Copyright 2008, Freescale, Inc. All rights reserved. * * * No part of this document must be reproduced in any form - including copied, * transcribed, printed or by any electronic means - without specific written * permission from Freescale Semiconductor. * *****************************************************************************/#include "MApp.h"#include "NVM_Interface.h"/************************************************************************************ ************************************************************************************* * Private macros ************************************************************************************* ************************************************************************************/#define CHANNEL_MAX 26#define CHANNEL_MIN 11/** Maximum size in bytes of a packet's data unit. */#define MAX_MSDU_SIZE 10 //102/************************************************************************************ ************************************************************************************* * Private prototypes ************************************************************************************* ************************************************************************************/static void App_HandleKeys(key_event_t events);void AppTask(event_t events);static uint8_t waitForMessage(nwkMessage_t *pMsg, uint8_t msgType);static uint8_t config(void);static uint8_t send(void);/************************************************************************************ ************************************************************************************* * Private type definitions ************************************************************************************* ************************************************************************************/enum {  eState_stopped,  eState_start,  eState_waitStartConfirm,  eState_send,};/** Error codes */enum {  errorNoError,  errorWrongConfirm,  errorNotSuccessful,  errorNoMessage,  errorAllocFailed,  errorInvalidParameter,  errorNoScanResults};/************************************************************************************ ************************************************************************************* * Private memory declarations ************************************************************************************* ************************************************************************************//** Flags when the module should next send a packet. Used to add delays between * packets. */bool_t isReadyToSend_test= TRUE;//****** Private global variables *********************************************/** Test state */static uint8_t state = eState_start;/** Application input queue for MLME messages. */static anchor_t mMlmeNwkInputQueue;/** Application input queue for MCPS messages. */static anchor_t mMcpsNwkInputQueue;/** The device's address, always 0x11 22 */static uint8_t shortAddress[2] = { 0x11, 0x22 };/** The Gateway's 802.15.4 PAN. */static uint8_t panId[2] = { 0xEF, 0xBE };/** The current logical channel (frequency band) */static uint8_t logicalChannel= CHANNEL_MIN;/** Total number of packets sent */static uint32_t sentCnt = 0;/** Number of packets sent with an error */static uint32_t errorCnt = 0;/** Number of packets data confirmations*/static uint32_t confCnt = 0;/** Sequence number for next packet */static uint8_t seqNumber = 0;static bool_t firstStart= TRUE;static uint8_t delayCounter = 0;/************************************************************************************ ************************************************************************************* * Public memory declarations ************************************************************************************* ************************************************************************************//* The current state of the applications state machine */uint8_t gState;/* This data set contains application variables to be preserved across resets */NvDataItemDescription_t const gaNvAppDataSet[] = { { NULL, 0 } /* Required end-of-table marker. */};/************************************************************************************ ************************************************************************************* * Public functions ************************************************************************************* ************************************************************************************/void DeepSleepWakeupStackProc(void);/***************************************************************************** * Initialization function for the App Task. This is called during * initialization and should contain any application specific initialization * (ie. hardware initialization/setup, table initialization, power up * notificaiton. * * Interface assumptions: None * * Return value: None * *****************************************************************************/void MApp_init(void) {  /* The initial application state */  gState = stateInit;  /* Initialize the MAC 802.15.4 extended address */  Init_MacExtendedAddress();  /* register keyboard callback function */  KBD_Init(App_HandleKeys);  /* initialize LED Module */  LED_Init();  /* Initialize the LPM module */  PWRLib_Init();  MSG_InitQueue(&mMlmeNwkInputQueue);  MSG_InitQueue(&mMcpsNwkInputQueue);  /* Enable MCU interrupts */  IrqControlLib_EnableAllIrqs();  /*signal app ready*/  Led2On();  Led1Off();  // Start running the AppTask.  TS_SendEvent(gAppTaskID_c, gAppEvtDummyEvent_c);}/***************************************************************************** *Mac Application Task event processor.  This function is called to * process all events for the task. Events include timers, messages and any * other user defined events * * Interface assumptions: None * * Return value: None *****************************************************************************/void AppTask(event_t events) {  /* Pointer for storing the messages */  void *pMsgIn;  /* Stores the status code returned by some functions. */  uint8_t rc;  /* Preset return code to contain the success code */  rc = errorNoError;  /* Try to get a message from MLME */  if (MSG_Pending(&mMlmeNwkInputQueue))    pMsgIn = MSG_DeQueue(&mMlmeNwkInputQueue);  else    pMsgIn = NULL;  switch (state) {  //-----------------------------------  case eState_start:    sentCnt = 0;    errorCnt = 0;    confCnt = 0;    seqNumber = 0;    rc = config();    if (rc == errorNoError)      state = eState_waitStartConfirm;    break;  case eState_waitStartConfirm:    /* Stay in this state until the Start confirm message arrives. */    rc = waitForMessage(pMsgIn, gNwkStartCnf_c);    if (rc == errorNoError) {      state = eState_send;    }    break;  case eState_send:    if (isReadyToSend_test) {      rc = send();      sentCnt++;      isReadyToSend_test = FALSE;    }  }  if (pMsgIn) {    /* Messages must always be freed. */    MSG_Free(pMsgIn);  }  /* Call the MAC main function until the function returns false, indicating   * there is no more work to do. */  //Mlme_Main();      /* Just to avoid the compiler warning */  (void)events;  // Let AppTask run again  TS_SendEvent(gAppTaskID_c, gAppEvtDummyEvent_c);}/************************************************************************************ ************************************************************************************* * Private functions ************************************************************************************* ************************************************************************************//***************************************************************************** * Handles all key events for this device. * Interface assumptions: None * Return value: None *****************************************************************************/static void App_HandleKeys(key_event_t events /*IN: Events from keyboard module  */) {  switch (events) {  case gKBD_EventSW1_c:  case gKBD_EventSW2_c:  case gKBD_EventSW3_c:  case gKBD_EventSW4_c:  case gKBD_EventLongSW1_c:  case gKBD_EventLongSW2_c:  case gKBD_EventLongSW3_c:  case gKBD_EventLongSW4_c:    //LED_ToggleLed(LED2);    //TS_SendEvent(gAppTaskID_c, gAppEvtDummyEvent_c);    break;  }}void nextChannel_test(void) {  logicalChannel++;  if (logicalChannel > CHANNEL_MAX)    logicalChannel = CHANNEL_MIN;}void stop_test(void) {  state = eState_stopped;}/** * This function analyzes the supplied message to determine whether or not the * message is of the expected type. It does not, as the name implies, wait for  * a message, thus blocking the execution of the state machine.  *  * @return one of the following values: * <ul> *  <li>errorNoError: The message was of the expected type.</li> *  <li>errorNoMessage: The message pointer is NULL.</li> *  <li>errorWrongConfirm: The message is not of the expected type.</li> * </ul> */uint8_t waitForMessage(nwkMessage_t *pMsg, uint8_t msgType) {  /* Do we have a message— If not, the exit with error code */  if (pMsg == NULL)    return errorNoMessage;  /* Is it the expected message type– If not then exit with error code */  if (pMsg->msgType != msgType)    return errorWrongConfirm;  /* Found the expected message. Return with success code */  return errorNoError;}uint8_t config(void) {  /* Message for the MLME will be allocated and attached to this pointer */  mlmeMessage_t *pMsg;  /* Pointer which is used for easy access inside the allocated message */  mlmeStartReq_t *pStartReq;  /* Return value from MSG_send - used for avoiding compiler warnings */  uint8_t ret;  /* Allocate a message for the MLME*/  pMsg = MSG_AllocType(mlmeMessage_t);  if (pMsg == NULL) // Allocation of a message buffer failed. */    return errorAllocFailed;  /* Set-up MAC PIB attributes. Please note that Set, Get,   and Reset messages are not freed by the MLME. */  /* We must always set the short address to something   else than 0xFFFF before starting a PAN. */  pMsg->msgType = gMlmeSetReq_c;  pMsg->msgData.setReq.pibAttribute = gMPibShortAddress_c;  pMsg->msgData.setReq.pibAttributeValue = (uint8_t *)shortAddress;  ret = MSG_Send(NWK_MLME, pMsg);  /* This is a MLME-START.req command */  pMsg->msgType = gMlmeStartReq_c;  /* Create the Start request message data. */  pStartReq = &pMsg->msgData.startReq;  FLib_MemCpy(pStartReq->panId, (void *)panId, 2);  pStartReq->logicalChannel = logicalChannel;  pStartReq->beaconOrder = 0x0F; // beacons off  pStartReq->superFrameOrder = 0x0F; // turn off beacons  pStartReq->panCoordinator = TRUE;  pStartReq->batteryLifeExt = FALSE;  pStartReq->coordRealignment = FALSE;  pStartReq->securityEnable = FALSE;  /* Send the Start request to the MLME. */  ret = MSG_Send(NWK_MLME, pMsg);  if (ret == gSuccess_c)    return errorNoError;  else    return errorInvalidParameter;}uint8_t send(void) {  uint8_t checksum = 0;  uint8_t i = 0;  nwkToMcpsMessage_t *pPacket;  /* Allocate packet *///  pPacket = MSG_Alloc(sizeof(nwkToMcpsMessage_t) - 1 + MAX_MSDU_SIZE);  pPacket = MSG_Alloc(gMaxRxTxDataLength_c);    if (pPacket == NULL)    return errorAllocFailed;  // Prepend with sequence number  pPacket->msgData.dataReq.pMsdu[0] = seqNumber;  for (i = 1; i < (MAX_MSDU_SIZE - 1); i++) {    pPacket->msgData.dataReq.pMsdu[i] = 0x11; // dummy data  }  // Apped checksum to packet  pPacket->msgData.dataReq.pMsdu[MAX_MSDU_SIZE - 1] = checksum;  // Build MCPS-Data Request message  pPacket->msgType = gMcpsDataReq_c;  pPacket->msgData.dataReq.srcAddr[0] = shortAddress[0];  pPacket->msgData.dataReq.srcAddr[1] = shortAddress[1];  pPacket->msgData.dataReq.dstAddr[0] = 0xFF; // broadcast  pPacket->msgData.dataReq.dstAddr[1] = 0xFF; // broadcast  pPacket->msgData.dataReq.dstPanId[0] = 0xFF; // broadcast  pPacket->msgData.dataReq.dstPanId[1] = 0xFF; // broadcast  pPacket->msgData.dataReq.srcPanId[0] = panId[0];  pPacket->msgData.dataReq.srcPanId[1] = panId[1];  pPacket->msgData.dataReq.dstAddrMode = gAddrModeShort_c;  pPacket->msgData.dataReq.srcAddrMode = gAddrModeShort_c;  pPacket->msgData.dataReq.msduLength = MAX_MSDU_SIZE;  pPacket->msgData.dataReq.msduHandle = seqNumber;  pPacket->msgData.dataReq.txOptions = 0; // no ack, no security  seqNumber++;  /* Send the Data Request to the MCPS */  return MSG_Send(NWK_MCPS, pPacket);}/***************************************************************************** * The DeepSleepWakeupStackProc(void) function is called each time the  * application exits the DeepSleep mode . *  * Return value: *     None *****************************************************************************/void DeepSleepWakeupStackProc(void) {  return;}/****************************************************************************** * The following functions are called by the MAC to put messages into the * Application's queue. They need to be defined even if they are not used * in order to avoid linker errors. ******************************************************************************/uint8_t MLME_NWK_SapHandler(nwkMessage_t *pMsg) {  /* Put the incoming MLME message in the applications input queue. */  MSG_Queue(&mMlmeNwkInputQueue, pMsg);  return gSuccess_c;}uint8_t MCPS_NWK_SapHandler(mcpsToNwkMessage_t *pMsg) {  confCnt++;  isReadyToSend_test = TRUE;  if (pMsg->msgData.dataCnf.status != gSuccess_c)    errorCnt++;  MSG_Free(pMsg);  return gSuccess_c;}uint8_t ASP_APP_SapHandler(aspToAppMsg_t *pMsg) {  /* If the message is not handled anywhere it must be freed. */  MSG_Free(pMsg);  return gSuccess_c;}/******************************************************************************/

 


Outcomes