Хабрахабр

[Из песочницы] STM32F103C8T6 как накопитель flash с файловой системой FAT12

STM32F103C8T6 как накопитель flash с файловой системой FAT12

При разработках устройств часто бывает необходимым хранить настройки вне рабочей программы. Еще лучше иметь возможность их модификации без использования специальных средств.

Способствовала распространенности также всем известная макетная плата Blue Pill Рассмотрим вариант хранения в пожалуй самых распространенных микроконтроллерах STM серии F103.

image
Имеющаяся в ней flash позволяет не только хранить и модифицировать настройки используя файловую систему FAT12 во внутреннем flash, но и организовать обновление прошивки.

Однако практически во всех STM32F103C8T6 установлено 128К. Согласно документации в STM32F103C8T6 имеется 64К flash памяти. Такая «фича» позволяет использовать микроконтроллер как flash накопитель объемом 128К — 20К (системные нужды FAT12) — размер прошивки. Об этом также упоминается в разных источниках — обычно ставят на 64К больше.

Использовать для снятия/заливки образа диска получалось. Многие энтузиасты, пытавшиеся использовать данный контроллер как накопитель flash, сталкивались с проблемой его использования в режиме файловой системы FAT12. При загрузке образа диска запись происходит последовательно, например: А вот при работе как с файловым накопителем начинались проблемы.
Эта проблема заключается в разной последовательности доступа к секторам (блокам).

-запись блока №1,
-запись блока №2,
-запись блока №3.

При записи данных FAT12 запись может происходить произвольно:

-запись блока №3,
-запись блока №1,
-запись блока №2.

Чтобы этого не происходило, в приведенном примере используется массив 512 байт для хранения соседнего сектора. И, так как для записи во flash требуется стирать всю страницу размером 1К, то при использовании в накопителе секторов размером 512 байт (а использовать другие размеры сектора не удается), если используется произвольный доступ — стирается информация в соседнем секторе. И запись должна происходить следующим образом:

— определяем адрес начала страницы,
— запоминаем соседний сектор,
— стираем страницу,
— пишем запомненный сектор,
— пишем данные.

Чтобы не углубляться в дебри железа без требуемой необходимости, проект я подготовил в CubeMX.

Приведу пример функции записи во flash через HAL (usbd_storage_if.c)

// функция записи во flash
void writeBuf (uint32_t page_addr, uint8_t *buf) 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();
}

Размер бинарного файла у меня получился около 20К, поэтому страница памяти данных у меня определена с 0x08006000 (24K).

Компилируем (исходники примера можно взять здесь).

Подключаем:

[ 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

Диск определился, все отлично!

Приступим к формированию раздела и форматированию нашего диска.

В Linux это делать достаточно просто из командной строки:

sudo fdisk /dev/sdb

отформатируем в FAT12:

sudo mkfs.fat /dev/sdb -F 12

Копируем файл для теста:

К примеру, форматирование и запись одного файла 30К займет (по отладочному журналу данного примера): Однако, не следует забывать, что по документации, число циклов перезаписи flash
гарантировано лишь в пределах 100000.

00106 44 67 Write_FS blk_addr=003 0x08006600

106 циклов перезаписи.

Спасибо за внимание! На этом — все.

Показать больше

Похожие публикации

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»