Board logo

标题: 请教:有关freescale zigbee内存分配和释放 [打印本页]

作者: yolandazhao    时间: 2006-9-8 17:06     标题: 请教:有关freescale zigbee内存分配和释放

我现在在MAC/PHY软件基础上做一些东西,用MAC层的内存分配函数MSG_Alloc()申请了一块内存空间,用来存放要发送的数据包,数据包发送之后,我调用内存释放函数MSG_Free()释放,但是调用MSG_Free()的话会自动发送一些乱码出去,为什么呢?


麻烦高手指点!


作者: seuafu2005    时间: 2006-9-8 17:27

MSG_Alloc()
MSG_Free()
都是用来开辟空间给上下层交换信息的消息队列用的。你要发送的数据通过mcps.dataRequest就可以了,为什么要自己去另外开辟空间?
自己开辟有可能影响程序的运行。

如果可能把你的程序帖出来看看
作者: yolandazhao    时间: 2006-9-8 17:34

我是申请一块空间pPacket用来存放dataRequest的,下面是源程序:

if( (numPendingPackets < MAX_PENDING_DATA_PACKETS) && (pPacket == NULL) )
{
/* If the maximum number of pending data buffes is below maximum limit
and we do not have a data buffer already then allocate one. */
pPacket = MSG_Alloc(sizeof(nwkToMcpsMessage_t) - 1 + DEFAULT_DATA_LENGTH);
}

if(pPacket != NULL)
{
/* If we have a buffer, then get data from the UART. */
uint8_t msduLength = Uart_Poll(pPacket->msgData.dataReq.msdu);
//dataLength = Uart_Poll(tempBuf);

//memcpy(pPacket->msgData.dataReq.msdu,tempBuf + 8, dataLength - 8);

//msduLength = dataLength - 8;
if(msduLength)
{
/* Data was available in the UART receive buffer. Now create an
MCPS-Data Request message containing the UART data. */
pPacket->msgType = gMcpsDataReq_c;
/* Create the header using coordinator information gained during
the scan procedure. Also use the short address we were assigned
by the coordinator during association. */
memcpy(pPacket->msgData.dataReq.dstAddr, coordInfo.coordAddress, 8);
//Uart_Print("Send data to the defined address!");
//memcpy(pPacket->msgData.dataReq.dstAddr, tempBuf, 8);
memcpy(pPacket->msgData.dataReq.srcAddr, myAddress, 8);
memcpy(pPacket->msgData.dataReq.dstPanId, coordInfo.coordPanId, 2);
memcpy(pPacket->msgData.dataReq.srcPanId, coordInfo.coordPanId, 2);
pPacket->msgData.dataReq.dstAddrMode = coordInfo.coordAddrMode;
pPacket->msgData.dataReq.srcAddrMode = myAddrMode;
pPacket->msgData.dataReq.msduLength = msduLength;
/* Request MAC level acknowledgement of the data packet */
pPacket->msgData.dataReq.txOptions = gTxOptsAck_c;
/* Give the data packet a handle. The handle is
returned in the MCPS-Data Confirm message. */
pPacket->msgData.dataReq.msduHandle = msduHandle++;

/* Send the Data Request to the MCPS */
NR MSG_Send(NWK_MCPS, pPacket);
/* Prepare for another data buffer */
MSG_Free(pPacket);
pPacket = NULL;
numPendingPackets++;
}
}
}
作者: seuafu2005    时间: 2006-9-8 17:53

* Send the Data Request to the MCPS */
NR MSG_Send(NWK_MCPS, pPacket);
/* Prepare for another data buffer */
MSG_Free(pPacket);pPacket = NULL;
numPendingPackets++;

不需要free的
在本层开辟的空间,在其他层处理了以后会自动free的
你free的话,等于刚开辟空间,下层还没有来得及处理,或者处理了一般就被free了
作者: yolandazhao    时间: 2006-9-11 08:44

哦,这样啊,谢谢!
但是如果不free的话,中心点重启之后,end device重新发起关联但是不重启,关联上之后,中心点就能发送三次数据包,以后就申请不到内存空间了,并且发送的三次数据,end device都没有收到,现在不知道问题在哪?

[此贴子已经被作者于2006-9-11 8:44:47编辑过]


作者: seuafu2005    时间: 2006-9-11 09:58

中心点重启的话,end device最好是重启,如果不重启,那么试着在关联以前发一下MLME-reset的命令,然后再关联。中心点相device是非直接方式,device没有取到数据的话,数据就一直在coordinator的缓存里面,缓存空间有限,所以三次以后就没有空间了。
估计也是你三次发送的时间太密集,一般来说中心点得不到device收到数据的ack的话,隔一定时间,好像要10秒以上,会自动丢弃数据的。 另外,也可以用data-purge的命令去清楚
作者: yolandazhao    时间: 2006-9-11 11:23

哦,知道了
但是现在要求是中心点重启的话,end device不能重启,我试试看看重连之前先发MLME_Reset行不行
作者: yolandazhao    时间: 2006-9-11 11:34

“中心点相device是非直接方式,device没有取到数据的话,数据就一直在coordinator的缓存里面,缓存空间有限,所以三次以后就没有空间了。”
那为什么end device 会取不到数据呢?根本原因在哪呢?
作者: seuafu2005    时间: 2006-9-11 11:41

device有没有执行poll的操作?
另外,估计是重启以后有些设置有变动吧,具体我也不清楚,可能要仔细分析一下
作者: yolandazhao    时间: 2006-9-11 11:50

device执行poll的操作了
我把coordinator的PanId,channel号和短地址都定死了,每次重启之后都是这些参数
作者: yolandazhao    时间: 2006-9-11 16:43

目前好用了,谢谢seuafu2005,你真是帮了俺的大忙了[em12][em12]
作者: yolandazhao    时间: 2006-9-11 17:07

to seuafu2005:
"一般来说中心点得不到device收到数据的ack的话,隔一定时间,好像要10秒以上,会自动丢弃数据的",如果发送几次之后没有内存空间了,返回null,那么以后隔一段时间(足够长的时间)再申请空间,还能申请到吗?还是就一直也申请不到了?我试了一下,好像是以后一直都申请不到了,这样岂不是死到这了?再次麻烦了,谢谢
作者: seuafu2005    时间: 2006-9-11 17:20

恭喜,说一下你的经验,如何设置就可以了?

我以前用15。4来做数据传输,coordinator向device发送数据,如果数据发送不成功,那么coordinator的mac层自动重发三次,如果还是不行,就会返回一个不成功的confirm信息,传送到mac的数据也会自动被丢弃。你一直都申请不到可能是其他地方的问题。

要注意,对于消息队列,你所分配的空间会在mac层free掉,而mac层上来的indication等需要你free
作者: yolandazhao    时间: 2006-9-11 17:43

呵呵,目前还没有找到如何修改设置,我只是在检测到关联断开之后就让device跳转到初始状态,相当于重启了
记得原来看过资料说:如果coordinator找不到device,它会保留数据,直到device poll它,它就可以发送数据了,是不是这样啊?
作者: seuafu2005    时间: 2006-9-12 10:24

我觉得coordinator不会一直保留,不然找不到的device数目多的话,coordinator不会有这么多空间保留数据的。应该有个时间过后会丢弃数据
作者: yolandazhao    时间: 2006-9-12 10:46

有道理
我这还是这样:如果申请不到空间的话,以后就一直申请不到。
还没有找到问题在哪
作者: tianandy    时间: 2006-10-7 21:50

我也来说说我的问题,呵呵 :
void App_TransmitData(void)
{
uint8_t msduLength = 0;
uint8_t morePackets = 1;
uint8_t deviceAddress = 0x01;
uint8_t ret;
static uint8_t dataBuffer[DEFAULT_DATA_LENGTH]; /* Prevent slow allocation on stack */

/* We transmit only if at least one device is associated. */
if(addressesMap == 0)
return;

/* Send packets only if we can send info to all End Devices */
if(numPendingPackets > 0)
{
if(packetDropped > 0)
{
Uart_Print("Packet dropped.\n");
packetDropped = 0;
}
return;
}

/* Get data to be transmitted from one source */
/* Try first the LED counter */
if(counterLEDsModified)
{
counterLEDsModified = FALSE;
packetDropped = FALSE;
dataBuffer[0] = counterLEDs & 0x0F;
msduLength = 1;
}
else
{
/* Else try to get data from the UART. */
msduLength = Uart_PollMessage(dataBuffer);
}

/* For every device associated, if there is still room in the queue
allocate and send a packet */
if(msduLength != 0)
{
/* Find the first associated end device. We have at least one.*/
while((deviceAddress & addressesMap) == 0)
{
deviceAddress = deviceAddress << 1;
}
/* Transmit packets to the devices */
do
{
morePackets = 0;
if (numPendingPackets < MAX_PENDING_DATA_PACKETS && NULL == pPacket)
{
pPacket = MSG_Alloc(sizeof(nwkToMcpsMessage_t) - 1 + DEFAULT_DATA_LENGTH);
if (pPacket != NULL)
{
/* Create an MCPS-Data Request message containing the data. */
pPacket->msgType = gMcpsDataReq_c;
/* Copy data to be sent to packet */
memcpy(pPacket->msgData.dataReq.msdu, (void *)dataBuffer, msduLength);
/* Create the header using device information stored when creating
the association response. In this simple example the use of short
addresses is hardcoded. In a real world application we must be
flexible, and use the address mode required by the given situation. */
pPacket->msgData.dataReq.dstAddr[0] = deviceAddress;
pPacket->msgData.dataReq.dstAddr[1] = 0;
memcpy(pPacket->msgData.dataReq.srcAddr, (void *)shortAddress, 2);
memcpy(pPacket->msgData.dataReq.dstPanId, (void *)panId, 2);
memcpy(pPacket->msgData.dataReq.srcPanId, (void *)panId, 2);
pPacket->msgData.dataReq.dstAddrMode = gAddrModeShort_c;
pPacket->msgData.dataReq.srcAddrMode = gAddrModeShort_c;
pPacket->msgData.dataReq.msduLength = msduLength;
/* Request MAC level acknowledgement, and
indirect transmission of the data packet */
pPacket->msgData.dataReq.txOptions = gTxOptsAck_c | gTxOptsIndirect_c;
/* Give the data packet a handle. The handle is
returned in the MCPS-Data Confirm message. */
pPacket->msgData.dataReq.msduHandle = msduHandle++;
/* Add the packet to tracking list in the purger module. */
ret = Purger_Track(pPacket->msgData.dataReq.msduHandle, 0, deviceAddress, counterLEDs);
/* Send the Data Request to the MCPS */
NR MSG_Send(NWK_MCPS, pPacket);
/* Prepare for another data buffer */
pPacket = NULL;
numPendingPackets++;
/* Move to next associated device */
do
{
deviceAddress = deviceAddress << 1;
}
while(((deviceAddress & addressesMap) == 0) && (deviceAddress < 0x10));
/* Continue if we haven't passed the last possible device address. */
morePackets = deviceAddress < 0x10;
}
else
{
Uart_Print("Packet NULL.\n");
}
}
}
while (morePackets);
}
}
就是星型网络中协调器发送数据的函数,从代码看是支持四个END Device,其地址为01,02,04,08。协调器往end device中发送数据,但是当连接上第4个时候,向第4个end device发送数据时候会出现 Packet NULL。前面3个都能正常发送数据的




欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) Powered by Discuz! 7.0.0