1.5 FLASH CRC
Test Name: FLASH Memory Test.
Purpose of test: Detect all single bit faults in FLASH memory.
Acceptable Measure (Annex. H): Modified checksum (H.2.19.3.1).
Description: A cyclic redundancy check (CRC) is an error detection technique used to find accidental errors in invariable memory. This method is commonly used to determine the correctness of data transmissions and data present in FLASH memory. Test should compute a checksum of the data and store it. In order to detect errors, a new checksum is computed on the same data and compared with the previous one. If they are different, there is an error.
- Two commonly used CRC standards are
supported:
- 16-bit CRC CCITT
- 32-bit CRC
- Two software implementations are
supported:
- Lookup table: This uses a CRC look-up table to speed up the computations. The look-up table requires 512 (for 16-bit) or 1024 (for 32-bit) bytes of flash memory.
- Direct computation: This calculates the checksum for each byte using a polynomial division. This version occupies no space in the Flash memory but is slower than the lookup table method.
API Documentation: FLASH - 16-bit CRC, FLASH - 32-bit CRC
Note that the AoUs listed in the Assumption of Use section below shall be followed to ensure correct operation. The Examples section show examples of how follow some of the AoUs for different use cases and different devices.
Assumptions of Use
- AoU-FLASH_MEMORY_CHECKSUM_CRC_TEST-01: Case 1 shown in Table 1-1 shall not be used when the Flash CRC test is included in the
application.
Reason: Since Case 1 configures the entire Flash as a BOOT section, the NVM controller will not be able to write to any address in the Flash and will not be able to store the calculated CRC value as a result.
- AoU-FLASH_MEMORY_CHECKSUM_CRC_TEST-02: The end address of the flash must
be restricted through linker options in the following way, given each case presented
in Table 1-1:
- Case 1: shall not be used
- Case 2: the Flash shall be restricted to end at BOOTEND
- Case 3: the Flash shall be restricted to end at BOOTEND
- Case 4: the Flash shall be restricted to end at APPEND
by adding the linker option:
-Wl,–defsym=__TEXT_REGION_LENGTH__=new_length
where:
- Case 1: shall not be used
- Case 2: new_length = size of the BOOT section
- Case 3: new_length = size of the BOOT section
- Case 4: new_length = size of the BOOT section + size of the APPCODE section
Reason: This ensures that the linker does not place the Flash write routines, provided in the NVMCTRL driver, in the same section that it is writing to. Additionally, it ensures that storing the CRC bytes does not overwrite any program code or program data in the Flash. Please refer to the device data sheet under the NVMCTRL section for more information. Note that in MPLAB X 5.50, such a linker option can be added by going to Project Properties -> XC8 Global Options -> XC8 Linker and add the command in "Additional Optons".
- AoU-FLASH_MEMORY_CHECKSUM_CRC_TEST-03: It is the responsibility of the
system integrator to ensure that the store address for the CRC bytes resides in the
following section, given each case presented in Table 1-1:
- Case 1: shall not be used
- Case 2: APPCODE
- Case 3: APPDATA
- Case 4: APPDATA
Reason: Routines running in the BOOT Flash section can only write to the APPCODE and APPDATA Flash sections. Routines running in the APPCODE Flash section can only write to the APPDATA Flash sections. Routines running in the APPDATA Flash sections cannot write to any Flash section.
- AoU-FLASH_MEMORY_CHECKSUM_CRC_TEST-04: It is the responsibility of the system integrator to ensure that the memory section where the CRC bytes are stored, defined by the value of the store address, does not overlap with any other data used by the application.
Case | BOOTSIZE* | CODESIZE** | BOOT Section | APPCODE Section | APPDATEA Section |
---|---|---|---|---|---|
1 | 0 | - | 0 to FLASHEND | - | - |
2 | > 0 | 0 | 0 to BOOTEND | BOOTEND to FLASHEND | - |
3 | > 0 | ≤ BOOTSIZE* | 0 to BOOTEND | - | BOOTEND to FLASHEND |
4 | > 0 | > BOOTSIZE* | 0 to BOOTEND | BOOTEND to APPEND | APPEND to FLASHEND |
*Fuse name may differ between device families (BOOTSIZE on AVR DA devices and BOOTEND on Tiny1 devices), but the functionality is the same.
**Fuse name may differ between device families (CODESIZE on AVR DA devices and APPEND on Tiny1 devices), but the functionality is the same.
AoU-02 and AoU-03 Examples
AVR64DA48
The AVR64DA48 has a Flash size equal to 0x10000 bytes (64 kB) and the functional description in the device data sheet under the NVMCTRL section lists a block size of 512 or 0x200 bytes. The number of blocks available in the Flash is given by dividing the Flash size by the block size, which yields:
0x10000 / 0x200 = 0x80 blocks
- Case 2: Using the fuse values equal to e.g. BOOTSIZE = 0x7F and CODESIZE = 0x0 results in a BOOT section with a size of 0x7F * 0x200 = 0xFE00, an APPCODE section with size of one block (0x200 bytes) and no APPDATA section. In this configuration, the storeAddress of the CRC bytes must reside in the APPCODE section and the following linker flag must be used: -Wl,–defsym=__TEXT_REGION_LENGTH__=0xFE00 where all the program code and data will be placed inside the BOOT section by the linker.
- Case 3: Using the fuse values equal to e.g. BOOTSIZE = 0x7F and CODESIZE = 0x1 results in a BOOT section with a size of 0x7F * 0x200 = 0xFE00 bytes, no APPCODE section and an APPDATA section equal to one block (0x200 bytes). In this configuration, the storeAddress of the CRC bytes must reside in the APPDATA section and the following linker flag must be used: -Wl,–defsym=__TEXT_REGION_LENGTH__=0xFE00 where all the program code and data will be placed inside the BOOT section by the linker.
- Case 4: Using the fuse values equal to e.g. BOOTSIZE = 0x1 and CODESIZE = 0x7F results in a BOOT section with a size equal to one block (0x200 bytes), an APPCODE section with a size of (0x7F – 0x1) * 0x200= 0xFC00 bytes and an APPDATA section equal to one block (0x200 bytes). In this configuration, the storeAddress of the CRC bytes must reside in the APPDATA section and the following linker flag must be used (where size of the BOOT section + size of the APPCODE section = 0x200 + 0xFC00 = 0xFE00): -Wl,–defsym=__TEXT_REGION_LENGTH__=0xFE00 where all the program code and data will be placed inside both the BOOT and APPCODE section by the linker (unless otherwise specified by other linker options to place a bootloader in the BOOT section for instance).
- Note: It is possible to reserve more than one block in APPCODE (case 2) or APPDATA (case 3 and 4) if required. As an example, for case 2: Using the fuse values equal to e.g. BOOTSIZE = 0x50 and CODESIZE = 0x0 results in a BOOT section with a size of 0x50 * 0x200 = 0xA000, an APPCODE section with the size of 0x30 blocks (0x6000 bytes) and no APPDATA section. In this configuration, the storeAddress of the CRC bytes must reside in the APPCODE section and the following linker flag must be used: -Wl,–defsym=__TEXT_REGION_LENGTH__=0xA000 where all the program code and data will be placed inside the BOOT section by the linker.
ATtiny1617
The ATtiny1617 has a Flash size equal to 0x4000 bytes (16 kB) and the functional description in the device data sheet under the NVMCTRL section lists a block size of 256 or 0x100 bytes. The number of blocks available in the Flash is given by dividing the Flash size by the block size, which yields:
0x4000 / 0x100 = 0x40 blocks
- Case 2: Using the fuse values equal to e.g. BOOTEND = 0x3F and APPEND = 0x0 results in a BOOT section with a size of 0x3F * 0x100 = 0x3F00, an APPCODE section with size of one block (0x100 bytes) and no APPDATA section. In this configuration, the storeAddress of the CRC bytes must reside in the APPCODE section and the following linker flag must be used: -Wl,–defsym=__TEXT_REGION_LENGTH__=0x3F00 where all the program code and data will be placed inside the BOOT section by the linker.
- Case 3: Using the fuse values equal to e.g. BOOTEND = 0x3F and APPEND = 0x1 results in a BOOT section with a size of 0x3F * 0x100 = 0x3F00 bytes, no APPCODE section and an APPDATA section equal to one block (0x100 bytes). In this configuration, the storeAddress of the CRC bytes must reside in the APPDATA section and the following linker flag must be used: -Wl,–defsym=__TEXT_REGION_LENGTH__=0x3F00 where all the program code and data will be placed inside the BOOT section by the linker.
- Case 4: Using the fuse values equal to e.g. BOOTEND = 0x1 and APPEND = 0x3F results in a BOOT section with a size equal to one block (0x100 bytes), an APPCODE section with a size of (0x3F – 0x1) * 0x100= 0x3E00 bytes and an APPDATA section equal to one block (0x100 bytes). In this configuration, the storeAddress of the CRC bytes must reside in the APPDATA section and the following linker flag must be used (where size of the BOOT section + size of the APPCODE section = 0x100 + 0x3E00 = 0x3F00): -Wl,–defsym=__TEXT_REGION_LENGTH__=0x3F00 where all the program code and data will be placed inside both the BOOT and APPCODE section by the linker (unless otherwise specified by other linker options to place a bootloader in the BOOT section for instance).
- Note: It is possible to reserve more than one block in APPCODE (case 2), APPDATA (case 3 and 4) and BOOT (case 4) if required. As an example, for Case 4: Using the fuse values equal to e.g. BOOTEND = 0x5 and APPEND = 0x20 results in a BOOT section with a size equal to 0x5 blocks (0x500 bytes), an APPCODE section with a size of (0x20 – 0x5) * 0x100 = 0x1500 bytes and an APPDATA section equal to 0x40 - 0x20 - 0x5 = 0x1B blocks (0x1B00 bytes). In this configuration, the storeAddress of the CRC bytes must reside in the APPDATA section and the following linker flag must be used (where size of the BOOT section + size of the APPCODE section = 0x500 + 0x1500 = 0x1A00): -Wl,–defsym=__TEXT_REGION_LENGTH__=0x1A00 where all the program code and data will be placed inside both the BOOT and APPCODE section by the linker (unless otherwise specified by other linker options to place a bootloader in the BOOT section for instance).