Структура хранилища SD-карты: принудительно с прямым порядком байтов/обратным порядком байтов?

В соответствии с руководством MAJENKO по оптимизации файлов SD-карты и данных. целостности, могу ли я заставить SDCard читать и записывать либо с прямым порядком байтов, либо с прямым порядком байтов?

Мне это нужно, чтобы поддерживать целостность данных резервного копирования в широком спектре IoT-устройств, используя различные платы (Arduino UNO, MEGA, Nano, NodeMCU и т. д.) для будущего анализа.

, 👍0


1 ответ


1

Многие полные библиотеки C имеют заголовочный файл sys/endian.h. Это определяет ряд макросов, чтобы вы могли узнать, каков порядок байтов вашего устройства. Он также обычно определяет ряд удобных макросов, которые могут преобразовать порядок следования байтов за вас.

htobe16(x)
htobe32(x)
betoh16(x)
betoh32(x)

Они преобразуют Host в Big Eиндийские значения и обратно.

htole16(x)
htole32(x)
letoh16(x)
letoh32(x)

И они преобразуют Хост в маленькие английские значенияи обратно.

Однако его предоставляют не многие встроенные библиотеки C, и не все из них предоставляют удобные макросы.

Это не так сложно реализовать самостоятельно, но это означает, что вы решаете, что делать в зависимости от целевой архитектуры. Что сводит на нет удобство файла endian.h.

Итак, вы действительно хотите повторно реализовать функциональность в форме, которую вы можете включить во все свои скетчи.

К счастью, компилятор предоставляет набор макросов, определяющих порядок следования байтов, которые вы можете использовать:

#define __ORDER_LITTLE_ENDIAN__ 1234
#define __FLOAT_WORD_ORDER__ __ORDER_LITTLE_ENDIAN__
#define __ORDER_PDP_ENDIAN__ 3412
#define __ORDER_BIG_ENDIAN__ 4321
#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__

Таким образом, вы можете проверить макрос __BYTE_ORDER__, чтобы увидеть, какому порядку байтов он соответствует, и использовать его, чтобы выбрать, должен ли htobe32(x) что-либо делать с порядком байтов. или нет.

В компиляторе PIC32 это делается в виде набора макросов, которые либо вызывают swap32 / swap16, либо передают значение без изменений:

#if __BYTE_ORDER__ == __LITTLE_ENDIAN__

#define htobe16 swap16
#define htobe32 swap32
#define betoh16 swap16
#define betoh32 swap32

#define htole16(x) (x)
#define htole32(x) (x)
#define letoh16(x) (x)
#define letoh32(x) (x)

#endif /* __BYTE_ORDER__ */

#if __BYTE_ORDER__ == __BIG_ENDIAN__

#define htole16 swap16
#define htole32 swap32
#define letoh16 swap16
#define letoh32 swap32

#define htobe16(x) (x)
#define htobe32(x) (x)
#define betoh16(x) (x)
#define betoh32(x) (x)

#endif /* __BYTE_ORDER__ */

Теперь, в зависимости от порядка байтов, он либо поменяет местами байты, либо оставит их без изменений. Теперь осталось только реализовать swap16 и swap32, которые я оставлю вам (подсказка: он просто возвращает значение с байтами в обратном порядке — битовый сдвиг и маскировка хороша для этого).

Затем вам нужно определиться с порядком байтов для вашего файла. Возможно, выберите обратный порядок байтов, поскольку он, вероятно, наиболее распространен. Поэтому всякий раз, когда вы помещаете значение в структуру для записи, вы передаете его либо через htole32(...), либо через htole16(...) в зависимости от типа данных. Затем всякий раз, когда вы читаете из прочитанной структуры, вы передаете значение либо через letoh32(...), либо через letoh16(...), чтобы получить его в хосте. порядок следования байтов.

,