NandFlash

Introdução à NandFlash

A NandFlash é uma tecnologia de memória flash que permite alta densidade de armazenamento, atinginod capacidades como 256 MB, com velocidades rápidas de escrita e apagagem. Sua aplicação exige interfaces de sistema especializadas para gerenciamento eficiente.

Comparação entre NandFlash e NorFlash

Característica NorFlash NandFlash
Capacidade 1 MB a 32 MB 16 MB a 511 MB
XIP (Execução no local) Sim Não
Velocidade de apagagem Lenta (cerca de 5 segudnos) Rápida (cerca de 3 ms)
Velocidade de escrita Lenta Rápida
Velocidade de leitura Rápida Rápida
Confiabilidade Alta, com baixa taxa de inversão de bits Moderada, requer mecanismos de correção de erros
Ciclos de apagagem 10.000 a 100.000 100.000 a 1.000.000
Vida útil Inferior à NandFlash Superior ao NorFlash
Interface Semelhante à RAM Interface de E/S
Método de acesso Aleatório Sequencial
Facilidade de uso Simples Complexa
Aplicação principal Armazenamento de código e dados críticos Armazenamento de dados gerais
Custo Elevado Reduzido

Pinagem Comum da NandFlash

  • I/O0 a I/O7: Linhas de entrada/saída de dados.
  • CE# (Chip Enable): Sinal de habilitação do chip; mantém o dispositivo em modo standby quando inativo.
  • WE# (Write Enable): Controla a gravação de dados, endereços ou comandos.
  • RE# (Read Enable): Ativa o buffer de saída de dados.
  • CLE (Command Latch Enable): Quando alto, comandos são capturados na borda de subida de WE#.
  • ALE (Address Latch Enable): Quando alto, endereços são capturados na borda de subida de WE#.
  • R/B# (Ready/Busy): Indica status do dispositivo; baixo quando ocupado, requer resistor de pull-up.

Estrutura Física da NandFlash

Usando o chip K9F2G08U0B como referência:

  • 1 Página = (2K + 64) bytes
  • 1 Bloco = 64 Páginas = (128K + 4K) bytes
  • 1 Dispositivo = 2048 Blocos = 128K Páginas = (256M + 8M) bytes

A memória inclui áreas adicionais para coreção de erros (ECC), conhecidas como OOB (Out Of Band) em sistemas Linux, essenciais para garantir a integridade dos dados.

Sequência de Endereçamento

Os endereços são divididos em: A0-A11 para endereçamento dentro da página (incluindo dados e ECC), e A12-A28 para endereçamento de páginas e blocos.

Características Especiais em Relação à RAM

Aspecto RAM NandFlash
Terminologia de operações Leitura/Escrita Leitura/Programação
Unidade mínima de leitura/escrita Byte Página
Unidade mínima de apagagem Byte Bloco
Significado do apagagem Apaga dados ou escreve zeros Apaga todo o bloco para 0xFF
Pré-requisito para escrita Escrita direta Apagar antes de escrever

Exemplos de Código para Operações

Função para Apagar um Bloco

/* Apaga um bloco especificado
   Parâmetros:
        bloco: número do bloco a ser apagado
   Retorno:
        0 para falha, 1 para sucesso */
unsigned char apagarBloco(unsigned int bloco) {
    unsigned int endereco_bloco = bloco << 6;
    selecionarChip();
    enviarComando(0x60);
    enviarEndereco(endereco_bloco & 0xFF);
    enviarEndereco((endereco_bloco >> 8) & 0xFF);
    enviarEndereco((endereco_bloco >> 16) & 0x01);
    enviarComando(0xD0);
    aguardarPronto();
    enviarComando(0x70);
    aguardarPronto();
    unsigned char status = lerDado();
    deselecionarChip();
    return (status & 0x1) ? 0 : 1;
}

Função para Ler uma Página

/* Lê dados de uma página
   Parâmetros:
        buffer: ponteiro para armazenar dados lidos
        endereco_origem: endereço de leitura no flash
   Retorno:
        0 para falha, 1 para sucesso */
static unsigned char lerPagina(unsigned char *buffer, unsigned int endereco_origem) {
    if (endereco_origem & MASCARA_BLOCO) return 0;
    selecionarChip();
    enviarComando(0x00);
    enviarEnderecoCompleto(endereco_origem);
    enviarComando(0x30);
    aguardarPronto();
    for (int i = 0; i < TAMANHO_SETOR; i++) {
        *buffer++ = lerDado();
    }
    deselecionarChip();
    return 1;
}

Função para Escrever uma Página

/* Escreve dados em uma página
   Parâmetros:
        buffer: ponteiro com dados a serem escritos
        endereco_destino: endereço de escrita no flash
   Retorno:
        0 para falha, 1 para sucesso */
static unsigned char escreverPagina(unsigned char *buffer, unsigned int endereco_destino) {
    if (endereco_destino & MASCARA_BLOCO) return 0;
    selecionarChip();
    enviarComando(0x80);
    enviarEnderecoCompleto(endereco_destino);
    for (int i = 0; i < TAMANHO_PAGINA; i++) {
        enviarDado(*buffer++);
    }
    enviarComando(0x10);
    aguardarPronto();
    enviarComando(0x70);
    aguardarPronto();
    unsigned char status = lerDado();
    deselecionarChip();
    return (status & 0x1) ? 0 : 1;
}

Função de Depuração para Imprimir Conteúdo

/* Imprime o conteúdo de uma página específica (para depuração) */
void imprimirPagina() {
    unsigned char bloco, pagina;
    unsigned char *destino = (unsigned char *)ENDERECO_MEMORIA;
    printf("\nLeitura de página NandFlash.\n");
    printf("Informe o bloco: ");
    bloco = getchar() - '0';
    printf("Informe a página: ");
    pagina = getchar() - '0';
    unsigned int endereco = ((bloco << 6) + pagina) << 11;
    if (lerPagina(destino, endereco)) {
        printf("Dados lidos (bloco %d, página %d):\n", bloco, pagina);
        for (int i = 0; i < TAMANHO_PAGINA; i++) {
            if (i % 16 == 0) printf("\n%4x: ", i);
            printf("%02x ", *destino++);
        }
    } else {
        printf("Erro na leitura.\n");
    }
}

Função para Enviar Endereço

/* Envia endereço completo ao dispositivo */
static void enviarEnderecoCompleto(unsigned int endereco) {
    unsigned int coluna = endereco & MASCARA_BLOCO;
    unsigned int pagina = endereco / TAMANHO_SETOR;
    enviarEndereco(coluna & 0xFF);
    pequenaEspera();
    enviarEndereco((coluna >> 8) & 0x0F);
    pequenaEspera();
    enviarEndereco(pagina & 0xFF);
    pequenaEspera();
    enviarEndereco((pagina >> 8) & 0xFF);
    pequenaEspera();
    enviarEndereco((pagina >> 16) & 0x01);
    pequenaEspera();
}

Nota: As chamadas de espera (por exemplo, pequenaEspera()) são críticas para sincronização, especialmente em frequências de clock elevadas como 400 MHz, para evitar erros de endereçamento.

Tags: NAND flash memória flash ECC Sistemas Embarcados interfaces de memória

Publicado em 6-28 01:15