Memory crash after appending just a few lines to buffer


#1

Hi guys

I want to append serial data to a buffer, but I am not really sure how to allocate memory to the buffer; the buffer seems to crash just after a few lines of data.

My code:

ascii * buffer;
.
.
.

void appli_entry_point() 
{
buffer = adl_memGet ( 50000 );	
 	 
	V24Handle = adl_fcmSubscribe ( USED_FLOW, V24CtrlHandler, V24DataHandler );
}

bool V24CtrlHandler ( u8 Event )
{
    bool bReturn = TRUE;
    s32 sReturn;
    TRACE (( 1, "serial event %d", Event ));    
    switch ( Event )
    {	
		case ADL_FCM_EVENT_FLOW_OPENNED :    	
        	sReturn = adl_fcmSwitchV24State ( V24Handle, ADL_FCM_V24_STATE_DATA );
            TRACE (( 1, "serial switch to datamode %d ", sReturn ));	
			bFCMIsReady = TRUE;
        break;
        
        case ADL_FCM_EVENT_RESUME :      
			break;
        
		case ADL_FCM_EVENT_MEM_RELEASE :        	
			break;        	
    }    
    return bReturn;	
}

bool V24DataHandler ( u16 Length, u8 * Data )
{
    int nwrite;
    u16     i;   
    TRACE (( 1, "Serial data event"));
    wm_strcat ( ( ascii * ) buffer, ( ascii * ) Data);
    wm_strcat ( ( ascii * ) buffer, ( ascii * ) "\n");
    TRACE (( 1, buffer )); 	
    return TRUE;	
}

I input this serial string: “$GPZDG,POS_GPS,DD,MM,YYYY,AA.BB,V*CS” line by line.

My results in terminal emulator:

Trace	DEV	1	Unable to find the string of the remote trace in the file (ID = 12654)
Trace	CUS4	1	Embedded Application : Main
Trace	RLU	1	Unable to find the string of the remote trace in the file (ID = 528)
Trace	CUS4	1	fcm subscribe
Trace	CUS4	1	timer subscribe
Trace	CUS4	1	serial event 0
Trace	CUS4	1	serial switch to datamode 0 
Trace	CUS4	1	serial event 2
Trace	RLU	1	Unable to find the string of the remote trace in the file (ID = 528)
Trace	CUS4	1	Serial data event
Trace	CUS4	1	$GPZDG,POS_GPS,DD,MM,YYYY,AA.BB,V*CS
			
Trace	CUS4	1	Serial data event
Trace	CUS4	1	$GPZDG,POS_GPS,DD,MM,YYYY,AA.BB,V*CS
			$GPZDG,POS_GPS,DD,MM,YYYY,AA.BB,V*CSp/ 
			
Trace	CUS4	1	Serial data event
Trace	CUS4	1	$GPZDG,POS_GPS,DD,MM,YYYY,AA.BB,V*CS
			$GPZDG,POS_GPS,DD,MM,YYYY,AA.BB,V*CSp/ 
			$GPZDG,POS_GPS,DD,MM,YYYY,AA.BB,V*CSp/ 

.
.
.

Trace	CUS4	1	Serial data event
Trace	CUS4	1	$GPZDG,POS_GPS,DD,MM,YYYY,AA.BB,V*CS
			$GPZDG,POS_GPS,DD,MM,YYYY,AA.BB,V*CSp/ 
			$GPZDG,POS_GPS,DD,MM,YYYY,AA.BB,V*CSp/ 
			$GPZDG,POS_GPS,DD,MM,YYYY,AA.BB,V*CSp/ 
			$GPZDG,POS_GPS,DD,MM,YYYY,AA.BB,V*CS[
			$GPZDG,POS_GPS,DD,MM,YYYY,AA.BB,V*CSp/ 
			
Trace	CUS4	1	Serial data event
Trace	CUS4	1	$GPZDG,POS_GPS,DD,MM,YYYY,AA.BB,V*CS
			$GPZDG,POS_GPS,DD,MM,YYYY,AA.BB,V*CSp/ 
			$GPZDG,POS_GPS,DD,MM,YYYY,AA.BB,V*CSp/ 
			$GPZDG,POS_GPS,DD,MM,YYYY,AA.BB,V*CSp/ 
			$GPZDG,POS_GPS,DD,MM,YYYY,AA.BB,V*CS[
			$GPZDG,POS_GPS,DD,MM,YYYY,AA.BB,V*CSp/ 
			$GPZDG,POS_GPS, ...
Trace	CUS4	1	Serial data event
Trace	CUS4	1	$GPZDG,POS_GPS,DD,MM,YYYY,AA.BB,V*CS
			$GPZDG,POS_GPS,DD,MM,YYYY,AA.BB,V*CSp/ 
			$GPZDG,POS_GPS,DD,MM,YYYY,AA.BB,V*CSp/ 
			$GPZDG,POS_GPS,DD,MM,YYYY,AA.BB,V*CSp/ 
			$GPZDG,POS_GPS,DD,MM,YYYY,AA.BB,V*CS[
			$GPZDG,POS_GPS,DD,MM,YYYY,AA.BB,V*CSp/ 
			$GPZDG,POS_GPS, ...
Trace	RTK	1	Except RTK ....161 57a080 1

The error messages windows I got from the terminal emulator:
Error messages: FATAL ERROR: buffer:Except RTK….%d%x%d
RTK Exception:status:161 param:57a080 taskid:1

What is wrong with my code? Advance thanks!


#2
bool V24DataHandler ( u16 Length, u8 * Data )

There are two parameters - Length & Data - because the data is not NUL-terminated.

The standard ‘C’ string library functions require that the data must be NUL-terminated - otherwise they will just run off the end of the buffer! :open_mouth:


#3

Hiya,

A couple of points:

Allocating approximately 50k of RAM on a processor that only has 1MByte ( = 8Mbits on Q2686H - don’t know about others) for total use (Baseband, firmware, your application) may not be the wisest thing to be doing. If the adl_memGet() is failing, you will be scribbling over somewhere in RAM, which may not be what you are after… You are probably better allocating just enough memory for a line of NMEA data and processing each line, rather than reading in large amounts and then post-processing.

Don’t forget to allocate memory to hold the NUL (0x00) character that is used as the end of string marker.

Also, it is reasonable coding practice to do your memory declaration as follows:

buffer = adl_memGet( 50000 * sizeof(ascii) );

This will ensure that you are actually allocating the right amount of memory for the data-type you are dealing with. Remember, you are cross-compiling to a different CPU here, with different data-type sizes that you may be used to. Also, allocating memory in this manner will save your bacon if Wavecom (and/or the compiler designers) decide to change the size of an ‘ascii’ (maybe to support unicode???). The ascii data-type is unlikely to change size across CPU’s - but the same cannot be said about the various integer and float types.

cheers, Dave


#4

Guys

Thanks for the advice, but I tried many different coding but my lame c just can’t get away the error messages.

I am using a Fastrack Supreme 20.

I tried from 200 to 20000, the error message still pops out after 5 serial strings “FATAL ERROR: buffer:Except RTK….%d%x%d.
RTK Exception:status:161 param:57a080 taskid:1”

buffer = adl_memGet( 2000 * sizeof(ascii) );

I tried (ascii*)“0x00”, (ascii*)‘0x00’, “0x00”, “x00”, (ascii*)"\0", and “\0” etc, the same eror mesage pops out: “…Access violation”. I tried looking for Append null character function in BUG but couldn’t find any.

bool V24DataHandler ( u16 Length, u8 * Data )
{
    int nwrite;
    u16     i;  		
    TRACE (( 1, "Serial data event"));    
    wm_strcat ( ( ascii * ) buffer, ( ascii * ) Data);    
    wm_strcat ( ( ascii * ) buffer, ( ascii * )"\x00");	
    TRACE (( 1, buffer )); 		
    return TRUE;	
}

Did I append the null character correctly? :mrgreen: My full source code below, advance thanks!

#include "adl_global.h"
#include "wip.h"

#define DST_SERVER    "209.90.82.23"     
#define DST_USER      "datataker"       
#define DST_PASSWORD  "password" 
#define DST_FILENAME  "data.txt"        
#define DST_ISPASSIVE TRUE             
#define     BKSP    '\x08'
#define     BKSPSEQ "\x08 \x08"
#define     USED_FLOW   ADL_FCM_FLOW_V24_UART1 

bool    bFCMIsReady = TRUE;
ascii * buffer;
static s8 	V24Handle;
static int offset = 0;
static wip_channel_t 
dst_ftp_cx   = NULL, 
dst_data     = NULL; 

static void evh_cx( wip_event_t *ev, void *ctx);
static void evh_data( wip_event_t *ev, void *ctx);
bool V24DataHandler ( u16 Length, u8 * Data );
bool V24CtrlHandler ( u8 Event );
void HelloWorld_TimerHandler ( u8 ID );

void appli_entry_point() 
{
    buffer = adl_memGet( 2000 * sizeof(ascii) );	
 	    
    TRACE (( 1, "fcm subscribe" ));  
    V24Handle = adl_fcmSubscribe ( USED_FLOW, V24CtrlHandler, V24DataHandler );

    TRACE (( 1, "timer subscribe" ));  
    //adl_tmrSubscribe ( TRUE, 200, ADL_TMR_TYPE_100MS, HelloWorld_TimerHandler ); //somehow at 200 the ftp wont write
}

static void evh_cx( wip_event_t *ev, void *ctx) 
{  
    switch( ev->kind) 
	{
		case WIP_CEV_OPEN:
            TRACE (( 1, "Make new file up FTP connection" ));
		    dst_data = wip_putFile( dst_ftp_cx, DST_FILENAME, evh_data, NULL);
		    if( ! dst_data) { wip_debug( "Can't create data channel"); return; }
		    break;

		case WIP_CEV_ERROR:
		    break;

		case WIP_CEV_PEER_CLOSE:
		    break;
	}
}

static void evh_data( wip_event_t *ev, void *ctx) 
{
    switch( ev->kind) 
    {
        case WIP_CEV_OPEN:
            break;

        case WIP_CEV_WRITE: 
        {
            int nwrite = wip_write( dst_data, buffer, sizeof( buffer) - 0);
            TRACE (( 1, "Write to FTP file ", ( ascii * ) buffer ));
    
            TRACE (( 1, "Close ftp connection \n", buffer ));
            wip_close( dst_data);   dst_data   = NULL;
	        wip_close( dst_ftp_cx); dst_ftp_cx = NULL;   
        }
            break; 

        case WIP_CEV_ERROR:    
            break;
    }
}
 
bool V24CtrlHandler ( u8 Event )
{
    bool bReturn = TRUE;
    s32 sReturn;
    TRACE (( 1, "serial event %d", Event ));    
    switch ( Event )
    {	
		case ADL_FCM_EVENT_FLOW_OPENNED :    	
        	sReturn = adl_fcmSwitchV24State ( V24Handle, ADL_FCM_V24_STATE_DATA );
            TRACE (( 1, "serial switch to datamode %d ", sReturn ));	
			bFCMIsReady = TRUE;
            break;
    
        case ADL_FCM_EVENT_RESUME :      
			break;
    
		case ADL_FCM_EVENT_MEM_RELEASE :        	
			break;        	
    }    
    return bReturn;	
}

bool V24DataHandler ( u16 Length, u8 * Data )
{
	int nwrite;
    u16     i;  		
	TRACE (( 1, "Serial data event"));    
    wm_strcat ( ( ascii * ) buffer, ( ascii * ) Data);    
    wm_strcat ( ( ascii * ) buffer, ( ascii * )"\x00");	
	TRACE (( 1, buffer )); 		
	return TRUE;	
}

void HelloWorld_TimerHandler ( u8 ID )
{
	TRACE (( 1, "Timer trigger" ));
	TRACE (( 1, "Connect to FTP" ));
  	dst_ftp_cx = wip_FTPCreateOpts (
    DST_SERVER,  evh_cx, NULL,
    WIP_COPT_USER,     DST_USER,
    WIP_COPT_PASSWORD, DST_PASSWORD,
    WIP_COPT_PASSIVE,  DST_ISPASSIVE,
    WIP_COPT_END);
}

#5

I think what you have here are basic ‘C’ problems - nothing specifically to do with Wavecom, the Fastrack, or Open-AT.

Therefore it may be worth you spending some time honing your ‘C’ skills before continuing with this.

No - you haven’t appended a NUL character at all!

wm_strcat ( ( ascii * ) buffer, ( ascii * ) Data);

As I told you before, all ‘C’ string functions rely upon there being a NUL termination - and ‘Data’ does not have a NUL termination!

Therefore this line of code will cause the processor to “run off the end” of your valid data - which will cause your application to crash!

You need to make use of the ‘Length’ parameter to ensure that you don’t “run off the end” of ‘Data’

Note also that you must not attempt to add a NUL directly at the end of ‘Data’, because it is just a pointer to some buffer that was allocated by some other part of the system - you cannot assume that it left room for you to add a NUL there!

If you want to add a NUL and use it as a ‘C’ string, you will need to use something like memcpy to copy the data to your own local buffer - and add the NUL there.

Again, this is standard ‘C’ stuff - nothing specific to Wavecom.