Sunteți pe pagina 1din 15

Pruebas de memoria basadas en software

por Michael Barr

Si alguna vez hubo una pieza de software incrustado maduro para su reutilización
es la prueba de memoria. En este artículo se muestra cómo probar los problemas
de memoria más comunes con un conjunto de tres funciones de prueba de memoria
de dominio público, portátiles y eficientes.

Introducción
Una pieza de software que casi todos los desarrolladores integrados deben escribir
en algún momento de su carrera es una prueba de memoria. A menudo, una vez
que el hardware del prototipo está listo, el diseñador de la placa desea cierta
seguridad de que ha conectado la dirección y las líneas de datos correctamente, y
que los diversos chips de memoria están funcionando correctamente. Y, incluso si
ese no es el caso, es deseable probar cualquier RAM integrada al menos tan a
menudo como el sistema se restablece. Depende del desarrollador de software
incrustado, entonces, para averiguar lo que puede salir mal y diseñar un conjunto
de pruebas que descubrirán problemas. A primera vista, escribir una prueba de
memoria puede parecer una tarea bastante simple. Sin embargo, al mirar el
problema más de cerca se dará cuenta de que puede ser difícil detectar problemas
de memoria sutiles con una simple prueba. De hecho, como resultado de la
ingenuidad del programador, muchos sistemas integrados incluyen pruebas de
memoria que detectarían solo los fallos de memoria más catastróficos. Tal vez
increíblemente, algunos de estos pueden ni siquiera notar que los chips de memoria
han sido eliminados de la placa! El propósito de una prueba de memoria es
confirmar que cada ubicación de almacenamiento en un dispositivo de memoria está
funcionando. En otras palabras, si almacena el número 50 en una dirección
determinada, espera encontrar ese número almacenado allí hasta que se escriba
otro número en esa misma dirección. La idea básica detrás de cualquier prueba de
memoria, entonces, es escribir algún conjunto de datos en cada dirección en el
dispositivo de memoria y verificar los datos leyéndolos de nuevo. Si todos los
valores leídos son los mismos que los que se escribieron, se dice que el dispositivo
de memoria pasa la prueba. Como verá, es sólo a través de una cuidadosa
selección del conjunto de valores de datos que puede estar seguro de que un
resultado de paso es significativo. Por supuesto, una prueba de memoria como la
que acabamos de describir es necesariamente destructiva. En el proceso de probar
la memoria, debe sobrescribir su contenido anterior. Dado que generalmente no es
práctico sobrescribir el contenido de memorias no volátiles, las pruebas descritas
en este artículo se utilizan generalmente solo para las pruebas de RAM. Sin
embargo, si el contenido de un dispositivo de memoria no volátil, como flash, no es
importante, ya que lo son durante la etapa de desarrollo del producto, estos mismos
algoritmos también se pueden utilizar para probar esos dispositivos.
Problemas comunes de memoria
Antes de implementar cualquiera de los posibles algoritmos de prueba, debe estar
familiarizado con los tipos de problemas de memoria que es probable que se
produzcan. Un concepto erróneo común entre los ingenieros de software es que la
mayoría de los problemas de memoria ocurren dentro de los propios chips. Aunque
un problema importante en un momento (hace unas décadas), problemas de este
tipo son cada vez más raros. Los fabricantes de dispositivos de memoria realizan
una variedad de pruebas de postproducción en cada lote de chips. Si hay un
problema con un lote en particular, es extremadamente poco probable que uno de
los chips defectuosos se abre camino en su sistema. El único tipo de problema de
chip de memoria que podría encontrar es un fallo catastrófico. Esto suele ser
causado por algún tipo de daño físico o eléctrico al chip después de la fabricación.
Las fallas catastróficas son poco frecuentes y generalmente afectan a grandes
porciones del chip. Puesto que un área grande se ve afectada, es razonable asumir
que la falla catastrófica será detectada por cualquier algoritmo de prueba decente.
En mi experiencia, la fuente más común de problemas de memoria real es la placa
de circuito. Los problemas típicos de la placa de circuito son problemas con el
cableado entre el procesador y el dispositivo de memoria, los chips de memoria que
faltan y los chips de memoria insertados incorrectamente. Estos son los problemas
que un buen algoritmo de prueba de memoria debe ser capaz de detectar. Tal
prueba también debe ser capaz de detectar errores catastróficos de memoria sin
buscarlos específicamente. Por lo tanto, vamos a discutir los problemas de la placa
de circuito con más detalle.

Problemas de cableado eléctrico


Un problema de cableado eléctrico podría ser causado por un error en el diseño o
la producción de la placa o como resultado de los daños recibidos después de la
fabricación. Cada uno de los cables que conecta el dispositivo de memoria al
procesador es uno de tres tipos: una línea de dirección, una línea de datos o una
línea de control. La dirección y las líneas de datos se utilizan para seleccionar la
ubicación de memoria y transferir los datos, respectivamente. Las líneas de control
indican al dispositivo de memoria si el procesador desea leer o escribir la ubicación
y exactamente cuándo se transferirán los datos. Desafortunadamente, uno o más
de estos cables podrían ser mal enrutados o dañados de tal manera que sea
cortocircuito (es decir, conectado a otro cable en la placa) o abierto (no conectado
a nada). Estos problemas son a menudo causados por un poco de salpicadura de
soldadura o un rastro roto, respectivamente.
Los problemas con las conexiones eléctricas al procesador harán que el dispositivo
de memoria se comporte incorrectamente. Los datos pueden almacenarse
incorrectamente, almacenarse en la dirección incorrecta o no almacenarse en
absoluto. Cada uno de estos síntomas se puede explicar por problemas de cableado
en las líneas de datos, dirección y control, respectivamente. Si el problema es con
una línea de datos, varios bits de datos pueden parecer estar "pegados" (es decir,
dos o más bits siempre contienen el mismo valor, independientemente de los datos
transmitidos). Del mismo modo, un bit de datos puede ser "alto" (siempre 1) o
"atascado bajo" (siempre 0). Estos problemas se pueden detectar escribiendo una
secuencia de valores de datos diseñados para probar que cada pin de datos se
puede establecer en 0 y 1, independientemente de todos los demás. Si una línea de
dirección tiene un problema de cableado, el contenido de dos ubicaciones de
memoria puede parecer superponerse. En otras palabras, los datos escritos en una
dirección sobrescribirán realmente el contenido de otra dirección en su lugar. Esto
sucede porque un bit de dirección que está cortocircuitado o abierto hará que el
dispositivo de memoria vea una dirección diferente a la seleccionada por el
procesador. Otra posibilidad es que una de las líneas de control esté corta o abierta.
Aunque teóricamente es posible desarrollar pruebas específicas para problemas de
línea de control, no es posible describir una prueba general para ellos. El
funcionamiento de muchas señales de control es específico del procesador o la
arquitectura de memoria. Afortunadamente, si hay un problema con una línea de
control, la memoria probablemente no funcionará en absoluto, y esto será detectado
por otras pruebas de memoria. Si sospecha que hay un problema con una línea de
control, es mejor buscar el consejo del diseñador de la placa antes de construir una
prueba específica.
Chips de memoria que faltan
Un chip de memoria que falta es claramente un problema que debe ser detectado.
Desafortunadamente, debido a la naturaleza capacitiva de los cables eléctricos
desconectados, algunas pruebas de memoria no detectarán este problema. Por
ejemplo, supongamos que ha decidido utilizar el siguiente algoritmo de prueba:
escribir el valor 1 en la primera ubicación de la memoria, verificar el valor leyéndolo
de nuevo, escribir 2 en la segunda ubicación, verificar el valor, escribir 3 en la tercera
ubicación, verificar, etc. Puesto que cada lectura se produce inmediatamente
después de la escritura correspondiente, es posible que los datos leídos no
representen nada más que el voltaje restante en el bus de datos de la escritura
anterior. Si los datos se leen demasiado rápido, parecerá que los datos se han
almacenado correctamente en la memoria, aunque no hay ningún chip de memoria
en el otro extremo del bus! Para detectar un chip de memoria que falta, la prueba
debe modificarse. En lugar de realizar la verificación leída inmediatamente después
de la escritura correspondiente, es deseable realizar varias escrituras consecutivas
seguidas del mismo número de lecturas consecutivas. Por ejemplo, escriba el valor
1 en la primera ubicación, 2 en la segunda ubicación y 3 en la tercera ubicación y,
a continuación, compruebe los datos en la primera ubicación, la segunda ubicación,
etc. Si los valores de datos son únicos (como están en la prueba que acabamos de
describir), se detectará el chip que falta: el primer valor leído de nuevo
corresponderá al último valor escrito (3), en lugar del primero (1).

Chips insertados incorrectamente


Si un chip de memoria está presente pero insertado incorrectamente en su zócalo,
el sistema generalmente se comportará como si hubiera un problema de cableado
o un chip faltante. En otras palabras, un cierto número de pines en el chip de
memoria no se conectará al zócalo en absoluto o se conectará en el lugar
equivocado. Estos pines formarán parte del bus de datos, el bus de direcciones o el
cableado de control. Así que siempre y cuando pruebe problemas de cableado y
chips que faltan, cualquier viruta insertada incorrectamente se detectará
automáticamente.

Desarrollo de una estrategia de prueba


Antes de continuar, revisemos rápidamente los tipos de problemas de memoria que
debemos ser capaces de detectar. Los chips de memoria rara vez tienen errores
internos, pero, si lo hacen, probablemente son catastróficos en la naturaleza y serán
detectados por cualquier prueba. Una fuente más común de problemas es la placa
de circuito, donde puede ocurrir un problema de cableado o un chip de memoria
puede faltar o insertarse incorrectamente. Pueden ocurrir otros problemas de
memoria, pero los que se describen aquí son los más comunes. Al seleccionar
cuidadosamente los datos de prueba y el orden en que se prueban las direcciones,
es posible detectar todos los problemas de memoria descritos anteriormente. Por lo
general, es mejor dividir la prueba de memoria en pequeñas piezas de una sola
mente. Esto ayuda a mejorar la eficiencia de la prueba general y la legibilidad del
código. Las pruebas más específicas también pueden proporcionar información más
detallada sobre el origen del problema, si se detecta una. He encontrado que es
mejor tener tres pruebas de memoria individuales: una prueba de bus de datos, una
prueba de bus de direcciones y una prueba de dispositivo. Las dos primeras
prueban para problemas de cableado eléctrico y chips insertados incorrectamente,
mientras que la tercera está destinada a detectar chips faltantes y fallas
catastróficas. Como consecuencia no intencionada, la prueba del dispositivo
también descubrirá problemas con el cableado del bus de control, aunque no puede
proporcionar información útil sobre la fuente de dicho problema. El orden en el que
ejecuta estas tres pruebas es importante. El orden correcto es: prueba de bus de
datos primero, seguido de la prueba de bus de direcciones y, a continuación, la
prueba del dispositivo. Esto se debe a que la prueba de bus de direcciones supone
un bus de datos de trabajo y los resultados de las pruebas del dispositivo no tienen
sentido a menos que tanto la dirección como los buses de datos sean buenos. Si se
produce un error en alguna de las pruebas, debe trabajar con el diseñador de la
placa para buscar el origen del problema. Al examinar el valor de datos o la dirección
en la que falló la prueba, él o ella debe ser capaz de aislar rápidamente el problema
en la placa de circuito.

Prueba de bus de datos

Lo primero que queremos probar es el cableado del bus de datos. Tenemos que
confirmar que cualquier valor colocado en el bus de datos por el procesador es
recibido correctamente por el dispositivo de memoria en el otro extremo. La forma
más obvia de probar eso es escribir todos los valores de datos posibles y comprobar
que el dispositivo de memoria almacena cada uno correctamente. Sin embargo, esa
no es la prueba más eficiente disponible. Un método más rápido es probar el bus
un bit a la vez. El bus de datos pasa la prueba si cada bit de datos se puede
establecer en 0 y 1, independientemente de los demás bits de datos. Una buena
manera de probar cada bit de forma independiente es realizar la llamada "prueba
de caminar 1". La Tabla 1 muestra los patrones de datos utilizados en una versión
de 8 bits de esta prueba. El nombre de esta prueba, caminando 1, proviene del
hecho de que un solo bit de datos se establece en 1 y "caminado" a través de toda
la palabra de datos. El número de valores de datos que se va a probar es el mismo
que el ancho del bus de datos. Esto reduce el número de patrones de prueba de 2n
a n, donde n es el ancho del bus de datos.

Tabla 1. Valores de datos consecutivos para la prueba de Walking 1

00000001
00000010

00000100

00001000

00010000

00100000

01000000

10000000

Puesto que estamos probando solo el bus de datos en este punto, todos los valores
de datos se pueden escribir en la misma dirección. Cualquier dirección dentro del
dispositivo de memoria servirá. Sin embargo, si el bus de datos se divide a medida
que se dirige a más de un chip de memoria, tendrá que realizar la prueba de bus de
datos en varias direcciones, una dentro de cada chip. Para realizar la prueba de
caminar 1, simplemente escriba el primer valor de datos en la tabla, verifíquelo
leyéndolo de nuevo, escriba el segundo valor, verifique, etc. Cuando llegue al final
de la tabla, la prueba se completará. Está bien hacer la lectura inmediatamente
después de la escritura correspondiente esta vez porque todavía no estamos
buscando fichas que faltan. De hecho, esta prueba proporciona resultados
significativos incluso si los chips de memoria no están instalados! La función
memTestDataBus(), en el listado 1, muestra cómo implementar la prueba de walking
1 en C. Se supone que el autor de la llamada seleccionará la dirección de prueba y
probará todo el conjunto de valores de datos en esa dirección. Si el bus de datos
funciona correctamente, la función devolverá 0. De lo contrario, devolverá el valor
de datos para el que se produjo un error en la prueba. El bit que se establece en el
valor devuelto corresponde a la primera línea de datos defectuosa, si existe.

1. typedef unsigned char datum; /* Set the data bus width to 8 bits. */
2. /**********************************************************************
3. *
4. * Function: memTestDataBus()
5. *
6. * Description: Test the data bus wiring in a memory region by
7. * performing a walking 1's test at a fixed address
8. * within that region. The address (and hence the
9. * memory region) is selected by the caller.
10. *
11. * Notes:
12. *
13. * Returns: 0 if the test succeeds.
14. * A non-zero result is the first pattern that failed.
15. *
16. **********************************************************************/
17. datum
18. memTestDataBus(volatile datum * address)
19. {
20. datum pattern;
21. /*
22. * Perform a walking 1's test at the given address.
23. */
24. for (pattern = 1; pattern != 0; pattern <<= 1)
25. {
26. /*
27. * Write the test pattern.
28. */
29. *address = pattern;
30. /*
31. * Read it back (immediately is okay for this test).
32. */
33. if (*address != pattern)
34. {
35. return (pattern);
36. }
37. }
38. return (0);
39. } /* memTestDataBus() */

Prueba de bus de dirección


Después de confirmar que el bus de datos funciona correctamente, debe probar el
bus de direcciones. Recuerde que los problemas de los buses de dirección
conducen a ubicaciones de memoria superpuestas. Hay muchas direcciones
posibles que podrían superponerse. Sin embargo, no es necesario comprobar todas
las combinaciones posibles. En su lugar, debe seguir el ejemplo de la prueba de
bus de datos anterior e intentar aislar cada bit de dirección durante las pruebas.
Sólo tiene que confirmar que cada uno de los pines de dirección se puede establecer
en 0 y 1 sin afectar a ninguno de los demás. El conjunto más pequeño de direcciones
que cubrirá todas las combinaciones posibles es el conjunto de direcciones de
"poder de dos". Estas direcciones son análogas al conjunto de valores de datos
utilizados en la prueba de walking 1. Las ubicaciones de memoria correspondientes
son 00001h, 00002h, 00004h, 00008h, 00010h, 00020h, etc. Además, la dirección
00000h también debe ser probada. La posibilidad de ubicaciones superpuestas
hace que la prueba de bus de direcciones sea más difícil de implementar. Después
de escribir en una de las direcciones, debe comprobar que ninguna de las otras se
ha sobrescrito. Es importante tener en cuenta que no todas las líneas de dirección
se pueden probar de esta manera. Parte de la dirección, los bits más a la izquierda,
selecciona el propio chip de memoria. Otra parte, los bits más a la derecha, puede
no ser significativa si el ancho del bus de datos es mayor que 8 bits. Estos bits
adicionales permanecerán constantes durante toda la prueba y reducirán el número
de direcciones de prueba. Por ejemplo, si el procesador tiene 32 bits de dirección,
puede dirigir hasta 4 gigabytes de memoria. Si desea probar un bloque de memoria
de 128 kilobytes, los 15 bits de dirección más significativos permanecerán
constantes. En ese caso, solamente los 17 bits más a la derecha del bus de
direcciones se pueden probar realmente. Para confirmar que no hay dos
ubicaciones de memoria superpuestas, primero debe escribir algún valor de datos
inicial en cada desplazamiento de potencia de dos dentro del dispositivo. A
continuación, escriba una nueva copia invertida de valor y una copia invertida del
valor inicial es una buena opción para el primer desplazamiento de prueba y
compruebe que el valor de datos inicial todavía se almacena en cada otro
desplazamiento de potencia de dos. Si encuentra una ubicación, distinta de la que
acaba de escribir, que contiene el nuevo valor de datos, ha encontrado un problema
con el bit de dirección actual. Si no se encuentra superposición, repita el
procedimiento para cada uno de los desfases restantes. La función
memTestAddressBus(), en el listado 2, muestra cómo se puede hacer esto en la
práctica. La función acepta dos parámetros. El primer parámetro es la dirección
base del bloque de memoria que se va a probar y el segundo es su tamaño, en
bytes. El tamaño se utiliza para determinar qué bits de dirección se deben probar.
Para obtener mejores resultados, la dirección base debe contener un 0 en cada uno
de esos bits. Si se produce un error en la prueba del bus de direcciones, se
devolverá la dirección en la que se detectó el primer error. De lo contrario, esta
función devuelve NULL para indicar que se ha realizado correctamente.

1. /**********************************************************************
2. *
3. * Function: memTestAddressBus()
4. *
5. * Description: Test the address bus wiring in a memory region by
6. * performing a walking 1's test on the relevant bits
7. * of the address and checking for aliasing. This test
8. * will find single-bit address failures such as stuck
9. * -high, stuck-low, and shorted pins. The base address
10. * and size of the region are selected by the caller.
11. *
12. * Notes: For best results, the selected base address should
13. * have enough LSB 0's to guarantee single address bit
14. * changes. For example, to test a 64-Kbyte region,
15. * select a base address on a 64-Kbyte boundary. Also,
16. * select the region size as a power-of-two--if at all
17. * possible.
18. *
19. * Returns: NULL if the test succeeds.
20. * A non-zero result is the first address at which an
21. * aliasing problem was uncovered. By examining the
22. * contents of memory, it may be possible to gather
23. * additional information about the problem.
24. *
25. **********************************************************************/
26. datum *
27. memTestAddressBus(volatile datum * baseAddress, unsigned long nBytes)
28. {
29. unsigned long addressMask = (nBytes/sizeof(datum) - 1);
30. unsigned long offset;
31. unsigned long testOffset;
32. datum pattern = (datum) 0xAAAAAAAA;
33. datum antipattern = (datum) 0x55555555;
34. /*
35. * Write the default pattern at each of the power-of-two offsets.
36. */
37. for (offset = 1; (offset & addressMask) != 0; offset <<= 1)
38. {
39. baseAddress[offset] = pattern;
40. }
41. /*
42. * Check for address bits stuck high.
43. */
44. testOffset = 0;
45. baseAddress[testOffset] = antipattern;
46. for (offset = 1; (offset & addressMask) != 0; offset <<= 1)
47. {
48. if (baseAddress[offset] != pattern)
49. {
50. return ((datum *) &baseAddress[offset]);
51. }
52. }
53. baseAddress[testOffset] = pattern;
54. /*
55. * Check for address bits stuck low or shorted.
56. */
57. for (testOffset = 1; (testOffset & addressMask) != 0; testOffset <<= 1)
58. {
59. baseAddress[testOffset] = antipattern;
60. if (baseAddress[0] != pattern)
61. {
62. return ((datum *) &baseAddress[testOffset]);
63. }
64. for (offset = 1; (offset & addressMask) != 0; offset <<= 1)
65. {
66. if ((baseAddress[offset] != pattern) && (offset != testOffset))
67. {
68. return ((datum *) &baseAddress[testOffset]);
69. }
70. }
71. baseAddress[testOffset] = pattern;
72. }
73. return (NULL);
74. } /* memTestAddressBus() */

Prueba del dispositivo


Una vez que sepa que la dirección y el cableado del bus de datos están funcionando,
es necesario probar la integridad del dispositivo de memoria en sí. Lo que hay que
probar es que cada bit en el dispositivo es capaz de sostener 0 y 1. Esta es una
prueba bastante sencilla de implementar, pero tarda mucho más en ejecutarse que
las dos anteriores. Para una prueba completa del dispositivo, debe visitar (escribir y
verificar) cada ubicación de memoria dos veces. Usted es libre de elegir cualquier
valor de datos para la primera pasada, siempre y cuando invierta ese valor durante
el segundo. Y dado que existe la posibilidad de que falten chips de memoria, es
mejor seleccionar un conjunto de datos que cambie con (pero no es equivalente a)
la dirección. Un ejemplo simple es una "prueba de incremento". Los valores de datos
para la prueba de incremento se muestran en las dos primeras columnas de la Tabla
2. La tercera columna muestra los valores de datos invertidos utilizados durante la
segunda pasada de esta prueba. Este último representa una prueba de decremento.
Hay muchas otras opciones posibles de datos, pero el patrón de datos en
incremento es adecuado y fácil de calcular.

Cuadro 2. Valores de datos para una prueba de incremento

Desplazamiento de memoria Valor binario Valor invertido


000h 00000001 11111110

001h 00000010 11111101

002h 00000011 11111100

003h 00000100 11111011

... ... ...

0FEh 11111111 00000000

0FFh 00000000 11111111

La función memTestDevice(), en el listado 3, implementa solo una prueba de


incremento/decremento de dos pasadas. Acepta dos parámetros del autor de la
llamada. El primer parámetro es la dirección inicial y el segundo es el número de
bytes que se van a probar. Estos parámetros proporcionan al usuario un máximo de
control sobre qué áreas de memoria se sobrescribirán. La función devolverá NULL
en caso de éxito. De lo contrario, se devuelve la primera dirección que contiene un
valor de datos incorrecto.

1. /**********************************************************************
2. *
3. * Function: memTestDevice()
4. *
5. * Description: Test the integrity of a physical memory device by
6. * performing an increment/decrement test over the
7. * entire region. In the process every storage bit
8. * in the device is tested as a zero and a one. The
9. * base address and the size of the region are
10. * selected by the caller.
11. *
12. * Notes:
13. *
14. * Returns: NULL if the test succeeds. Also, in that case, the
15. * entire memory region will be filled with zeros.
16. *
17. * A non-zero result is the first address at which an
18. * incorrect value was read back. By examining the
19. * contents of memory, it may be possible to gather
20. * additional information about the problem.
21. *
22. **********************************************************************/
23. datum *
24. memTestDevice(volatile datum * baseAddress, unsigned long nBytes)
25. {
26. unsigned long offset;
27. unsigned long nWords = nBytes / sizeof(datum);
28. datum pattern;
29. datum antipattern;
30. /*
31. * Fill memory with a known pattern.
32. */
33. for (pattern = 1, offset = 0; offset < nWords; pattern++, offset++)
34. {
35. baseAddress[offset] = pattern;
36. }
37. /*
38. * Check each location and invert it for the second pass.
39. */
40. for (pattern = 1, offset = 0; offset < nWords; pattern++, offset++)
41. {
42. if (baseAddress[offset] != pattern)
43. {
44. return ((datum *) &baseAddress[offset]);
45. }
46. antipattern = ~pattern;
47. baseAddress[offset] = antipattern;
48. }
49. /*
50. * Check each location for the inverted pattern and zero it.
51. */
52. for (pattern = 1, offset = 0; offset < nWords; pattern++, offset++)
53. {
54. antipattern = ~pattern;
55. if (baseAddress[offset] != antipattern)
56. {
57. return ((datum *) &baseAddress[offset]);
58. }
59. }
60. return (NULL);
61. } /* memTestDevice() */
Putting It All Together
Para que nuestra discusión sea más concreta, consideremos un ejemplo práctico.
Supongamos que queríamos probar un fragmento de 64 kilobytes de SRAM en la
dirección 0x0000000. Para ello, llamamos a cada una de las tres rutinas de prueba
en el orden correcto, como se muestra en el listado 4. En cada caso, el primer
parámetro es la dirección base del bloque de memoria. Si el ancho del bus de datos
es mayor que 8 bits, se requieren un par de modificaciones. Si cualquiera de las
rutinas de prueba de memoria individuales devuelve un valor distinto de cero (o no
NULL), puede activar un LED rojo para indicar visualmente el error. De lo contrario,
después de que las tres pruebas se hayan completado correctamente, es posible
que active un LED verde. En caso de error, la rutina de prueba que ha fallado
devolverá información sobre el problema encontrado. Esta información puede ser
útil al comunicarse con el diseñador de hardware o el técnico sobre la naturaleza
del problema. Sin embargo, solo es visible si estamos ejecutando el programa de
prueba en un depurador o emulador. En la mayoría de los casos, simplemente
descargaría toda la suite y la dejaría ejecutar. A continuación, si y sólo si se
encuentra un problema de memoria, ¿necesitaría usar un depurador para recorrer
el programa y examinar los códigos de retorno de la función individual y el contenido
del dispositivo de memoria para ver qué prueba ha fallado y por qué.

1. /**********************************************************************
2. *
3. * Function: memTest()
4. *
5. * Description: Test a 64-k chunk of SRAM.
6. *
7. * Notes:
8. *
9. * Returns: 0 on success.
10. * Otherwise -1 indicates failure.
11. *
12. **********************************************************************/
13. int
14. memTest(void)
15. {
16. #define BASE_ADDRESS (volatile datum *) 0x00000000
17. #define NUM_BYTES 64 * 1024
18. if ((memTestDataBus(BASE_ADDRESS) != 0) ||
19. (memTestAddressBus(BASE_ADDRESS, NUM_BYTES) != NULL) ||
20. (memTestDevice(BASE_ADDRESS, NUM_BYTES) != NULL))
21. {
22. return (-1);
23. }
24. else
25. {
26. return (0);
27. }
28.
29. } /* memTest() */

Listado 4 - Ponerlo todo junto desafortunadamente, no siempre es posible escribir


pruebas de memoria en un lenguaje de alto nivel. Por ejemplo, el lenguaje C
requiere el uso de una pila. Pero una pila en sí requiere memoria de trabajo. Esto
puede ser razonable en un sistema con más de un dispositivo de memoria. Por
ejemplo, puede crear una pila en un área de RAM que ya se sabe que funciona,
mientras prueba otro dispositivo de memoria. En una situación común de este tipo,
una pequeña SRAM podría ser probada desde el ensamblado y la pila podría ser
creada allí después. Entonces un bloque más grande de DRAM podría ser probado
usando un algoritmo de prueba más agradable, como el mostrado arriba. Si no
puede asumir suficiente RAM de trabajo para la pila y las necesidades de datos del
programa de prueba, tendrá que volver a escribir estas rutinas de prueba de
memoria completamente en lenguaje ensamblador. Otra opción es ejecutar el
programa de prueba de memoria desde un emulador en circuito. En este caso,
puede optar por colocar la pila en un área de la propia memoria interna del emulador.
Al mover la memoria interna del emulador en el mapa de memoria de destino, puede
probar sistemáticamente cada dispositivo de memoria en el destino. La necesidad
de pruebas de memoria es quizás más evidente durante el desarrollo del producto,
cuando la fiabilidad del hardware y su diseño todavía no se han demostrado. Sin
embargo, la memoria es uno de los recursos más críticos en cualquier sistema
integrado, por lo que también puede ser deseable incluir una prueba de memoria en
la versión final de su software. En ese caso, la prueba de memoria y otras pruebas
de confianza de hardware se deben ejecutar cada vez que el sistema se enciende
o se restablece. Juntos, este conjunto de pruebas inicial forma un conjunto de
diagnósticos de hardware. Si uno o más de los diagnósticos fallan, se puede llamar
a un técnico de reparación para diagnosticar el problema y reparar o reemplazar el
hardware defectuoso.

Copyright (c) 2000 de Michael BarrEste artículo está adaptado del material del
capítulo 6 del libro Programming Embedded Systems in C and C++ (ISBN 1-56592-
354-5). Se imprime aquí con el permiso de O'Reilly & Associates, Inc.

S-ar putea să vă placă și