Hi,
I'm using a linkerscript file that I borrowed from another project.
MEMORY
{
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 256K
RAM (rwx) : ORIGIN = 0x1FFFF800, LENGTH = 8K
}
So far my applications haven't used much memory, so the 'artifical' limit of 8KB RAM isn't an issue (the device has 32KB), but I'd like to make the linkerscript reflect reality.
Is this correct for the MKL27Z256:
MEMORY
{
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 256K
RAM (rwx) : ORIGIN = 0x1FFFFE00, LENGTH = 32K
}
Does my code need to be aware of the split in the SRAM? If it does, should I set my RAM ORIGIN to be 0x2000_0000 and have a size of 24K?
Solved! Go to Solution.
Hi Joey Gouly
SRAM is divided into 2 Blocks, 1/4 is allocated SRAM_L and 3/4 is allocated to SRAM_U, in this case is from 0x1FFFE000 to 0x1FFFFFFF and from 0x20000000 to 0x200005FFF. Problem here is when any object is stored sharing both sections, if this case occurs, we need to modify linker file to allocate a dummy section/variable in this limit to avoid any crashing due SRAM access.
This characteristic is because they are accessed from different buses (and sometimes their power supply are from difference sources) so we have to be sure that any object (variable, structure) is not stored by overlapping both sections, for example, next image shows a scenario where a 32-bit variable is stored between these blocks:
In this case, there would be an access problem and program would crash.
I recommend you to check this this post to find more information about RAM sizes and how to kill this size limit:
https://mcuoneclipse.com/2013/07/10/freertos-heap-with-segmented-kinetis-k-sram/
How to kill the memory size limit for the variable?
Have a great day,
Jorge Alcala
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Thanks for the discussions, I have more understanding about the SRAM_L and SRAM_U.
Thanks,
All,
just to add what I am missing here.
The main reason for spliting SRAM to SRAM_L and SRAM_U was that Cortex M4 is accesing these two separated memories by separated buses. To allow simultaneous e.g. fetch the instruction (on SRAM_L) with data access (on SRAM_U) - Harvard architecture.
Cortex M3/M4
SRAM_L memory is placed in CODE memory region which is accesible by CODE bus. The Coretx M3/M4 cores can fetch the instruction / access data from this region without penalty (CODE bus is father split into the I-CODE and D-CODE bus). If core request to fetch the instruction the I-CODE is switched to CODE bus, if data access is requested by core then D-CODE is switched to CODE bus. NOTE: D-CODE bus has higher priority on switch when simultaneous requests occurs.
SRAM_U memory is placed in SRAM memory region which is accessible by SYSTEM bus (primarily designed for data access, code execution from this region is possible but at the expense of 1 wait state due to buses synchronization).
When there is a variable defined at the boundary of both CODE/SRAM regions then core does not know how to access this variable (part is accesssible by CODE bus and part by SYSTEM bus). Hence fault is generated.
Cortex M0/M0+
has von Neumann architecture. Hence both memory regions are accessible by the same SYSTEM bus. No problem should appear. However, most probably because of compatibility the SRAM is split into the lower and upper part.
regards
R.
Hi Joey Gouly
SRAM is divided into 2 Blocks, 1/4 is allocated SRAM_L and 3/4 is allocated to SRAM_U, in this case is from 0x1FFFE000 to 0x1FFFFFFF and from 0x20000000 to 0x200005FFF. Problem here is when any object is stored sharing both sections, if this case occurs, we need to modify linker file to allocate a dummy section/variable in this limit to avoid any crashing due SRAM access.
This characteristic is because they are accessed from different buses (and sometimes their power supply are from difference sources) so we have to be sure that any object (variable, structure) is not stored by overlapping both sections, for example, next image shows a scenario where a 32-bit variable is stored between these blocks:
In this case, there would be an access problem and program would crash.
I recommend you to check this this post to find more information about RAM sizes and how to kill this size limit:
https://mcuoneclipse.com/2013/07/10/freertos-heap-with-segmented-kinetis-k-sram/
How to kill the memory size limit for the variable?
Have a great day,
Jorge Alcala
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Hi Joey and Jorge,
Actually since you're talking about an L series device, the split doesn't mean anything and RAM (SRAM_L and SRAM_U) could be treated as one contiguous block. The split is just a remnant of legacy code (i.e., it's there because that's just what we had always done), specifically from K series devices which operate a little differently from L series devices.
Now, the split did originate and HAS MEANING for K series devices (and other M4 devices) as the M4 operates a little differently. For the K series, what Jorge mentions is exactly correct. You can "crash the system" if a misaligned access occurs across the boundary (which can be tricky to find and cause you lots of grief). In addition, for the K series devices, SRAM_L is optimized for code while SRAM_U is meant for data. If code is placed in SRAM_U, it will still run but at a penalty, so slightly slower than if it were placed in SRAM_L. There might also be a penalty for accessing data that might be placed in SRAM_L but I'm not 100% certain of that. The L series devices do not have this configuration and thus, memory could be treated as one contiguous block.
Regards,
Chris
Thanks for those links!
Since I don't need high RAM usage, I'm just going to define my RAM to be SRAM_U only, at 24 KB.
So far I've been using 8 KB without issue!
Thanks,
Joey