Como grabar datos en memoria

Hola,

Hoy me he parado a pensar como podrías guardar en memoria (sin entrar en detalles de que tipo, tamaño, etc). Tampoco usando sistemas de archivos fat ... "a pelo". ;) Ya aviso que es un poco "paja mental". Imaginemos que quieres guardar datos que ocupan 10 bytes (por poner una cifra fácil).

¿Se hacen mecanismos para saber cuando empieza y/o acaba cada dato dentro de la memoria? Me explico, si el programa en algún paso hace algo no esperado, y hace un salto de una posición de más en la memoria o algo similar, perderé todos los datos, ya que no cuadrarán mis "slots" de 10bytes de forma lógica.

Pero por otro lado, si empiezas a poner "marcas", comes memoria un poco a lo tonto....Es decir, podría hacer en forma de protocolo secuencial que tengo un determinado byte al inicio, otro byte específico al final y alguno en medio de los datos. De esta forma podría ir mirando si se cumple el patrón cuando estoy leyendo los datos de la memoria. En caso de que falle, pues avanzo hasta encontrar el patrón de nuevo....

Otra manera sería metiendo un checksum cada x bytes, o cosas así...

Estoy pensando en que si guardas 1 Mb, por decir algo, y tu programa hace algo raro, como sabes dónde ha fallado, y lo peor que todo, si no tienes ciertas marcas, tampoco tienes ningún mecanismo para saber si está bien....

Es una pregunta un roco enrevesada y rara, lo sé, pero no sé ni como plantearsela a mi amigo google. También la duda me ha surgido, al plantearme hacer una cosilla con una memoria que escribes de forma secuencial (no le vas dando direcciones absolutas cada vez que quieres escribir. Le dices dónde empezar, y va autoincrementándose la dirección de memoria cada vez que le mandas un byte nuevo a grabar (por rapidez) ). Se me ocurre que si meto la pata en algún punto de mi programa, y por lo que sea mando un byte de más (por decir algo), ya no tendría lógica los datos leidos de 10bytes en 10bytes a partir de ese punto....

:D

Creo recordar ... hablo de memoria eh ¡¡

El sistema FAT tiene una zona donde se graba una tabla de contenidos, que tienen el nombre del archivo y la direccion de comienzo y final del archivo. no recuerdo si tenia alguna otra informacion.

si se borra un archivo lo que hace es poner un ( creo recordar) simbolo $ al comienzo del nombre, y de esta manera el SO ignora esa entrada de la tabla de contenidos., pero la zona de la memoria donde ha grabado esos datos lo deja intacto de aqui que algunos programas de recuperacion de datos buscaran estas entradas, cambiaban el primer caracter y listo, si no se habia tocado el resto de la memoria podias recuperar el dato.

el cheksun se lo puedes agregar por programacion, y una vez grabado comprobar el cheksun para ver si se ha grabado correctamente pero con uno solo te vale al final del archivo, otra opcion es comparar lo grabado con lo que querias escribir, si no de la totalidad, antes de que se te acabe la ram, o bloques de 100 en 100 bytes .... por ejemplo.

Hola,

No quiero implementar Fat, ni nada parecido... Simplemente antes de reinventar la rueda, quería saber si hay documentación o métodos que se utilizan para hacer lo que pregunto. Me refiero, imagina que los datos individuales que guardo es una estructura de 10 bytes, y voy todo el rato guardandola sin más, pero por lo que sea el micro se resetea, fallo de corriente, fallo en el programa, etc y sólo he guardado 8 bytes ó he saltado una posición de memoria, etc. Entonces si no tengo ningun mecanismo de saber dónde/empieza cada dato ó cada X datos, pues lo tengo mal.... Tampoco pregunto por un método para ver la integridad de la memoria. Es algo que pensando que pasaría si mis rutinas hicieran algo extraño, cómo detectaría bien los datos guardados.... Ya que al final al leer, no voy a tener problema, las direcciones que le pida, pues me da los datos.... otra cosa es que tenga sentido lo que leo.

No sé si me explico bien....

Yo no entiendo tu contexto de "no saber en qué posición de memoria estás". En todo caso me imagino el símil de por ejemplo estás descargando un fichero de internet, y se te corta la conexión. Lo que querrías es poder continuar la descarga desde donde se ha cortado, ¿no? ¿Y por 10 bytes merece la pena?

Porque si el micro se resetea, tu programa se reseta.

O intenta explicarlo un poquito más :blush:

A ver si me explico mejor....Son ejemplos que he puesto de cosas que pueden pasar genéricas. Sobretodo que alguna rutina haga algo que no espero.

La gracia esta que es un sistema de adquisición de datos que voy a ir grabando datos adquiridos. Pero tampoco voy a comprobar cada dato grabado corresponde con el orginal adquirido, ya que tardaría mucho tiempo. Antes de hacer ésto, se me ocurre ir poniendo "marcas" cada ciertos datos. De esta forma, luego al descargar los datos, podría basarme en dichas "marcas". Ya que con estas "marcas" podría buscar el patrón de grabación para saber si ha ido algo mal.

Pongamos que no hago nada, y voy grabado cada dato (10 bytes) en la memoria. Por lo que sea, en la mitad, una rutina me envia un byte da más para grabar (un error en la programación). Luego al leer la memoria e ir reconstruyendo de nuevo los datos, pues no tendrá sentido a partir de cuando se envió dicho byte de más.

Es decir, en el mundo "ideal" que no hay fallos, cuando descargase los datos grabados , pues voy haciendo myvar1=primeros 10 bytes, myvar2=los siguientes 10, myvar3....

;)

Mas o menos lo pillo. En los primeros bytes de la memoria se podría poner el ultimo byte grabado porque hacer un checksum de los datos guardados y grabarlo no lo veo sentido.

pero grabar el último dato no me soluciona nada... Lo ideal, es algo que sabes que dato/s están mal y pasas de ellos. Al menos así no pierdes todo lo grabado.

Vale, ahora si lo entiendo. No sabría ahora mismo como plantearlo, le doy vueltas al tema a ver si se me ocurre algo.

Yo sigo sin entender. Si por ejemplo te doy dos datos, Dato 1: 56 // Dato 2: 94 ¿Cuál está mal? :roll_eyes:

Es que veo que no estás preguntando nada concreto y estás mezclandonos muchas cosas. Si estás copiando/transfiriendo datos en el espacio o en el tiempo (de una memoria a otra, o preservarlos en la misma memoria), los mecanismos checksum permiten comprobar que se han copiado bien. Si estás leyendo datos de un sensor, el acondicionamiento y el sentido común dicen qué datos pueden ser aberrantes. P.ej. si lees temperaturas en una habitación de una casa y de repente aparece una de 230ºC evidentemente estará mal, o si el rango de medida sólo va de 20 a 30ºC una medida de 40 también estará mal. Si quieres inventarte ficheros/registros a la hora de guardar en una memoria, pues o creas una especie de tabla FAT con posiciones, o al menos creas una cabecera para cada registro.

¿Cuál es la pregunta? O_o

Yo sigo sin entender. Si por ejemplo te doy dos datos, Dato 1: 56 // Dato 2: 94 ¿Cuál está mal? smiley-roll

Eso mismo es lo que quiero saber!! . Por eso estoy preguntando si hay mecanismos genéricos o ideas de cómo hacerlo. Pero el dato que guardo, puede que no sea tan fácil como un byte. Puede que sea una estructura del tipo: struct MyStruct { byte Identificador; byte dato0; byte dato1; }; Si imaginamos que tengo: MyStruct variable1 = { 30 , 1 , 2 }; MyStruct variable2= { 31 , 3 , 4 };

Y voy guardando en memoria un dato detrás de otro. Si por lo que sea, grabo un dato entre medio de variable 1 y variable 2, pues no tengo manera de saber dónde me empieza mi variable 2. Ya que al volver al leer de la memoria, me creeré que los 3 primeros bytes corresponde a variable 1 y los siguientes 3 a variable 2, pero resulta que no es así.

¿Por qué todo ésto? Pues no quería entrar en todo el detalle. Pero es una memoria por SPI, y voy a tener otro dispositivo por SPI. Imaginemos que hago mal cierta rutina, y por la razón que sea, no cambio el chip select en el momento adecuado....podría seguir enviando bytes a la memoria que van a ser grabados que son "basura". Pues resulta que al leer lo que se ha grabado y volver a recomponerlo, estaría haciendolo mal y encima sería complicado de depurar lo que está pasando....

Digamos que cada (por poner un número) 30 bytes que he enviado por SPI a la memoria para grabar, voy calculando el checksum y lo grabo a continuación. Pues al descargar los datos grabados, podría ir haciendo una "ventana" de lectura de 30 bytes y que mire si el 31 corresponde al checksum de las anteriores. Si algo falla, pues vas desplazando la ventana hasta que encuentres de nuevo dicho patrón y descartas la parte de memoria que no ha cumplido dichas condiciones. Por poner un ejemplo de un mecanismo que se me ocurre.

Como me parece algo genérico, preguntaba qué se suele hacer ó si hay algún sitio de referencia para que pueda ver cómo se resuelven problemas similares.

Es que veo que no estás preguntando nada concreto y estás mezclandonos muchas cosas.

Tranki colega! Seguramente me estoy explicando muy mal. Tampoco quiero poner nervioso al personal, no hace falta que te molestes en contestarme si va a resultar un problema.

Gracias por tu tiempo!

Yo también llevo unos días dándole vueltas a este tema, ya que puede que tenga que hacer algo similar. Lo más sencillo es poner un byte delimitador conocido tras cada estructura o un crc, según la fiabilidad que quieras tener, aunque sí, a costa de espacio gastado "inútilmente".

Si guardas la longitud de la cadena guardada en el primer/os byte esos los vas a machacar a escrituras, por lo que si vas a hacerlo trabajar a largo plazo, tendrás que tirar la memoria por 1 byte que ya no mantiene la carga.

Un saludo

lo que se utiliza en digital en transmisiones para detección automática de error es el código hamming

quizás puedas aplicarlo a grabación de datos en memoria.

Como te han dicho dependerá del grado de fiabilidad que le quieras dar a los datos, redundancia es otra de las posibilidades, redundancia inversa.

todo ello tiene la pega de que consumes espacio de información "inútil", entrecomillado pues es útil para la detección de errores

http://es.wikipedia.org/wiki/C%C3%B3digo_Hamming

un saludo

El código hamming es detector y además corrector de errores, pero en este caso que no habría que corregir nada, ya que si falla es que faltan datos, no que haya bailado un bit, por lo que no se podría corregir. Me refiero a que no te puedes aprovechar de los beneficios del hamming.

Yo pondría el típico CRC de sumar todos los valores, aunque haga overflow y restarlo a 0xFF

[quote author=Igor R link=topic=79787.msg603072#msg603072 date=1321916561]Si por lo que sea, grabo un dato entre medio de variable 1 y variable 2[…][/quote]Porque tu programa esté mal diseñado dices. Pues no programes a ojo, haz un diagrama de flujo si hace falta.
Un checksum no es para saber si una aplicación está mal programada, no veo el sentido de ese planteamiento. Es para saber si la información se ha transmitido o preservado bien (y corregirla si se puede). Lo bueno que tienen los computadores es que hacen lo que se les ordena, así que ordénale bien. xD

chiva, tú lo que dices es cómo delimitar una estructura en una memoria (llámalo registro, fichero, …). No veo cómo eso ayuda a encontrar fallos de programación.

O sea, por ejemplo, cómo debería ser lo que guardo:
0x05 0x12 CRC/delimitador 0x56 0x45 0x86 CRC/delimitador 0x20 0x89…
Pero se me cuela un A3 por una instrucción mía que no debería estar donde está, así que esto se me guarda:
0x05 0x12 CRC/delimitador 0xA3 0x56 0x45 CRC/delimitador 0x86 0x20…

¿Y bien? :blush:
Que por cierto aun no me he entendido de dónde salen esos datos que guardas. Si te vienen de un sensor, no veo por qué serías capaz de saber que ese A3 no es una lectura correcta y la ha metido el programa.

Ese dato 0xA3 es un extra, no sustituye el de la estructura, por lo que sería

0x05 0x12 CRC/delimitador 0xA3 0x56 0x45 0x86 CRC/delimitador 0x86 0x20

Por lo que tomaría como CRC el 0x86, que fallaría, bueno, hay 1 posibilidad entre 255 de que casualmente coincida el dato erróneo con el CRC.

Pongo un link interesante que me ha pasado Chiva. A ver si a Razorblade le queda claro de lo que estamos hablando...

Aquí hay otro lectura interesante...

Y por último, Algorithms and Data Structures for Flash Memories La introducción resume bien mis dudas: "Flash memory is a type of electrically erasable programmable read-only memory (eeprom). Be- cause flash memories are nonvolatile and relatively dense, they are now used to store files and other persistent objects in handheld computers, mobile phones, digital cameras, portable music players, and many other computer systems in which magnetic disks are inappropriate. Flash, like earlier eeprom devices, suffers from two limitations. First, bits can only be cleared by erasing a large block of memory. Second, each block can only sustain a limited number of erasures, after which it can no longer reliably store data. Due to these limitations, sophisticated data structures and algorithms are required to effectively use flash memories. These algorithms and data struc- tures support efficient not-in-place updates of data, reduce the number of erasures, and level the wear of the blocks in the device."

Igual me expreso mal yo, porque el texto que has citado en rojo habla de que los dispositivos de almacenamiento cascan antes o después o no son capaces de preservar los datos.

Razorblade: Si estás copiando/transfiriendo datos en el espacio o en el tiempo (de una memoria a otra, o preservarlos en la misma memoria), los mecanismos checksum permiten comprobar que se han copiado bien.

En negrita se ve mejor.

También has puesto un documento (el segundo) que habla de cuando programas por ejemplo la BIOS del ordenador y se va la luz. O en un caso más cercano, del bootloader de Arduino, que da igual que el programa que le metas a Arduino no sirva para nada y se quede pillado, gracias al bootloader siempre vas a poder reprogramarlo sin necesidad de un programador ICSP. Estamos en las mismas, es una transferencia de información de un sitio a otro: CRC, byte de posición. Y el tema bootloader, en ningún mensaje vuestro me pareció leer nada parecido.

Y los otros documentos tratan sobre formatos lógicos y sistemas de ficheros para memorias Flash (sectores, etc..), para cuando tienes que borrar datos que están entre otros datos, sustituirlos..., y dijiste que no era de lo que hablabas.

Al final dices que chiva sí que lo ha entendido con su último mensaje, y [u]simplemente[/u] era tener una estructura de tamaño FIJO y DELIMITADA con un byte CONOCIDO y que exclusivamente es delimitador (me da igual principio que final); un puñetero byte conocido que te indique cuándo empieza o termina una estructura. Pero de acuerdo, ya veo tu pregunta, ¿cómo hacerlo sin usar delimitadores que ocupen memoria? Creo que nadie te ha respondido a eso o entendido la pregunta bien porque es evidente, la magia no existe. Lo llamas "usar memoria a lo tonto", siendo que creo que tiene una finalidad bien clara. ¡Encima también te gustaría que se pudiera saber qué datos sobran o están mal!

Más que paja mental... esto es un sueño. :P