Tool/software: TI-RTOS
Hello,
I am using network terminal application for CC3220MODASF.
Minor changes were made to the application. Below is the snippet:
1) Calling function 'RXStatisticsCollect' instead of 'RxTask' from function 'cmdTranceiverModecallback' in file 'transceiver_cmd.c' :
if(!strcmp((char *)&menuOpt , "1"))
{
/* Calling RX radio options */
// ret = RxTask();
ret = RXStatisticsCollect();
menuDisp = TRUE;
}
2) Definition of function 'RXStatisticsCollect' :
#define MAX_RECV_LOOPS 2000
#define MAX_STATS_POINTS 1000
#define MAX_BUFF_SIZE 1544
struct QuickStats {
SlTransceiverRxOverHead_t framehdr;
int identifier;
int loopnum;
int recvbytes;
};
struct QuickStats qst[MAX_STATS_POINTS];
static int RXStatisticsCollect()
{
int iSoc;
char acBuffer[MAX_BUFF_SIZE]; //MAX_BUFF_SIZE=1500
// SlGetRxStatResponse_t rxStatResp;
//char cChar;
// int iIndex;
int iChannel;
long lRetVal = -1;
int iRightInput = 0;
char acCmdStore[512];
struct SlTimeval_t timeval;
// SlTransceiverRxOverHead_t *rxFrameHeader = NULL;
int counter = 0;
int expected_id = 0;
int iterations = 0;
int i = 0;
int firstMatchDone = 0;
int lossCnt = 0;
int totLossCnt = 0;
int firstValidTimeStamp = 0;
int lastValidTimeStamp = 0;
int minRSSI = 0;
int maxRSSI = 0;
int rateChanged = 0;
int rate = 0;
timeval.tv_sec = 0; // Seconds
timeval.tv_usec = 20000; // Microseconds.
memset(acBuffer, 0, sizeof(acBuffer));
//
//Prompt the user for channel number
//
do
{
//UART_PRINT("\n\rEnter the channel to listen[1-13]:");
UART_PRINT(lineBreak);
UART_PRINT(lineBreak);
UART_PRINT(lineBreak);
UART_PRINT("\n\r\tChoose Rx channel: [1,13]\n\r");
//
// Wait to receive a character over UART
//
lRetVal = GetCmd(acCmdStore, sizeof(acCmdStore));
UART_PRINT("\n\r Return value of GetCmd = %d", lRetVal);
if(lRetVal == 0)
{
//
// No input. Just an enter pressed probably. Display a prompt.
//
UART_PRINT("\n\rEnter Valid Input.");
iRightInput = 0;
}
else
{
iChannel = (int)strtoul(acCmdStore,0,10);
if(iChannel <= 0 || iChannel > 13)
{
UART_PRINT("\n\rWrong Input");
iRightInput = 0;
}
else
{
iRightInput = 1;
}
}
}while(!iRightInput);
UART_PRINT("\n\rPress any key to start collecting statistics...");
//
// Wait to receive a character over UART
//
//MAP_UARTCharGet(CONSOLE);
getch();
UART_PRINT("\n\rCollecting Statistics...Please wait...!!!");
//
//Start Rx statistics collection
//
// lRetVal = sl_WlanRxStatStart();
// ASSERT_ON_ERROR(lRetVal);
//
//Open Socket on the channel to listen
//
iSoc = sl_Socket(SL_AF_RF,SL_SOCK_RAW,iChannel);
ASSERT_ON_ERROR(iSoc, SL_SOCKET_ERROR);
// Enable receive timeout
lRetVal = sl_SetSockOpt(iSoc,SL_SOL_SOCKET,SL_SO_RCVTIMEO, &timeval, \
sizeof(timeval));
ASSERT_ON_ERROR(lRetVal, SL_SOCKET_ERROR);
while (MAX_RECV_LOOPS > iterations)
{
if (firstMatchDone)
{
iterations++;
}
lRetVal = sl_Recv(iSoc, acBuffer, MAX_BUFF_SIZE, 0);
if(lRetVal < 0 && lRetVal != SL_ERROR_BSD_EAGAIN /* SL_EAGAIN */)
//if(lRetVal < 0)
{
//error
ASSERT_ON_ERROR(sl_Close(iSoc), SL_SOCKET_ERROR);
ASSERT_ON_ERROR(lRetVal, SL_SOCKET_ERROR);
}
#if 0
UART_PRINT("\n\r sl_Recv RetVal = %d", lRetVal);
#endif
if (acBuffer[12] == 0x00 &&
acBuffer[13] == 0x23 &&
acBuffer[14] == 0x75 &&
acBuffer[15] == 0x55 &&
acBuffer[16] == 0x55 &&
acBuffer[17] == 0x55)
{
firstMatchDone = 1;
qst[counter].framehdr = *((SlTransceiverRxOverHead_t *)acBuffer);
qst[counter].identifier = *((int *)&acBuffer[88]);
qst[counter].loopnum = iterations;
qst[counter].recvbytes = lRetVal;
counter++;
((SlTransceiverRxOverHead_t *)acBuffer)->Timestamp = 0; //to catch dummy recv, i.e. sl_Recv returns without writing anything to the buffer
if (MAX_STATS_POINTS <= counter)
{
break;
}
}
else
{
continue;
}
}
UART_PRINT("\n\r Receive Terminated");
if (MAX_STATS_POINTS <= counter)
{
UART_PRINT("\n\r Reason is targetted number of stats collected.\n\r Target = %d, Collected = %d\n\r", MAX_STATS_POINTS, counter);
}
else
{
UART_PRINT("\n\r Reason is max number of recv iterations exhausted.\n\r Limit = %d, Iterations done = %d\n\r", MAX_RECV_LOOPS, iterations);
}
UART_PRINT("\n\rTS(us), Rate Num, Ch, Pkt Id, Loop, Rx bytes, Rssi(dB)");
minRSSI = qst[0].framehdr.Rssi;
maxRSSI = qst[0].framehdr.Rssi;
rate = qst[0].framehdr.Rate;
for (i = 0; i < counter; i++)
// for (i = 0; i < 1000; i++)
{
UART_PRINT("\n\r%u, %u, %u, %u, %d, %d, %i", qst[i].framehdr.Timestamp,
qst[i].framehdr.Rate, qst[i].framehdr.Channel, qst[i].identifier,
qst[i].loopnum, qst[i].recvbytes, qst[i].framehdr.Rssi);
/* Calculate losses only for stats of a correctly received packet */
if ((0 != qst[i].framehdr.Timestamp) &&
(0 <= qst[i].recvbytes))
{
if(minRSSI > qst[i].framehdr.Rssi)
{
minRSSI = qst[i].framehdr.Rssi;
}
if(maxRSSI < qst[i].framehdr.Rssi)
{
maxRSSI = qst[i].framehdr.Rssi;
}
if (!firstValidTimeStamp)
{
firstValidTimeStamp = qst[i].framehdr.Timestamp;
}
lastValidTimeStamp = qst[i].framehdr.Timestamp;
if (rate != qst[i].framehdr.Rate)
{
rateChanged++;
}
if (qst[i].identifier != expected_id)
{
// UART_PRINT("\n\r Id received is not the expected id (%d)\n\r", expected_id);
lossCnt = qst[i].identifier - expected_id;
totLossCnt += lossCnt;
}
expected_id = qst[i].identifier + 1;
}
}
#if 0
UART_PRINT("\n\rTotal Loss = %d.\n\rThroughput = %f Mbps.\n\rPacket Error Rate = %f.\n\rMin RSSI = %d and Max RSSI = %d.\n\rNum of times the rate changed = %d.", totLossCnt, ((float)((counter - totLossCnt) * qst[0].recvbytes * 8)/(float)(lastValidTimeStamp - firstValidTimeStamp)), ((float)totLossCnt/(float)counter), minRSSI, maxRSSI, rateChanged);
#endif
UART_PRINT("\n\rTotal Loss = %d.\n\r", totLossCnt);
if (lastValidTimeStamp - firstValidTimeStamp)
{
UART_PRINT("Throughput = %f Mbps.\n\r", ((float)((counter - totLossCnt) * qst[0].recvbytes * 8)/(float)(lastValidTimeStamp - firstValidTimeStamp)));
}
else
{
UART_PRINT("Throughput = undefined\n\r");
}
if (counter)
{
UART_PRINT("Packet Error Rate = %f.\n\r", ((float)totLossCnt/(float)counter));
}
else
{
UART_PRINT("Packet Error Rate = undefined\n\r");
}
UART_PRINT("Min RSSI = %d and Max RSSI = %d.\n\r", minRSSI, maxRSSI);
UART_PRINT("Num of times the rate changed = %d.", rateChanged);
//
//Close the socket
//
lRetVal = sl_Close(iSoc);
ASSERT_ON_ERROR(lRetVal, SL_SOCKET_ERROR);
return 0;
}
My query is :
If I declare 'struct QuickStats qst[MAX_STATS_POINTS]' within the function 'RXStatisticsCollect', the board is getting hanged.
On declaring it global, the functionality is working fine.
Why is this difference in the above two cases? What is causing the board to hang if the structure is local to function?
--
Thanks,
Vaishali.