Add verification for SRAM

Source: Internet
Author: User

The data in the product's SRAM is inexplicably messy and has encountered many problems. It has not been determined the cause, one of the reasons is that the backup battery is not powered, and the voltage is too low, causing data loss. After blocking this cause, there will still be a problem with zero stars in the future, there has never been an effective solution.

Finally, I couldn't stand it. I was prepared to launch a program and add Error Correction Codes to the data in the SRAM. Like the NAND Flash verification, at least I could detect whether it was a human-caused data disorder, if the data is not disordered, the program will prompt that the data has encountered an error. It uses 12k-word by 16bit SRAM. Due to the tight SRAM space, only 1 kb of word space is extracted for storing the verification code ).

After studying the ECC verification algorithm of NAND Flash, we finally decided to divide the entire SRAM space into 256 pages based on 512 word/page, with three verification bytes for each page, the size of all page verification bytes is 1.5 kbyte. The solution is feasible and put into practice.

First, modify the algorithm. Since the ECC algorithm of NAND Flash uses 256 Bytes/page for verification, we must modify the algorithm based on the actual situation of 256 wrod/page. I will not repeat the original ECC verification algorithm here because of the many online verification algorithms. I only paste the modified algorithm code.

# Include "sramecc. H"

Static inline int countbits (int16u byte)
{
Int res = 0;

For (; byte> = 1)
Res + = byte & 0x01;
Return res;
}

Static int32s sram_calculate_ecc (const int16u * data, int8u * ecc_code, int16u ecc_code_num)
{
Int16u I, idx;
Int8u reg1, reg2, reg3, tmp_ecc0, tmp_ecc1;

Reg1 = 0;
Reg2 = 0;
Reg3 = 0;
Tmp_ecc0 = 0;
Tmp_ecc1 = 0;
 
For (I = 0; I <256; I ++)
{
// Get cp0 ~ CP7 from table
If (I <ecc_code_num)
Idx = ecc_precalc_table [* Data ++];
Else
Idx = ecc_precalc_table [0];

Reg1 ^ = (idx & 0xff );

// Row bit XOR is 1
If (idx & 0x100)
{
Reg3 ^ = I;
Reg2 ^ = ~ I;
}
}
// Printf ("reg2: % x reg3: % x \ n", reg2, reg3 );
//---------------------------------------------------------
// | Reg2 | rp14 | rp12 | rp10 | rp8 | rp6 | rp4 | RP2 | Rp0 |
// | --------------------------------------------------------
// | Reg3 | rp15 | rp13 | rp11 | rp9 | RP7 | rp5 | RP3 | RP1 |
//---------------------------------------------------------

// Adjust
Tmp_ecc1 | = (reg3 & 0x80)> 0; // rp15
Tmp_ecc1 | = (reg2 & 0x80)> 1; // rp14
Tmp_ecc1 | = (reg3 & 0x40)> 1; // rp13
Tmp_ecc1 | = (reg2 & 0x40)> 2; // rp12
Tmp_ecc1 | = (reg3 & 0x20)> 2; // rp11
Tmp_ecc1 | = (reg2 & 0x20)> 3; // rp10
Tmp_ecc1 | = (reg3 & 0x10)> 3; // rp9
Tmp_ecc1 | = (reg2 & 0x10)> 4; // rp8

Tmp_ecc0 | = (reg3 & 0x08) <4; // RP7
Tmp_ecc0 | = (reg2 & 0x08) <3; // rp6
Tmp_ecc0 | = (reg3 & 0x04) <3; // rp5
Tmp_ecc0 | = (reg2 & 0x04) <2; // rp4
Tmp_ecc0 | = (reg3 & 0x02) <2; // RP3
Tmp_ecc0 | = (reg2 & 0x02) <1; // RP2
Tmp_ecc0 | = (reg3 & 0x01) <1; // RP1
Tmp_ecc0 | = (reg3 & 0x01) <0; // Rp0

Ecc_code [0] = tmp_ecc0;
Ecc_code [1] = tmp_ecc1;
Ecc_code [2] = reg1;
// Printf ("tmp_ecc0: % x \ n", tmp_ecc0, tmp_ecc1, reg1 );
Return 0;
}

Static int32s sram_correct_data (int16u * data, int8u * read_ecc, int8u * calc_ecc)
{
Int8u S0, S1, S2;

S0 = calc_ecc [0] ^ read_ecc [0];
S1 = calc_ecc [1] ^ read_ecc [1];
S2 = calc_ecc [2] ^ read_ecc [2];
# Ifdef ecc_debug
// Printf ("sram_correct_data! \ N ");
// Printf ("calc_ecc: 0x % x 0x % x 0x % x \ n", calc_ecc [0], calc_ecc [1], calc_ecc [2]);
// Printf ("read_ecc: 0x % x 0x % x 0x % x \ n", read_ecc [0], read_ecc [1], read_ecc [2]);
Printf ("% 2x % 2x % 2x,", S0, S1, S2 );
# Endif
If (S0 | S1 | S2) = 0)
{
Return 0;
}

If (S0 ^ (S0> 1) & 0x55) = 0x54 &&
(S1 ^ (S1> 1) & 0x55) = 0x55 &&
(S2 ^ (s2> 1) & 0x55) = 0x55)
{
Int32u byteoffs = 0, bitnum = 0;
Byteoffs | = (S1 <0) & 0x80; // rp15
Byteoffs | = (S1 <1) & 0x40; // rp13
Byteoffs | = (S1 <2) & 0x20; // rp11
Byteoffs | = (S1 <3) & 0x10; // rp9

Byteoffs | = (S0> 4) & 0x08; // RP7
Byteoffs | = (S0> 3) & 0x04; // rp5
Byteoffs | = (S0> 2) & 0x02; // RP3
Byteoffs | = (S0> 1) & 0x01; // RP1

// The value of bitnum is the bit which error
Bitnum | = (s2> 4) & 0x08;
Bitnum | = (s2> 3) & 0x04;
Bitnum | = (s2> 2) & 0x02;
Bitnum | = (s2> 1) & 0x01;

// Correct data
Data [byteoffs] ^ = (1 <bitnum );

# Ifdef ecc_debug
Printf ("data [% 2x] = % 4x % x,", byteoffs, data [byteoffs], bitnum );
# Endif
Return 1;
}
Else if (countbits (S0 | (int16u) S1 <8) | (int16u) S2 <16) = 1)
{
Return 1;
}
Else
{
Printf ("Page: % d \ n", (data-pvirtualaddress)/256 );
Printf ("calc_ecc: 0x % x 0x % x 0x % x \ n", calc_ecc [0], calc_ecc [1], calc_ecc [2]);
Printf ("read_ecc: 0x % x 0x % x 0x % x \ n", read_ecc [0], read_ecc [1], read_ecc [2]);
Return 2;
}
}

Compared with the 256 byte/Page algorithm, there are not many changes, but to be honest, there are only a few changes, which took me a whole day, I don't fully understand whether the original Chu algorithm dared to work ~ Sramecc. h stores the ecc_precalc_table. This table contains 65536 pre-calculated verification codes, of which the low 8 bits are the column check bits and the 8th bits are the row check bits. There is a lot of data, and you can generate it by knowing the algorithm, it is not listed here. The code for generating the algorithm is as follows:

# Define bit0 (x) & 0x0001)> 0)
# Define bit1 (x) & 0x0002)> 1)
# Define bit2 (x) & 0x0004)> 2)
# Define bit3 (x) & 0x0008)> 3)
# Define bit4 (x) & 0x0010)> 4)
# Define bit5 (x) & 0x0020)> 5)
# Define bit6 (x) & 0x0040)> 6)
# Define bit7 (x) & 0x0080)> 7)
# Define bit8 (x) & 0x0100)> 8)
# Define bit9 (x) & 0x0200)> 9)
# Define bit10 (x) & 0x0400)> 10)
# Define bit11 (x) & 0x0800)> 11)
# Define bit12 (x) & 0x1000)> 12)
# Define bit13 (x) & 0x2000)> 13)
# Define bit14 (x) & 0X4000)> 14)
# Define bit15 (x) & 0x8000)> 15)

# Include <stdio. h>

Int main (void)
{
Int I, j = 0;
Unsigned short xbyte;
For (I = 0; I <65536; I ++)
{
Xbyte = 0;
If (bit0 (I) ^ bit2 (I) ^ bit4 (I) ^ bit6 (I) ^ bit8 (I) ^ bit10 (I) ^ bit12 (I) ^ bit14 (I ))
Xbyte | = 0x0001;
If (bit1 (I) ^ bit3 (I) ^ bit5 (I) ^ bit7 (I) ^ bit9 (I) ^ bit11 (I) ^ bit13 (I) ^ bit15 (I ))
 
Xbyte | = 0x0002;
If (bit0 (I) ^ bit1 (I) ^ bit4 (I) ^ bit5 (I) ^ bit8 (I) ^ bit9 (I) ^ bit12 (I) ^ bit13 (I ))
Xbyte | = 0x0004;
If (bit2 (I) ^ bit3 (I) ^ bit6 (I) ^ bit7 (I) ^ bit10 (I) ^ bit11 (I) ^ bit14 (I) ^ bit15 (I ))
Xbyte | = 0x0008;

If (bit0 (I) ^ bit1 (I) ^ bit2 (I) ^ bit3 (I) ^ bit8 (I) ^ bit9 (I) ^ bit10 (I) ^ bit11 (I ))
Xbyte | = 0x0010;
If (bit4 (I) ^ bit5 (I) ^ bit6 (I) ^ bit7 (I) ^ bit12 (I) ^ bit13 (I) ^ bit14 (I) ^ bit15 (I ))
Xbyte | = 0x0020;
If (bit0 (I) ^ bit1 (I) ^ bit2 (I) ^ bit3 (I) ^ bit4 (I) ^ bit5 (I) ^ bit6 (I) ^ bit7 (I ))
Xbyte | = 0x0040;
If (bit8 (I) ^ bit9 (I) ^ bit10 (I) ^ bit11 (I) ^ bit12 (I) ^ bit13 (I) ^ bit14 (I) ^ bit15 (I ))
Xbyte | = 0x0080;

If (bit0 (I) ^ bit1 (I) ^ bit2 (I) ^ bit3 (I) ^ bit4 (I) ^ bit5 (I) ^ bit6 (I) ^ bit7 (I) ^ bit8 (I) ^ bit9 (I) ^ bit10 (I) ^ bit11 (I) ^ bit12 (I) ^ bit13 (I) ^ bit14 (I) ^ bit15 (I ))
Xbyte | = 0x0100;

If (j = 31)
{
Printf ("0x % 03x, \ n", xbyte );
J = 0;

}
Else
{
Printf ("0x % 03x,", xbyte );
J ++;

}

}
Return 0;
}

So far, the algorithm has been completed. You only need to call the relevant functions as needed.

Second, change the interface. This step is divided into two small steps: ① writing interface code. The above algorithm function must be embedded into the interface code, and the access location of the ECC code on each page must be implemented. If it is multi-threaded, you also need to add a mutex lock to each page. ② Unify the interfaces in the system. This step is the most troublesome to unify the operations on the SRAM in the system according to the actual situation, because you need to find all the read and write operations in the original system and change them to a unified interface, it cannot bring new problems. This step is just because of the system, so there is nothing to say. If you want to change it, don't bring new problems.

Finally, fully debug the code and test it according to the treatment of the new Code to ensure no problem.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.