1/ Вынеси data из структуры fifo_t, оставь только указатель на внешний массив. Это позволит создавать очереди разной длины. Нужно вбудет объявлять сначала массив, потом экземпляр fifo_t и инициализировать указатель.
2/ Не нужна функция fifo_init() — структуру можно инициализировать при объявлении как обычную переменную
3/ Каждый экземпляр очереди должен работать с элементами одного типа/длины. Соответственно, в fifo_t стоит внести поле element_size и тогда при чтении и записи будет уже известно, сколько байт читать или писать — не потребуется указывать параметры этим функциям.
4/ Зачем функциям чтения и записи параметр offset? Фифо очередь должна сама знать, с какого элемента писать и с какого элемента читать и есть ли элементы вообще. ???
Перехвачена то может быть, но инкремент хвоста ведется только в прерывании. А в основном потоке ведется инкремент головы. В итоге, они между собой не конфликтуют. Нет, бывают конечно конфликты, когда нужно выяснить сколько элементов в буфере, но тогда уж можно и прерывания запретить.
Как это должно выглядеть? Что-то вида:
Ну, точно не «const», так как ты его только на этапе компиляции заполнить сможешь.
А вообще, правильно. Вообще. нужно как-то найти силы, оформить и выложить свой Fifo.
Да, реализация действительно красивее :) Особенно понравилось решение с маской, избавляемся от условного перехода, что есть гут ) Да и от лишней переменной…
Вот кстати не мог вспомнить 3й пункт в вопросы, а это как раз были потоковые обращения… Да, на данный момент отключаю прерывания перед вызовом функций, внутрь библиотеки это не вносил, т.к. считаю что про манипуляции с прерываниями нужно помнить в контексте проекта… И кстати без count тоже вопрос… Конструкция вида
fifo->data[fifo->tail++] =((u8*) data)[i];
тоже ведь может быть не атомарной, управление может быть перехвачено уже после обращения к массиву, но до инкремента «хвоста»… Или я не прав?
Вот кстати на данном этапе почитываю C# Троелсена, и действительно в С хочется иметь плюшки ООП =) Теперь понимаю, почему ты на плюсах пишешь… Наверное тоже попробую, только пока углубиться в изучение не получится, боюсь что вместе с шарпом в голове каша получится — буду путать нюансы…
А по поводу длины буфера внутри структуры — вот как-то проскакивала такая мысль, но потом решил что не получится, и даже не проверил…
Как это должно выглядеть? Что-то вида:
Но подозреваю что не совсем так, компилятор то должен знать длину массива уже на этапе объявления… (Сейчас IAR не стоит, точнее стоит только для STM8)
Все, мне пора убегать :) Спасибо за пояснение.
FIFO_LENGTH — это длина буфера, которую нужно задефайнить в заголовке.
Предлагаю тебе внести в fifo_t количество элементов в этому буфере :)
Можно использовать класс и один из чего методов будет количеством записей.
если мы укажем к примеру 5 байт в первом вызове, то мы запишем 4 байта полезных данных
Если ты пишешь на Си, то можно сделать кучу функций «fifo_put_int», «fifo_put_char» итп. Если на C++, то можно перегрузить fifo_put для работы с нужным типом данных, можно сделать шаблон fifo_putв котором вызывать внутреннюю fifo_put c sizeof(T) в качестве размера.
Еще, буферы с count — не потокобезопасны. Если одни поток (прерывания) будут писать, а другой (задача) будет читать, то это все нужно объявлять как volatile и блокировать прерывания на время обращений к count.
В качестве альтернативы можно обойтись без count, используя только head, tail запас в один байт :)
Аналогично. Лишь бы у вас была переменная, которая соответствовала бы скорости работы шаговика. Преобразование задания скорости в период переключения обмоток шаговика — это уже задача преобразователя. Но тут встает проблема — зависимость между процентным значением скорости и абсолютным значением периода переключения — обратная, то бишь — гиперболическая.
Один из простых методов преобразования одной переменной в другое — метод линеаризации. Про него будет моя сегодняшняя статья.
А возможно данный метод «прикрутить» к шаговому двигателю? То есть, я могу расчитать по основным характеристикам двигателя его максимальную частоту вращения, максимальное ускорение. Соответсвенно как может быть выглядить код управления шаговым двигатемем по интенсивности?
Обычно стоит, но когда нужно избавиться от синфазной помехи в каком-то медленном и мега-чувствительном аналоге, можно и резистор в землю поставить. Такое я пару раз видел в аудио ЦАПах, там рекомендовали ставить бусинки в землю. Естественно, падение на этом резисторе не должно превышать неких разумных пределов, обычно 0.3 вольта.
2/ Не нужна функция fifo_init() — структуру можно инициализировать при объявлении как обычную переменную
3/ Каждый экземпляр очереди должен работать с элементами одного типа/длины. Соответственно, в fifo_t стоит внести поле element_size и тогда при чтении и записи будет уже известно, сколько байт читать или писать — не потребуется указывать параметры этим функциям.
4/ Зачем функциям чтения и записи параметр offset? Фифо очередь должна сама знать, с какого элемента писать и с какого элемента читать и есть ли элементы вообще. ???
Ну, точно не «const», так как ты его только на этапе компиляции заполнить сможешь.
А вообще, правильно. Вообще. нужно как-то найти силы, оформить и выложить свой Fifo.
тоже ведь может быть не атомарной, управление может быть перехвачено уже после обращения к массиву, но до инкремента «хвоста»… Или я не прав?
Вот кстати на данном этапе почитываю C# Троелсена, и действительно в С хочется иметь плюшки ООП =) Теперь понимаю, почему ты на плюсах пишешь… Наверное тоже попробую, только пока углубиться в изучение не получится, боюсь что вместе с шарпом в голове каша получится — буду путать нюансы…
А по поводу длины буфера внутри структуры — вот как-то проскакивала такая мысль, но потом решил что не получится, и даже не проверил…
Как это должно выглядеть? Что-то вида:
Но подозреваю что не совсем так, компилятор то должен знать длину массива уже на этапе объявления… (Сейчас IAR не стоит, точнее стоит только для STM8)
Все, мне пора убегать :) Спасибо за пояснение.
Можно использовать класс и один из чего методов будет количеством записей.
Если ты пишешь на Си, то можно сделать кучу функций «fifo_put_int», «fifo_put_char» итп. Если на C++, то можно перегрузить fifo_put для работы с нужным типом данных, можно сделать шаблон fifo_putв котором вызывать внутреннюю fifo_put c sizeof(T) в качестве размера.
Еще, буферы с count — не потокобезопасны. Если одни поток (прерывания) будут писать, а другой (задача) будет читать, то это все нужно объявлять как volatile и блокировать прерывания на время обращений к count.
В качестве альтернативы можно обойтись без count, используя только head, tail запас в один байт :)
Один из простых методов преобразования одной переменной в другое — метод линеаризации. Про него будет моя сегодняшняя статья.
но совет с tie хороший
но без форсирования.
tqfp.org/rln_electro/zaschita-ot-drebezga-mehanicheskogo-enkodera.html