Arduino Memory Paul Mac Dougal Triembed org July
Arduino Memory Paul Mac. Dougal Triembed. org July 11, 2016
Disclaimer • I will be talking about Arduino UNO with ATmega 328 P processor. ATTiny, Edison, Cortex M 0, … will differ in important ways. • I will be talking about the 1. 6. 7 Arduino IDE. Details may differ in important ways if you are using a different IDE.
ATmega 328 P Memory • 32 k. Bytes FLASH • 2 k. Bytes internal SRAM • 1 k. Bytes EEPROM
Harvard Architecture • ATmega chips are “Harvard Architecture” • This means they have one memory for instructions (the 32 K of FLASH) and another memory for data (the 2 K of SRAM) Image from Wikipedia
Data address space • 2 K SRAM plus 256 B of interrupt vectors • Address 0 -255 – interrupt vectors • Address 256 – 2303 – SRAM – Initialized global variables (. DATA) – Uninitialized global variables (. BSS) – Heap – Stack
Program Address Space • • 32 K FLASH Addresses 0 – 32767 Initialized global variable values (. DATA) Bootloader Arduino support code Libraries Your code
IDE info • When you compile and upload a program, the IDE will tell you how much program space (FLASH) is used. • And how much data space (SRAM) is used by global variables Sketch uses 3, 694 bytes (11%) of program storage space. Maximum is 32, 256 bytes. Global variables use 304 bytes (14%) of dynamic memory, leaving 1, 744 bytes for local variables. Maximum is 2, 048 bytes.
The compiler knows all! • • . Data: __data_start to __data_end. BSS: __bss_start to __bss_end Heap: __heap_start to __brkval Stack: SP to RAMEND
You can access these symbols in your code • extern char *__data_start; • extern char *__data_end; • extern char *__bss_start; • extern char *__bss_end; • extern char *__heap_start; • extern char *__brkval; • SP • RAMEND
+--------+ + data + + variables + +----------------+ + bss + + variables + +----------------+ + + + heap + +--------+ available = 711 +--------+ + stack + +--------+ __data_start = 256 data_size = 618 __data_end-1 __bss_start = 873 = 874 bss_size = 658 __bss_end-1 __heap_start = 1531 = 1532 heap_size = 38 heap_end = 1569 Current STACK = 2280 stack_size = 23 RAMEND = 2303 Global variables use 1, 276 bytes (62%) of dynamic memory, leaving 772 bytes for local variables.
What if you want more detail? • When you install the Arduino IDE, the Atmel AVR tools are placed in: . . . hardwaretoolsavrbin – avr-nm. exe – dump symbols – avr-objdump. exe – dump more
The IDE uses a temporary directory for compiling. E. g. C: UserspaulApp. DataLocalTemp build 25 a 60484 b 83419 d 86 b 0 f 9123905 ed 449. tmp There, you will find an elf file that contains the code to be uploaded to the Arduino. You can run nm on that file: avr-nm. exe –n *. ino. elf
00000000 00000001 0000003 d 0000003 e 0000003 f 00000068 0000007 f 00000093 000000 a 7 000000 bb 000000 c 5 000000 cf 000000 da 000000 dc. . . T B D N – – – a W T a a T T t T T T T T W __tmp_reg__ __vector_default __vectors __zero_reg__ __SP_L__ __SP_H__ __SREG__ __trampolines_end __trampolines_start _ZZ 5 setup. E 3__c digital_pin_to_timer_PGM digital_pin_to_bit_mask_PGM digital_pin_to_port_PGM port_to_input_PGM port_to_output_PGM port_to_mode_PGM __ctors_start __ctors_end __dtors_start __init . text. bss. data debugging symbol 00800100. . . 0080036 a. . . 00800519 00800527 00800528 00800529 0080052 a 0080052 b 0080052 c 0080052 d 0080052 e 00800552 00800553 00800557 0080055 b 008005 f 8 008005 fa 008005 fc 00810000 D __data_start B __bss_start D __data_end b b b B B B N N N _ZL 6 buffer _ZL 5 error _ZL 5 state _ZN 8 SPIClass 13 interrupt. Save. E _ZN 8 SPIClass 13 interrupt. Mask. E _ZN 8 SPIClass 13 interrupt. Mode. E Servo. Count _ZL 7 Channel _ZL 6 servos timer 0_fract timer 0_millis timer 0_overflow_count Serial __brkval __flp __bss_end __heap_start _end __eeprom_end
So, which are your biggest routines? 00000 cc 8 00000 e 9 e 0000101 c 00001126 000012 f 8 000016 a 2 000019 b 4 00001 adc 00001 c 82 00001 f 14 00001 ff 2 bytes 00002146 T T T _Z 9 draw. Glyphhhhh _Z 17 copy. Page. To. Displaysh _Z 14 draw. Backgroundv setup _Z 10 draw. Lat. Lonfhh _Z 13 handle. Displayv _Z 10 handle_GPSv _Z 10 handle. Timev _Z 20 handle_state_machin _Z 9 handle_swv loop t. . . 470 382 266 466 938 786 296 422 658 222 bytes bytes bytes 350
How can I move stuff to FLASH? • Use PROGMEM variable modifier #include <avr/pgmspace. h> const unsigned char PROGMEM glyph. Width[] = { 0, 5, 10, 6, 10, 11, 10, 10, 10, 2, 9, 13, 11, 12, 11, 11}; uint 8_t width = pgm_read_byte_near((int)(&glyph. Width[0]) + n); ----------------------#define pgm_read_byte_near(address_short) __LPM((uint 16_t)(address_short))
Not limited to bytes • pgm_read_word_near • pgm_read_dword_near • pgm_read_float_near • pgm_read_ptr_near
PSTR() • # define PSTR(s) (__extension__({static const char __c[ ] PROGMEM = (s); &__c[0]; }))
P versions • • • • memchr_P memcmp_P memccpy_P memmem_P memrchr_P strcat_P strchrnul_P strcmp_P strcpy_P strcasecmp_P strcasestr_P strcspn_P • • • • strlcat_P strlcpy_P __strlen_P strncmp_P strncasecmp_P strncat_P strncpy_P strpbrk_P strrchr_P strsep_P strspn_P strstr_P strtok_r. P
Example #include <avr/pgmspace. h> unsigned char input. Buffer[20]; if (0 == strcmp_P(input. Buffer, PSTR("SUCCESS")) { }
F() Serial. print(“This string is in SRAM”); Serial. print(F(“This string is in FLASH”));
Resources • http: //www. nongnu. org/avr-libc/usermanual/malloc. html • wikipedia • http: //www. gammon. com. au/progmem
Backup Slides
F() WString. h class __Flash. String. Helper; #define F(string_literal) (reinterpret_cast<const __Flash. String. Helper *>(PSTR(string_literal))) size_t Print: : print(const __Flash. String. Helper *ifsh) { PGM_P p = reinterpret_cast<PGM_P>(ifsh); size_t n = 0; while (1) { unsigned char c = pgm_read_byte(p++); if (c == 0) break; if (write(c)) n++; else break; } return n; }
von Neumann Architecture • Von Neumann machines have one memory in which both instructions and data are stored Image from Wikipedia
Modified Harvard Architecture • Intel and ARM processors are “modified” Harvard. They have caches that hold either data or instructions, but both are fed from a single memory source.
• A - The symbol's value is absolute, and will not be changed by further linking. • B, b - The symbol is in the uninitialized data section (known as BSS). • C - The symbol is common. Common symbols are uninitialized data. When linking, multiple common symbols may appear with the same name. If the symbol is defined anywhere, the common symbols are treated as undefined references. For more details on common symbols, see the discussion of – warn-common in Linker options. • D, d - The symbol is in the initialized data section. • G, g - The symbol is in an initialized data section for small objects. Some object file formats permit more efficient access to small data objects, such as a global int variable as opposed to a large global array. • I - For PE format files this indicates that the symbol is in a section specific to the implementation of DLLs. For ELF format files this indicates that the symbol is an indirect function. This is a GNU extension to the standard set of ELF symbol types. It indicates a symbol which if referenced by a relocation does not evaluate to its address, but instead must be invoked at runtime. The runtime execution will then return the value to be used in the relocation. • I - The symbol is an indirect reference to another symbol. • N - The symbol is a debugging symbol. • p - The symbols is in a stack unwind section. • R, r - The symbol is in a read only data section. • S, s - The symbol is in an uninitialized data section for small objects. • T, t - The symbol is in the text (code) section. • U - The symbol is undefined. • u - The symbol is a unique global symbol. This is a GNU extension to the standard set of ELF symbol bindings. For such a symbol the dynamic linker will make sure that in the entire process there is just one symbol with this name and type in use. • V, v - The symbol is a weak object. When a weak defined symbol is linked with a normal defined symbol, the normal defined symbol is used with no error. When a weak undefined symbol is linked and the symbol is not defined, the value of the weak symbol becomes zero with no error. On some systems, uppercase indicates that a default value has been specified. • W, w - The symbol is a weak symbol that has not been specifically tagged as a weak object symbol. When a weak defined symbol is linked with a normal defined symbol, the normal defined symbol is used with no error. When a weak undefined symbol is linked and the symbol is not defined, the value of the symbol is determined in a system-specific manner without error. On some systems, uppercase indicates that a default value has been specified.
- Slides: 26