[Explicación detallada dos] Conocimientos que debe conocer antes de escribir el controlador para Nand Flash

1.2.15.1. Precauciones para el programa de página

La operación de escritura de Nand flash se llama Programa, que generalmente se expresa en unidades de página.

Algunos Nand Flash, como K9K8G08U0A, admiten la programación de página parcial (Programa de página parcial), pero existen algunas restricciones: en la misma página, la programación de página parcial continua no puede exceder de 4 veces.

Generalmente, las operaciones de programación se realizan en unidades de páginas y la programación de página parcial rara vez se usa.

Con respecto a esta parte de la programación de páginas, originalmente era una operación de escritura de página, pero se usaron dos o más comandos para implementarla. Parece que la operación es redundante e ineficiente, pero de hecho, hay consideraciones especiales:

Al menos para el borrado de bloques, el primer comando 0x60 es el comando de configuración de borrado, luego se pasa la dirección del bloque que se va a borrar y luego se pasa el comando de confirmación de borrado 0xD0 para iniciar la operación de borrado.

Este diseño de enviar comandos en dos pasos para completar una sola operación, es decir, el modo de comando de configurar primero y luego confirmar el último, es para evitar ruidos externos no intencionales / imprevistos, como ciertos ruidos. Se genera un comando 0x60. En este momento, incluso si Nand Flash lo considera erróneamente como una operación de borrado, pero no hay una operación de confirmación posterior 0xD0, Nand Flash no borrará los datos, lo que hace que los datos sean más seguros y no será un mal funcionamiento debido al ruido.

1.2.15.2. Explicación detallada del proceso de operación de lectura

Tomemos la operación de lectura más simple como ejemplo para explicar cómo entender el diagrama de secuencia y convertir los requisitos en el diagrama de secuencia en código.

Antes de explicar el diagrama de tiempos, primero averigüemos qué tenemos que hacer:

Desde una determinada página de Nand Flash, leemos los datos que queramos.

Para implementar esta función, se involucran varias partes del conocimiento. Incluso si no conocemos los detalles de Nand Flash, pero a través de la introducción del conocimiento básico, es fácil pensar en al menos qué comandos deben usarse en función de nuestro sentido común., cómo enviar estos comandos, cómo calcular la dirección requerida, cómo leer los datos que queremos y así sucesivamente.

Aquí hay una explicación paso a paso, lo que se debe hacer y cómo hacerlo:

1.2.15.2.1. Qué comandos deben usarse

En primer lugar, es necesario comprender qué comando se usa para leer datos:

De acuerdo con la introducción anterior del conjunto de comandos de Nand Flash, sabemos que para leer datos se usa el comando Leer, este comando requiere 2 ciclos, el primer ciclo envía 0x00 y el segundo ciclo envía 0x30.

1.2.15.2.2. Trabajos preparatorios antes de enviar la orden y significado específico de cada señal en el cronograma.

Después de saber qué comandos usar, aprenda a enviar estos comandos.

[inmediato] inmediato

Antes de comenzar con la explicación, necesito ser prolijo sobre la palabra "habilitar", en caso de que algunos lectores sean los mismos que yo antes, al escuchar este tipo de palabras, es el primer contacto, o si no tienen mucho contacto, es fácil confundirse Confundido (aunque este vocabulario es el vocabulario más básico para algunos profesionales, 囧).

Habilitar (Habilitar) se refiere al significado de hacer (una determinada señal) efectiva y hacerla efectiva, y cómo "hacerla" y "habilitarla". . . . Por ejemplo, el número de línea CLE en la figura anterior es efectivo en nivel alto. Si está configurado en nivel alto en este momento, lo llamamos habilitando CLE, que significa hacerlo efectivo.

Figura 1.7. Diagrama de tiempo de la operación de lectura de datos de Nand Flash

Diagrama de tiempo de operación de lectura de datos de Nand Flash

 

[Nota] Nota
Esta imagen proviene de la hoja de datos de Nand Flash del modelo K9K8G08U0A de Samsung.

Echemos un vistazo a la línea vertical amarilla en el borde de ① en la Figura 6 especialmente marcada.

El momento de la línea vertical amarilla es el momento anterior al envío del comando 0x00 del primer ciclo de la operación de lectura.

Veamos, en ese momento, qué valor corresponde a las varias filas por las que pasa, y para comprender mejor por qué necesitamos ese valor.

  1. La primera línea que cruza la línea vertical amarilla es CLE. Recuerda el pin de habilitar (CLE) en la introducción anterior, ¿verdad? CLE, establezca CLE en 1, significa que lo que va a enviar a Nand Flash a través del puerto multiplex de E / S es un comando, no una dirección u otro tipo de datos. Solo configurando CLE en 1 y haciéndolo efectivo, se puede notificar la lógica interna del hardware. Lo que recibirá a continuación es el comando, y la lógica interna del hardware colocará el comando recibido en el registro de comandos para lograr la corrección más adelante. De lo contrario, si no establece CLE en 1 para que sea válido, el hardware estará perdido y no sabrá si está pasando datos o comandos.
  2. Y la segunda línea es CE #, y el valor en ese momento es 0. La razón es muy simple, ya que desea enviar un comando a Nand Flash, primero debe seleccionarlo, por lo tanto, debe asegurarse de que el CE # sea bajo para que sea válido, es decir, la selección de chip es válida.
  3. La tercera línea es WE #, que significa habilitación de escritura. Debido a que el siguiente paso es escribir comandos en Nand Flash, para que WE # sea válido, configúrelo en un nivel bajo.
  4. En la cuarta línea, ALE es de nivel bajo y ALE es de nivel alto activo, lo que significa que no es válido. En consecuencia, la introducción anterior hace que CLE sea efectivo, porque el dato a ser datos es el comando (en este caso, se envía el 0x30 del segundo ciclo del comando de lectura mostrado en la figura), no la dirección. Si en otras ocasiones, como la próxima vez que desea ingresar la dirección, debe hacerla válida y hacer que CLE sea inválido.
  5. La quinta línea, RE #, es alta en este momento y no es válida. Se puede ver que es válido solo cuando pasa a un nivel bajo después de las siguientes 6 etapas, porque en ese momento, se requiere un comando de lectura para leer los datos.
  6. La sexta línea es el foco de nuestra introducción. Los puertos de E / S de entrada y salida multiplexados. En este momento, no hay datos de entrada. A continuación, en diferentes etapas, se introducirán o saldrán diferentes datos / direcciones.
  7. La séptima línea, R / B #, nivel alto, indica R (Listo) / listo, porque en la quinta etapa, el hardware interno, en la cuarta etapa, luego de recibir el comando de lectura desde el exterior, los datos de la página Un poco El bit se envía al registro de página. Durante este tiempo, el sistema está ocupado trabajando, lo que pertenece a la etapa de ocupado. Por lo tanto, R / B # se vuelve bajo, lo que indica que el estado Ocupado está ocupado.

Después de introducir el valor de cada señal en el tiempo ① y por qué es este valor, creo que en cada momento posterior, cada valor de la señal diferente correspondiente será analizado lentamente por usted mismo, y será fácil de entender la secuencia de operación específica. y el principio está arriba.

1.2.15.2.3. Cómo calcular la dirección de fila y la dirección de columna que queremos pasar

Antes de introducir el proceso detallado de lectura de datos, hay una cosa más que hacer, es decir, primero debemos entender las direcciones que queremos visitar y cómo resolver estas direcciones, y luego pasarlas un poco para que el hardware puede reconocerlos.

Aquí, tomemos nuevamente como ejemplo K9K8G08U0A. Este Nand Flash tiene un total de 8192 bloques, cada bloque tiene 64 páginas y cada página tiene 2K + 64 Bytes.

Supongamos que queremos acceder a la dirección de 1208 bytes en la página 64 en el bloque 7000. En este momento, primero debemos calcular la dirección específica:

Dirección física

= Tamaño de bloque × número de bloque + tamaño de página × número de página + dirección de página

= 128K × 7000 + 2K × 64 + 1208

= 0x36B204B8

A continuación, veremos cómo convertir esta dirección física real al formato requerido por Nand Flash.

Antes de explicar la composición de la dirección, echemos un vistazo a la introducción del ciclo de direcciones en su hoja de datos:

Figura 1.8. Composición del ciclo de direcciones Nand Flash

Composición del ciclo de direcciones Nand Flash

 

Combinando las etapas 2 y 3 en la Figura 1.7 "Diagrama de tiempo de la operación de lectura de datos Flash Nand" , podemos ver que hay 5 ciclos de direcciones Flash Nand, 2 ciclos de columnas y 3 ciclos de filas.

  1. En consecuencia, la dirección de la columna A0 ~ A10 es la dirección dentro de la página, y el rango de direcciones es de 0 a 2047.

    Los lectores atentos pueden haber notado, ¿por qué hay un A11 adicional aquí?

    De esta forma, de A0 a A11, hay 12 bits en total, y el rango que se puede representar es 0 ~ 212, es decir, 0 ~ 4096.

    De hecho, debido a que visitamos la dirección en la página, es posible que visitemos la posición de oob, es decir, dentro del rango de 64 bytes de 2048-2111. Por lo tanto, aquí solo se usan 2048 ~ 2111 para indicar la dirección en la página. El tamaño del área Oob es de 64 bytes.

  2. En consecuencia, A12 ~ A30 se denominan números de página. El número de página se puede ubicar en qué página.

    A18 ~ A30 indican el número de bloque correspondiente, es decir, a qué bloque pertenece.

Después de una breve explicación de la composición de la dirección, es fácil analizar la dirección en el ejemplo anterior.

Tenga en cuenta que el siguiente método es incorrecto:

0x36B204B8 = 11 0110 1011 0010 0000  0 100 1011 1 000, asignados respectivamente a los ciclos 5 dirección es:

1er ciclo A7 ~ A0 1011 1000 = 0xB8
2do ciclo A11 ~ A8 0 100 = 0x04
3er período A19 ~ A12 0010 0000 = 0x20
Cuarto ciclo A27 ~ A20 0110 1011 = 0x6B
5to ciclo A30 ~ A28 11 = 0x03
[Nota] Nota
En correspondencia con la Figura 1.7 "Diagrama de temporización de la operación de lectura de datos flash Nand" , * L significa nivel del suelo. Dado que esos bits no se utilizan, es obligatorio establecerlo en 0 en la hoja de datos, por lo que existe el segundo ciclo anterior. Los 4 superiores los bits del medio son 0000. Los otros bits después de A30 son similares en principio, todos son 0.

En cuanto a por qué el método de cálculo anterior es incorrecto, se debe a que en el proceso de cálculo anterior, el valor del undécimo bit, que originalmente pertenece al bit A11 del número de página, se calcula como el valor en la dirección de la página.

Debería calcularse así, que es correcto:

0x36B204B8 = 11 0110 1011 0010 0000  0 100 1011 1000

1er ciclo A7 ~ A0 1011 1000 = 0xB8
2do ciclo A10 ~ A8 100 = 0x04
3er período A19 ~ A12 010 0000  0  = 0x40
Cuarto ciclo A27 ~ A20 110 1011 0 = 0xD6
5to ciclo A30 ~ A28 11 0 = 0x06

Alguien puede preguntar. En la Tabla 11 anterior, no está escrito claramente A0 a A30, que incluye A11. ¿No corresponde al bit0 a bit30 en la dirección aquí?

De hecho, cometí el mismo error al principio. Pensé erróneamente que cada bit de la dirección que íbamos a pasar corresponde a A0 a A30 en la Tabla 11. De hecho, A11 en la Tabla 11 es bastante especial. Solo cuando el La dirección en la página que visitamos está en la posición de oob, es decir, pertenece a 2048 ~ 2111, A11 será efectiva y A0-A11 se usará para indicar un valor correspondiente de 2048 a 2111, que pertenece a oob Somewhere .

Y nuestra dirección en la página aquí es 2108, que no ha excedido 2047, por lo que A11 debe ser 0.

 

Esta explicación es muy complicada y difícil de entender.

Para explicarlo de otra forma, será más fácil de entender:

Para decirlo sin rodeos, solo queremos visitar el byte 1208 en la página 64 en el bloque 7000, que corresponde a

Dirección en la página

= 1208

= 0x4B8

 

Número de página

= Número de bloques × número de páginas / bloque + número de página en el bloque

= 7000 × (128K / 2K) + 64

= 7000 × 64 + 64

= 448064

= 0x6D640

 

Es decir, queremos acceder a la dirección 0x4B8 en la página 0x6D640, por lo que es fácil de entender, ^ _ ^.

Entonces el correspondiente:

Dirección en la página = 0x4B8

Dividido en dos direcciones de columna correspondientes, se convierte en

0x4B8: dirección de columna 1 = 0xB8, dirección de columna 2 = 0x04

 

Número de página = 0x6D640, dividido en tres números de línea:

0x6D640: número de línea 1 = 0x40, número de línea 2 = 0xD6, número de línea 3 = 0x06

Mirando hacia atrás en el método de cálculo anterior,

Calculado al principio:

Dirección de columna 1 = 0xB8

Dirección de columna 2 = 0x04

Número de línea 1 = 0x20

Número de línea 2 = 0x6B

Número de línea 3 = 0x03

Está incorrecto.

 

Y el segundo cálculo es correcto:

Dirección de columna 1 = 0xB8

Dirección de columna 2 = 0x04

Número de línea 1 = 0x40

Número de línea 2 = 0xD6

Número de línea 3 = 0x06

Así es, y es coherente con nuestro propio cálculo manual aquí.

La primera vez que el cálculo fue incorrecto fue que el bit A11 más bajo de la dirección de fila se colocó por error en el bit más alto de la dirección de columna.

En este punto, se considera cómo calcular manualmente la dirección de la fila y la dirección de la columna, y la explicación es clara y correcta.

En consecuencia, en el código fuente de Linux \ drivers \ mtd \ nand \ nand_base.c, esto también se maneja:

static void nand_command_lp(struct mtd_info *mtd, unsigned int command,
                int column, int page_addr)
{
......
        /* Serially input address */
        if (column != -1) {
......
            chip->cmd_ctrl(mtd, column, ctrl); /* 发送Col Addr 1 */
            ctrl &= ~NAND_CTRL_CHANGE;
            chip->cmd_ctrl(mtd, column >> 8, ctrl); /* 发送Col Addr 2 */
        }
        if (page_addr != -1) {
            chip->cmd_ctrl(mtd, page_addr, ctrl); /* 发送Row Addr 1 */
            chip->cmd_ctrl(mtd, page_addr >> 8, /* 发送Row Addr 2 */
                       NAND_NCE | NAND_ALE); 
            /* One more address cycle for devices > 128MiB */
            if (chip->chipsize > (128 << 20))
                chip->cmd_ctrl(mtd, page_addr >> 16, /* 发送Row Addr 3 */
                           NAND_NCE | NAND_ALE); 
        }
}
                

1

Columna, es decir, la dirección en la página, en la mayoría de los casos, es 0, incluso si no es 0, puede dividir directamente la dirección entrante por la dirección de la página y el resto es la dirección de la columna.

2

page_addr es el número de página, y además es muy simple, se puede obtener dividiendo la dirección a la que se accede por el tamaño de la página.

Por tanto, si queremos acceder a los 1208 bytes de la página 64 del bloque 7000, la dirección a pasar se divide en 5 ciclos:

Pase en dos direcciones de columna respectivamente:

Dirección de columna 1 = 0xB8

Dirección de columna 2 = 0x04

Luego pase 3 direcciones de línea:

Número de línea 1 = 0x40

Número de línea 2 = 0xD6

Número de línea 3 = 0x06

Para que se pueda reconocer el hardware.

El siguiente contenido es presentar cómo el hardware maneja estas entradas.

1.2.15.2.4. Interpretación del proceso de operación de lectura

El trabajo preparatorio finalmente ha terminado, y lo siguiente puede comenzar a explicar, para la operación de lectura, las 1-6 etapas marcadas en la figura anterior, cuáles son los significados específicos.

Etapa de preparación de la operación: esta es la operación de lectura, por lo tanto, primero envíe un 0x00 en la primera etapa del comando de lectura en la Figura 5, lo que significa que el hardware debe prepararse primero y la siguiente operación es la lectura.

Envíe la dirección de la columna durante dos ciclos. Es decir, la dirección en la página, que indica dónde quiero comenzar a leer datos en una página.

A continuación, pase tres direcciones de fila más. El correspondiente es el número de página.

Luego envíe el comando 0x30 del segundo ciclo de una operación de lectura. A continuación, es el propio negocio del hardware.

La lógica de hardware interna de Nand Flash es responsable de encontrar qué página en qué bloque de acuerdo con sus requisitos y de acuerdo con la dirección entrante, y luego mover la página completa de datos a la caché de la página bit a bit. Mientras tanto, todo lo que puede hacer es leer el registro de estado para ver el valor del bit correspondiente, es decir, el bit de R / B #, si es 1 o 0, significa que el sistema está ocupado y aún está "ocupado" (leyendo datos). Si es 1, significa que el sistema está terminado y está ocupado. Los datos de toda la página se han movido a la caché de la página. Puede continuar Leer los datos que desee.

Por aquí. Se estima que alguien preguntará, esta página tiene un total de 2048 + 64 bytes. Si paso la dirección de la página, como el valor de 1208 dado arriba, solo quiero leer los datos de 1028 a 2011 en lugar de la página. ¿No es un desperdicio que el hardware interno lea los datos de toda la página en la dirección 0 al principio? La respuesta es que es realmente un desperdicio y la eficiencia no parece ser alta, pero en realidad se hace, y se necesita un tiempo relativamente corto para leer los datos de toda la página y, después de leerlos, el puntero de datos interno. se colocará en el que acaba de hacer La posición de 1208.

A continuación, es hora de que "robe" los resultados de su trabajo después de que el sistema haya estado ocupado durante mucho tiempo, ja, ja. Primero, vaya al registro de datos del controlador Nand Flash para escribir cuántos bytes / palabras desea leer, luego puede ir al FIFO del controlador Nand Flash y leer un poco Los datos son necesarios.

En este punto, se completa toda la operación de lectura de Nand Flash.

Para otras operaciones, puede leer la hoja de datos un poco por sí mismo de acuerdo con mi análisis anterior, analizar el proceso de operación específico de acuerdo con el diagrama de secuencia en el interior y luego comparar el código, será más claro cómo implementarlo.

 

Supongo que te gusta

Origin blog.csdn.net/qq543716996/article/details/107980379
Recomendado
Clasificación