This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Compiler/CCSTUDIO: Decl statics & array issues

Guru 56033 points
Part Number: CCSTUDIO


Tool/software: TI C/C++ Compiler

Why are static variables not being initiated to 0x0 by C++ definition of a static variable? 

How to initiate CCS array[] (all cells) to 0x0? Classic C++ method to initiate array cells via empty braces {} declaring are marked as error when compiled.  

CCS defined array are being limited to 8 bytes pointer index that can not search beyond the argument value set by (char) length, should be 255 bytes not bits. CCS debug shows the argument pointer only fills the array cells from bytes 0-7 via the input buffer assignment. Attempting to ever flush the passing buffer or the argument value after index value is found fails to return the pfn command structure defined by (argc, argv[]). That is especially true when hexadecimal values passed to char, CCS9.1 debug element array value often changes 0xff to '0' as other char are entering the F6 stepped array buffer. Very confusing when the displayed value suddenly changes like that and often differs from char that was input from FIFO.

Serial character passing of buffer contents via (char) into *char argument pointer of an called function produce truncated buffer lengths. Sometimes the full length of FIFO input stream of the callers array buffer is passed to the called function - more often not no matter the timeout length set in the while loop caller from a 5ms GPTM interval.

This is a small array buffer pointed to by static integer [I] and incremented via (for loop) as it passes char into the next called function to test command argument values. The buffer is often truncated when being passed to the called function being much shorter by several bytes than the UART FIFO (for [I]) loop RX data being buffered. The POP function of array value from a FIFO randomly stumbles. However the while loop PUSH function from array to FIFO is working great via same GPTM 5ms while calls. Seemingly this is a Thumb instruction execution issue on back to back Reads of UARTDR register via (HWREG for blocking loop shown below). The compiler 18.12.3.LTS is responsible to produce the correct tool chain Thumb instructions in this case as not to stumble during loading array BUFFER via POP of read sensitive register UARTDR.

#define BUFFER  20

char MyArray[BUFFER] = {};

// Called from UART receive interrupt: 
/* Process commands from UART RX data
 * and return events with 33ms timeout */
while(GetCmd(BUFFER, (SYSTEM_CLOCK / 30)));


int
GetCmd(char *buffer, uint32_t timeout)
{
    static char *Cchar;
    Cchar = buffer;
    static uintptr_t i;
    int ret = 0;
    static uint32_t Timeout;

	/* Timeout for getting RXD FIFO bytes */
	for(Timeout = 0; Timeout < timeout; Timeout++)
	{
		/* Load RX data elements */
		for(i = 0; i < 32; i++)
		//while (len  != '\0')
		{
			//len = strlen(Cchar);
			/* Check if receiver is Not full, NonBlocking
			 * characters are received into FIFO */
			if(!(HWREG(UART2_BASE + UART_O_FR) & UART_FR_RXFE))
			{
				// Cchar[i] = UARTCharGetBlocking(UART2_BASE) & 0xFF;//
				Cchar[i] = (HWREG(UART2_BASE + UART_O_DR));

				/* FIFO not empty */
				ret = 1;
			}

			/* The RX FIFO is full */
			if (i >= 32)
			{
				/* Scan the argument buffer for commands
				 * and process only valid command/s */
				ret = CheckNexCommands();

				/* Playback the receiver buffer */
				UARTprintf(">>Playback RXD\n");
				i=0;
				while(i < 32)
				{
					/* System clock 8.33ns time, 208us delay */
					SysCtlDelay(SYSTEM_CLOCK / 4800);
					/* Print 0x70 return variable name */
					UARTprintf("Rx:%c :%x\n", CcRxBuff[i], CcRxBuff[i]);
					i++;
				}								
				
				return(ret);
			}
				/* Print 0x70 return variable name */
				UARTprintf("Rx:%c %x\n", Cchar[i], Cchar[i]);

				/* Scan the input buffer for commands
				 * Process valid command/s */
				ret = (CheckForCommands());
				
		}
	}

    return(ret);

}

  • BP101 said:
    Why are static variables not being initiated to 0x0 by C++ definition of a static variable? 

    Static variables like Cchar are part of an uninitialized output section named .bss.  Startup code, which comes from the TI RTS library, clears all the memory allocated to .bss. Do you use the startup code from the TI RTS library?

    BP101 said:
    Classic C++ method to initiate array cells via empty braces {} declaring are marked as error when compiled.

    I cannot reproduce that behavior.  For the source file that sees this error, please follow the directions in the article How to Submit a Compiler Test Case.

    Thanks and regards,

    -George

  • George Mock said:
    Static variables like Cchar are part of an uninitialized output section named .bss.  Startup code, which comes from the TI RTS library, clears all the memory allocated to .bss. Do you use the startup code from the TI RTS library?

    If you mean libc.a it is in the project include path and build paths tab, this is non-OS code. CCS debug of the array cell shows 0x0 on left side but has many other /xxx/ bytes shown, not sure where they came from other than memory address space during initialization.  Yet (static int)  is not being set to 0x0 when an array pointer. We must explicitly set static (int) to 0x0 or the passed contents from Cchar[i] are not started anywhere above cell 0x0 inside limited BUFFER space. Edit: rtsv7M4_T_le_v4SPD16_eabi.lib

    Recently discovered Cchar[i] in the (for) loop i=0 with #defined BUFFER cell pointer via (i) is not being reset 0x0 upon return to the (for) loop i=0. So the array cell contents of BUFFER are Not being incremented from  0x0 upon next call into function. So BUFFER is considered truncated in strings being passed to reads of BUFFER in other functions. IE: the passing data to another function via header (* dbyte) into BUFFER is not keeping contiguous with Cchar[I] cell loading, the cell pointer is not starting from 0x0 as it should each time for loop is initialized. 

  • I modified the code above post to produce the results shown in both captures of Cchar[I] and CcRxBuff[BUFFER].

    Other times the pointer may start from 0x0 in both the argument buffer in the called function from the passed char* from CcRxBuff[] . Yet when pointer into BUFFER is tested inside the function posted the printed CcRxBuff[] results are not re-started from I=0x0. However the results are often truncated after byte 16 of the UART FIFO being B2B read from UARTDR in read sensitive register C+ POP.

  • Hi George,

    Sorry for the delay have been bamboozled by this pointer bug for week or so.

    George Mock said:
    I cannot reproduce that behavior.  For the source file that sees this error, please follow the directions in the article How to Submit a Compiler Test Case.

    The global defined MyArry[BUFFER] = {} is not what I was referring to. The pointer of the global BUFFER in the function declarations that accesses the array via the header pass thorough. The declaration below should allow {} to initialize the Global buffer and may account for the array pointer Cchar[I] getting disconnected from the Global BUFFER cell floor?

  • George Mock said:
    Do you use the startup code from the TI RTS library?

    Correct the startup.ccs code does not seem to clear out all the array cells on far right only as 0x0. Yet startup.ccs .bss clear seems to leave odd data, debug shows "!\3102!\360\001" have no idea what all those bytes came from. Do suspect corruption of BUFFER  passed data into called function header (*buffer) is not what was or should have been received into global BUFFER.

    First few bytes are correct in argument array copied from global BUFFER, the other bytes are unknown data without the trailing '!' 0x21. Notice the inline printing of RX data is correct but not when BUFFER is replayed after bulk copy of contents via char* header passing. The top code if(i>32) loads buffer contents to caller shown below.

    Passing of BUFFER contents to called function does not and should not write into array cells of the caller as seems occurs during passing of char *. 

    iPStatus = CmdLineProcess(CcRxBuff);

      

  • Found the cause of array corruption.

    Second code example attempting to read contents of BUFFER via command s2 was writing into the array cells rather than pointing to them via = n. Warning "char" can  not be assigned to entity of type "char *" in 1st example. Yet the other code parts to convert hexadecimal to integers require "char" type, not "char *".

    Attempting to merge two individual RX array hex bytes and into integer string proves difficult. So much easier via machine language than C++. And atoi was subtracting 0x30, '0' from the hex strings, no warning with 1st C+ syntax below but not other clib.a calls for hex string conversions to integers. So I have added HexToChar() conversion is not compatible with array char type pointer value being the physical cell number.

    What to do as WA to make this work?

    static char *hextoint0 = 0;
    static char *hextoint1 = 0;
    static int int0 = 0;		
    
    /* Get the arguments */
    hextoint0 = CcRxBuff[6]; // Warning cannot "char" to type "char *"
    hextoint1 = CcRxBuff[7]; // Warning cannot "char" to type "char *"
    strncat(hextoint0, hextoint1, 2);
    /* Convert char to integer */
    int0 = HexToDec(hextoint0);
    
    // Other method fails to make "char *"
    
    /* Get the arguments */
    *hextoint0 = CcRxBuff[6]; // Causes MCU repeating reset
    *hextoint1 = CcRxBuff[7]; // Causes MCU repeating reset
    strncat(hextoint0, hextoint1, 2);
    /* Convert char to integer */
    int0 = HexToDec(hextoint0);
  • I rewrote the HexToDec() so it did not require passing a pointer char*. Then strncat() would not compile (char type warning) 86 it out of equation.

    The MCU resets was caused from char* = CcRxBuff[n]  and stopped after hextointN = CcRxBuff[N]. So attempting to pass the array pointer *hextointN into strncat() caused MCU resets.

    Atoi() does not correctly convert hexadecimal values into integers since it assumes they are ASCii char and subtracts 0x30. 

    How does the ANSI C standards (libc.a) handle NonASCii hexadecimal to integer conversions? It would seem TI has a way to convert 2 byte wide hexadecimal strings UART data from the outside world back into integers?

  • BP101 said:
    Atoi() does not correctly convert hexadecimal values into integers

    By hexadecimal values I presume you mean strings of ASCII characters that, when taken as a whole, represent values written with base-16 (also called hexadecimal) digits.  Examples would include: "1234", "abcdef", "ba9876", and so on.  You cannot convert such strings with atoi.  Instead, use strtol or strtoul.  Note TI documentation does not cover standard RTS functions like these.  Please learn about them in your preferred book, website, etc. on the C programming language.

    Thanks and regards,

    -George