How can we reduce the excessive RAM use by this core

The official STMicroelectronics Arduino core
User avatar
RogerClark
Posts: 6131
Joined: Mon Apr 27, 2015 10:36 am
Location: Melbourne, Australia
Contact:

How can we reduce the excessive RAM use by this core

Post by RogerClark » Fri Nov 18, 2016 10:14 pm

Guys,

Rick has noticed that the RAM usage of this core is very high. Blank sketch takes 9k of RAM vs libmaple uses 2k.

The main reason for this appears to be arrays of data in RAM, most of which is static and does not need to be there

I've made a start at fixing some of this, looking at the pwm code which had an array of all PWM capable pins, which has to store the HAL timHandle data, but also included pin / port definitions which don't change, as well as setup data, which doesnt change.

The WIP branch https://github.com/stm32duino/Arduino_C ... 1/tree/WIP has a this fix, which halves the amount of RAM taken for the PWM config (and saves just under 1k)

But though investigating this problem, I noticed that things like this

Code: Select all

PinDescription g_intPinConfigured[MAX_DIGITAL_IOS];
where

Code: Select all

typedef struct _PinDescription
{
  uint32_t arduino_id;
  uint32_t ulPin ;
  GPIO_TypeDef  * ulPort;
  uint32_t mode;
  bool configured;
} PinDescription ;
but the only thing that gets changed in

intPinConfigured is

bool configured;

as the code does things like this

Code: Select all

      
      g_intPinConfigured[pin] = g_APinDescription[i];
      g_intPinConfigured[pin].configured = true;
Which looks really strange to me.

I must admit, I'm not entirely sure what the compiler does for

g_intPinConfigured[pin] = g_APinDescription;

I don't think it did a memcpy, (but perhaps it does)

Of if not, it will assign a g_intPinConfigured[X] as a pointer to g_APinDescription[Y]

In which case this doesn't need to be an array of structs, it needs to be an array of pointers to structs

Code: Select all

PinDescription g_intPinConfigured[MAX_DIGITAL_IOS];
But I've not looked at the code in details to determine precisely which of these two scenarios it expects

stevestrong
Posts: 1350
Joined: Mon Oct 19, 2015 12:06 am
Location: Munich, Germany

Re: How can we reduce the excessive RAM use by this core

Post by stevestrong » Sat Nov 19, 2016 8:32 am

RogerClark wrote: In which case this doesn't need to be an array of structs, it needs to be an array of pointers to structs
I agree.
In this case it should be an array of pointers:

Code: Select all

PinDescription * g_intPinConfigured[MAX_DIGITAL_IOS];
The array "g_APinDescription[]" should be then stored in FLASH (having removed the member "configured"), the others like "g_intPinConfigured[]" will be placed in RAM.
One could then make the member "#.configured" equivalent to whether the pointer stored in "g_intPinConfigured[]" is NULL or has been written with a non-zero value.

danieleff
Posts: 302
Joined: Thu Sep 01, 2016 8:52 pm
Location: Hungary
Contact:

Re: How can we reduce the excessive RAM use by this core

Post by danieleff » Sat Nov 19, 2016 8:42 am

I made a .map analizer: http://danieleff.com/stm32/map_analizer ... uepill.map
You can upload .map files from the build directory, and it will show the sizes of the objects. I put a few examples there.
The advantage to the standard arm-none-eabi-nm is that this also shows the source file that the object was included from.
EDIT: I mean I made it so RAM usage can be analyzed more easily.

User avatar
RogerClark
Posts: 6131
Joined: Mon Apr 27, 2015 10:36 am
Location: Melbourne, Australia
Contact:

Re: How can we reduce the excessive RAM use by this core

Post by RogerClark » Sat Nov 19, 2016 8:54 am

Thanks @danieleff

BTW.

I've realised that g_intPinConfigured[pin] = g_APinDescription; does actually do memcpy on the struct
Last edited by RogerClark on Sat Nov 19, 2016 9:15 am, edited 2 times in total.

stevestrong
Posts: 1350
Joined: Mon Oct 19, 2015 12:06 am
Location: Munich, Germany

Re: How can we reduce the excessive RAM use by this core

Post by stevestrong » Sat Nov 19, 2016 8:58 am

Hm, I have the feeling that the originator of this code comes from the PC world where the RAM size is never an issue.
Looking at the map from danieleff (nice feature, thank you!) it seems that the struct

Code: Select all

analog_config_str g_analog_config[NB_ANALOG_CHANNELS]
could be placed entirely in FLASH, because it will never be changed.

User avatar
RogerClark
Posts: 6131
Joined: Mon Apr 27, 2015 10:36 am
Location: Melbourne, Australia
Contact:

Re: How can we reduce the excessive RAM use by this core

Post by RogerClark » Sat Nov 19, 2016 9:14 am

Yes. I agree the developers don't seem to have considered RAM usage

Actually that struct does have 1 member timHandle that needs to be in RAM (See the same file in the WIP branch)

I think the dac member also needs to be in RAM

stevestrong
Posts: 1350
Joined: Mon Oct 19, 2015 12:06 am
Location: Munich, Germany

Re: How can we reduce the excessive RAM use by this core

Post by stevestrong » Sat Nov 19, 2016 9:33 am

I see what you mean, you're right.
Do you refer to "dacInstance" or "dacChannel"? Or both?
One could make separated structs, one part in FLASH, the other in RAM? I think it has been discussed already.

User avatar
RogerClark
Posts: 6131
Joined: Mon Apr 27, 2015 10:36 am
Location: Melbourne, Australia
Contact:

Re: How can we reduce the excessive RAM use by this core

Post by RogerClark » Sat Nov 19, 2016 9:51 am

stevestrong wrote:I see what you mean, you're right.

One could make separated structs, one part in FLASH, the other in RAM? I think it has been discussed already.
Thats what I did ;-)

https://github.com/stm32duino/Arduino_C ... log.c#L104
Last edited by RogerClark on Sat Nov 19, 2016 10:27 am, edited 1 time in total.

stevestrong
Posts: 1350
Joined: Mon Oct 19, 2015 12:06 am
Location: Munich, Germany

Re: How can we reduce the excessive RAM use by this core

Post by stevestrong » Sat Nov 19, 2016 9:57 am

Looks very nice :)
In the same context, I see huge RAM saving potential in USB stuff, like reduction of data size uin32 to uint8 by features of USB_CfgTypeDef.
Reducing the number of endpoints from 15 down to 7 would be also not bad, I don't think that all endpoints will be used simultaneously in any application.

User avatar
RogerClark
Posts: 6131
Joined: Mon Apr 27, 2015 10:36 am
Location: Melbourne, Australia
Contact:

Re: How can we reduce the excessive RAM use by this core

Post by RogerClark » Sat Nov 19, 2016 10:44 am

stevestrong wrote:Looks very nice :)
In the same context, I see huge RAM saving potential in USB stuff, like reduction of data size uin32 to uint8 by features of USB_CfgTypeDef.
Reducing the number of endpoints from 15 down to 7 would be also not bad, I don't think that all endpoints will be used simultaneously in any application.
Good idea

I'm sure @vassilis probably used the default usb files from STM which have worst case values

Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest