2 Overview
Flash memory is organized into pages consisting of several words. In general for AVR, a word is 2 bytes or 16 bits. For the AVR EA, the page size is 128 bytes. Independent of page size, the Flash is split into two physical sections: Non Read-While-Write (NRWW) and Read-While-Write (NRWW). The NRWW section starts at the start of the Flash and, by that, overlaps the BOOT section and the APPCODE/APPDATA section, depending on the fuse settings. It’s important to note that writing to the same section as the code is running from is impossible. In the example where the NRWW overlaps the boundary between the BOOT/APPCODE or BOOT/APPDATA sections, the uninterrupted code needs to be placed in the BOOT section to run while an erase/write cycle is underway in APPCODE/APPDATA. If configuring to have BOOT/APPCODE/APPDATA, the uninterrupted code can also be in the NRWW part of the APPCODE section to program APPDATA without halting the CPU.
The syntax "RWW section" refers to which section is being programmed (erased or written) and not the one read. Only code located inside the NRWW Flash is accessible by either executing a CPU instruction or reading data while programming the RWW section.
It follows that the main differences between the NRWW and RWW sections are:
- When erasing or writing to a page located inside the RWW section using code running from the NRWW section, code and data can continue to be run and read from the NRWW section, enabling the continuous operation of the CPU while the program memory operation is running.
- When erasing or writing to a page in the NRWW section, the CPU is halted during the operation. An exception to this is when writing from the BOOT section to the APPCODE or APPDATA section that overlaps with the NRWW section.
- One example is a Bootloader scenario where the CPU acts upon commands received via a communication peripheral (I2C/USART) from the Host while simultaneously programming the APPCODE/APPDATA sections in program memory
- Another use case is a data logging scenario in which an analog peripheral interrupts CPU operation when data that at once must to be saved to program memory, becomes available
To understand how to implement the Read-While-Write (RWW) feature on AVR EA, it helps to look at the program memory from a Physical, Logical, and Code/Data Space point of view. Physically, the program memory is designed with fixed NRWW and RWW sections. These are non-changeable and depend on the part number - see the "Memory Overview" section in the data sheet. Store the code and data in the respective physical sections to use the RWW use case.
The Logical sections are BOOT, APPCODE and APPDATA. These sections can be adjusted through the BOOTSIZE and CODESIZE fuses, as shown in the image below. Note - depending on the fuse configuration, the physical NRWW section can be used for both BOOT and APPCODE/APPDATA. See the data sheet in the NVMCTRL peripheral Memory Organization section for a detailed explanation. Note that you can access the code space via the data space through the Flash mapping feature, available on devices with a program memory exceeding 32kB. See the data sheet in the NVMCTRL peripheral Memory Access section for a detailed explanation.
To implement this allocation, linker-named attributes with assigned addresses are given as linker options, and the named attributes are used when declaring both functions and data.
// the .rww_data section is at address 0x2000 (word address 0x1000) #define RWW_DATA_SECTION __attribute__((used, section(".rww_data"))) const RWW_DATA_SECTION uint8_t rww_array[DATA_SIZE] = {0};
// the .nrww_program section is at address 0x0400 (word address 0x0200) #define NRWW_PROG_SECTION __attribute__((section(".nrww_program"))) void NRWW_SECTION_CODE FillBuffer(void);
Use the RWW_PROG_SECTION attribute for routines that will not execute during Flash programming or erase. These are blocking and must be placed in the physical RWW section. Examples of these are the setup routines.
Below is an example of the use of attribute sections.
If using a bootloader in the project, the bootloader code is placed first, from the Flash start (0x0000) until the BOOTEND (BOOTSIZE *256 -1). The BOOTSIZE fuse settings determine the BOOT section size. The Application code (App code) is placed after the BOOT (as long as CODESIZE > BOOTSIZE), which means that the application code may reside both in NRWW and RWW, making it possible to move functions into the NRWW section. Functions or interrupts placed in the NRWW section can run while erasing/writing the RWW section. However, take steps to ensure there are no interrupts or jumps to code located inside the RWW while operation on the RWW is ongoing, leading to the software ending up in an unknown state.
Flash Section Erased/Written | Flash Section Accessed | CPU |
---|---|---|
NRWW section | NRWW section | Halted |
RWW section | NRWW section | Running |
NRWW section | RWW section | Halted |
RWW section | RWW section | Halted |
Find the Flash memory size and the NRWW/RWW sections in the AVR EA’s data sheet.