Memory Fragmentation

I am new here. I have been programming 8052 forever (Assembly). I looked at Arduino last year, but dropped it after reading a plethora of posts about memory fragmentation and subsequently feeling like it was not somethin one could use professionally.

I am looking again....

In the 8052 world, we define memory locations for every variable. We always know where they are (at least we should) and how big they are. If we need to do something with them, we go 'em, put them in a working space ( like the accumulator), do what we need to, and put 'em back. (That is a gross simplification).

Is this type of variable declaration by memory address a reasonable Arduino strategy?
Assign variables a name and a memory location. Sort of, give it a home and always know where it lives.

Thanks

I looked at Arduino last year, but dropped it after reading a plethora of posts about memory fragmentation

That sounds like it relates to use use of Strings in the small amount of memory available.

The answer is not to use Strings

  1. You can program the arduino in assembler (Atmel Studio, also to get rid of the arduino core).

  2. Memory fragmentation is a phenomenon tied to dynamic memory allocation. If you don't use malloc or new, you will not have memory fragmentation

In the 8052 world, we define memory locations for every variable. We always know where they are (at least we should) and how big they are.

that sounds like a good idea on small micro-controllers. you can do the same on your Arduino.

Is this type of variable declaration by memory address a reasonable Arduino strategy?

if you don't want to work in assembly, best is to use C or C++ (and possibly the Arduino IDE) let the compiler decide and optimize for you. It will be responsible for fetching the data, putting the bytes in the right registers, performing the right operations and storing the results where needed.

but you can do manually what the compiler/linker would do for you

Memory allocation in Arduinos works in EXACTLY the same way it does in every other MCU ever made, including your 8052. There is absolutely NO difference whatsoever. If you're going to make major design decisions based on poorly understood Internet "factoids", you''re going to have a very difficult life, and make some very poor decisions....

Regards,
Ray L.

Read the Arduino Memory Tutorial to understand the different types of memory available.

Then simply don't use big-S strings or any other dynamic memory.

To those who answered my questions with good information.....Thank you.

To reply#4...

Your comments on how difficult my life will be and making poor decisions....really? I simply asked a question.

In Assembly one can write things such as

I2C_POINTER EQU 068H
I2C_LEN EQU 069H

There are addresses where variables are stored. I simply wanted to know if this was available in the Arduino IDE or even a viable strategy.

You made a lot of assumptions. I thought this was where one comes to ask such questions. Not sure why you need to make it personal. It serves no purpose other that to drive people away from the forum.

If you want to write your AVR code in assembler, then the comments in reply #4 are spot-on.

But then you miss-out on all the benefits of using C/C++.

However, if you want to agonise and obsess about every byte, and live your code development life in the slow lane, assembler is the way to go.

In Assembly one can write things such as

I2C_POINTER EQU 068H
I2C_LEN EQU 069H

There are addresses where variables are stored. I simply wanted to know if this was available in the Arduino IDE or even a viable strategy.

You don't do that EXACTLY, but if you say:

 uint8_t * i2c_pointer;
 uint8_t i2c_len;

then the compiler will statically allocate memory for those variables, and you won't have any "fragmentation" problems. (although, you can use up all your memory at compile time, in which case you'll get warning messages from the compiler)

  1. Memory fragmentation is a phenomenon tied to dynamic memory allocation. If you don't use malloc or new, you will not have memory fragmentation

This. But the problem is that the C++ language, and the libraries provided by Arduino, C++, and by various well-meaning 3rd parties, don't always make it obvious exactly when dynamic memory allocation is used.

The various problems caused by Strings are a fine example - when you use Arduino String you probably never have a call to malloc() or new() in your program, but the various String operations (String c = String("A") + String("B"); ) will do them for you, often causing problems...

Great answer.

I am now lead to conclude that the fragmentation issue was mostly related to the overuse use of "Strings".
I have never been a fan of Strings. I use them occasionally but only as constants (.ie: "Please wait...").

Thanks

In the C++/Arduino world, it's further complicated because you have have strings that a simple character arrays (which includes your "please wait" example. These use statically allocated memory, and they're "fine" to use, but a bit annoying to manipulate.) Then you have Strings (upper-case 'S'), which use dynamic memory allocation (invisibly, as far as the user knows) to permit a range of "intuitive" operations.

dr1952:
In Assembly one can write things such as

I2C_POINTER EQU 068H
I2C_LEN EQU 069H

You could, but that is not how you write in assembler.

Rather it looks like this:

   ORG   068H
I2C_POINTER    FCB
I2C_LEN        FCB

I may be mixing my assembler language. :roll_eyes:

And a pointer is not usually a single byte, by the way, but you may be using it in a different context. :grinning:

The point is that the "C" representation closely follows the assembler in form.

Its rough in here.

The two lines of code ...

I2C_POINTER EQU 068H
I2C_LEN EQU 069H

were straight out of a project that has been in mass production since 2009 using an Silicon Labs 8052.

It IS correct.

You have no idea what the project or the processor were, but felt some need to correct me. Your post has nothing to do with the question at hand.

Maybe this is why forums are such a source of misinformation

hang in there - it gets fun after a while :slight_smile:

In Assembly one can write things such as

I2C_POINTER EQU 068H
I2C_LEN EQU 069H

There are addresses where variables are stored.

But that code does not reserve any memory for those variables - accessing those locations without other code to reserve memory there (or maybe the "variables" are actually memory-mapped registers?), is just as dangerous in assembler as it would be in C to define a pointer without initialising it, and then dereferencing the pointer.

The memory is "reserved" simply by the programmer remembering not to put anything else in the same location.

Reminds me of The Story of Mel, a Real Programmer.

“You never know where it's going to put things”,
he explained, “so you'd have to use separate constants”.

For simple programs you can avoid dynamic memory allocations and constrain yourself to the same limitations as you do in Assembly. You can even setup pointers to fixed memory addresses like in your example:

uint8_t *i2c_pointer=(uint8_t*)0x68;

The memory fragmentation is general dynamic memory allocation problem (dynamic store) that's not limited only to Arduino or C/C++, and not only to Strings either. Even in Assembly you have this same problem, but you may have opted to avoid dynamic allocations just like you could do in C/C++. A lot of memory allocations are done from "stack" (LIFO) and "global store" that don't suffer from the fragmentation.

If you haven't already, I highly suggest you to look into C/C++ because that'll massively improve your productivity and enable solving more complex problems without meaningful impact on performance/memory management. For performance intensive parts you can still revert to writing inline Assembly (Assembly embedded into C/C++ code), but in vast majority of cases compiler does good enough job that you can focus your efforts elsewhere. You can also go back and check the assembly code generated by the compiler for a specific piece of code, and decide if the piece of code is something worth optimizing with hand written Asm.

MorganS:
Reminds me of The Story of Mel, a Real Programmer.

Exactly!

dr1952:
To those who answered my questions with good information.....Thank you.

To reply#4...

Your comments on how difficult my life will be and making poor decisions....really? I simply asked a question.

In Assembly one can write things such as

I2C_POINTER EQU 068H
I2C_LEN EQU 069H

There are addresses where variables are stored. I simply wanted to know if this was available in the Arduino IDE or even a viable strategy.

You made a lot of assumptions. I thought this was where one comes to ask such questions. Not sure why you need to make it personal. It serves no purpose other that to drive people away from the forum.

Just to jump in here, yeah, that happens some times. Looks like you shrugged it off and continued. Good.

I started with assembly on the 8080/80186, Z8000, and PDP-11. I was comfortable.

I started with Turbo Pascal, then Turbo C. At first I saw C as just a high level assembler.
Using Assembly It is comfortable, putting things exactly where you want them and knowing where everything it. Moving to a compiler and IDE is a radical change.

I used Turbo Pascal to write a number cruncher with in-line assembly to directly drive the 187 math co-processor. I was able to move from 64 bits precision to 80 bits.

And yes, to the unstated question, getting started with a modern compiler and IDE can be a real pain in the ass. For example the IDE says you must create a project. I don't want a stinking project, just compile this chunk of code. It won't do it.

But, in the long run, if you ever leave embedded projects or you want to create a much larger project, you really need to make the jump. It does take a huge load off of you and puts it on the compiler.

Remember than the Arduino is a very small processor. When, or if, you make the leap to larger projects, and working within larger environments, (Windows or Linux) assembly just doesn't cut it any more.