Test Name: FLASH Memory Test.
Purpose of test: Detect all single bit faults in FLASH memory.
Requirement ID: SW_FLASH_MEMORY_CHECKSUM_CRC_TEST_01
Acceptable Measure: Modified checksum.
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:
SW_FLASH_MEMORY_CHECKSUM_CRC_TEST_01 - CRC16, SW_FLASH_MEMORY_CHECKSUM_CRC_TEST_01 - CRC32
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 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:
- 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:
- 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.
Table 1. Flash Section Locations. Flash Section Locations given Fuse settings Adapted from AVR128DA48 device data
sheet
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).