avatar
Рейтинг
0.00
Сила
0.00

Публикации

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

1. Как уже сказали, лучше в структуре объявить лишь указатель на массив. А уж предоставить собственно массив для буфера — пусть будет задача пользователя.
2. Как обезопасить работу с указателями? Возьмите себе за привычку всегда проверять в начале функций все указатели на NULL, и сразу выдавать ошибку если был передан неинициализированный указатель.
3. Ваша функция выдаст ошибку, если данные не помещаются в буфер целиком. Может оно и верно. А возможно будет удобнее, если функция будет класть в очередь что может, и возвращать количество реально записанных байт. Тут стоит подумать. Вообще подход возвращать что-то более полезное чем 0 и -1 приветствуется.
4. Если функция не изменяет никаких данных в массиве, переданном ей в качестве аргумента, то указатель на этот массив стоит объявлять как const void *. Например, если у меня есть строка «Hello, world!» (как раз тип const), и я хочу запихать ее в буфер.
5. Может стоит добавить функции для записи/чтения одного единственного байта, а не массива. Иногда бывает полезно при использовании в алгоритмах.
6. Кто-то предгалал не использовать переменную count, которая хранит размер данных в очереди. Но тут есть одна проблема — когда буфер заполнится полностью, не получится ли так, что head станет равно tail?
Что я хочу сказать: изначально у нас head = 0, tail = 0. Допустим, мы пишем в очередь FIFO_LENGTH байт данных. Тогда и head станет под конец равным FIFO_LENGTH, и выполнится условие if (fifo->tail == FIFO_LENGTH), что сбросит его опять в 0. Тем самым «очистив буфер». Решений тут два:
1) Хранить не tail и head, а tail и length. А head вычислять.
2) Оставлять в буфере всегда 1 байт.

7. Старайтесь не писать в алгоритмах «жесткие» сравнения: по типу if (fifo->head == FIFO_LENGTH).
Особенно это касается сравнений чисел с плавающей запятой. Ваш алгоритм может быть более стойким к изменениям, если написать if (fifo->head >= FIFO_LENGTH). Или, если совсем заморочиться, та же операция в более общем виде:
while(fifo->head >= FIFO_LENGTH){ fifo->head -= FIFO_LENGTH; } // по сути то же, что и fifo->head %= FIFO_LENGTH

8. Если пишете код «для всех» (библиотеку), то старайтесь делать так, чтобы он заработал сразу у всех.
Например, объявления переменных в середине функции и особенно в for(int i = 0; ...) могут вылезти ошибками при компиляции gcc с флагами -pedantic и -ansi. Еще можно порадовать любителей C++, если вставить в нужные места
Спойлер
#ifdef __cplusplus
extern «C» {
#endif

#ifdef __cplusplus
} // extern «C»
#endif


Еще можно отказаться от «нестандартных» названий типов, и выкинуть из кода #include <stm32f10x.h>. Тогда код можно будет использовать, например, для написания программы для AVR.