В предыдущей статье был рассмотрен вариант использования микроконтроллера STM32F103C8T6 как flash накопителя с внутренней файловой системой FAT12. Теперь можно рассмотреть, каким образом получить данные из нашей внутренней файловой системы. К примеру нам необходимо хранить некие настройки нашей программы.
Для хранения именованных настроек особого усложнения структур формата данных не потребуется. Примем следующий формат — одна настройка = один файл. К примеру, нам необходимо хранить скорость подключения по UART и допустим, задержку в миллисекундах мигания светодиода. Создадим (в любом текстовом редакторе) в нашей файловой системе файлы UART_SPD.SET и DELAY_BL.SET. Запишем в них значения: соответственно 115200 и 1000.
Чтобы получить эти данные, обратившись к нашей внутренней FAT12 потребуется либо взять стандартную библиотеку HAL FatFs и попытаться ее приспособить под внутреннюю flash. Или пойти более простым и удобным способом — написать свою функцию чтения файловых данных FAT12, что мы и сделаем:
Теперь — получаем значение необходимой настройки:
В массиве fdata будет находится строка «115200», которую можно перевести в целое используя функцию atoi():
Проект с исходниками можно взять здесь.
На этом — всё. Спасибо за внимание!
Для хранения именованных настроек особого усложнения структур формата данных не потребуется. Примем следующий формат — одна настройка = один файл. К примеру, нам необходимо хранить скорость подключения по UART и допустим, задержку в миллисекундах мигания светодиода. Создадим (в любом текстовом редакторе) в нашей файловой системе файлы UART_SPD.SET и DELAY_BL.SET. Запишем в них значения: соответственно 115200 и 1000.
Чтобы получить эти данные, обратившись к нашей внутренней FAT12 потребуется либо взять стандартную библиотеку HAL FatFs и попытаться ее приспособить под внутреннюю flash. Или пойти более простым и удобным способом — написать свою функцию чтения файловых данных FAT12, что мы и сделаем:
uint8_t f12_read_data (
char *file_name, // имя файла для поиска в формате 11 символов - "NAME TXT"
char **file_data, // здесь будут данные найденного файла
char *file_list, // здесь будет список файлов
uint16_t file_list_size) { // размер для списка файлов
// FAT12 - http://elm-chan.org/docs/fat_e.html
uint16_t BPB_BytsPerSec;
uint8_t BPB_NumFATs;
uint16_t BPB_RootEntCnt;
uint16_t BPB_RsvdSecCnt;
uint16_t BPB_FATSz16;
uint8_t BPB_SecPerClus;
uint16_t BS_BootSign;
uint8_t found=0;
uint16_t cluster_no;
char *fname;
uint32_t SEEK_FAT12_NAMES_OFFSET;
uint32_t SEEK_FAT12_NAMES_OFFSET_END;
uint32_t SEEK_DATA_OFFSET;
uint32_t fs;
// Получим данные FAT12
BPB_BytsPerSec=uint16_t_from_internal_flash(PAGE_ADDR+11);
BPB_NumFATs=uint8_t_from_internal_flash(PAGE_ADDR+16);
BPB_RootEntCnt=uint16_t_from_internal_flash(PAGE_ADDR+17);
BPB_RsvdSecCnt=uint16_t_from_internal_flash(PAGE_ADDR+14);
BPB_FATSz16=uint16_t_from_internal_flash(PAGE_ADDR+22);
BPB_SecPerClus=uint8_t_from_internal_flash(PAGE_ADDR+13);
BS_BootSign=uint16_t_from_internal_flash(PAGE_ADDR+510);
if (BS_BootSign != 0xAA55) { // неверная сигнатура boot сектора FAT
return FAT12_ERR_BAD_FAT;
}
SEEK_FAT12_NAMES_OFFSET = (BPB_RsvdSecCnt+(BPB_FATSz16 * BPB_NumFATs)) * BPB_BytsPerSec; // отступ на начало имен
SEEK_FAT12_NAMES_OFFSET_END=SEEK_FAT12_NAMES_OFFSET +
(((32 * BPB_RootEntCnt + BPB_BytsPerSec - 1) / BPB_BytsPerSec) * BPB_BytsPerSec); // отступ на конец имен
SEEK_DATA_OFFSET= BPB_BytsPerSec * BPB_RsvdSecCnt+ // Boot сектор + резерв
((BPB_FATSz16 * BPB_NumFATs) * BPB_BytsPerSec) + // Размер FAT
BPB_RootEntCnt*32; // Размер имен и хар-к файлов
if (file_list_size > 0) // обнулить строку списка файлов
file_list[0]=0;
while (SEEK_FAT12_NAMES_OFFSET < SEEK_FAT12_NAMES_OFFSET_END) {
fname = char_from_internal_flash(PAGE_ADDR+SEEK_FAT12_NAMES_OFFSET);
cluster_no = uint16_t_from_internal_flash(PAGE_ADDR + SEEK_FAT12_NAMES_OFFSET + 0x1A);
fs = uint32_t_from_internal_flash(PAGE_ADDR + SEEK_FAT12_NAMES_OFFSET + 0x1C);
if ((file_list_size > 0) &&
(strlen(file_list)+20 < file_list_size) &&
(cluster_no > 0)) {
sprintf(file_list,"%s%11s %06d bytes\r\n",
file_list,fname, fs); // дополним полный список файлов
}
for (int i=0;i<9;i++) { // упрощенный поиск по имени файла
if (fname[i] != file_name[i]) {
found=0;
break;
}
found=1;
}
if (found==1)
break;
SEEK_FAT12_NAMES_OFFSET+=0x20;
}
if (found == 0) {
return FAT12_ERR_FILE_NOT_FOUND;
}
if ( *file_data != 0 ) {
*file_data=char_from_internal_flash(PAGE_ADDR+(cluster_no-2) *
(BPB_SecPerClus * BPB_BytsPerSec) + // Размер кластера
SEEK_DATA_OFFSET);
}
return 0;
}
Теперь — получаем значение необходимой настройки:
f12_read_data("UART_SPDSET" /*имена без точек, дополнение по 11 символов - пробелами*/,&fdata, file_list, 200);
В массиве fdata будет находится строка «115200», которую можно перевести в целое используя функцию atoi():
Проект с исходниками можно взять здесь.
На этом — всё. Спасибо за внимание!