Go Down

Topic: Leer bancos de memoria SD (Read 5980 times) previous topic - next topic

StringCGE

#15
Feb 26, 2017, 02:48 am Last Edit: Feb 26, 2017, 03:02 am by StringCGE
Como selecciono entre disco lógico y disco fisico.
Estoy confundiéndome mas.

que es exactamente esto

Detalle      Direccion

SDFile       SD.h

*_file;       SD.h

sync();      FILE.cpp


No se de donde salen

typedef SDLib::File    SDFile;

y esto me marea aun mas SDLib es una clase que tiene a una funcion/metodo File

SdFile::open()

que seria algo asi

SDLIB::FILE::open()

lo único que quiero es tener la capacidad de escribir y leer en la eeprom.... SD XD.

y sacar unicamente las funciones que me permiten esto para que el programa no sea tan pesado ya que mi arduino uno se esta quedando corto de memoria.

Si puedo ver cuantas direcciones de memoria tiene una SD lo del sistema de archivos sera liberdad de quien quiera hacerse uno propio.

Otra cosa.
Code: [Select]
uint8_t Sd2Card::writeBlock(uint32_t blockNumber, const uint8_t* src) {
chipSelectHigh();
  return true;
}

Sin contar lo que retorna Fail solo me queda esto

Que me lleva a esto.
Code: [Select]
void Sd2Card::chipSelectHigh(void) {
  digitalWrite(chipSelectPin_, HIGH);
#ifdef USE_SPI_LIB
  if (chip_select_asserted) {
    chip_select_asserted = 0;
    SDCARD_SPI.endTransaction();
  }
#endif
}


SDCARD_SPI.transfer(b);

return SDCARD_SPI.transfer(0xFF);

SDCARD_SPI.begin();

Le estoy siguiendo el paso pero la verdad estoy mareado en esto.


Gracias por el aporte.

Lucario448

#16
Feb 26, 2017, 06:57 am Last Edit: Feb 26, 2017, 06:57 am by Lucario448
Como selecciono entre disco lógico y disco fisico.


que es exactamente esto

Detalle      Direccion

SDFile       SD.h

*_file;       SD.h

sync();      FILE.cpp
Uno y dos hacen referencia al objeto File; el tercero es básicamente flush.


typedef SDLib::File    SDFile;

y esto me marea aun mas SDLib es una clase que tiene a una funcion/metodo File

SdFile::open()

que seria algo asi

SDLIB::FILE::open()
Creo que es tenía que ver con el atributo friendly, que es como "maquillar" una clase para hacerla más fácil de usar.

lo único que quiero es tener la capacidad de escribir y leer en la eeprom.... SD XD.
Paciencia, que ya tengo la "beta" de la librería.


y sacar unicamente las funciones que me permiten esto para que el programa no sea tan pesado ya que mi arduino uno se esta quedando corto de memoria.
Ese de hecho es un tema del que necesito ayuda, porque quisiera saber qué se le puede quitar a Sd2Card; solo uso las funciones init, cardSize, readBlock y writeBlock de esta clase.

Si puedo ver cuantas direcciones de memoria tiene una SD lo del sistema de archivos sera liberdad de quien quiera hacerse uno propio.
Sd2Card y mi librería de hecho permiten eso; mediante la lectura de un registro en la tarjeta SD se obtiene su capacidad en sectores. Cuando leí la de una de supuestamente 4 GB, la cantidad de sectores apunta a que es de 3.75 GB ._.


Otra cosa.
Code: [Select]
uint8_t Sd2Card::writeBlock(uint32_t blockNumber, const uint8_t* src) {
chipSelectHigh();
  return true;
}

Sin contar lo que retorna Fail solo me queda esto
Ese es parte del "corazón" de mi librería.


Le estoy siguiendo el paso pero la verdad estoy mareado en esto.
Lo sé, a mi también.

Solo que apenas me di cuenta que ahí está justo lo que necesito, me puse manos a la obra con la librería esa.



Qué por cierto ya la tengo lista para hacer pruebas, lo llamaría "en beta" porque no es la versión definitiva hasta que pasar por el arduo proceso de probar y probar. Al ser así, tampoco tiene forma de librería, por ahora son solo varios archivos en una sola carpeta.
Recuerden que el .ino es el que manda a subir.

ferminolaiz

Lo de los 3.75 GB es por cuestión de unidades.

https://es.wikipedia.org/wiki/Kilobyte
https://es.wikipedia.org/wiki/Kibibyte

Técnicamente son 4GB, y 3.7x GiB. si los bloques se dividieran de a 500 bytes, debería dar 4GB; el hecho es que windows desde sus inicios creó una confusión interesante en torno a esto :P

Toma un tiempo acostumbrarse a pensarlo así (personalmente aún no termino de aceptarlo), pero bueno, tal parece que así es..

Saludos!

Lucario448

Oh sí, la confusión del prefijo decimal vs prefijo binario.



NOTA IMPORTANTE: para los que los que quieran hacer pruebas con lo que les acabo de dar en post anterior, deben cambiar esta línea en el archivo SdRaw.cpp:

Code: [Select]
if (!card.init(cs, mode)) return false;
Por:
Code: [Select]
if (!card.init(mode, cs)) return false;

Sin esta correción, la tarjeta nunca se inicializa.

StringCGE

Ahora este es mi problema.

Lo que quiero hacer es comunicarme directamente a la SD y con transfer lo hago y lo que se me complica es el hecho de poder escribir en el serial un valor HEX y que le llegue a una variable tipo uint8_t ese valor en HEX.

Ejemplo

Monitor serial 0xFF

Arduino Serial.readString() capturo la cadena

Arduino ?????????

De cadena a HEX no se como hacer cast.

Lucario448

Se me ocurre:

Code: [Select]
byte b = atoi(elString.c_str(), 16);

StringCGE

#21
Mar 01, 2017, 03:05 am Last Edit: Mar 01, 2017, 03:11 am by StringCGE
const char *__s Error
no se si me indica que debe ser un puntero a un array de char o únicamente soporta un char

Si alguien sabe como optimizar esto.

Code: [Select]
Trans(0x00,0x00,0x00,0x00,0x00,0x00);

Code: [Select]
void Trans(uint8_t trA,uint8_t trB,uint8_t trC,uint8_t trD,uint8_t trE,uint8_t trF){
  data_01[0]=trA;
  data_01[1]=trB;
  data_01[2]=trC;
  data_01[3]=trD;
  data_01[4]=trE;
  data_01[5]=trF;
  cli();
  for(uint8_t i = 0;i<=6;i++){
    data_03[i] = SPI.transfer(data_01[i]);
  }
  sei();
  Serial.print("Respuesta ");
  for(uint8_t i = 0;i<=6;i++){
    Serial.print(data_03[i],HEX);
    Serial.print("-");
  }
  Serial.println();
}



Lo que se hasta ahora es que mandando este comando (inicializacion)

Code: [Select]
Trans(0x40,0x00,0x00,0x00,0x00,0x95);

la SD me responde 0x01 y luego pasa a responder mandando 0xFF  pero antes del comando de inicializacion la SD manda 0x00

No quiero tener que estar cargando y cargando opciones por cada HEX a probar si tengo un monitor serial por el cual mandar los HEX

otra opción seria

Code: [Select]
int algo = Serial.readString().toInt;
uint8_t = u_int_8;
switch (algo){
case 1:
u_int_8 = 0x00;
break;
case 2
u_int_8 = 0x01:
break;
hasta el infinito y mas aca

StringCGE

Alguien encontró algo para leer un solo sector de una sd y escribir un solo sector o mejor aun escribir byte a byte en una SD.


Ahora intento una comunicación entre VB y arduino pero según arduino VB le envía 6 caracteres inicialmente luego 7 sin enviar nada y luego 8,28,38,48 y asi de largo.

Se que tengo que abrir un post nuevo pero si aun no termino con esta duda de escribir byte a byte ¿Sera que me animo a esto otro?

Lucario448

Alguien encontró algo para leer un solo sector de una sd y escribir un solo sector o mejor aun escribir byte a byte en una SD.
¿No lo lograste? Pues... yo ya sé cómo; y lo hice a manera de librería.

No lo he sacado "públicamente" porque aún no tiene documentación. No lo he documentado porque no se me ocurren ejemplos que expliquen el uso de mi librería (especialemente porque tú eres el único que conozco que le serviría algo así). O por lo menos, no se me ocurren ejemplos de EEPROM (que es el uso que se le puede dar a una tarjeta SD con esta modalidad)

Metaconta

Hola:

Extremadamente interesante este tema. No toco las tarjetas estas de SD desde el 2005 cuando era estudiante de electrónica. Eran de unos 512 MB que costaba como barato 60 €, incluido pendrive.

Antes hacía cosas pero con PIC y en asm. Voy a buscar información genérica de como funcionan por dentro estas tarjetas, es lo que hay que saber antes de entrar en este mundo, primero conocer, luego tener ideas para poder actuar.

¿Qué sabe el pez sobre el agua,







por donde lleva nadando toda su vida?

Antes había mucha información en www.microchip.con ejemplos en asm y C para PIC. Tiene que haber a estas alturas de la vida para arduino si o si.

Si encuentro algo, se los hago saber.

StringCGE

Pues seria bueno aprender otros lenguajes y aprender mas de AVR y por cierto ya estoy mas cerca de poder escribir una SD a mi modo.

El objetivo es poder formatear otra SD o guardar String, imagenes o cualquier otra cosa

(Arduino master)->(SD master)->(SD usuario).

Las dos comparten el bus SPI pero la lectura byte a byte o bloque a bloque es para no usar la memoria del arduino en guardar los datos del formato fat y asi arduino recoje los datos de la (SD master) y se los pasa a la (SD usuario) en el caso de dar formato .

Quisiera ver como funciona esa libreria o saber que hace para ver que mas le pongo a mi libreria.

Tambien quiero publicarla pero de tal manera que siendo de codigo abierto se pueda dar fe que yo la hice por motivo de posterior uso en una universidad y no me tachen de copion porque esta en internet.

Lucario448

Quisiera ver como funciona esa libreria
¿Sabes cómo se usa un objeto File de la librería SD? Exactamente igual.

Las adicionales son:
Direccionamiento por sectores.
En tarjetas mayores a 4 GB, el direccionamiento por bytes es relativo (seek, position, available); por esta razón, existe el concepto de "banco de memoria", el cuál consiste en dividir (por software) la tarjeta SD en bancos de 4 GB. El direccionamiento por sectores siempre es absoluto.
Un ligero cambio en los readString: Estos terminan al encontrarse con '\0'

StringCGE

Entiendo el concepto de direccionamiento pero no lo he implementado ya que no tengo una SD de mayor tamaño.

Usas la librería SD o parte de ella esta implementada en tu librería.

Ya logre iniciar una tarjeta SDHC de 4GB solo con mi código y la libreria de SPI, ya leo un sector y escribo en ese sector, y ya termine con la escritura de un solo byte.
Ahora voy por la escritura de cadenas.

Pero no se interpretar la info de la sd y eso lo dejo para un poco después.

Gracias.
Cuando este mi codigo lo hago libreria y Se ve lo que se hace.

Lucario448

Entiendo el concepto de direccionamiento pero no lo he implementado ya que no tengo una SD de mayor tamaño.
El concepto del "banco de memoria" se debe a que si direccionamos a nivel de bytes con 32 bits (unsigned long); no podríamos trabajar más de 4 GB. Si direccionamos a nivel de sectores, el máximo sería 2 TB. Como a la fecha no existen tarjetas SD de dicha capacidad, de momento esa limitante no existe.


Usas la librería SD o parte de ella esta implementada en tu librería.
Parte; específicamente la clase Sd2Card (el "corazón") y sus dependencias.


Ahora voy por la escritura de cadenas.
No tiene mucha ciencia: pides un array y la longitud de este; lo que tienes que hacer es escribir desde el elemento cero hasta longitud - 1. Si haces la actualización del bloque completo por un único byte, ahí es donde las cosas se pondrían lentas si lo haces así múltiples veces (actualizar un bloque tarda un tiempo del rango de los milisegundos); por eso mi implementación involucra un búfer de 512 bytes.


Pero no se interpretar la info de la sd
En mi caso, la única información que me interesa, es la cantidad total de sectores que posee la tarjeta (retornado también por la función size). Con esta información es como determino la capacidad de esta, y la vez si necesita manejarse por bancos (>4 GB).
Datos como ese no están explícitamente guardados en los registros, algunos se tienen que calcular. El registro utilizado para determinar la capacidad, se le llama CSD.

Para leer los registros de la tarjeta, hay que enviar ciertos comandos (como todo lo demás).

StringCGE

Lo de Byte a Byte es por que quiero poder guardar algo asi

Code: [Select]
int a = 5;

pero en la SD y luego almacenar variables de todo tipo y que el usuario pueda estructurar sus variables mas o menos como documentos pero que la clase se encargue de no escribir una en sima de otra dentro de la sd.

Ahora mi programa funciona asi.

Buffer de 512 porque es un sector de ese tamaño físicamente y es la menor unidad en la que se puede acceder.

Cambio un valor del Buffer y se lo envio de vuelta a la SD.

Como tu dices Lucario448 que se pierde tiempo en enviar byte por byte a la SD.

Es verdad y no tiene sentido, pero si yo lograba escribir un solo byte en la SD sin alterar el resto del sector, podia escribir tantos byte como se me antoje y si tengo un archivo el cual ya esta hecho pero solo quiero cambiar una porción de este mientras el código se ejecuta. Hay entra la escritura byte a byte que puede ser de a 2 byte o mas incluso puede ser de 3 sectores y 200 byte por poner un ejemplo, y es por eso que ahora hago un método para escribir cadena de caracteres.

la particularidad que tiene mi método es que.

Supongamos que se te ocurre escribir desde el sector 4 en la posición 490 una cadena de 50 caracteres.
Logicamente que no entra en ese sector.
entonces mi método pretende escribir lo que puede en el sector 4 y el resto en el sector 5 sin alterar lo que hay en ese sector en los lugares que no ocupo la cadena de 50 caracteres.

La funcion size a breves rasgos ¿de donde toma el valor de la cantidad de memoria?.

size esta sobrecargada verdad.

porque size tambien da la cantidad de caracteres que tiene un documento.

Vi un archivo txt con el programa HxD y la particularidad es que una cadena como por ejemplo "stringCGE" se escribe saltando un byte asi"S-t-r-i-n-g-C-G-E"

que ocupe los chart bytes consecutivos.
aun no se si es el formato o que pero size en la libreria SD lo que me da es la cantidad de caracteres que tiene un archivo TXT.

¿Sera que se puedo escribir un boceto en la SD y que arduino lea ese boceto y lo ejecute?

Lokuras mias como entrenamiento
"Discúlpenme si es que jodo tanto sabiendo tan poco"


Go Up