Best way to deal with split RAM configuration on Kinetis K series?

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

Best way to deal with split RAM configuration on Kinetis K series?

1,231 Views
scottm
Senior Contributor II

I discovered the hard way that the Kinetis K series parts I'm using (K22FN1M0 and K22DX256) have two banks of RAM and that objects can't span banks.

The default linker file creates two memory regions:

  m_data      (RW) : ORIGIN = 0x1FFFC000, LENGTH = 0x00004000

  m_data_20000000 (RW) : ORIGIN = 0x20000000, LENGTH = 0x00004000

It's apparently left to the user to manually place objects in the .m_data_20000000 section to make use of the second bank.  I can certainly do that, but the same application code is used across two different Kinetis MCUs and one ColdFire MCU.  I'd rather not have to explicitly place everything in the linker file or have to add macros to the code for section placement.

It seems like a simple solution ought to be to place a dummy variable at the boundary.  Is there a down side to doing this?  What's the easiest way to do this with the GNU linker?  I'm not running any code from RAM (bootloader pieces notwithstanding) so performance isn't a concern.

Thanks,

Scott

0 Kudos
4 Replies

612 Views
mjbcswitzerland
Specialist V

Scott

You can see this and its discussion thread:

http://mcuoneclipse.com/2013/07/10/freertos-heap-with-segmented-kinetis-k-sram/

Practically you shouldn't have any problem with objects as long as they are correctly aligned. The only exception being if you are doing burst DMA transfers across the boundary, in which case there may be an involved object (memoy area) that needs to be controlled to a certain area.

In fact I have worked with around 60 different Kinetis parts to date and been involved with around 100 developments projects (with developer or consultant role) and have never encountered a case where the segmentation actually needed to be "specifically" controlled.

In case you are using unnaturally aligned object accesses it is worth avoiding it anyway since it is less efficient for the Cortex-M4 HW (and Coldfire), plus it will fail also on Cortex-M0+ parts (non-portable) since the HW generally doesn't support such accesses.

Regards

Mark

0 Kudos

612 Views
scottm
Senior Contributor II

I did see that thread, but since I'm not using heap, that particular workaround didn't help me.

The object that was causing me trouble was indeed a buffer for a DMA transfer (specifically for the I2S peripheral) but I don't think it even got as far as the start of the DMA transfer - presumably because it's filling 24-bit frames using unaligned writes.  I don't think there's a good way around that but it's not a major impact on the performance.

Maybe I'll create a section before the expanded m_data section for manual placement.  m_data has all of the wildcards and I'd prefer to keep the manual placement as clean as possible.

Thanks,

Scott

0 Kudos

612 Views
mjbcswitzerland
Specialist V

Scott

Are you sure that you have a problem with split-RAM or just that the DMA alignment is a problem?

Although the Cortex M4 core can read/write misaligned addresses the DMA has to be aligned correctly otherwise it will fail. Eg. If you are performing 32 bit transfers ensure that they are all 32 bit aligned (if the DMA doesn't occur, check its error register to see whether it aborted due to something like this).

If you do find that the buffer is straddling the spit RAM it is simpest to leave an area free before the start of m_data which code can use for fixed buffers (addressed by code in the memory map using something like unsigned long *ptrBuf = (unsigned long *)(START_OF_RAM);

where START_OF_RAM is 0x1FFFC000 for your chip.

This avoids the actual C code having to use sections or pragmas which are not compatible with other compilers - only the linker script needs to be modified to keep enough free RAM to be used before its own variables are located.

This is also explained on page 25 of http://www.utasker.com/docs/uTasker/USB_User_Guide.PDF, which is specifically for locating USB buffers on the Coldfire but equally relevant for Kinetis and general buffers.

Regards

Mark

0 Kudos

612 Views
scottm
Senior Contributor II

It wasn't getting as far as the start of the DMA transfer, so I'm fairly certain the hardfault was being triggered by the code filling the buffer.  For now I've manually placed the buffer and another large object or two in m_data_20000000.  My concerns now are mostly stylistic.  For years I've maintained code that was shared between at least 3 different HC(S)08 parts and later a ColdFire part and the code got full of macros to handle things like differing zero page sizes.  I've been very pleased so far with the clean separation I've been able to maintain between the application code and the hardware-specific parts of this project.

0 Kudos