Should malloc be used to reduce initial RAM usage?

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

Should malloc be used to reduce initial RAM usage?

Post by RogerClark » Sat Nov 19, 2016 11:43 pm

Guys,

With the STM core it takes a lot of RAM, because worst case arrays of HAL structures are defined for things like PWM (timers) and various other things.

One way to reduce this considerably is to only allocate the timer handler structure that the HAL uses, when its actually needed; using malloc.

But I can see a potential problem with this, because the Arduino IDE reports the amount of free RAM, and this would not include any RAM that pinMode would need to allocate for PWM etc.

I don't think free'ing the memory if the pinMode was changed, would be a good idea as it could cause memory fragmentation.
So ultimately the sketch could use as much memory using malloc as it did with static arrays.

But the issue is that this is hidden from the user, and if they setup pin mode on all available pins on the F103 its going to consume around 2k of RAM.

I've taken a look at what the ESP8266 core does, in case this gives any ideas, and they seem to use malloc for the UART buffer, not for anything else.
So there is a slight precedence for this, but not a major one.

However, there doesn't seem to be an alternative to doing this, because a blank sketch on the Blue PIll (with USB) was taking around 9k of RAM before the changes to use malloc.

There are ways to partially reduce the RAM requirement without using malloc, but I think without malloc its unlikely we can get the RAM requirement below 5k, which is over twice the amount LibMaple takes

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

Re: Should malloc be used to reduce initial RAM usage?

Post by danieleff » Tue Nov 22, 2016 7:25 am

mbed uses one global

Code: Select all

static TIM_HandleTypeDef TimHandle;
and just changes TimHandle.Instance every time.
https://developer.mbed.org/users/mbed_o ... mout_api.c , lines 39, 77, 187.
BTW I think that is wrong.

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

Re: Should malloc be used to reduce initial RAM usage?

Post by stevestrong » Tue Nov 22, 2016 9:23 am

-1 for malloc.
As you mentioned, it is not transparent for the user how much RAM can he use for other purposes.

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

Re: Should malloc be used to reduce initial RAM usage?

Post by RogerClark » Tue Nov 22, 2016 10:01 am

@danieleff

I agree the mbed code looks incorrect.

I guess it may be OK because none of the DMA channels etc that are in TIM_HandleTypeDef are used, so perhaps the only thing which is different is the hardware port.

It still seems an incorrect use of TIM_HandleTypeDef, but if STM developed the mbed code, or perhaps if the mbed developers worked with the STM HAL developers, it is OK in these circumstances.


Frederic Pillion @ STM said I can ask him questions about the HAL, which he can pass on to the HAL team if necessary, so I will ask him to find out if its OK to use the same principals as the mbed code.


@stevstrong

OK. I knew using malloc was perhaps going to be a problem, but it saves a lot of RAM ;-)

But if STM agree the mbed code for PWM is OK, then we only need one TIM_HandleTypeDef !

User avatar
GrumpyOldPizza
Posts: 174
Joined: Fri Apr 15, 2016 4:15 pm
Location: Denver, CO

Re: Should malloc be used to reduce initial RAM usage?

Post by GrumpyOldPizza » Tue Nov 22, 2016 1:44 pm

danieleff wrote:mbed uses one global

Code: Select all

static TIM_HandleTypeDef TimHandle;
and just changes TimHandle.Instance every time.
https://developer.mbed.org/users/mbed_o ... mout_api.c , lines 39, 77, 187.
BTW I think that is wrong.
Didn't see this instance, but they do the same thing with I2C. And there it effectively prevents you from having more than 1 I2C port going at the same time due to race conditions.

User avatar
GrumpyOldPizza
Posts: 174
Joined: Fri Apr 15, 2016 4:15 pm
Location: Denver, CO

Re: Should malloc be used to reduce initial RAM usage?

Post by GrumpyOldPizza » Tue Nov 22, 2016 1:46 pm

stevestrong wrote:-1 for malloc.
As you mentioned, it is not transparent for the user how much RAM can he use for other purposes.
Malloc in embedded systems is a bad idea to begin with. In an Arduino API based system it's even worse, because none of the APIs there has a return code that would tell you that you are out of memory. It just wouldn't work without any indication to the users as to what had happened.

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

Re: Should malloc be used to reduce initial RAM usage?

Post by RogerClark » Tue Nov 22, 2016 8:03 pm

I got a reply from Laurent at STM, and he thinks it is probably OK, just to make a local var for the Timer Handle struct, and just just change the Instance pointer, in a similar way to what mbed does.

This was basically what I did in my initial attempt to reduce the RAM use, as the pointer to Instance ( pointer to the hardware port) is easily available via the main pin description array.

I will manually modify the code back to that method, until we find a problem with it or a better solution, as I agree malloc is not ideal.


BTW.
String uses malloc in the Arduino API doesn't it?
( I don't use String in my code, but its used extensively on the ESP8266 core, so its unavoidable if you use that MCU with the Arduino API)

Edit.
I forgot to say, Laurent agrees that there is a bug in the mbed PWM as the pwmfree() function does not seem to actually turn off the pwm timer

User avatar
Wi6Labs
Posts: 25
Joined: Fri Sep 16, 2016 11:39 am
Location: Rennes, France
Contact:

Re: Should malloc be used to reduce initial RAM usage?

Post by Wi6Labs » Wed Nov 23, 2016 9:47 am

GrumpyOldPizza wrote:
stevestrong wrote:-1 for malloc.
As you mentioned, it is not transparent for the user how much RAM can he use for other purposes.
Malloc in embedded systems is a bad idea to begin with. In an Arduino API based system it's even worse, because none of the APIs there has a return code that would tell you that you are out of memory. It just wouldn't work without any indication to the users as to what had happened.
Is the source code will stay readable if we use malloc? We are not very sure but we are curious how you will implement it in the code.
Wi6Labs team

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

Re: Should malloc be used to reduce initial RAM usage?

Post by RogerClark » Wed Nov 23, 2016 7:55 pm

malloc will be removed, in favour of using a local variable for the timer handle, and just updating the Instance property, like mbed does

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

Re: Should malloc be used to reduce initial RAM usage?

Post by RogerClark » Thu Nov 24, 2016 7:02 am

I have pushed an update to the WIP branch which does not use malloc

It uses a similar system that mbed uses.

Mbed has one global TIM_HandleTypeDef struct, which it uses when calling the HAL, it just changes the Instance property (which is a pointer to the timer registers in queston) depending on which timer channel is needed.

I asked Frederic and Laurent @STM about the mbed code and Laurent thought it was OK to use the same system, but that it doesnt need to use a global, as anything setup for one timer channel would not be valid if was then started on another channel.

So I'm using local vars of this in both the pmw_start and pwm_stop functions.

I have tested this with one PWM channel and it seems fine, and it is possible to switch to pinMode(x,OUTPUT) and use digital write, and the to back to calling analogWrite without any problems

Interestingly, both LibMaple and the STM core behave in the same way in this regard, in that you have to call pinMode(x, OUTPUT) if you want to switch to using digitalWrite on the same pin instead of using PWM.

I will test this on multiple PWM pins when I get chance

Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest