STM32F103C8T6 como unidade flash com sistema de arquivos FAT12

Ao desenvolver dispositivos, geralmente é necessário armazenar configurações fora do programa de trabalho. É ainda melhor poder modificá-los sem usar ferramentas especiais.

Considere a opção de armazenamento talvez nos microcontroladores STM F103 mais comuns. A conhecida placa de ensaio Blue Pill também contribuiu para a prevalência.

imagem
O flash disponível nele permite não apenas armazenar e modificar as configurações usando o sistema de arquivos FAT12 no flash interno, mas também organizar uma atualização de firmware.

De acordo com a documentação, o STM32F103C8T6 possui 64K de memória flash. No entanto, em quase todos os STM32F103C8T6, 128K estão instalados. Isso também é mencionado em várias fontes - eles costumam colocar 64K a mais. Esse "recurso" permite que você use o microcontrolador como uma unidade flash com capacidade de 128K - 20K (o sistema precisa de FAT12) - o tamanho do firmware.

Muitos entusiastas que tentaram usar este controlador como uma unidade flash encontraram o problema de seu uso no modo de sistema de arquivos FAT12. Use para remover / preencher a imagem do disco exibida. Mas, ao trabalhar como uma unidade de arquivo, os problemas começaram.

Esse problema consiste em uma sequência diferente de acesso aos setores (blocos). Quando uma imagem de disco é carregada, a gravação ocorre sequencialmente, por exemplo:

- bloco de gravação número 1,
- bloco de gravação número 2,
- registre o número do bloco 3.

Ao gravar dados FAT12, a gravação pode ocorrer arbitrariamente:

- registre o bloco número 3,
- bloco de gravação número 1,
- registre o número do bloco 2.

E, como gravar em flash requer apagar a página 1K inteira, ao usar setores de 512 bytes na unidade (e você não pode usar outros setores), se o acesso aleatório for usado, as informações no setor vizinho serão apagadas. Para impedir que isso aconteça, o exemplo acima usa uma matriz de 512 bytes para armazenar o setor vizinho. E a gravação deve ser a seguinte:

- determine o endereço do início da página,
- lembre-se do setor vizinho,
- apague a página,
- escreva um setor memorizado,
- escreve dados.

Para não me aprofundar na selva de ferro sem a necessidade necessária, preparei o projeto no CubeMX.

Vou dar um exemplo de uma função para gravar em flash via HAL (usbd_storage_if.c)

//    flash void writeBuf (uint32_t page_addr, uint8_t *buf){ uint32_t erase_addr=get_erase_addr(page_addr); uint32_t buf_erase_addr; uint32_t buf32; if (page_addr != erase_addr) { buf_erase_addr=erase_addr; } else { buf_erase_addr=erase_addr+STORAGE_BLK_SIZ; } HAL_FLASH_Unlock(); //      set_buf_before_erase(buf_erase_addr); //       FLASH_EraseInitTypeDef EraseInitStruct; uint32_t PAGEError = 0; EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES; EraseInitStruct.PageAddress = erase_addr; EraseInitStruct.NbPages = 1; HAL_FLASHEx_Erase(&EraseInitStruct,&PAGEError); //    for (int i=0; i<STORAGE_BLK_SIZ/4;i++) { HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD,buf_erase_addr,blk_buff[i]); buf_erase_addr+=4; } //   for (int i=0; i<STORAGE_BLK_SIZ/4;i++) { buf32=*(uint32_t *)&buf[i*4]; HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, page_addr,buf32); page_addr+=4; } HAL_FLASH_Lock(); } 

O tamanho do arquivo binário que obtive em torno de 20K, portanto, minha página de memória de dados é definida com 0x08006000 (24K).

Nós compilamos (o código fonte do exemplo pode ser obtido aqui).

Nós conectamos:

 [ 8193.499792] sd 4:0:0:0: Attached scsi generic sg2 type 0 [ 8193.502050] sd 4:0:0:0: [sdb] 128 512-byte logical blocks: (65.5 kB/64.0 KiB) [ 8193.502719] sd 4:0:0:0: [sdb] Write Protect is off [ 8193.502722] sd 4:0:0:0: [sdb] Mode Sense: 00 00 00 00 [ 8193.503439] sd 4:0:0:0: [sdb] Asking for cache data failed [ 8193.503445] sd 4:0:0:0: [sdb] Assuming drive cache: write through [ 8193.523812] sdb: [ 8193.526914] sd 4:0:0:0: [sdb] Attached SCSI removable disk 

O disco está determinado, está tudo bem!

Vamos começar a formar a partição e formatar o nosso disco.

No Linux, isso é bastante simples na linha de comando:

 sudo fdisk /dev/sdb 



formato no FAT12:

 sudo mkfs.fat /dev/sdb -F 12 

Copie o arquivo para o teste:



No entanto, não se deve esquecer que, de acordo com a documentação, o número de ciclos de reescrita do flash
garantido apenas dentro de 100.000. Por exemplo, a formatação e gravação de um único arquivo 30K serão necessárias (de acordo com o log de depuração deste exemplo):

 00106 44 67 Write_FS blk_addr=003 0x08006600 

106 reescrever ciclos.

A questão permanece - como posso ler dados acessando arquivos FAT12 diretamente?
Sobre isso no próximo artigo.
Obrigado pela atenção!

Source: https://habr.com/ru/post/pt441660/


All Articles