K65 - How to write to the SDRAM using MCUXpresso IDE

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

K65 - How to write to the SDRAM using MCUXpresso IDE

2,323 Views
joseph_jean-jac
Contributor III

Hello Everyone,

I am trying to find out what the size of the SDRAM is on the K65 and how to write to it using MCUXpresso IDE? I been using the 256 kb SRAM and just "remembered" that the K65 has SDRAM. Weirdly enough the quick start guide doesn't mention how much memory it has.

***UPDATE I just found the K65 user guide and it mentions the K65 has 64 Mb of SDRAM. I just need help on how to write to it. I believe this will solve my issue of "FreeRTOS doesn't have enough memory in the heap to start the kernel". 

As usual, any help is greatly appreciated!

Thanks!

16 Replies

1,788 Views
jingpan
NXP TechSupport
NXP TechSupport

Hi Joseph,

I think you must have a TWR-K65F board. The SDRAM demo is in The demo is in SDK_2.2_TWR-K65F180M\boards\twrk65f180m\driver_examples\sdramc

Regards,

Jing

1,788 Views
joseph_jean-jac
Contributor III

Thank you Jing Pan, 

I was able to import the SDK demo you mentioned and it ran perfectly. All the code for configuring the SDRAM controller is there and I was able to see the test printf() values ("SDRAM memory write start...", etc) in the console. 

0 Kudos

1,788 Views
mjbcswitzerland
Specialist V

Hi

"FreeRTOS doesn't have enough memory in the heap to start the kernel" is not a message in FreeRTOs and so must be from the caller.

The kernel requires only a few Bytes/kBytes of SRAM and so SDRAM will not be required.

Possibly the environment is reacting to errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY and you need to correctly configure pvPortMalloc() to us whatever HEAP management system you are using.

Regards

Mark

Complete K66 solutions, training and support:http://www.utasker.com/kinetis.html
Kinetis K66:
- http://www.utasker.com/kinetis/TWR-K65F180M.html
- http://www.utasker.com/kinetis/FRDM-K66F.html
- http://www.utasker.com/kinetis/TEENSY_3.6.html

0 Kudos

1,788 Views
joseph_jean-jac
Contributor III

Hi Mark, thanks for the response!

How would I configure pvPortMalloc to use a particular HEAP management system? I was not aware I had to do this in the first place. 

0 Kudos

1,788 Views
BlackNight
NXP Employee
NXP Employee

See FreeRTOS - Memory management options for the FreeRTOS small footprint, professional grade, real time... 

one way is to have only one of the heap_*.c files compiled with your application. You can exclude the other ones from the build, see Exclude Source Files from Build in Eclipse | MCU on Eclipse 

I hope this helps,

Erich

1,788 Views
joseph_jean-jac
Contributor III

Thanks Erich!

Those links were helpful. It seems the IDE automatically decided I would be using heap_4.c and thus excluded the other heap_#.c files. I am still getting the unfortunate  configASSERT( xReturn != errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY ); error.

Is there something else I am suppose to do in the pvPortMalloc() function definition?

In the meantime I will try writing to the SDRAM. Even though technically speaking, I shouldn't need the SDRAM at this point since the FreeRTOS kernel only uses up at most a few Kb's as Mark mentioned. 

0 Kudos

1,788 Views
mjbcswitzerland
Specialist V

Hi

Put a break point in

extern void *pvPortMalloc(int iSize) {}

and see why it returns 0.

Maybe it is still missing a hook or maybe the heap management system hasn't been given any memory to work with. Or too little.
Finally check the size of stack that you are demanding for tasks (usStackDepth - 3rd parameter in xTaskCreate(), which is multiplied by 4) to ensure a reasonable value is being passed.

Each user task needs its stack depth (in long words) plus a TCB task control block (around 92 bytes).
And the IDLE task requires 360 bytes heap for its stack, plus a TCB.
And the timer service task 720 bytes heap, plus a TCB
Timers ques need about 200 bytes per default

With this heap memory it should be able to start.

You can also use static allocation instead of dynamic with the configuration flag

#define configSUPPORT_STATIC_ALLOCATION 1

In case of continued problems use the uTasker project since it contains setups for all Kinetis processors with or without FreeRTOS with different heap management options (avoiding library ones).

Regards

Mark

1,788 Views
joseph_jean-jac
Contributor III

For the 3rd parameter in xTaskCreate(), I passed in configMINIMAL_STACK_SIZE. As you mentioned this parameter value is read in words, with each word being 4 bytes. 

In FreeRTOSConfig.h, I changed the value of configMINIMAL_STACK_SIZE to 8192, which is roughly 32 kb to be on the complete safe side that there was enough memory. 

In FreeRTOSConfig.h,  I also changed the value of configTOTAL_HEAP_SIZE to 50 kb. I noticed if I change the value of configTOTAL_HEAP_SIZE to 200 kb, I get an error message stating there was an overflow of exactly 33,140 bytes on the SRAM_UPPER region. When I change the value of configTOTAL_HEAP_SIZE anywhere from 140 kb to just below 167 kb, I get a semi host hardfault. 

If I keep the value of configTOTAL_HEAP_SIZE anywhere from 130 kb and below (as long as it is greater than the kb size of configMINIMAL_STACK_SIZE), I get the  configASSERT( xReturn != errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY ) error message.

The above observations are interesting to note, is semi-hosting problematic when enabled while creating tasks in FreeRTOS? I use semi-hosting to print out results in the IDE console. 

Based on the values of the constants I mentioned above, the heap management system was definitely given plenty of memory to work with. The default values before I changed them was 90 (360 bytes) for configMINIMAL_STACK_SIZE and 10,240 bytes for configTOTAL_HEAP_SIZE. However you mentioned something regarding pvPortMalloc(), that "maybe it is still missing a hook". What does that statement mean? 

As far as putting a break point in pvPortMalloc() goes, I did that and right before the last line of that function,

return pvReturn‍

 I entered a printf() statement to print out the pointer value of PvReturn and this was the following result: pvReturn is 0x20005230.

So it turns out PvReturn is not actually returning zero. I think it might be the "hook part" it is missing as you mentioned earlier. 

 

0 Kudos

1,788 Views
mjbcswitzerland
Specialist V

Hi

pvReturn is 0x20005230


This sounds right so nothing is missing.
However don't forget that this will be called multiple times during configuration and the pointer will change each time - it will return 0 if the heap is exhausted, which still may be the case after a number of calls.

Add

if (pvReturn == 0) {

// some code that will allow a break point to be set

}

and see whether the break is hit, which it probably still will be.

In the uTasker project I run FreeRTOS on the K65 with 2k of HEAP in a basic configuration so your present values look to be very exaggerated and together with the overall project configuration (beware that things like printf() also use heap) it looks like your really have heap issues.

I avoid semi-hosting because it may have impacts on the operation (there are various reports of side effects). Using UART output in DMA mode is almost zero overhead, or similar output via USB VCOM or Telnet are more natural and don't need the debugger connected to test and record such operation (also remotely resp. in the field).

Basically the K65 has a lot of SRAM and I never needed more that 48k heap to run any application (including quite full featured ones).

Regards

Mark

1,788 Views
joseph_jean-jac
Contributor III

Hi Mark,

so I ran a couple of tests which I think confirms your point that this is really a semi-hosting issue.

1st Test:

I kept configMINIMAL_STACK_SIZE to 8192, which is roughly 32 kb and the value of configTOTAL_HEAP_SIZE to 50 kb. I went through the debugger one step at a time, and as soon as pvPortMalloc() was for the 1st time inside vTaskStartScheduler(), pvReturn returned a value of 0. When pvPortMalloc() was called twice before vTaskStartScheduler() was called, pvReturn returned a valid memory address (verified via printf() ) each of those two times, however as soon as pvPortMalloc() was called inside vTaskStartScheduler(), it returned a value of 0.

2nd Test:

I changed configMINIMAL_STACK_SIZE to 500 which is about 2 kb and I kept the value of configTOTAL_HEAP_SIZE at 50 kb. In this 2nd run, pvPortMalloc() was called twice before vTaskStartScheduler() was called, which pvReturn returned a valid memory address (verified via printf() ) each of those two times. When vTaskStartScheduler() was called, pvPortMalloc() was called 5 times within that function, each time returning a valid memory address ( verified via printf() ), however after the 5th call of pvPortMalloc(), the debugger hitted line 1997 in vTaskStartScheduler(), the following line was:

if (xPortStartScheduler() != pdFALSE)‍‍‍

 this resulted in a semi-host hard fault in the semi-host hard fault handler.c file. 

After performing these two tests, I changed the SDK debug console to UART, I opened up TeraTerm, selected the serial COM port that said" mbed Serial Port", in my case COM4, then I changed the serial port settings to 115200 for speed, 8 bit for data, none for parity, 1 bit for stop bits, and none for flow control. I also went to the Terminal settings and set "Receive" value to "LF". When I tried running my code again in MCUXpresso IDE, I didn't see anything printed in the console (expected behavior), however I did not see anything printed out in TeraTerm either. Not only that, but I still received a semi-host hard fault. 

I feel like the heap issue is resolved after those 2 tests (I now use 500 words for stack size and keep HEAP size at 50 kb). It is now my configuration settings in regards to switching from semi-hosting to UART. I followed the tutorial here on this site for that process, it was pretty straight forward. I'm not sure what I could have missed or done wrong. 

0 Kudos

1,788 Views
josephjean-jacq
Contributor III

Could someone help me with getting the UART output on my terminal screen (teraterm)?

Thanks,

Joseph

0 Kudos

1,788 Views
jingpan
NXP TechSupport
NXP TechSupport

Hi,

If you want to print to COM port, just change a setting to Quickstart Panel->Quick Settings-> SDK Debug Console->UART Console.

Regards,

Jing

0 Kudos

1,788 Views
joseph_jean-jac
Contributor III

Thanks, Jing I did that and went to tera term serial port settings and used the following values: 115200 for baud rate, 8 bits for data,  none for parity, 1 for stop bits, and none for flow control. I also set “receive” to “LF” in terminal settings. 

In tera term I selected the COM port that said “mbed serial port” and even tried reinstalling the mbed serial driver, yet I still get nothing on the tera term terminal screen.

0 Kudos

1,788 Views
joseph_jean-jac
Contributor III

***UPDATE

So after much digging around, it turns despite me selecting UART console in the SDK debug settings, printf() was still mapped to the standard C printf() library function definition, instead of being mapped to DbgConsole_Printf()

To resolve this issue, I had to go inside the "fsl_debug_console.h" and and wrote the following line of code:

#define printf DbgConsole_Printf‍

Then I had to include that header file in any .cpp file that used printf(). Rather annoying, but it worked. I am now able to output through UART in TeraTerm. I suspect the reason this is happening is because SDK_DEBUGCONSOLE_UART is never defined. How do I know this? Because I wrote the 2nd set of lines after the 1 set of lines in "fsl_debug_console.h":

/* mcux will handle this macro, not define it here */
#if (!defined(__MCUXPRESSO))
#define SDK_DEBUGCONSOLE_UART
#endif‍‍‍‍
#ifdef SDK_DEBUGCONSOLE_UART
#warning "SDK_DEBUGCONSOLE_UART IS DEFINED"
#else
#warning "SDK_DEBUGCONSOLE_UART IS NOT DEFINED"
#endif‍‍‍‍‍

After building the code, I would look at the warnings and see the following message: SDK_DEBUGCONSOLE_UART IS NOT DEFINED.  This is weird to say the least because MCUXpresso is suppose to define that constant for me based on the code I saw in "fsl_debug_console.h". It seems this whole switching from semi-host to UART doesn't work very well in MCUXpresso. You are probably better off creating a new project and selecting UART from the start, to ensure everything is configured properly from the ground up. 

My heap issue seems to be resolved now that I am now longer getting configASSERT( xReturn != errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY ) after running my code. However I am now getting a semi-host hard fault. How is this possible when I am clearly using UART (as verified by TeraTerm output)? Are there any other .h/.c /.cpp files that comes with semi-hosting code when you initially create your project with semi-hosting?

Once again, any help is greatly appreciated!!

0 Kudos

1,787 Views
mjbcswitzerland
Specialist V

Hi Joseph

Can I simply suggest that you use the uTasker project? It has solved all of the typical issues for just about all Kinetis parts so avoids any need to port when moving between Kinetis parts or development environments.

You can run your original FreeRTOS project without any difficulties and take advantage of the highly efficient uTasker parts (many drivers and protocols that are full integrated) where needed or when it makes more sense.

I just built for the TWR-K65F showing three FreeRTOS tasks handing:
- flashing blue LED at 0.5Hz
- UART interface task (just received and echos on the OpenDA VCOM)
- HS USB task (just receives and echoes on a USB-CDC connection)

It does also USB-MSD composite (with a FAT emulator) controlled by a uTasker task, and a uTasker task is also flashing the green LED at 2.5Hz, showing how both worlds can be mixed as desired to get the simplest and most efficient behavior to suit the project's requirements.

I invested 10 minutes to configure, build and test, using 6.8k Heap allocated for FreeRTOS and all tasks.

The binary is attached in case you want to test on your board (keep the HS USB cable connected since it is required for operation). You can load it via the OpenSDA loader.

This would give you a turn key solution and allow you to concentrate on product development rather than first needing to solve the various issues involved with patching together the various parts.

Regards

Mark

Complete K66 solutions, training and support:http://www.utasker.com/kinetis.html
Kinetis K66:
- http://www.utasker.com/kinetis/TWR-K65F180M.html
- http://www.utasker.com/kinetis/FRDM-K66F.html
- http://www.utasker.com/kinetis/TEENSY_3.6.html

1,787 Views
joseph_jean-jac
Contributor III

Hi Mark,

Thanks for your help, the uTasker project does indeed sound intriguing to use, however unfortunately that is a software design decision that I can not make. 

- Joseph 

0 Kudos