ATMEGA32 Flash Memory Organization
In ATMEGA32 MCU, The Flash memory is divided into two sections, one Application section and one Boot Loader section. The Application section contains the main code for the application, while the Boot Loader section contains the code for the actual Self-programming. The SPM (Store Program Memory) instruction can only be executed from the Boot Loader section. but, this doesn’t mean you can’t use The Boot Loader section for ordinary application code as our example would show. The Flash memory is divided into pages containing 64 words (128 byte) each. The entire memory span, both Application and Boot Loader sections, is divided into pages.
The size of the Boot Loader section can be selected using the BOOTSZ0 and BOOTSZ1 Fuses. The fuses select one of four predefined sizes. The BOOTSZx Fuses can be changed using Serial or Parallel Programming. If a Boot Loader is implemented, it can be called either directly from the Application code using calls or jumps(which we would implement), or by programming the BOOTRST Fuse. When the BOOTRST Fuse is programmed, the CPU will start execution in the Boot Loader section on Reset, instead of starting at address 0x0000. The BOOTRST Fuse can be changed using Serial or Parallel Programming also.
In addition to the selectable division between the application and Boot Loader sections, the Flash is also divided into two fixed-size sections. The first section is the Read-While Write (RWW) section. The second is the No-Read-While-Write (NRWW) section. The NRWW section size always equals the largest selectable Boot Loader section size, thus the Boot Loader section occupies all or part of the NRWW section.
The difference between the sections is that the NRWW section is accessible while updating the RWW section. It is not possible to access the RWW section when it’s being updated. When the NRWW is updated (like when updating the Boot Loader code itself), the CPU is halted during the whole operation. In other words, No-Read-While-Writing to the NRWW section, but possible to Read-While-Writing to the RWW section. This functionality makes it possible to continue execution of critical code while updating the RWW section.
Using the SPM Instruction
All Self-programming operations are performed using the SPM (Store Program Memory) instruction. The operation is selected using the SPMCR Register
When using the SPM function:
1.the SPMEN bit must always be set within four cycles prior to executing the SPM instruction to prevent unintentional Flash updates.
2.all interrupts must be disabled between setting the SPMEN bit and executing the SPM instruction, thus exceeding the 4-cycle limit.
3.Before writing new data to a page, the page must be erased.
4.The Z-register is used to select the page to be erased. Set up the Z-register to point to a byte in the page to be erased. The lower bits selecting the byte within the page are ignored. register are ignored.
5.To erase a page, set the PGERS and SPMEN bits and execute the SPM instruction.
6.Loading Page Buffer To write new data to a page, The Page Buffer is a separate (not SRAM) write-only buffer holding one temporary page. This buffer must be filled word by word. The buffer is copied to Flash memory in one operation. The Z-register is used to select the word to be written into the buffer. The LSB of Z is ignored, as an entire word is always written in one operation. Single byte access is not possible.
7. To write a word to the Page Buffer, load the word into the R1:R0 Registers. Set the Z-register to point to the correct word and set only the SPMEN bit.
8. Page Write When the Page Buffer is loaded with new data, it must be written to Flash memory. To do this, set up the Z-register the same way as described before. Then set the PGWRT and SPMEN bits in the SPMCR Register and execute the SPM instruction within four cycles.
9. if the RWW section accessed without re-enabling it after an erase or write operation, all addresses in the RRW section read 0xFFFF. This applies both when reading the Flash using LPM(Load Program Memory) and if performing calls or jumps into the RWW section. The consequence of performing a jump into the RWW section without enabling it will therefore be that the program code “0xFFFF” is executed, eventually leading to that the program counter “falls” through the code space until it meets the first executable code. The first executable code would in that case be encountered on the first address of the NRWW section.
10. All write operations to the EEPROM must be finished before executing the SPM instruction and vice versa. Write/erase of the Flash and EEPROM cannot occur simultaneously.
The application and Boot Loader section can be protected on different levels using the lock bits. There are four levels of protection for both sections.
the example is made using the Atmega32, so all code will be tailored to that chip.
Code was developed in Atmel studio 7.
the source files are uploaded on bitbucket FOUND HERE
to run the program :
1.unprogram the BOOTSZ0 and BOOTSZ1 to configure the smallest boot section size, cause the code size of the bootloader section is less that 128 word.
2. Add the bootloader section to the linker configurations, so it knows where to place our flash memory writing function by right clicking on your project in the “solution explorer” and clicking “properties”
- Select “All Configurations” from Configurations.
- Click “Memory Settings” under AVR/GNU Linker.
- Click the green plus for the FLASH segment.
- Type “.bootloader=[start address of your bootloader section as defined by your fuse selection]” 0x3F00 if your BOOTsz0 and BOOTsz1 are unprogrammed.
- Hit OK.
- build the example project.
- download it to your controller.
This concludes bootloader explanation, in the next article I’m gonna talk about bootloader design for embedded systems.
If you have any question concerning the article, you can leave it as a comment.follow us on our facebook page and stay tuned.