LPC1778 On Chip SRAM

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

LPC1778 On Chip SRAM

1,472 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by arion2001 on Wed Feb 11 00:27:07 MST 2015
Hi,

I am trying to understand the reason when you declare a variable on a compiler while talking to LPC1778 the SRAM memory range that it went to is the on-chip SRAM address 0x2000 0000 but not 0x1000 0000.

I was doing a simple function to observe the result. The address value that I obtained on the variable Pass_Value is on the 0x2000 0000 range. My understanding was that I thought it should have been on the main on chip SRAM(address starts from 0x1000 0000) but that is not so. Did I understand things incorrectly here? Is it possible to make it write to the 0x1000 0000 address range? The size there is significantly larger.
The memory map is shown on the attached file. The memory map result picture shows the result of what I did.

unsigned char Casting(unsigned long input)
{

  unsigned char Pass_Value = 0;  
  Passing(&Pass_Value);
  return 0;

}

void Passing(unsigned char *Pass_Value)
{   
  DQRead_Addr =  Pass_Value; 
  return 0;
}


Labels (1)
0 Kudos
4 Replies

1,387 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by nerd herd on Thu Feb 12 11:00:13 MST 2015
Hi arion2001,

Where a variable gets declared is completely independent of the device itself and is based on the compiler and linker script. Every IDE has its own version of a linker script and the syntax inside it and unfortunately we do not support Crossworks.

Is it possible for you to download our free LPCXpresso IDE and LPCOpen software platform to explore this further?
0 Kudos

1,387 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by arion2001 on Wed Feb 11 21:21:14 MST 2015
Hi guys,

Thanks for the reply. I am using Crossworks Rowley compiler for the time being.

Well the linker only tells you the where but does not explain the why. Also could you kindly point out what you stated in the linker file that explains what is it I am looking for?

Here is some of the snippet I extracted from the linker file:
.bss            0x10001014      0x89c
                0x10001014                __bss_start__ = .
 *(.bss .bss.* .gnu.linkonce.b.*)
 .bss.main_task
                0x10001014       0x2c THUMB Flash Debug/main_ctl.o
                0x10001014                main_task
 .bss.new_task  0x10001040       0x2c THUMB Flash Debug/main_ctl.o
                0x10001040                new_task
 .bss.new_task_stack
                0x1000106c      0x808 THUMB Flash Debug/main_ctl.o
                0x1000106c                new_task_stack
 .bss.new_address
                0x10001874        0x4 THUMB Flash Debug/Memory_Op.o
                0x10001874                new_address
 .bss.DQRead_Addr
                0x10001878        0x4 THUMB Flash Debug/Memory_Op.o
                0x10001878                DQRead_Addr
 .bss.PollingStat
                0x1000187c        0x1 THUMB Flash Debug/Memory_Op.o
                0x1000187c                PollingStat
 *fill*         0x1000187d        0x1 00
 .bss.Read_1    0x1000187e        0x2 THUMB Flash Debug/Memory_Op.o
                0x1000187e                Read_1
 .bss.Read_2    0x10001880        0x2 THUMB Flash Debug/Memory_Op.o
                0x10001880                Read_2
 .bss.Read_3    0x10001882        0x2 THUMB Flash Debug/Memory_Op.o
                0x10001882                Read_3
 .bss.userTimerISR


heap           0x20000000       0x80
                0x20000000                __heap_start__ = .
 *(.heap .heap.*)
                0x20000080                . = ALIGN (MAX ((__heap_start__ + __HEAPSIZE__), .), 0x4)
 *fill*         0x20000000       0x80 00
                0x20000080                __heap_end__ = (__heap_start__ + SIZEOF (.heap))
                0x20000080                __heap_load_end__ = __heap_end__
                0x00000001                . = ASSERT (((__heap_end__ >= __AHBSRAM_segment_start__) && (__heap_end__ <= __AHBSRAM_segment_end__)), error: .heap is too large to fit in AHBSRAM memory segment)
                0x20000080                __stack_load_start__ = ALIGN (__heap_end__, 0x4)

.stack          0x20000080       0x80
                0x20000080                __stack_start__ = .
 *(.stack .stack.*)
                0x20000100                . = ALIGN (MAX ((__stack_start__ + __STACKSIZE__), .), 0x4)
 *fill*         0x20000080       0x80 00
                0x20000100                __stack_end__ = (__stack_start__ + SIZEOF (.stack))
                0x20000100                __stack_load_end__ = __stack_end__
                0x00000001                . = ASSERT (((__stack_end__ >= __AHBSRAM_segment_start__) && (__stack_end__ <= __AHBSRAM_segment_end__)), error: .stack is too large to fit in AHBSRAM memory segment)
                0x20000100                __stack_process_load_start__ = ALIGN (__stack_end__, 0x4)

.stack_process  0x20000100        0x0
                0x20000100                __stack_process_start__ = .
 *(.stack_process .stack_process.*)
                0x20000100                . = ALIGN (MAX ((__stack_process_start__ + __STACKSIZE_PROCESS__), .), 0x4)
                0x20000100                __stack_process_end__ = (__stack_process_start__ + SIZEOF (.stack_process))
                0x20000100                __stack_process_load_end__ = __stack_process_end__
                0x20000100                __AHBSRAM_segment_used_end__ = (ALIGN (__stack_end__, 0x4) + SIZEOF (.stack_process))


What I discovered is that, when you declare a local variable of a function in the compiler your variable are stored in address range of 0x2000 0000 which belongs to the peripheral. Whereas if a global variable is declared, it goes to the address range of 0x1000 0000. In the snippet I posted, the variables Read_1, Read_2 and Read_3 are global variables. My question would be, is this how the architecture of LPC1778 is defined to be? How do I recognize it and understand where my information is going through the spec/manual? Or do I need to experiment with it to clarify this understanding?

The reason I ask this question is because, initially the pre-conceived notion/understanding I had when writting a program was that they are stored on a heap, and since the way the manual is written mentioned that range 0x2000 0000 is typically used for peripheral data, one would think that your variables be it global or local would be stored in another heap location maybe the main on-chip which is 0x1000 0000. Turns out that was not exactly correct.
0 Kudos

1,387 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by nerd herd on Wed Feb 11 09:54:00 MST 2015
Hi arion2001,

Like wmues mentioned, the linker script is usually the IDE proprietary file that indicates the different memory regions for the target MCU and project you are working on. Usually IDEs have a GUI interface to make simple changes without having the user bother with editing the linker script them self.

I noticed you are a different IDE than the three NXP supports, as well as an older CMSIS based project. In case you did not know, we have a software platform called LPCOpen which contains an assortment of different sample software examples supported specific evaluation boards and on the three IDEs we support (Keil uVision, IAR EWARM, and our in-house free LPCXpresso). Here's a link if you are interested:

http://www.lpcware.com/content/nxpfile/lpcopen-software-development-platform-lpc17xx-packages

Using these software packages as the base of your project makes it easier for us to support you in case you have more questions in the future. :)
0 Kudos

1,387 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by wmues on Wed Feb 11 09:21:15 MST 2015
The memory locations are set up in your linker script.

Very easy to change this.

regards
Wolfgang
0 Kudos