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.
First my apologies... I think this is such a basic question and I should know the answer already, but I don't.
How can I check memory usage? I would like to know about general memory, where all my RAM variables are, and I would also like to know about the stack. I'm having a very strange problem, and I don't think it has to do with variables passed into a function, but how do I know all that is working?
Thanks very much.
Hi,
I will use an example to show where the variables are stored. I will use pwm_invert example in C:\ti\TivaWare_C_Series-2.2.0.295\examples\boards\ek-tm4c1294xl\pwm_invert but you can pick any example.
If you look at the source code, you will find a global variable g_ui32SysClock. Where would this global variable reside? There are two ways to find the address of this variable. First method is view this global variable in the expression window. The second method is through the .map file. In the .map file, you will find all information about where in memory variables and functions are located. A map file is a table of symbols, their locations and their size. You can find the map file in the Debug directory of the project. See below where g_ui32SysClock is stored at the address 0x20000208.
If you have local variables declared inside a function then they will be stored on the stack. The map file will tell where the stack is stored in the memory. Below is a snippet of the map file and the linker command file. As you can see the stack starts at 0x20000000. The __STACK_TOP is at 0x20000200. The size of the stack is 512 bytes which is equal to 0x200. The size of the stack is defined in the linker command file.
****************************************************************************** TI ARM Linker PC v18.12.0 ****************************************************************************** >> Linked Tue Mar 5 08:35:22 2024 OUTPUT FILE NAME: <pwm_invert.out> ENTRY POINT SYMBOL: "_c_int00_noargs" address: 00000c7d MEMORY CONFIGURATION name origin length used unused attr fill ---------------------- -------- --------- -------- -------- ---- -------- FLASH 00000000 00100000 00000fde 000ff022 R X SRAM 20000000 00040000 00000209 0003fdf7 RW X SEGMENT ALLOCATION MAP run origin load origin length init length attrs members ---------- ----------- ---------- ----------- ----- ------- 00000000 00000000 00000fe0 00000fe0 r-x 00000000 00000000 00000200 00000200 r-- .intvecs 00000200 00000200 00000b2a 00000b2a r-x .text 00000d2c 00000d2c 00000284 00000284 r-- .const 00000fb0 00000fb0 00000030 00000030 r-- .cinit 20000000 20000000 0000020c 00000000 rw- 20000000 20000000 00000200 00000000 rw- .stack 20000200 20000200 00000005 00000000 rw- .data 20000208 20000208 00000004 00000000 rw- .bss SECTION ALLOCATION MAP output attributes/ section page origin length input sections -------- ---- ---------- ---------- ---------------- .intvecs 0 00000000 00000200 00000000 00000200 startup_ccs.obj (.intvecs) .text 0 00000200 00000b2a 00000200 0000030c uartstdio.obj (.text:UARTvprintf) 0000050c 00000260 pwm_invert.obj (.text:main) 0000076c 00000200 driverlib.lib : sysctl.obj (.text:SysCtlClockFreqSet) 0000096c 0000009c rtsv7M4_T_le_v4SPD16_eabi.lib : memcpy_t2.asm.obj (.text) 00000a08 00000074 uartstdio.obj (.text:UARTStdioConfig) 00000a7c 00000068 pwm_invert.obj (.text:ConfigureUART) 00000ae4 00000068 rtsv7M4_T_le_v4SPD16_eabi.lib : copy_decompress_lzss.c.obj (.text:decompress:lzss:__TI_decompress_lzss) 00000b4c 00000064 uartstdio.obj (.text:UARTwrite) 00000bb0 00000048 driverlib.lib : sysctl.obj (.text:_SysCtlFrequencyGet) 00000bf8 00000044 rtsv7M4_T_le_v4SPD16_eabi.lib : autoinit.c.obj (.text:__TI_auto_init_nobinit_nopinit:__TI_auto_init_nobinit_nopinit) 00000c3c 00000040 : u_divt2.asm.obj (.text) 00000c7c 00000034 : boot_cortex_m.c.obj (.text:_c_int00_noargs:_c_int00_noargs) 00000cb0 00000024 uartstdio.obj (.text:UARTprintf) 00000cd4 00000020 driverlib.lib : sysctl.obj (.text:_SysCtlMemTimingGet) 00000cf4 00000012 rtsv7M4_T_le_v4SPD16_eabi.lib : copy_zero_init.c.obj (.text:decompress:ZI:__TI_zero_init_nomemset:__TI_zero_init_nomemset) 00000d06 0000000e : copy_decompress_none.c.obj (.text:decompress:none:__TI_decompress_none) 00000d14 00000006 startup_ccs.obj (.text:ResetISR) 00000d1a 00000004 rtsv7M4_T_le_v4SPD16_eabi.lib : pre_init.c.obj (.text:_system_pre_init) 00000d1e 00000004 : exit.c.obj (.text:abort:abort) 00000d22 00000002 startup_ccs.obj (.text:FaultISR) 00000d24 00000002 startup_ccs.obj (.text:IntDefaultHandler) 00000d26 00000002 startup_ccs.obj (.text:NmiSR) 00000d28 00000002 rtsv7M4_T_le_v4SPD16_eabi.lib : div0.asm.obj (.text) .const 0 00000d2c 00000284 00000d2c 000001b0 driverlib.lib : sysctl.obj (.const:g_pppui32XTALtoVCO) 00000edc 0000006c : sysctl.obj (.const:g_pui32Xtals) 00000f48 00000030 : sysctl.obj (.const:g_sXTALtoMEMTIM) 00000f78 00000012 uartstdio.obj (.const:.string) 00000f8a 00000002 --HOLE-- [fill = 0] 00000f8c 0000000c uartstdio.obj (.const:g_ui32UARTBase) 00000f98 0000000c uartstdio.obj (.const:g_ui32UARTPeriph) 00000fa4 00000008 driverlib.lib : sysctl.obj (.const:g_pui32VCOFrequencies) 00000fac 00000004 uartstdio.obj (.const) .cinit 0 00000fb0 00000030 00000fb0 0000000c (__TI_handler_table) 00000fbc 00000004 --HOLE-- [fill = 0] 00000fc0 00000008 (.cinit..bss.load) [load image, compression = zero_init] 00000fc8 00000007 (.cinit..data.load) [load image, compression = lzss] 00000fcf 00000001 --HOLE-- [fill = 0] 00000fd0 00000010 (__TI_cinit_table) .init_array * 0 00000000 00000000 UNINITIALIZED .data 0 20000200 00000005 UNINITIALIZED 20000200 00000005 uartstdio.obj (.data) .bss 0 20000208 00000004 UNINITIALIZED 20000208 00000004 (.common:g_ui32SysClock) .stack 0 20000000 00000200 UNINITIALIZED 20000000 00000004 rtsv7M4_T_le_v4SPD16_eabi.lib : boot_cortex_m.c.obj (.stack) 20000004 000001fc --HOLE-- .binit 0 00000000 00000000 MODULE SUMMARY Module code ro data rw data ------ ---- ------- ------- .\ pwm_invert.obj 712 0 4 startup_ccs.obj 12 512 0 +--+----------------------------+------+---------+---------+ Total: 724 512 4 .\utils\ uartstdio.obj 1032 46 5 +--+----------------------------+------+---------+---------+ Total: 1032 46 5 C:/ti/TivaWare_C_Series-2.2.0.295/driverlib/ccs/Debug/driverlib.lib sysctl.obj 616 596 0 +--+----------------------------+------+---------+---------+ Total: 616 596 0 C:\ti\ccs1011\ccs\tools\compiler\ti_cgt-arm_18.12.0.LTS\lib\rtsv7M4_T_le_v4SPD16_eabi.lib memcpy_t2.asm.obj 156 0 0 copy_decompress_lzss.c.obj 104 0 0 autoinit.c.obj 68 0 0 u_divt2.asm.obj 64 0 0 boot_cortex_m.c.obj 52 0 0 copy_zero_init.c.obj 18 0 0 copy_decompress_none.c.obj 14 0 0 exit.c.obj 4 0 0 pre_init.c.obj 4 0 0 div0.asm.obj 2 0 0 +--+----------------------------+------+---------+---------+ Total: 486 0 0 Stack: 0 0 512 Linker Generated: 0 43 0 +--+----------------------------+------+---------+---------+ Grand Total: 2858 1197 521 LINKER GENERATED COPY TABLES __TI_cinit_table @ 00000fd0 records: 2, size/record: 8, table size: 16 .bss: load addr=00000fc0, load size=00000008 bytes, run addr=20000208, run size=00000004 bytes, compression=zero_init .data: load addr=00000fc8, load size=00000007 bytes, run addr=20000200, run size=00000005 bytes, compression=lzss LINKER GENERATED HANDLER TABLE __TI_handler_table @ 00000fb0 records: 3, size/record: 4, table size: 12 index: 0, handler: __TI_decompress_lzss index: 1, handler: __TI_decompress_none index: 2, handler: __TI_zero_init GLOBAL SYMBOLS: SORTED ALPHABETICALLY BY Name address name ------- ---- 00000d1f C$$EXIT 00000a7d ConfigureUART 00000d15 ResetISR 0000076d SysCtlClockFreqSet 00000a09 UARTStdioConfig 00000cb1 UARTprintf 00000201 UARTvprintf 00000b4d UARTwrite 20000200 __STACK_END 00000200 __STACK_SIZE 20000200 __STACK_TOP 00000fd0 __TI_CINIT_Base 00000fe0 __TI_CINIT_Limit 00000fb0 __TI_Handler_Table_Base 00000fbc __TI_Handler_Table_Limit 00000bf9 __TI_auto_init_nobinit_nopinit 00000ae5 __TI_decompress_lzss 00000d07 __TI_decompress_none ffffffff __TI_pprof_out_hndl ffffffff __TI_prof_data_size ffffffff __TI_prof_data_start 00000000 __TI_static_base__ 00000cf5 __TI_zero_init_nomemset 00000d29 __aeabi_idiv0 00000d29 __aeabi_ldiv0 0000096d __aeabi_memcpy 0000096d __aeabi_memcpy4 0000096d __aeabi_memcpy8 00000c3d __aeabi_uidiv 00000c3d __aeabi_uidivmod ffffffff __binit__ ffffffff __c_args__ UNDEFED __mpu_init 20000000 __stack 00000c7d _c_int00_noargs UNDEFED _system_post_cinit 00000d1b _system_pre_init 00000d1f abort ffffffff binit 00000000 g_pfnVectors 20000208 g_ui32SysClock 0000050d main 0000096d memcpy GLOBAL SYMBOLS: SORTED BY Symbol Address address name ------- ---- 00000000 __TI_static_base__ 00000000 g_pfnVectors 00000200 __STACK_SIZE 00000201 UARTvprintf 0000050d main 0000076d SysCtlClockFreqSet 0000096d __aeabi_memcpy 0000096d __aeabi_memcpy4 0000096d __aeabi_memcpy8 0000096d memcpy 00000a09 UARTStdioConfig 00000a7d ConfigureUART 00000ae5 __TI_decompress_lzss 00000b4d UARTwrite 00000bf9 __TI_auto_init_nobinit_nopinit 00000c3d __aeabi_uidiv 00000c3d __aeabi_uidivmod 00000c7d _c_int00_noargs 00000cb1 UARTprintf 00000cf5 __TI_zero_init_nomemset 00000d07 __TI_decompress_none 00000d15 ResetISR 00000d1b _system_pre_init 00000d1f C$$EXIT 00000d1f abort 00000d29 __aeabi_idiv0 00000d29 __aeabi_ldiv0 00000fb0 __TI_Handler_Table_Base 00000fbc __TI_Handler_Table_Limit 00000fd0 __TI_CINIT_Base 00000fe0 __TI_CINIT_Limit 20000000 __stack 20000200 __STACK_END 20000200 __STACK_TOP 20000208 g_ui32SysClock ffffffff __TI_pprof_out_hndl ffffffff __TI_prof_data_size ffffffff __TI_prof_data_start ffffffff __binit__ ffffffff __c_args__ ffffffff binit UNDEFED __mpu_init UNDEFED _system_post_cinit [43 symbols]
--retain=g_pfnVectors /* The following command line options are set as part of the CCS project. */ /* If you are building using the command line, or for some reason want to */ /* define them here, you can uncomment and modify these lines as needed. */ /* If you are using CCS for building, it is probably better to make any such */ /* modifications in your CCS project and leave this file alone. */ /* */ /* --heap_size=0 */ /* --stack_size=256 */ /* --library=rtsv7M3_T_le_eabi.lib */ /* The starting address of the application. Normally the interrupt vectors */ /* must be located at the beginning of the application. */ #define APP_BASE 0x00000000 #define RAM_BASE 0x20000000 /* System memory map */ MEMORY { /* Application stored in and executes from internal flash */ FLASH (RX) : origin = APP_BASE, length = 0x00100000 /* Application uses internal RAM for data */ SRAM (RWX) : origin = 0x20000000, length = 0x00040000 } /* Section allocation in memory */ SECTIONS { .intvecs: > APP_BASE .text : > FLASH .const : > FLASH .cinit : > FLASH .pinit : > FLASH .init_array : > FLASH .vtable : > RAM_BASE .data : > SRAM .bss : > SRAM .sysmem : > SRAM .stack : > SRAM #ifdef __TI_COMPILER_VERSION__ #if __TI_COMPILER_VERSION__ >= 15009000 .TI.ramfunc : {} load=FLASH, run=SRAM, table(BINIT) #endif #endif } __STACK_TOP = __stack + 512;
Thank you very, very much. I will look at this in more detail soon. Before I make a reply as to this resolving my issue, can you go just one step further and clarify specifically how I would know if I'm running out of room in RAM (too many variables, arrays, etc.)?
I have more global variables than local variables, so I think I'm hardly using the stack. Measuring stack depth at run time must be an entirely different subject.
Hi,
how I would know if I'm running out of room in RAM (too many variables, arrays, etc.)?
If you are running out of room in RAM (there is 256kB of RAM on this device) then you wouldn't be able to compile your project. During compile/link time, you would have seen an error message that says insufficient RAM. If you are talking about dynamic memory allocation using malloc then that is a different story. But malloc should fail during allocation because you will get a NULL pointer.
Again, refer to the map file. The map file will tell you how much RAM is used. See below example.
Should I be concerned about a stack usage of 1,444? The line is showing yellow.
Please take a look at this thread answered by Ki about the inclusive stack. https://e2e.ti.com/support/wireless-connectivity/sub-1-ghz-group/sub-1-ghz/f/sub-1-ghz-forum/980863/cc1312r-stack-usage-in-ccs-10
Also check your .cmd file if you have allocated enough stack for it.