В декабре 2017 года компания ARM представила обществу новую версию операционной системы для ARM микроконтроллеров «arm mbed os v.5.7» (17 января 2018 вышла версия 5.7.3), которая получила в своем составе интегрированную авторскую файловую систему, незатейливо названную «LittleFileSystem», или просто «LittleFS». Предлагаю сегодня поговорить об этой новинке.
Основными достоинствами файловой системы «LittleFS» являются:
Система поддерживает полный набор POSIX функций для работы с файлами и директориями.
Напомню, что файловая система интегрирована в состав активно развиваемой и поддерживаемой производителем операционной системы arm mbed os, так что немного сказать об этой ОС для ARM микроконтроллеров придется и мне, несмотря на определенное количество материалов о ней, опубликованных на ресурсе. Поэтому здесь я немного отвлекусь на mbed os, и тот, кто имеет уже опыт работы с ней, могут пролистать следующие несколько абзацев.
Операционная система написана на C/C++, и основным достоинством ОС, и её же основным недостатком, по моему мнению (как бы парадоксально это ни звучало), является действительно высокий уровень абстракции от аппаратной части.
Те, кто при работе с микроконтроллерами STM32 (именно в привязке к ним я веду беседу) пользовался библиотеками HAL и SPL (а тем более те, кто копошился в регистрах вручную), помнят, сколько строк кода необходимо было создать для настройки, к примеру, прерывания по падающему фронту на выводе PA_5: разрешение тактирование порта, настройка режима работы конкретного вывода, настройка собственно прерывания, разрешение прерывания – и только потом описание обработчика.
В mbed os все делается намного проще.
Сначала я дал имя прерыванию и указал вывод, по изменению состояния которого я хочу вызвать прерывание. Во второй строке я указал признак, по которому мне нужно переходить в обработчик (fall, падающий фронт сигнала), и указал название самого обработчика прерывания (led_blink).
Высокий уровень абстракции удобен, но при этом начинающий новичок совершенно не понимает, что в данный момент происходит в микроконтроллере, и что на самом деле одна строка кода вызывает запись десятков значений в десятки регистров. И это, конечно, не очень хорошо.
Самый простой способ начать работу с mbed os – это отправиться на портал mbed.com, и зарегистрироваться там в качестве разработчика (элементарная регистрация с подтверждением по e-mail). С этого момента вам доступен онлайн компилятор, который сыграет немаловажную роль для старта. Вкратце, что мы собираемся сделать: в качестве старта и чтобы нам было полегче, мы возьмем любой пример, включающий в свой состав mbed os из репозитория на портале os.mbed.com, и потом его импортируем в виде проекта для нашей IDE и в идеале, для нашего микроконтроллера. ОС, кстати, является также инструментом маркетинга, и для ее использования ARM рекомендует так называемые «mbed-enabled» отладочные платы, и на первый взгляд может показаться, что для mbed os подходят только платы из каталога на сайте. Но это, конечно же, не так.
В верхнем правом углу нам доступна кнопка выбора отладочной платы, с которой мы собираемся работать (конечно же, предполагается, что мы приобрели одну из плат, находящихся в каталоге).
После нажатия на кнопку, появится окошко выбора конкретной платы. Там же, в окошке, будет кнопка с большим зеленым плюсом «Add Platform».
В отдельном окне браузера откроется окно выбора платформ, среди множества которых выберем «STMicroelectronics», и подберем плату, на которой установлен такой же микроконтроллер, как тот, с которым мы собираемся работать. Мне повезло – на моей самодельной отладочной плате стоит микроконтроллер «STM32F103RBT6», как и на плате «Nucleo-F103RB».
В ближайшем будущем я планирую написать небольшой материал о том, как реализовать проект с arm mbed os под любой произвольный МК.
На странице с описанием платы, которую мы выбрали в селекторе, справа, жмем кнопку «Add to your Mbed Compiler».
Тут же, чуть ниже, расположены примеры. Мы выберем самый маленький и простой – «Nucleo_blink_led».
В открывшемся окне, справа вверху, жмем кнопку «Import Into Compiler».
Откроется Ваш онлайн компилятор и попросит подтверждения импорта проекта. После подтверждения мы увидим наш проект в дереве проектов слева.
Осталось дело за малым – импортировать проект под нашу десктопную IDE. Онлайн компилятор поддерживает массу IDE, среди которых «IAR for ARM», «KEIL uVision», «CooCox CoIDE», и много прочих сред. Я пользуюсь средой «IAR for ARM v.8.20.1», ARM же для работы с mbed os рекомендует IAR версии не ниже 7.5.
Справа, в блоке «Program Details», жмем на кнопку «Export».
В появившемся всплывающем окне «Export program» выбираем платформу и среду разработки, которая установлена на нашем компьютере.
После нажатия на кнопку «Export» онлайн компилятор немного подумает, и в браузере начнется закачка архива с проектом. Распаковываем в любом удобном для нас месте, открываем среду разработки, открываем проект, вычищаем все ненужное нам в главном файле «main.cpp», начинаем работать.
Кстати, все в том же блоке «Program details», прежде чем экспортировать проект, можно оценить степень нагрузки проекта на на встроенную flash и оперативную память нашего тарджет-контроллера. Откроем вкладку «Build».
На этом, пожалуй, я закончу и без того затянувшийся экскурс в быстрый старт с mbed os, и вернусь к разговору о LittleFS.
Для корректной работы с файловой системой мы должны включить в проект заголовочные файлы «LittleFileSystem.h» и, обязательно, заголовочный файл носителя. Я предполагаю работу с SD-картой, поэтому включаю в проект файл «SDBlockDevice.h». Среди прочих устройств доступны MBRBlockDevice, HeapBlockDevice (очень удобен для тренировки, так как не требует присутствия физического носителя), и другие типы устройств.
Итак, я предлагаю рассмотреть нашу последовательность действий при построении стартового проекта для работы с «LittleFS». Сначала мы должны создать объекты устройства (и инициализировать его выводы) и файловой системы. Затем мы смонтируем файловую систему, создадим пару файлов на носителе, откроем корневую директорию и считаем из нее список файлов, содержащихся в ней.
Обратим внимание на древо наследования классов для работы с потоками, реализованных в mbed os.
Как видим, для работы с файлами у нас реализован целый класс «File». Для работы с директориями существует класс «Dir». Их описание можно почитать на страницах File и Dir.
Однако на практике проявился один интересный нюанс.
При попытке объявить объект класса «File» и использовать метод File (FileSystem *fs, const char *path, int flags=O_RDONLY), призванный создавать файлы, компилятор отказался признать объект.
А при использовании стандартных методов работы с потоками («stdio.h») для создания файла, и при попытке дальнейшей работы с ним с помощью методов класса «File», таких, к примеру, как read или write, операционная система весело сваливалась в mbed_die(), обработчик неисправимой системной ошибки.
Поэтому пока что я ограничусь написанием письма в саппорт ARM, и работать с файлами будем с помощью средств stdio, что, возможно, для кого-то окажется делом более привычным. Полное описание функционала «stdio» можно найти, к примеру, на этом сайте.
Итак, код:
Сначала мы создаем объекты классов SDBlockDevice (и тут же его инициализируем, передавая названия выводов в строгой последовательности в соответствии с назначением: mosi, miso, sclk, cs) и LittleFileSystem (fs).
Затем, уже в функции «main», пробуем смонтировать файловую систему (что у нас, конечно же, не получится при использовании новой SD карты). Форматируем носитель, и монтируем файловую систему снова.
Далее, пробуем поочередно открыть файлы «LittleFS.txt» и «Habrahabr.txt», и, не находя их, создаем. После открытия файл обязательно должен быть закрыт.
После благополучных операций с файлами, мы вычитываем содержимое корневой директории и выводим названия файлов в терминал ввода/вывода. Закрываем директорию.
Демонтируем файловую систему и докладываем в терминал о благополучной проверке работы файловой системы.
А вот скриншот сообщений в терминале отладчика.
Итак, сегодня мы поговорили о перспективной и, на мой взгляд, весьма современной файловой системе для микроконтроллеров под названием «LittleFileSystem».
Когда разрешится вопрос с использованием «родных» средств работы с файлами и директориями (с помощью классов File и Dir), обещаю апдейт к статье.
Благодарю за внимание.
Не успел материал пройти премодерацию, как меня осенило — я неверно пытался использовать методы класса File. Для создания (или открытия существующего) файла необходимо использовать метод open(FileSystem *fs, const char *path, int flags=O_RDONLY);.
В итоге, код дополнится новыми объектами классов File и Dir для работы с файлами и директориями, к примеру,
Так что весь пример работы с помощью интегрированных в ОС mbed os средств работы с файлами и директориями несколько преобразится. Также, кроме того, что мы создаем и/или открываем файлы, давайте уже туда что-нибудь запишем и считаем. Для этих целей создадим два буфера: из одного будет записываться в файл строка, а во второй мы считаем содержимое файла.
Итак, код для операций с содержимым SD-карты (между тем, как мы смонтируем и демонтируем файловую систему).
В самом начале мы пытаемся открыть файл testing.txt для чтения/записи. Обратите внимание, что кроме основных параметров (файловая система и название файла), мы передаем методу флаги O_RDWR и O_TRUNC, объединенные с помощью битовой операции «или»: так предполагают правила работы с ОС. Первый означает, что мы создаем или открываем файл для записи/чтения, второй — что файл будет полностью перезаписан, даже если он существует, и наполнен какой-либо информацией. Полный список флагов приведен с заголовочном файле "mbed_retarget.h":
В случае успешного открытия (создания) файла мы пишем в него то, что содержится в буфере block, а точнее, первые 10 байт. Результатом выполнения операции будет количество записанных байт при успешной записи, и это значение мы выводим в терминал при отладке.
Чтобы успешно считать данные из файла, нам нужно вернуться в начало файла, и мы это делаем с помощью fhandle.rewind(). Считанные байты мы тоже считаем, и их число выводим в терминал, как и объем файла (fhandle.size()).
В процессе отладки заглядываем в буфер rblock, в который мы считывали строку из файла. Все в порядке:
С файлом мы побаловались, теперь посмотрим, что же находится в корневом каталоге файловой системы. Открываем директорию и получаем номер записи в каталоге: dhandle.readdir(). Теперь мы считываем название всех файлов, пока dhandle.read(e) не вернёт «0» — записей в директории больше нет. Выводим названия файлов, закрываем каталог.
Любуемся строками в отладочном терминале.
Еще раз всем спасибо.
Основными достоинствами файловой системы «LittleFS» являются:
- Низкая требовательность к ресурсам микроконтроллера. Код не использует рекурсивных вызовов и работает без динамического выделения памяти. В «LittleFS» объем потребляемой ОЗУ всегда остается постоянным, несмотря на то, какие объемы записываются на накопитель, и на объем самого накопителя;
- Наличие программных средств для выравнивания износа носителя (так называемый wear leveling), позволяющих свести к минимуму повторное использование блоков носителя;
- Устойчивость к сбоям по питанию. Данная особенность является штатно рассматривающей прекращение подачи питания носителя, и использует механизм «copy-on-write (COW)», при котором данные не перезаписываются, а сохраняются на новое место.
Система поддерживает полный набор POSIX функций для работы с файлами и директориями.
Напомню, что файловая система интегрирована в состав активно развиваемой и поддерживаемой производителем операционной системы arm mbed os, так что немного сказать об этой ОС для ARM микроконтроллеров придется и мне, несмотря на определенное количество материалов о ней, опубликованных на ресурсе. Поэтому здесь я немного отвлекусь на mbed os, и тот, кто имеет уже опыт работы с ней, могут пролистать следующие несколько абзацев.
Операционная система написана на C/C++, и основным достоинством ОС, и её же основным недостатком, по моему мнению (как бы парадоксально это ни звучало), является действительно высокий уровень абстракции от аппаратной части.
Те, кто при работе с микроконтроллерами STM32 (именно в привязке к ним я веду беседу) пользовался библиотеками HAL и SPL (а тем более те, кто копошился в регистрах вручную), помнят, сколько строк кода необходимо было создать для настройки, к примеру, прерывания по падающему фронту на выводе PA_5: разрешение тактирование порта, настройка режима работы конкретного вывода, настройка собственно прерывания, разрешение прерывания – и только потом описание обработчика.
В mbed os все делается намного проще.
InterruptIn irq_button1(PA_5);
irq_button1.fall(led_blink);
Сначала я дал имя прерыванию и указал вывод, по изменению состояния которого я хочу вызвать прерывание. Во второй строке я указал признак, по которому мне нужно переходить в обработчик (fall, падающий фронт сигнала), и указал название самого обработчика прерывания (led_blink).
Высокий уровень абстракции удобен, но при этом начинающий новичок совершенно не понимает, что в данный момент происходит в микроконтроллере, и что на самом деле одна строка кода вызывает запись десятков значений в десятки регистров. И это, конечно, не очень хорошо.
Самый простой способ начать работу с mbed os – это отправиться на портал mbed.com, и зарегистрироваться там в качестве разработчика (элементарная регистрация с подтверждением по e-mail). С этого момента вам доступен онлайн компилятор, который сыграет немаловажную роль для старта. Вкратце, что мы собираемся сделать: в качестве старта и чтобы нам было полегче, мы возьмем любой пример, включающий в свой состав mbed os из репозитория на портале os.mbed.com, и потом его импортируем в виде проекта для нашей IDE и в идеале, для нашего микроконтроллера. ОС, кстати, является также инструментом маркетинга, и для ее использования ARM рекомендует так называемые «mbed-enabled» отладочные платы, и на первый взгляд может показаться, что для mbed os подходят только платы из каталога на сайте. Но это, конечно же, не так.
В верхнем правом углу нам доступна кнопка выбора отладочной платы, с которой мы собираемся работать (конечно же, предполагается, что мы приобрели одну из плат, находящихся в каталоге).
После нажатия на кнопку, появится окошко выбора конкретной платы. Там же, в окошке, будет кнопка с большим зеленым плюсом «Add Platform».
В отдельном окне браузера откроется окно выбора платформ, среди множества которых выберем «STMicroelectronics», и подберем плату, на которой установлен такой же микроконтроллер, как тот, с которым мы собираемся работать. Мне повезло – на моей самодельной отладочной плате стоит микроконтроллер «STM32F103RBT6», как и на плате «Nucleo-F103RB».
В ближайшем будущем я планирую написать небольшой материал о том, как реализовать проект с arm mbed os под любой произвольный МК.
На странице с описанием платы, которую мы выбрали в селекторе, справа, жмем кнопку «Add to your Mbed Compiler».
Тут же, чуть ниже, расположены примеры. Мы выберем самый маленький и простой – «Nucleo_blink_led».
В открывшемся окне, справа вверху, жмем кнопку «Import Into Compiler».
Откроется Ваш онлайн компилятор и попросит подтверждения импорта проекта. После подтверждения мы увидим наш проект в дереве проектов слева.
Осталось дело за малым – импортировать проект под нашу десктопную IDE. Онлайн компилятор поддерживает массу IDE, среди которых «IAR for ARM», «KEIL uVision», «CooCox CoIDE», и много прочих сред. Я пользуюсь средой «IAR for ARM v.8.20.1», ARM же для работы с mbed os рекомендует IAR версии не ниже 7.5.
Справа, в блоке «Program Details», жмем на кнопку «Export».
В появившемся всплывающем окне «Export program» выбираем платформу и среду разработки, которая установлена на нашем компьютере.
После нажатия на кнопку «Export» онлайн компилятор немного подумает, и в браузере начнется закачка архива с проектом. Распаковываем в любом удобном для нас месте, открываем среду разработки, открываем проект, вычищаем все ненужное нам в главном файле «main.cpp», начинаем работать.
Кстати, все в том же блоке «Program details», прежде чем экспортировать проект, можно оценить степень нагрузки проекта на на встроенную flash и оперативную память нашего тарджет-контроллера. Откроем вкладку «Build».
На этом, пожалуй, я закончу и без того затянувшийся экскурс в быстрый старт с mbed os, и вернусь к разговору о LittleFS.
Для корректной работы с файловой системой мы должны включить в проект заголовочные файлы «LittleFileSystem.h» и, обязательно, заголовочный файл носителя. Я предполагаю работу с SD-картой, поэтому включаю в проект файл «SDBlockDevice.h». Среди прочих устройств доступны MBRBlockDevice, HeapBlockDevice (очень удобен для тренировки, так как не требует присутствия физического носителя), и другие типы устройств.
// Block device
#include "SDBlockDevice.h"
// File system
#include "LittleFileSystem.h"
Итак, я предлагаю рассмотреть нашу последовательность действий при построении стартового проекта для работы с «LittleFS». Сначала мы должны создать объекты устройства (и инициализировать его выводы) и файловой системы. Затем мы смонтируем файловую систему, создадим пару файлов на носителе, откроем корневую директорию и считаем из нее список файлов, содержащихся в ней.
Обратим внимание на древо наследования классов для работы с потоками, реализованных в mbed os.
Как видим, для работы с файлами у нас реализован целый класс «File». Для работы с директориями существует класс «Dir». Их описание можно почитать на страницах File и Dir.
Однако на практике проявился один интересный нюанс.
При попытке объявить объект класса «File» и использовать метод File (FileSystem *fs, const char *path, int flags=O_RDONLY), призванный создавать файлы, компилятор отказался признать объект.
А при использовании стандартных методов работы с потоками («stdio.h») для создания файла, и при попытке дальнейшей работы с ним с помощью методов класса «File», таких, к примеру, как read или write, операционная система весело сваливалась в mbed_die(), обработчик неисправимой системной ошибки.
Поэтому пока что я ограничусь написанием письма в саппорт ARM, и работать с файлами будем с помощью средств stdio, что, возможно, для кого-то окажется делом более привычным. Полное описание функционала «stdio» можно найти, к примеру, на этом сайте.
Итак, код:
#include "mbed.h"
#include <stdio.h>
#include <errno.h>
// Block device
#include "SDBlockDevice.h"
// File systems
#include "LittleFileSystem.h"
SDBlockDevice bdsd(PB_15, PB_14, PB_13, PB_12); // mosi, miso, sclk, cs
LittleFileSystem fs("fs");
/******************************************************************************/
// main() runs in its own thread in the OS
int main() {
printf("--- Mbed OS filesystem example ---\n");
// Try to mount the filesystem
printf("Mounting the filesystem... ");
fflush(stdout);
int err = fs.mount(&bdsd);
printf("%s\n", (err ? "Fail :(" : "OK"));
if (err) {
// Reformat if we can't mount the filesystem
// this should only happen on the first boot
printf("No filesystem found, formatting... ");
fflush(stdout);
err = fs.reformat(&bdsd);
printf("%s\n", (err ? "Fail :(" : "OK"));
if (err) {
error("error: %s (%d)\n", strerror(-err), err);
}
}
// Open the LittleFS.txt file
FILE *f = fopen("/fs/LittleFS.txt", "r+");
printf("%s\n", (!f ? "Fail :(" : "OK"));
if (!f) {
// Create the LittleFS file if it doesn't exist
printf("No file found, creating a new file... ");
fflush(stdout);
f = fopen("/fs/LittleFS.txt", "w+");
printf("%s\n", (!f ? "Fail :(" : "OK"));
if (!f) {
error("error: %s (%d)\n", strerror(errno), -errno);
}
}
printf("\r Closing \"/fs/LittleFS.txt\"... ");
fflush(stdout);
err = fclose(f);
printf("%s\n", (err < 0 ? "Fail :(" : "OK"));
if (err < 0) {
error("error: %s (%d)\n", strerror(errno), -errno);
}
// Open the Habrahabr.txt file
f = fopen("/fs/Habrahabr.txt", "r+");
printf("%s\n", (!f ? "Fail :(" : "OK"));
if (!f) {
// Create the LittleFS file if it doesn't exist
printf("No file found, creating a new file... ");
fflush(stdout);
f = fopen("/fs/Habrahabr.txt", "w+");
printf("%s\n", (!f ? "Fail :(" : "OK"));
if (!f) {
error("error: %s (%d)\n", strerror(errno), -errno);
}
}
printf("\r Closing \"/fs/Habrahabr.txt\"... ");
fflush(stdout);
err = fclose(f);
printf("%s\n", (err < 0 ? "Fail :(" : "OK"));
if (err < 0) {
error("error: %s (%d)\n", strerror(errno), -errno);
}
// Display the root directory
printf("Opening the root directory... ");
fflush(stdout);
DIR *d = opendir("/fs/");
printf("%s\n", (!d ? "Fail :(" : "OK"));
if (!d) {
error("error: %s (%d)\n", strerror(errno), -errno);
}
printf("root directory:\n");
while (true) {
struct dirent *e = readdir(d);
if (!e) {
break;
}
printf(" %s\n", e->d_name);
}
printf("Closing the root directory... ");
fflush(stdout);
err = closedir(d);
printf("%s\n", (err < 0 ? "Fail :(" : "OK"));
if (err < 0) {
error("error: %s (%d)\n", strerror(errno), -errno);
}
// Unmounting
printf("Unmounting... ");
fflush(stdout);
err = fs.unmount();
printf("%s\n", (err < 0 ? "Fail :(" : "OK"));
if (err < 0) {
error("error: %s (%d)\n", strerror(-err), err);
}
printf("LittleFS tested successfully!\n");
}
Сначала мы создаем объекты классов SDBlockDevice (и тут же его инициализируем, передавая названия выводов в строгой последовательности в соответствии с назначением: mosi, miso, sclk, cs) и LittleFileSystem (fs).
Затем, уже в функции «main», пробуем смонтировать файловую систему (что у нас, конечно же, не получится при использовании новой SD карты). Форматируем носитель, и монтируем файловую систему снова.
Далее, пробуем поочередно открыть файлы «LittleFS.txt» и «Habrahabr.txt», и, не находя их, создаем. После открытия файл обязательно должен быть закрыт.
После благополучных операций с файлами, мы вычитываем содержимое корневой директории и выводим названия файлов в терминал ввода/вывода. Закрываем директорию.
Демонтируем файловую систему и докладываем в терминал о благополучной проверке работы файловой системы.
А вот скриншот сообщений в терминале отладчика.
Итак, сегодня мы поговорили о перспективной и, на мой взгляд, весьма современной файловой системе для микроконтроллеров под названием «LittleFileSystem».
Когда разрешится вопрос с использованием «родных» средств работы с файлами и директориями (с помощью классов File и Dir), обещаю апдейт к статье.
Благодарю за внимание.
UPDATE.
Не успел материал пройти премодерацию, как меня осенило — я неверно пытался использовать методы класса File. Для создания (или открытия существующего) файла необходимо использовать метод open(FileSystem *fs, const char *path, int flags=O_RDONLY);.
В итоге, код дополнится новыми объектами классов File и Dir для работы с файлами и директориями, к примеру,
File fhandle;
Dir dhandle;
Так что весь пример работы с помощью интегрированных в ОС mbed os средств работы с файлами и директориями несколько преобразится. Также, кроме того, что мы создаем и/или открываем файлы, давайте уже туда что-нибудь запишем и считаем. Для этих целей создадим два буфера: из одного будет записываться в файл строка, а во второй мы считаем содержимое файла.
#define BLOCK_SIZE 16
char block[BLOCK_SIZE] = "tasty cake";
char rblock[BLOCK_SIZE];
Итак, код для операций с содержимым SD-карты (между тем, как мы смонтируем и демонтируем файловую систему).
/******************************************************************************/
err = fhandle.open(&fs,"testing.txt", (O_RDWR|O_TRUNC));
if (err<0){
printf("No file found, creating a new file...\n");
fflush(stdout);
err = fhandle.open(&fs,"testing.txt", (O_RDWR|O_CREAT));}
err = fhandle.write(block,10);
if (err<0) printf("Writing error!\n");
printf("Written bytes (%d) ones\n", err);
fhandle.rewind(); //go to the file beginning
err = fhandle.read(rblock,10);
if (err<0) printf("Reading error!\n");
printf("Read bytes (%d) ones\n", err);
printf("Read from file: %s\n", rblock);
err = fhandle.size();
printf("File size (%d) bytes\n", err);
printf("Closing file...");
err = fhandle.close();
if (err<0) printf("Closing file failure!\n");
else printf("...OK\n");
/******************************************************************************/
// Display the root directory
printf("Opening the root directory... ");
fflush(stdout);
err = dhandle.open(&fs,"/");
if (err<0) printf("Opening directory error\n");
else printf("OK\n");
printf("root directory:\n");
struct dirent *e = dhandle.readdir(); //Get the directory entry
while (true) {
err = dhandle.read(e); //Read while != 0 (end)
if (!err) {
break;
}
printf(" %s\n", e->d_name);
}
printf("Closing the root directory... ");
fflush(stdout);
err = dhandle.close();
if (err<0) printf("Closing directory error\n");
else printf("OK\n");
/******************************************************************************/
В самом начале мы пытаемся открыть файл testing.txt для чтения/записи. Обратите внимание, что кроме основных параметров (файловая система и название файла), мы передаем методу флаги O_RDWR и O_TRUNC, объединенные с помощью битовой операции «или»: так предполагают правила работы с ОС. Первый означает, что мы создаем или открываем файл для записи/чтения, второй — что файл будет полностью перезаписан, даже если он существует, и наполнен какой-либо информацией. Полный список флагов приведен с заголовочном файле "mbed_retarget.h":
#define O_RDONLY 0 ///< Open for reading
#define O_WRONLY 1 ///< Open for writing
#define O_RDWR 2 ///< Open for reading and writing
#define O_CREAT 0x0200 ///< Create file if it does not exist
#define O_TRUNC 0x0400 ///< Truncate file to zero length
#define O_EXCL 0x0800 ///< Fail if file exists
#define O_APPEND 0x0008 ///< Set file offset to end of file prior to each write
#define O_BINARY 0x8000 ///< Open file in binary mode
В случае успешного открытия (создания) файла мы пишем в него то, что содержится в буфере block, а точнее, первые 10 байт. Результатом выполнения операции будет количество записанных байт при успешной записи, и это значение мы выводим в терминал при отладке.
Чтобы успешно считать данные из файла, нам нужно вернуться в начало файла, и мы это делаем с помощью fhandle.rewind(). Считанные байты мы тоже считаем, и их число выводим в терминал, как и объем файла (fhandle.size()).
В процессе отладки заглядываем в буфер rblock, в который мы считывали строку из файла. Все в порядке:
С файлом мы побаловались, теперь посмотрим, что же находится в корневом каталоге файловой системы. Открываем директорию и получаем номер записи в каталоге: dhandle.readdir(). Теперь мы считываем название всех файлов, пока dhandle.read(e) не вернёт «0» — записей в директории больше нет. Выводим названия файлов, закрываем каталог.
Любуемся строками в отладочном терминале.
Еще раз всем спасибо.