Hot answers tagged

43

My general rule for embedded systems is to only malloc() large buffers and only once, at the start of the program, e.g., in setup(). The trouble comes when you allocate and de-allocate memory. Over a long run session, memory becomes fragmented and eventually an allocation fails due to lack of a sufficiently large free area, even though the total free memory ...


18

I have taken a look at the algorithm used by malloc(), from avr-libc, and there seems to be a few usage patterns that are safe from the point of view of heap fragmentation: 1. Allocate only long-lived buffers By this I mean: allocate all you need at the beginning of the program, and never free it. Of course, in this case, you could as well use static ...


17

Typically, when writing Arduino sketches, you will avoid dynamic allocation (be it with malloc or new for C++ instances), people rather use global -or static- variables, or local (stack) variables. Using dynamic allocation can lead to several problems: memory leaks (if you lose a pointer to a memory you previously allocated, or more likely if you forget to ...


15

If you really want to recurse (and as @jippie said it is a bad idea; subliminal message: don't do it) and want to know how much you can recurse, then you will have to perform some calculation and experiments; also you generally will have only an approximation of it as it depends a lot on the memory state at the time your recursive function will be called. ...


15

You can use the functions provided AVRGCC: Monitoring Stack Usage The function was intended to check the stack usage but what it reports is the actual RAM that has never been used (during execution). It does so by "painting" (filling) the RAM with a known value (0xC5), and then checking the RAM area counting how many bytes have still the same initial value. ...


10

First off, a sketch that uses Serial cannot really be considered an empty sketch as Serial drags along a lot of function definitions, at least one Serial class instance (more on Arduino Mega, for instance), plus probably some more global variables... sizeof Serial may be interesting to display as Serial is not limited to the TX and RX buffers, as you seem ...


10

The main issues you can have with memory usage at runtime are: no available memory in the heap for dynamic allocations (malloc or new) no room left on the stack when calling a function Both are actually the same as the AVR SRAM (2K on Arduino) is used for both (in addition to static data which size never changes during program execution). Generally, ...


9

I disagree with people who think you shouldn't use it or it is generally unnecessary. I believe it can be dangerous if you don't know the ins and outs of it, but it is useful. I do have cases where I don't know (and shouldn't care to know) the size of a structure or a buffer (at compile time or run time), especially when it comes to libraries I send out into ...


9

Using dynamic allocation (via malloc/free or new/delete) isn't inherently bad as such. In fact, for something like string processing (e.g. via the String object), it's often quite helpful. That's because many sketches use several small fragments of strings, which eventually get combined into a larger one. Using dynamic allocation lets you use only as much ...


9

sizeof doesn't return the number of elements. It returns the number of bytes. Since they are uint16_t arrays each element is 2 bytes - hence twice the size. The reason your last number is only 40928 is because of integer wraparound. You only provide a 16-bit unsigned variable to store it in, so all you get is the lower 16 bits of the answer. 92000 + 40000 +...


8

Recursion is bad practice on a microcontroller as you already stated yourself and you probably want to avoid it whenever possible. On the Arduino site there are some examples and libraries available for checking free RAM size. You can for example use this to figure out when to break recursion or a bit trickier/riskier to profile your sketch and hard code the ...


7

It depends on the function. Every time a function is called, a new frame is pushed onto the stack. It will usually contain various critical items, potentially including: Return address (the point in the code from which the function was called). The local instance pointer (this) if calling a member function. Parameters passed into the function. Register ...


7

When you figure out how to locate the generated .elf file in your temporary directory, you can execute the command below to dump a SRAM usage, where project.elf is to be replaced with the generated .elf file. The advantage of this output is the ability to inspect how your SRAM is used. Do all the variables need to be global, are they really all required? ...


7

I investigated this at some length a while back. On this page about putting constant data into program memory I obsessively tracked down every last byte of memory used in a small sketch. This was the sketch: #include "memdebug.h" void setup () { Serial.begin (115200); Serial.println (); Serial.print (F("Free memory = ")); ...


7

The microcontroller is executing one command at a time from..where? Flash memory directly. The AVR core can only execute instructions from Flash memory. It uses a two-bus system known as Harvard Architecture, where the Instruction Bus is connected to Flash and is used to execute instructions, and the Data Bus is connected to SRAM, EEPROM, all the ...


7

Isn't the space taken up by the local variable supposed to be freed up from the SRAM once the functions runs because I have declared the variable locally? This is correct. The local arrays you have take up RAM only while the corresponding function is executing. They do not consume any static RAM (i.e. .data and .bss, what the Arduino IDE improperly ...


6

Expanding on my previous comment... The RAM memory map of an AVR-based Arduino looks like this: ┌──────┬─────┬──────┬──────────┬───────┐ │ data │ bss │ heap │→ free ←│ stack │ └──────┴─────┴──────┴──────────┴───────┘ The data and bss sections are fixed, and their size can be known at compile time. However, the stack and the heap grow and shrink ...


6

When you are asking yourself what is eating so much RAM, the first step is to look at the symbol table in the ELF file. If you use a makefile, you probably know where to find the ELF file. If you are using the Arduino IDE, go to File / Preferences, check “Show verbose output during compilation”, compile and look at the output: you will see the temporary ...


6

There are SRAM ICs / boards, however, don't expect 100 MB, more like 1 MB (with the pin numbers and connectivity / protocols that an Arduino offers). With Flash you can get much further, but it can only be written a number of times; not sure if that suits your requirements. Beyond that, I'm afraid the real problem is in the processing speed. Mixing 100 ...


5

It's stored in both the FLASH and SRAM because it's initialized array. To store in FLASH only you need use PROGMEM attribute. const unsigned PROGMEM char g1[]= ... You cannot access directly but using memcpy_P() function.


5

The AVR (the microcontroller family traditionally used on Arduino boards) is a Harvard Architecture, meaning that executable code and variables are in two separate memories - in this case flash and SRAM. The executable code never leaves flash memory. When you call a function the return address is usually pushed to the stack - the exception is when the ...


5

Local variables and function parameters are stored on the stack. However, that is not a reason not to use them. Computers are designed to work that way. Stack memory is only in use while a function is active. As soon as the function returns, the memory is freed. Stack memory is a GOOD Thing. You don't want to use recursive functions with lots of levels of ...


5

const means different things in different contexts as far as storage goes. For a simple numeric value the compiler will generally replace the constant with the literal value. Any mathematics using purely constants or literals will be replaced at compile time with the result. For instance, the code: const int a = 3; const int b = 4; void setup() { int ...


5

You must declare the array in global space or static, and make sure the function you pass the buffer pointer to knows it is in PROGMEM. void send22() { static unsigned int irSignal[] PROGMEM= {8988, 4548, 572, 1688, 572, 1688, 600, 532, 572, 568, 572, 572, 576, 572, 572, 580, 572, 1724, 544, 556, 576, 1684, 600, 1660, 608, 532, 604, 540, 608, 540, 600, ...


4

Only the function's data is stored on the stack; its code stays in flash. You can't really reduce SRAM use by using EEPROM instead because, as you have seen, EEPROM isn't addressable in the same way. The code to read and store EEPROM also needs to use some SRAM - probably as much SRAM as you were trying to save! EEPROM is also slow to write, and has a ...


4

Is it a really bad idea to use malloc() and free() with Arduino? The short answer is yes. Below are the reasons why: It is all about understanding what an MPU is and how to program within the constraints of the available resources. The Arduino Uno uses an ATmega328p MPU with 32KB ISP flash memory, 1024B EEPROM, and 2KB SRAM. That is not a lot of memory ...


4

I found it! I was returning an int8_t variable from my mod function, causing me to not be able to iterate over more than 126 LEDs. Now this little Arduino Uno is maxing out it's RAM at 409 LEDs!


4

To elaborate on Edgar Bonet's answer and my comment under it, you cannot usefully put PROGMEM variables as local variables because local (non-static) variables have to be allocated on the stack. void lookUpInSBox(size_t which, byte *address, byte* binaryOutcome, size_t addressFrom){ ... const uint8_t SBoxes[8][4][16] PROGMEM = { ...


4

You have likely run out of RAM. You have 431 integers in the look-up table alone. That equates to 862 bytes of SRAM. You also have a buffer of 75 floats, which equates to 300 bytes. This is in addition to all your other variables and function calls. The Arduino Uno only has 2KB of SRAM. Solutions: 1) Move your LUT to Flash (ie. program space) using the ...


4

Use the F() macro for all double-quoted strings you print. Change lines like this: Serial.println(" degC."); ...to this: Serial.println( F(" degC.") ); This will save about 100 bytes of RAM. And as BrettAM suggested, put that table into PROGMEM: const int LUT_Therm[constLUTArraySize] PROGMEM = //LUT containing ADC values { 223, 224, 225, 226, ...


Only top voted, non community-wiki answers of a minimum length are eligible