Self-diagnostic test for coupling faults in internal SRAM memory.
The test classb_sram_test() divides the internal SRAM into CLASSB_NSECS sections that are tested in turns with a March algorithm (see March X). The simplest behavior of the test is when there is no overlap between memory sections. In this case all sections have the same size, except possibly the last one (see CLASSB_NSECS). The first memory section (referred to as the buffer) is reserved: it is used by the test to store the content of the other sections while they are being tested (for more details see classb_buffer).
If there is overlap (see CLASSB_OVERLAP), every time a memory section is tested, a part of the previous section is tested as well. Note that this does not apply to the buffer, since it is the first section. The size of the buffer is then expanded with respect to the previous case. Further, the size of the second section is decreased correspondingly.
If there should be an error in internal SRAM the error handler CLASSB_ERROR_HANDLER_SRAM() would be called.
The chosen algorithm is March X. This consists on the following steps:
\[ \Updownarrow ( w_\mathbf{D} ) ; \Uparrow ( r_\mathbf{D} , w_{\bar{\mathbf{D}}} ); \Downarrow ( r_{\bar{\mathbf{D}}} , w_\mathbf{D} ); \Updownarrow ( r_\mathbf{D} ) \; , \]
where \(w\) denotes a write operation, \(r\) denotes a read operation, \(\mathbf{D}\) is any data background, \(\bar{\mathbf{D}}\) is the complement of \(\mathbf{D}\) and the arrows refer to the addressing order. In our implementation we have chosen \(\mathbf{D} = \textnormal{0x00}\).
Under the restricted coupling faults (CFs) model, the interleaved organization of the memory in XMEGA avoids any kind of intra-word CFs. However, in order to detect some intra-word CFs that are not considered by this fault model, we have included the following optional march element:
\[ \Updownarrow ( w_\mathbf{D_0} , r_\mathbf{D_0} , \ldots , w_\mathbf{D_d} , r_\mathbf{D_d}) \; , \]
where the background sequence is \( \textnormal{0x00, 0xFF, 0x55, 0xAA, 0x33, 0xCC, 0x0F, 0xF0} \). This intra-word test is only executed if CLASSB_SRAM_INTRAWORD_TEST is defined. The elements that correspond to the first two data backgrounds are redundant because the first part of the test includes them. This optional test will detect all intra-word state CFs considered by the unrestricted CF model.
Functions | |
void | classb_march_x (register volatile uint8_t *p_sram, register volatile uint8_t *p_buffer, register uint16_t size) |
Run March X algorithm on specified memory range. More... | |
uint8_t | classb_buffer [CLASSB_SEC_SIZE+CLASSB_OVERLAP_SIZE] |
Buffer for temporary storage of SRAM sections during test. More... | |
Configuration settings | |
#define | CLASSB_NSECS 16 |
Number of sections to divide the SRAM into for testing. More... | |
#define | CLASSB_OVERLAP 25UL |
Overlap between memory sections (in % of CLASSB_SEC_SIZE ). More... | |
#define | CLASSB_SRAM_INTRAWORD_TEST |
Configuration to enable intra-word test. More... | |
Constants for internal use | |
| |
#define | CLASSB_SEC_SIZE (INTERNAL_SRAM_SIZE / CLASSB_NSECS) |
Size of each segment, in bytes. More... | |
#define | CLASSB_SEC_REM (INTERNAL_SRAM_SIZE % CLASSB_NSECS) |
Size of the last test segment, in bytes. More... | |
#define | CLASSB_OVERLAP_SIZE ((CLASSB_SEC_SIZE * CLASSB_OVERLAP) / 100) |
Size of overlap in bytes. More... | |
#define | CLASSB_NSEC_TOTAL CLASSB_NSECS |
Total number of segments including remainder, if present. More... | |
Class B test | |
void | classb_sram_test (void) |
Execute March X test on one memory section at a time. More... | |
#define CLASSB_NSEC_TOTAL CLASSB_NSECS |
Total number of segments including remainder, if present.
Referenced by classb_sram_test().
#define CLASSB_NSECS 16 |
Number of sections to divide the SRAM into for testing.
It is advisable that INTERNAL_SRAM_SIZE
is divisible by the number of sections and, therefore, recommended values are 2, 4, 8, 16, etc. Otherwise an extra section will be added with the remainder of the division as size.
Note that the higher the number of sections, the smaller the size of classb_buffer, i.e. the section of memory that is reserved for the test) and the faster each partial test is completed.
Referenced by classb_sram_test(), and oven_classb_run_tests().
#define CLASSB_OVERLAP 25UL |
Overlap between memory sections (in % of CLASSB_SEC_SIZE
).
#define CLASSB_OVERLAP_SIZE ((CLASSB_SEC_SIZE * CLASSB_OVERLAP) / 100) |
Size of overlap in bytes.
When testing a memory section, the algorithm starts CLASSB_OVERLAP_SIZE
bytes before the start address of the section.
Referenced by classb_sram_test().
#define CLASSB_SEC_REM (INTERNAL_SRAM_SIZE % CLASSB_NSECS) |
Size of the last test segment, in bytes.
This indicates the remaining bytes to test in the case when INTERNAL_SRAM_SIZE
is not divisible by CLASSB_NSECS.
Referenced by classb_sram_test().
#define CLASSB_SEC_SIZE (INTERNAL_SRAM_SIZE / CLASSB_NSECS) |
Size of each segment, in bytes.
Referenced by classb_sram_test().
#define CLASSB_SRAM_INTRAWORD_TEST |
Configuration to enable intra-word test.
Defining this symbol will add intra-word testing after the inter-word test.
Given the layout of the memory, the probability of intra-word coupling faults is greatly diminished. However, for extra safety, the test can be expanded to check some intra-word coupling faults.
void classb_march_x | ( | register volatile uint8_t * | p_sram, |
register volatile uint8_t * | p_buffer, | ||
register uint16_t | size | ||
) |
Run March X algorithm on specified memory range.
The following steps are followed:
This function requires that all variables are placed in registers by the compiler. This is achieved by using the register
specifier (probably not necessary if the right level of optimization is chosen).
If there should be an error in SRAM a local variable (implemented in a register) would be flagged. This would lead to the error handler CLASSB_ERROR_HANDLER_SRAM() being called.
p_sram | Pointer to first byte in memory area to be tested |
p_buffer | Pointer to first byte in the buffer |
size | Size of area to be tested in bytes. |
References CLASSB_ERROR_HANDLER_SRAM.
Referenced by classb_sram_test().
void classb_sram_test | ( | void | ) |
Execute March X test on one memory section at a time.
This function keeps track of which section to test, and tests them in order.
The test behaves as follows for a general section:
CLASSB_SEC_SIZE
.CLASSB_SEC_SIZE
+ CLASSB_OVERLAP_SIZE
.CLASSB_OVERLAP_SIZE
bytes before the start of the current section, thus overlapping CLASSB_OVERLAP_SIZE
bytes with the previous section.Special cases of memory sections are:
INTERNAL_SRAM_START
and is of size CLASSB_SEC_SIZE
+ CLASSB_OVERLAP_SIZE
. In this case there is no previous segment, so no overlap is necessary. The total number of bytes to test is then the size of the buffer.CLASSB_SEC_SIZE
- CLASSB_OVERLAP_SIZE:
the size of this section was reduced by CLASSB_OVERLAP_SIZE
bytes in order to expand the buffer by the same number of bytes. The test starts CLASSB_OVERLAP_SIZE
bytes before the beginning of the section, and * the total number of bytes tested is then CLASSB_SEC_SIZE
.CLASSB_SEC_REM
, so the total number of bytes to test will be CLASSB_SEC_REM
+ CLASSB_OVERLAP_SIZE
. References classb_buffer, classb_march_x(), CLASSB_NSEC_TOTAL, CLASSB_NSECS, CLASSB_OVERLAP_SIZE, CLASSB_SEC_REM, and CLASSB_SEC_SIZE.
Referenced by oven_classb_run_tests(), and ovenctl_periodic_classb_tests().
uint8_t classb_buffer[CLASSB_SEC_SIZE+CLASSB_OVERLAP_SIZE] |
Buffer for temporary storage of SRAM sections during test.
This buffer is placed in the beginning of SRAM, and its size in Bytes should be (INTERNAL_SRAM_SIZE
/ CLASSB_NSECS
) + CLASSB_OVERLAP_SIZE
.
As an example, let us suppose the device has INTERNAL_SRAM_SIZE
= 4096 Bytes of SRAM, CLASSB_NSECS = 8 and CLASSB_OVERLAP = 25. Since the number of sections is a divisor of INTERNAL_SRAM_SIZE
, there would be exactly 8 sections, each with a size of 512 Bytes. With 25% overlap, we need to extend the first section (the buffer) by 128 Bytes, and the second section is shortened accordingly. Therefore, we would have to reserve 512 + 128 = 640 Bytes for the buffer.
Refer to the compiler's device header file for INTERNAL_SRAM_START
and INTERNAL_SRAM_SIZE
.
The implementation depends on the compiler:
For IAR it is easy because variables can be placed in a specific address using the location pragma directive.
For GCC the following steps should be followed:
INTERNAL_SRAM_START
, for example:.data
section has to be moved so that there is no overlap, i.e., the start should be INTERNAL_SRAM_START
+ the buffer size. Continuing on the earlier example, we get a buffer size of 640 = 0x280, so we would need to set:Referenced by classb_sram_test().