SE 746-NT Embedded Software Systems Development
-
Upload
flashdomain -
Category
Documents
-
view
464 -
download
1
description
Transcript of SE 746-NT Embedded Software Systems Development
SE 746-NTEmbedded Software Systems Development
Robert Oshana
Lecture #6
For more information, please contact:NTU Tape Orders:NTU Media Services: (970) 495-6455
Lecture 6
More Hardware fundamentals - Memory
Agenda
• Memory testing
• Validating memory contents
• Flash memory
Electrical wiring problems
• Data line problems– Bits might appear to be stuck– Two or more bits contain the same value
regardless of the data being transferred– “stuck high” (always 1)– “stuck low” (always 0)
• Detected by writing a sequence of data values designed to test each data pin can be set to 0 and 1, independently of all others
Electrical wiring problems
• Address wiring problems– Contents of two memory locations may
appear to overlap• Data written to one address will overwrite
the contents of another address
– Memory device is “seeing” an address different from the one the processor has selected
Electrical wiring problems
• Control lines– Hard to describe a general test for
testing for control lines open or closed– Operation specific to processor or
memory architecture– Problems here usually indicate that
memory will not work at all– Seek advice of designer for how to test
Missing memory chips
• Missing memory chips may not be detected!– Capacitance nature of unconnected electrical
wires– Some memory tests do write followed
immediately by a read– This could result in reading remaining voltage
from the previous write– If read to quickly, it appears there is data being
stored when there is nothing there!
Missing memory chips
– Perform several consecutive writes followed by the same number of reads
• Write value 1 to memory location A• Write value 2 to memory location B• Write value 3 to memory location C• Read from location A• Read from location B• Read from location C• If no memory, first value read will correspond to last
value written instead of first
Improperly inserted chips
• Symptom is that system will behave as though there is a wiring problem or a missing chip– Some number of pins not connected at all or
connected to the wrong locations– Could be part of the address, data, or control
lines
• Tests for missing chips and wiring problems will catch this problem as well
Developing a test strategy
• Carefully select the test data• Carefully select the order in which
addresses are tested• Break your memory into small testable
pieces– Improves efficiency of test– Improves readability of code
• More specific tests can provide more detailed information if desired
Developing a test strategy
• Three individual tests– Data bus test (wiring and improperly
inserted chip test)– Address bus test (wiring and improperly
inserted chip test)– Device test (missing chips and
catastrophic failures)
Developing a test strategy
• Order to execute tests– 1. Data bus test; – 2. Address bus test; assumes a working
data bus– 3. Device test; assumes working
address and data bus
• Most of the problems can be found by looking at the data
Data bus test
• Verify that the value placed on the bus is correctly received by the memory device on the other end
• Test the bus one bit at a time– Passes if each data bit can be set to 0
and 1, independently of the other data bits
• “walking 1’s test”
Data bus test
• Reduces number of test patterns from 2**n to n, where n is the width of the data bus
• Because we are testing the data bus, all data values can be written to the same address (any address will do)
• If data bus splits you must test one address within each chip
Data bus test
• Write the first value to memory
• Verify it by reading it back
• Write the second value
• Etc• Ok to read back
immediately (not looking for missing chips yet)
• 00000001• 00000010• 00000100• 00001000• 00010000• 00100000• 01000000• 10000000
/**********************************************************Function: memTestDataBus()**Decription: Test the data bus wiring in a memory region by* performing a walking 1’s test at a fixed address* within that region. The address (and hence the* memory region) is selected by the caller.*** Returns: 0 if the test succeeds* A nonzero result is the first pattern that failed•*•*********************************************************/•datum•memTestDataBus(volatile datum * address)•{• datum pattern;
•/*•* perform a walking 1’s test at the given address•*/
•memTestDataBus(volatile datum * address)•{• datum pattern;
•/*•* perform a walking 1’s test at the given address•*/•for (pattern = 1; pattern != 0; pattern <<= 1)•{• /*• * write the test pattern• */• • *address = pattern;
• /*• * read it back (immediately is ok for this test)• */
if (*address != pattern) { return (pattern); }
• }• return (0);
•} /* memTestDataBus() */
Address bus test
• Next test to run after confirming that the data test passes
• Many possible addresses that could overlap– Try to isolate each address bit during
testing (like the data test)– Confirm each address pin can be set to
0 and 1
Address bus test
• Use “power of 2” address– 00001h, 00002h, 00004h, 00008h,
00010h, 00020h, etc– Also test 00000h
• Possibility of overlapping locations makes this test harder to implement– After writing to one of the addresses,
must check that none of the others have been over written
Address bus test
• Not all addresses can be tested this way– Leftmost bits select the memory chip– Rightmost bits may not be significant if
data bus width greater than 8 bits– These bits will remain constant
throughout the test and reduce the number of test addresses
Address bus test
• Example; for 20 bit address range– Can address 1 M of memory– 128K byte block test implies three MSBs
will remain constant (128K byte is 1/8th of the total 1M address range)
– Only 17 rightmost bits of the address bus can actually be tested
Address bus test
• To confirm no 2 memory addresses overlap– Write an initial data value at each power of 2
offset within the device– Write an inverted data value to the first test
offset– Verify initial data value is still stored at every
other power of 2 location– Problem with current address bit if any other
power of 2 location is not right– Repeat for remaining offsets
/**********************************************************Function: memTestAddressBus()**Decription: Test the address bus wiring in memory region by* performing a walking 1’s test on the relevant bits* of the address and checking for aliasing. The •* base address and size of the region are selected•* by the user.•*•* Notes: For best results, the selected base address should•* enough LSB 0’s to guarantee single address bit•* changes (to test a 64 KB region, select a base•* address on a 64 KB boundary•*** Returns: NULL if the test succeeds* A nonzero result is the first address that failed•*•*********************************************************/•datum *•memTestAddressBus(volatile datum * baseAddress, unsigned long nBytes)•{
•memTestAddressBus(volatile datum * baseAddress, unsigned long nBytes)•{• unsigned long addressMask = (nBytes –1);• unsigned long offset;• unsigned long testOffset;
• datum pattern = (datum) 0xAAAAAAAA;• datum antipattern = (datum) 0x55555555;
•/*•* write the default pattern at each of the power of two offsets•*/
• for (offset = sizeof(datum); (offset & addressMask) != 0; offset <<=1)• {• baseAddress[offset] = pattern;• /*• * check for address bits stuck high• */• testOffset = 0;• baseAddress[testOffset] = antipattern;
• for (offset = sizeof(datum); (offset & addressMask) != 0; offset <<=1)• {
• if (baseAddress[offset] != antipattern• {• return ((datum *) &baseAddress[offset] );• }• }
• baseAddress[testOffset] = pattern;
• /*• * check for address bits stuck low or shorted• */• for (offset = sizeof(datum); (offset & addressMask) != 0; testOffset <<=1)• {• baseAddress[testOffset] = antipattern;• • for (offset = sizeof(datum); (offset & addressMask) != 0; offset <<=1)• {• if ((baseAddress[offset] != pattern) && (offset != testOffset))• {• return ((datum *) &baseAddress[testOffset] );• }• }• baseAddress[testOffset] = pattern;• }• return (NULL);•} /* memTestAddressBus() */
•baseAddress[testOffset] = pattern;
• }
• return (NULL);
•} /* memTestAddressBus() */
Device test
• Used to test the integrity of the memory device itself
• Test every bit in device is capable of holding a 1 and a 0
• Easy to implement but harder to execute• Must write and verify every location
twice• Any value for the first half – invert for
the second half
Device test
• First do an increment test
• Second pass is a decrement test
• Incrementing data pattern is adequate and easy to compute
Device test
Memory offset Binary value Inverted value
00h 00000001 11111110
001h 00000010 11111101
002h 00000011 11111100
003h 00000100 11111011
…….. …….. …….
0FEh 11111111 00000000
0FFh 00000000 11111111
Example
• Test the second 64K byte chunk of SRAM on an embedded device (Arcom board)
• Recall the memory map talked about earlier;
Memory map for example
EPROM (128K)
Flash memory (128K)
Unused
Zilog SCC
Unused
SRAM (128K)
FFFFFh
E0000h
C0000h
72000h70000h
20000h
00000h
2nd 64K byteSegment is10000h
Example
• Width of data bus (80188EB) is 8 bits• Total of 64K bytes to be tested
– Rightmost 16 bits of address bus
• If any of the tests return nonzero value (error) then turn on red LED to indicate error (and return useful information)
• If all tests pass turn on green LED
/*********************************************************Function: main()**Decription: Test the 2nd 64K byte bank of SRAM** Returns: 0 on success* Otherwise –1 indicates error•*•*********************************************************/•main(void)•(
•if ((memTestDataBus(BASE_ADDRESS) != 0) ||• (memTestAddressBus(BASE_ADDRESS, NUM_BYTES) != NULL ||• (memTestDevice(BASE_ADDRESS, NUM_BYTES) != NULL))•{
•toggleLed(LED_RED);•return(-1);
•}•else•{
•toggleLed(LED_GREEN);•return(0);
•}•} /* main() */
Example • Not always possible to test memory in HOL
– C/C++ require a stack– Stack required working memory– Create stack in an area known to be working –
test it from assembly
• Or, the memory test can be run from an emulator– Place the stack in emulator memory– Move the emulator to different areas in the
target memory map to test all locations
Example
• Memory testing most useful during product development when design is unproven
• Memory is so important it might make sense to always test it– Run during power on or reset– Forms part of a hardware diagnostics
Validating memory contents
• Memory tests do not make much sense for Rom devices and some hybrid devices that have programs that cannot be overwritten
• However same memory problems can occur!– Improper insertion, etc
• Need a confirmation for these devices as well
Validating memory contents
• Confirmation techniques– Checksum– Cyclic redundancy checks
Checksums
• Way to tell if a program stored in a non-volatile device is still good
• Compute a checksum of the program when you know its good– E.g. prior to programming the ROM
• Re-calculate the checksum each time you wan to verify contents are still good– Compare to previous value
Checksums
• Careful selection of the checksum algorithm can increase the probability of reducing specific types of errors
• Simplest– Add up all the data bytes (or words for a 16
bit checksum)– Discard the carries– If all data (including stored checksum) is
overwritten with 0’s, this data corruption will be hard to detect
Checksums
• Overcome this weakness by inverting the result as a final step
• This approach still cannot detect many of the common data errors– If one bit changed from 0 to 1 and
another bit in the same column changed from 1 to 0, the algorithm would still compute the same checksum
Checksums
• Where to store checksums?– Define it as a constant in the routine that
verifies the data (must compute ahead of time)
• Good for the programmer• May change many times
– Store in a fixed checksum in memory (like the very last location of the memory device being verified)
– Store in another non-volatile device
Cyclic redundancy check
• A specific checksum algorithm designed to detect the most common data errors
• Has mathematical origins
• Used often in embedded applications that require storage or transmission of large blocks of data
Cyclic redundancy check
• Some math;– Consider the data to be a long string of 1’s
and 0’s (called the message)– Binary string is divided by a smaller string
called the generator polynomial– The remainder is the CRC checksum– Careful selection of the generator
polynomial will produce a checksum that can detect most errors within a message, including up to 99.99% of all burst errors
Cyclic redundancy check
• Best generator polynomials are adapted as international standards
• Parameters of a CRC standard– Width (in bits)– Generator polynomial– Divisor (binary representation of the
polynomial)– Initial value for the remainder– Value to XOR with the final remainder
Cyclic redundancy check
• Example standard; CCITT– Checksum size (width) 16 bits– Generator polynomial; x**16 + x**12 +
x**5 + 1– Divisor (polynomial); 0x1021– Initial remainder; 0xFFFF– Final XOR value; 0x0000
Flash memory
• Complicated from the programmers point of view
• Reading is the same as reading from any other device (for the most part)
• Flash devices enter a “read” mode during initialization
• Writing is harder– Each memory location must be erased before
it is written– If not, result is some logical combo
Flash memory
– Only one sector, or block, can be erased at a time
• Cannot erase a single byte• Size of sector varies by device (16Kbytes)
– Process of erasing varies by device• Usually best to add a layer (API)• Called the Flash driver
Flash driver
• Purpose is to hide the details of the chip from the software
• Simple API– erase– Write
• S/W calls the API– More portable (if flash devices change)
#include “tgt188eb.h”
/* *Features of the AMD 29F010 flash memory device•*/•#define FLASH_SIZE 0x20000•#define FLASH_BLOCK_SIZE 0x04000•#define UNLOCK1_OFFSET 0x5555•#define UNLOCK2_OFFSET 0x2AAA•#define COMMAND_OFFSET 0x5555•#define FLASH_CMD_UNLOCK1 0xAA•#define FLASH_CMD_UNLOCK2 0x55•#define FLASH_CMD_READ_RESET 0xF0•#define FLASH_CMD_AUTOSELECT 0x90•#define FLASH_CMD_BYTE_PROGRAM 0xA0•#define FLASH_CMD_ERASE_SETUP 0x80•#define FLASH_CMD_CHIP ERASE 0x30•#define FLASH_CMD_SECTOR_ERASE 0x30
•#define DQ7 0x80•#define DQ5 0x20
/***********************************************************•Function: flashWrite()•* •* Description; write data to consecutive locations in the flash•*•* Notes; This function is specific to the AMD 29F1020 Flash•* memory. In that device, a byte that has been•* previously written must be erased before it can be•* rewritten successfully•*•* Returns; Number of bytes successfully written•**********************************************************/•int•flashWrite(unsigned char * baseAddress,• const unsigned char data[]• unsigned int nBYtes)•{• unsigned char * flashBase = FLASH_BASE;• unsigned int offset;
• for (offset = 0; offset < nBytes; offset++)• {
/* * issue the command sequence for byte program */ flashBase[UNLOCK1_OFFSET] = FLASH_CMD_UNLOCK1; flashBase[UNLOCK2_OFFSET] = FLASH_CMD_UNLOCK2; flashBase[COMMAND_OFFSET] = FLASH_CMD_BYTE_PROGRAM;
/* * perform the actual write operation */ baseAddress[offeset] = data[offset]; /* * wait for the operation to complete or time out */ while ((baseAddress[offset] & DQ7 != (data[offset] & DQ7)) && ! (baseAddress[offset] & DQ5));
if ((baseAddress[offset] & DQ7) != data[offset] & DQ7)) { break; } } return(offset);} /* flashWrite() */
Flash driver
• There are more robust implementations that handle errors– The point is – this can be complicated!
• Flash can also be used as a small file system because of nonvolatility
• API can handle this as well– Open– Close– Read– write
SE 746-NTEmbedded Software Systems Development
Robert Oshana
End of Lecture
For more information, please contact:NTU Tape Orders:NTU Media Services: (970) 495-6455