I bought TWR-MEM module. Are DVD contain code examples for MRAM use with K60? If No, where I can get code examples?
Solved! Go to Solution.
Hi Evgeni,
it depends on what you want to do with Flexbus if you need to edit linker file or not.
- If you want to execute code from external MRAM or you need to reference specific data variables then you need to edit linker file.
- If you want just to save raw data it is not necessary to edit linker file.
You may find useful the following documents.
Relocating Code and Data Using the CW GCC Linker File for Kinetis
Relocating Code and Data Using the KDS GCC Linker File for Kinetis
Regarding the pinout. Please let me know where you find the different configurations. I did not get this part.
Best regards,
Carlos
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Hello Evgeni,
please take a look on the Flexbus examples I attached to this post FlexBus in 16 bit mode and 8 bit access
They are usingK60 and K70 with CW and KDS. Some of the examples use TWR.MEM. They have also a document explaining the examples.
Regards,
Carlos
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Hi Carlos.
Thanks for your response.
In FlexBus code examples I can view that MEM FlexBus use is very simple. But from this view I have the next question:
Up to this time I used with Tower K60ND512 and K60FN MCUs. Are I need to use K60FX MCU for MEM FlexBus? If 'YES', how can I update MCU type into already worked project from ND or FN to FX type? There are any reference for change MCU type (from K40 to K60 for example) for Kinetis MCUs?
Are I need to change/update linker file?
Thanks.
Evgeni.
Hi Evgeni,
regarding to the usage of of K60FN and K60FX. For this specific case you can use ony of them. K60FX features flex memory and K60FN does not, but this is a feature completely apart and it has no relation on using TWR-MEM with Flexbus.
Regarding to the porting form K40 to K60, I strongly recommend to create a brand new project for K60 and copy/add all your source files. This is the cleanest way to port a project and the way the experts recommend us to do it.
You can take this specific Flexbus configuration from K40 to K60 and it should work.
Best regards,
Carlos
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Hi Carlos.
Thanks for your answer.
1) Are I need to change/update K60 linker file for MRAM operations or enough only HW port and GPIO initialisation?
2) I see different pinout configuration in your link example (AN4393.pdf) and datasheet "Using FlexBus Interface for Kinetis Microcontrollers" (that described later). What condition for select one from them or use as described in "Using FlexBus Interface ..."?
"Using FlexBus Interface for Kinetis Microcontrollers" example:
// HW initialisation
// Enable the clock to the FlexBus
SIM_SCGC7 |= SIM_SCGC7_FLEXBUS_MASK;
// FlexBus Clock not divided
SIM_CLKDIV1 |= SIM_CLKDIV1_OUTDIV3(0x0);
// Set the GPIO ports clocks
SIM_SCGC5 = SIM_SCGC5_PORTA_MASK | SIM_SCGC5_PORTB_MASK | SIM_SCGC5_PORTC_MASK |
SIM_SCGC5_PORTD_MASK | SIM_SCGC5_PORTE_MASK;
PORTB_PCR11 = PORT_PCR_MUX(5); // fb_ad[18]
PORTB_PCR16 = PORT_PCR_MUX(5); // fb_ad[17]
PORTB_PCR17 = PORT_PCR_MUX(5); // fb_ad[16]
PORTB_PCR18 = PORT_PCR_MUX(5); // fb_ad[15]
PORTC_PCR0 = PORT_PCR_MUX(5); // fb_ad[14]
PORTC_PCR1 = PORT_PCR_MUX(5); // fb_ad[13]
PORTC_PCR2 = PORT_PCR_MUX(5); // fb_ad[12]
PORTC_PCR4 = PORT_PCR_MUX(5); // fb_ad[11]
PORTC_PCR5 = PORT_PCR_MUX(5); // fb_ad[10]
PORTC_PCR6 = PORT_PCR_MUX(5); // fb_ad[9]
PORTC_PCR7 = PORT_PCR_MUX(5); // fb_ad[8]
PORTC_PCR8 = PORT_PCR_MUX(5); // fb_ad[7]
PORTC_PCR9 = PORT_PCR_MUX(5); // fb_ad[6]
PORTC_PCR10 = PORT_PCR_MUX(5); // fb_ad[5]
PORTD_PCR2 = PORT_PCR_MUX(5); // fb_ad[4]
PORTD_PCR3 = PORT_PCR_MUX(5); // fb_ad[3]
PORTD_PCR4 = PORT_PCR_MUX(5); // fb_ad[2]
PORTD_PCR5 = PORT_PCR_MUX(5); // fb_ad[1]
PORTD_PCR6 = PORT_PCR_MUX(5); // fb_ad[0]
PORTB_PCR20 = PORT_PCR_MUX(5); // fb_ad[31] used as d[7]
PORTB_PCR21 = PORT_PCR_MUX(5); // fb_ad[30] used as d[6]
PORTB_PCR22 = PORT_PCR_MUX(5); // fb_ad[29] used as d[5]
PORTB_PCR23 = PORT_PCR_MUX(5); // fb_ad[28] used as d[4]
PORTC_PCR12 = PORT_PCR_MUX(5); // fb_ad[27] used as d[3]
PORTC_PCR13 = PORT_PCR_MUX(5); // fb_ad[26] used as d[2]
PORTC_PCR14 = PORT_PCR_MUX(5); // fb_ad[25] used as d[1]
PORTC_PCR15 = PORT_PCR_MUX(5); // fb_ad[24] used as d[0]
PORTB_PCR19 = PORT_PCR_MUX(5); // fb_oe_b
PORTC_PCR11 = PORT_PCR_MUX(5); // fb_rw_b
PORTD_PCR1 = PORT_PCR_MUX(5); // fb_cs0_b
PORTD_PCR0 = PORT_PCR_MUX(5); // fb_ale
#define MRAM_START_ADDRESS(*(volatile unsigned char*)(0x60000000))
FB_CSAR0 = (unsigned int)&MRAM_START_ADDRESS; //Set Base address
FB_CSCR0 = FB_CSCR_PS(1) // 8-bit port
| FB_CSCR_AA_MASK // auto-acknowledge
| FB_CSCR_WS(0x2) // 2 wait states
FB_CSMR0 = FB_CSMR_BAM(0x7) // Set base address mask for 512K address space
| FB_CSMR_V_MASK; // Enable cs valid signal
For read and write test:
uint8 wdata8 = 0x5A; // data to write to mram
uint8 rdata8; // variable to read mram
for(n=0x00000;n<0x000F;n++) // address offset
{
*(vuint8*)(&MRAM_START_ADDRESS + n) = wdata8;
rdata8 = 0x00; // clear data variable
rdata8 = (*(vuint8*)(&MRAM_START_ADDRESS + n));
}
Thanks.
Evgeni
Hi Evgeni,
it depends on what you want to do with Flexbus if you need to edit linker file or not.
- If you want to execute code from external MRAM or you need to reference specific data variables then you need to edit linker file.
- If you want just to save raw data it is not necessary to edit linker file.
You may find useful the following documents.
Relocating Code and Data Using the CW GCC Linker File for Kinetis
Relocating Code and Data Using the KDS GCC Linker File for Kinetis
Regarding the pinout. Please let me know where you find the different configurations. I did not get this part.
Best regards,
Carlos
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Hello I am trying to use MRAM module of towerk60f120m integrated on flexbus as extended RAM
what changes are required in linker file to use MRAM as extension of internal RAM(i.e. 128K).? compiler should able to store variable in MRAM automatically if internal SRAM goes out of memory
Best regards
Hardik Dave
Hi Hardik,
the compiler is not the one who place variables in memory, it is the linker. Besides, the linker is used for many different processors with different memory sizes, and it is possible to have in your hardware any external memory and the linker is not aware of that. This is why it is used the linker file, here you can set the memory configurations that the linker must consider.
Regards,
Carlos
There is no 'automatic' magic to do this. 'section' directives can be added to the linker script and things like large arrays could be placed in such sections leaving RAM for the more ordinary stuff, or everything gets moved to MRAM. Compiler places variables in data or bss sections normally.
I designed MRAM out of my system when I found a Refrigerator Strength Magnet, used by a near by reed switch,would damage the MRAM. It did not just change bits, it destroyed some underlying bias mechanism destroying the device, in the failure report I got back from Everspin. :-( Pay attention to the Gauss ratings and distance now in the data sheets.
Hello,
Thanks for your reply.
As you have suggested I am trying to locate all my variables to external MRAM on tower kit k60F120M module. I have changed linker file accordingly but I am getting hardfault while mqx init function execution.
can yo please look at attached linker file am I missing something? what else changes are required in mqx project to work with MRAM
Linker File
/****************************************************************************************************************************************************/
ENTRY(__boot)
/*
using both, gnulib & ewl symbols
_cfm - to keep vectors.c variables
__init_hardware - must be used from bsp.a, not from librt.a
*/
EXTERN(_cfm __init_hardware)
MEMORY
{
vectorrom (RX): ORIGIN = 0x00000000, LENGTH = 0x00000400
cfmprotrom (R): ORIGIN = 0x00000400, LENGTH = 0x00000020
rom (RX): ORIGIN = 0x00000420, LENGTH = 0x000FFBE0 /* Code + Const data */
ram (RWX): ORIGIN = 0x60000000, LENGTH = 0x00080000 /* DDR2 - RW data */
sram (RWX): ORIGIN = 0x1FFF0000, LENGTH = 0x00020000 /* SRAM - RW data */
/* kernel space starts after RAM variables (Location of MQX Kernel data + MQX heap) */
end_of_kd (RW): ORIGIN = 0x6007FFF0, LENGTH = 0x00000000
/* Boot stack reused by MQX Kernel data */
bstack (RW): ORIGIN = 0x2000FA00, LENGTH = 0x00000200 /* Boot stack */
end_bstack (RW): ORIGIN = 0x2000FC00, LENGTH = 0x00000000 /* Boot stack end address requires 4B alignment */
}
SECTIONS
{
__INTERNAL_SRAM_BASE = 0x1FFF0000;
__INTERNAL_SRAM_SIZE = 0x00020000;
__INTERNAL_FLASH_BASE = 0x00000000;
__INTERNAL_FLASH_SIZE = 0x00100000;
__INTERNAL_FLEXNVM_BASE = 0;
__INTERNAL_FLEXNVM_SIZE = 0;
__UNCACHED_DATA_END = 0x2000FFF0;
__EXTERNAL_MRAM_BASE = 0x60000000;
__EXTERNAL_MRAM_SIZE = 0x00080000;
__EXTERNAL_MRAM_ROM_BASE = 0x60000000;
__EXTERNAL_MRAM_ROM_SIZE = 0x00000000;
__EXTERNAL_MRAM_RAM_BASE = 0x60000000;
__EXTERNAL_MRAM_RAM_SIZE = 0x00080000;
__EXTERNAL_DDR2_RAM_BASE = 0x00000000;
__EXTERNAL_DDR2_RAM_SIZE = 0x00000000;
__EXTERNAL_LCD_BASE = 0xA0000000;
__EXTERNAL_LCD_SIZE = 0x1FFFF;
__EXTERNAL_LCD_DC_BASE = 0xA0010000;
/* MQX link time configurations */
__DEFAULT_PROCESSOR_NUMBER = 1;
__DEFAULT_INTERRUPT_STACK_SIZE = 1024;
__KERNEL_DATA_VERIFY_ENABLE = 0; /* Test SDRAM read/write */
/* Flashx configurations */
__FLASHX_SECT_SIZE = 0x1000;
.vectors :
{
__vector_table = .;
__VECTOR_TABLE_ROM_START = __vector_table;
KEEP(*(.vectors_rom))
. = ALIGN (0x4);
} > vectorrom
.cfmprotect :
{
KEEP(*(.cfmconfig))
. = ALIGN (0x4);
} > cfmprotrom
.text :
{
*(KERNEL)
*(S_BOOT)
*(IPSUM)
*(.text*)
*(.eh_frame)
KEEP (*(.init))
KEEP (*(.fini))
. = ALIGN(0x4);
*(.rodata*)
. = ALIGN(0x4);
*(.rdata*)
. = ALIGN(0x4);
*(.exception)
. = ALIGN(0x4);
__exception_table_start__ = .;
__exception_table_end__ = .;
__sinit__ = .;
} > rom
.ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } > rom
.ARM : {
__exidx_start = .;
*(.ARM.exidx*)
__exidx_end = .;
} > rom
.ctors :
{
__CTOR_LIST__ = .;
/* gcc uses crtbegin.o to find the start of
the constructors, so we make sure it is
first. Because this is a wildcard, it
doesn't matter if the user does not
actually link against crtbegin.o; the
linker won't look for a file to match a
wildcard. The wildcard also means that it
doesn't matter which directory crtbegin.o
is in. */
KEEP (*crtbegin.o(.ctors))
/* We don't want to include the .ctor section from
from the crtend.o file until after the sorted ctors.
The .ctor section from the crtend file contains the
end of ctors marker and it must be last */
KEEP (*(EXCLUDE_FILE (*crtend.o ) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
__CTOR_END__ = .;
} > rom
.dtors :
{
__DTOR_LIST__ = .;
KEEP (*crtbegin.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o ) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
__DTOR_END__ = .;
} > rom
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array*))
PROVIDE_HIDDEN (__preinit_array_end = .);
} > rom
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array*))
PROVIDE_HIDDEN (__init_array_end = .);
} > rom
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT(.fini_array.*)))
KEEP (*(.fini_array*))
PROVIDE_HIDDEN (__fini_array_end = .);
} > rom
.data :
{
. = ALIGN(128);
/* create _sdata symbol which keep
relocation(execution) address of data start */
_sdata = .;
__VECTOR_TABLE_RAM_START = .;
KEEP(*(.vectors_ram))
__START_DATA = .;
*(.data*)
__END_DATA = .;
. = ALIGN(0x4);
__START_SDATA = .;
*(.sdata*)
__END_SDATA = .;
. = ALIGN(0x4);
__SDA_BASE = .;
__SDA_BASE_ = __SDA_BASE;
. = ALIGN(0x4);
/* create _edata symbol which keep
relocation(execution) address of data end */
_edata = .;
} > ram AT> rom
/* fill "__S_romp" table with memory region(s) to perform "rom to ram copy" */
.romp :
{
__S_romp = .;
LONG(LOADADDR(.data)); /* source (rom) address */
LONG(_sdata); /* target (ram) address */
LONG(_edata - _sdata); /* size */
/* null terminated */
LONG(0);
LONG(0);
LONG(0);
} > rom
.rom_end_data :
{
_rom_data_end = .;
} > rom
.bss :
{
. = ALIGN(0x10);
__START_SBSS = .;
*(.sbss*)
*(SCOMMON)
__END_SBSS = .;
__START_BSS = .;
__bss_start__ = __START_BSS;
*(.bss*)
*(COMMON)
__END_BSS = .;
__bss_end__ = __END_BSS;
. = ALIGN(0x10);
} > ram
/* move "location counter" to next relocated address */
. = ALIGN(0x10);
.kernel_data :
{
__KERNEL_DATA_START = ALIGN(0x10);
}
.end_of_kernel_data :
{
__KERNEL_DATA_END = .;
__KERNEL_AREA_END = .;
} > end_of_kd
.boot_stack :
{
_stack_end = .;
} > bstack
.end_of_boot_stack :
{
_stack_addr = .;
_estack = _stack_addr;
__SP_INIT = _stack_addr;
__BOOT_STACK_ADDRESS = .;
} > end_bstack
.sram_data :
{
/* create _sdata symbol which keep
relocation(execution) address of data start */
. = ALIGN(512);
__BDT_BASE = .;
*(.usb_bdt)
__BDT_END = .;
__SRAM_POOL = .;
__UNCACHED_DATA_START = .;
} > sram
/* flashx working area spans across the whole rest of Flash memory */
_flashx_start = _rom_data_end;
__FLASHX_START_ADDR = ((_flashx_start + __FLASHX_SECT_SIZE - 1) / __FLASHX_SECT_SIZE) * __FLASHX_SECT_SIZE;
__FLASHX_END_ADDR = __INTERNAL_FLASH_BASE + __INTERNAL_FLASH_SIZE;
}
/****************************************************************************************************************************************************/
Best Regards
Hardik
On which line of initialization are you having the fault. Most linkely you are attempting to access MRAM before configuring Flexbus.
Dear Carlos,
In our custom application we have requirement to add more RAM which has K60 controller.
I am currently evaluating MRAM option with the help of Tower kit K60F120M with MRAM module
1. flexbus is initialised in init_hw.c as available in mqx 4.2 (no changes)
2. linker is changed which is attached as above post
3. in mqx.c file at time of mqx_init system gets restarted (external mram is not accessible from mqx.c file).
Note:
1. with the default linker file we can able to access mram from TASK just like EEPROM
2. with attached linker file variables pointing to external mram is not accessible from mqx_init function due to which it restarts
3. it seems flexbus comes into running mode at time of task startup only.
Thanks and regards
Hardik Dave
Thanks for your help.