Al desarrollar dispositivos, a menudo es necesario almacenar configuraciones fuera del programa de trabajo. Es aún mejor poder modificarlos sin usar herramientas especiales.
Considere la opción de almacenamiento en quizás los microcontroladores STM F103 más comunes. La conocida placa de pruebas Blue Pill también contribuyó a la prevalencia.

El flash disponible en él permite no solo almacenar y modificar las configuraciones usando el sistema de archivos FAT12 en el flash interno, sino también organizar una actualización de firmware.
Según la documentación, el STM32F103C8T6 tiene 64K de memoria flash. Sin embargo, en casi todos los STM32F103C8T6, 128K está instalado. Esto también se menciona en varias fuentes: generalmente ponen 64K más. Esta "característica" le permite utilizar el microcontrolador como una unidad flash con una capacidad de 128K - 20K (el sistema necesita FAT12), el tamaño del firmware.
Muchos entusiastas que intentaron usar este controlador como unidad flash encontraron el problema de su uso en el modo de sistema de archivos FAT12. Use para eliminar / llenar la imagen del disco que resultó. Pero cuando se trabaja como con una unidad de archivo, comienzan los problemas.
Este problema consiste en una secuencia diferente de acceso a sectores (bloques). Cuando se carga una imagen de disco, la grabación ocurre secuencialmente, por ejemplo:
-grabación del bloque número 1,
-grabación del bloque número 2,
-grabar bloque número 3.
Al escribir datos FAT12, la grabación puede ocurrir arbitrariamente:
-grabar bloque número 3,
-grabación del bloque número 1,
-grabar bloque número 2.
Y, dado que escribir en flash requiere borrar toda la página de 1K, cuando se usan sectores de 512 bytes en la unidad (y no se pueden usar otros sectores), si se usa acceso aleatorio, se borra la información del sector vecino. Para evitar que esto suceda, el ejemplo anterior utiliza una matriz de 512 bytes para almacenar el sector vecino. Y la grabación debería ser la siguiente:
- determinar la dirección del comienzo de la página,
- recuerda el sector vecino,
- borrar la página,
- escribir un sector memorizado,
- Escribir datos.
Para no profundizar en la jungla de hierro sin la necesidad requerida, preparé el proyecto en CubeMX.
Daré un ejemplo de una función para escribir en flash a través de 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(); }
El tamaño del archivo binario obtuve aproximadamente 20K, por lo que mi página de memoria de datos se define con 0x08006000 (24K).
Compilamos (el código fuente del ejemplo se puede tomar aquí).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
El disco está determinado, ¡todo está bien!
Comencemos formando la partición y formateando nuestro disco.
En Linux, esto es bastante simple desde la línea de comandos:
sudo fdisk /dev/sdb

formato en FAT12:
sudo mkfs.fat /dev/sdb -F 12
Copie el archivo para la prueba:

Sin embargo, no se debe olvidar que, según la documentación, el número de ciclos de reescritura flash
garantizado solo dentro de 100,000. Por ejemplo, formatear y escribir un solo archivo de 30K tomará (de acuerdo con el registro de depuración de este ejemplo):
00106 44 67 Write_FS blk_addr=003 0x08006600
106 ciclos de reescritura.
La pregunta sigue siendo: ¿cómo puedo leer los datos accediendo directamente a los archivos FAT12?
Sobre esto en el
próximo artículo.Gracias por su atencion!