Естественно если вы заливаете прошивку с компа, то запись уже идет большими блоками и уже довольно оптимально. И это совершенно другое. Про программирование с компа речи и не шло, было про оперирование данными в микроконтроллере.
Про USB и fatfs говорю потому, что обе эти возможности должны или могут быть реализованы сразу. И у каждой есть ограничения и особенности.
Можно было бы выделить под USB 4 килобайта, что бы сразу писать, но такой роскоши нет или может не быть.
На лету как раз не выйдет, потому что скорость записи существенно меньше скорости поступления данных.
При использовании fatfs и USB MSC у вас будет буфер размером в 512 байт, что всего 2 страницы. При типовой реализации будут лишние записи и стирания, если переписывать данные. Однако если чуть поднакопить изменения в буфере и записать все разом операций будет меньше.
Что именно вы пишете, мне кажется мы говорим о разных применениях?
Точно-точно, прошу прощения, потерял восьмёрку в расчетах. Однако это не сильно меняет ситуацию. А наоборот показывает, что операция длится ещё дольше и хорошо бы свести лишние записи к минимуму.
А теперь рассказываете про выделение кеш. Что не так?
Кэш не выделяется, а используется уже готовый буфер, который и так использовался бы при записи данных. И в статье описано, и в комментах вам отвечал.
Время записи, физической записи, в тактах SPI считать крайне неправильная идея. Вы учитываете лишь малую часть этого процесса.
Временные характеристики операций
Время на пересылку 260 байт (1 команда + 3 адрес + 256 данные) при ваших 10 МГц будет 26 мкс, что 4,5% (в лучшем случае) от всех временных затрат.
Взгляните на рисунок и будет понятно, что ни о каких 1.2 Мбайт/сек речи и быть не может.
От чего и выбраны магические константы w, e и r, которые от чипа к чипу меняются.
Если пишите один байт, то у вас будет только время записи байта, а вот если переписываете - время стирания и переписывания всего сектора: tse + tpp * n, где n - количество страниц в секторе (в примере было 8, в жизни 16).
Использование DMA немного помогло бы, тут я согласен, но не кардинально. В довесок мы бы получили отложенный возврат статуса операции и обработки ошибок. Можно использовать неблокирующий способ передачи, но нужно будет дополнительно усложнить логику уровнем выше.
Ваш драйвер не решает эту проблему.
Как раз за счет уменьшения этих операций и решает.
Медленно будет если не использовать кэширование, так как будет по две страницы писаться.
Но если записывать только по смене сектора и по таймауту, то будет быстрее.
Вижу, что вы не особо внимательно прочли. 4 килобайта в любом случае выделять, так как стереть можно минимум сектор, а он как раз 4 килобайта. Либо их использовать как временный буфер, либо ещё и в качестве кэша.
Посмотрите как реализованы fatfs и stm USB msc, вызывается и пишется блоками по 512 байт. Вот и пример, а выделять отдельно по 4кб для USB и fat глупо, особенно если в чипе всего 20 килобайт оперативы.
Я привел хоть и синтетический пример, но не такой уж и далекий от реального положения вещей
Для mutex стандартной терминологией является down/up, выбор take/give неоправдан в случае если код публикуется для масс.
Не готов согласиться, down/up не совсем отражает суть действия и сходу понятны куда меньше.
take/give тоже не идеал, но имхо ближе к сути, и для знакомых с freeRTOS намного яснее отражает суть. lock/unlock - тоже было бы норм, но...
Где происходит оборачивание навроде spi_cs_activate()/spi_cs_deactivate() более аккуратно выглядит static inline функция, внутри которой всего 3 действия: захват-действие-отпуск, где действие - это вызов еще одной вложенной static inline.
Напишите понятнее, что имеется ввиду? Все функции для работы с spi: прижатие чип селекта, приём и передача определены в другом модуле, здесь им делать нечего.
На 144 строке было бы аккуратнее с early-exit и continue.
Для индикаторных светодиодов внутри помещения для уменьшения номенклатуры резисторов можно пренебречь небольшим отличием светимости, главное, что бы опознавалось нормально.
Если вам не нужно числовое представление, то лучше сразу в строку загонять, будет еще лаконичнее
к тому же, без лишних вычислений.
Нечего в исходниках делать переменной информации.
А гит или что-то аналогичное использовать полезно ?
Можно сделать проще:
Используем make
Используем в коде
Для идентификации имя ветки избыточно, достаточно хэша комита
Код, в частности на си, это не команды для железа, а всего лишь человекочитаемое представление оных.
Эффективность решения задачи зависит не только от того какие вы флаги оптимизации включите, а то, как реализуете алгоритм.
Всё это называется: "не читал, но осуждаю". Дело не в макросах и комментариях.
Не вижу смысла больше общаться с вами, никаких аргументов вы не приводите.
Так это доступно уровнем выше))
Пару ключиков для линкера, реализуем функции _write, _read, _lseek и остальные, и дело в шляпе - пользуемся fprintf и всеми остальными благами)
Или можно не сильно заморачиваясь использовать функции fatfs: f_open, f_write, f_read.
Ткните пальцем в код, где есть куски, которые завися от железа.
Реальный пример уже приводил, FatFs и ST USB MSC. Возьмите другую связку, например FatFs + AVR USB Software Library.
При любом раскладе взаимодействие будет сводится к блочному чтению, по умолчанию это будут 2 страницы, если конечно у вас нет большего буфера.
От железа зависит только скорость пересылки данных, даже не от самого железа, а от его возможностей.
Реализация алгоритма не связана с конкретным ядром. Возьмите хоть arm, хоть avr, хоть risc-v, все едино. И ничего не поменяется.
Основной посыл не писать сразу данные, а поднакопить их.
Естественно если вы заливаете прошивку с компа, то запись уже идет большими блоками и уже довольно оптимально. И это совершенно другое. Про программирование с компа речи и не шло, было про оперирование данными в микроконтроллере.
Про USB и fatfs говорю потому, что обе эти возможности должны или могут быть реализованы сразу. И у каждой есть ограничения и особенности.
Можно было бы выделить под USB 4 килобайта, что бы сразу писать, но такой роскоши нет или может не быть.
На лету как раз не выйдет, потому что скорость записи существенно меньше скорости поступления данных.
При использовании fatfs и USB MSC у вас будет буфер размером в 512 байт, что всего 2 страницы. При типовой реализации будут лишние записи и стирания, если переписывать данные. Однако если чуть поднакопить изменения в буфере и записать все разом операций будет меньше.
Что именно вы пишете, мне кажется мы говорим о разных применениях?
Никто не заставляет, можно и даже нужно. Равно как и запись данных которые уже там есть, расширь проверку не просто на пустоту, но и на равенство.
Это очень хорошая идея
Точно-точно, прошу прощения, потерял восьмёрку в расчетах. Однако это не сильно меняет ситуацию. А наоборот показывает, что операция длится ещё дольше и хорошо бы свести лишние записи к минимуму.
Кэш не выделяется, а используется уже готовый буфер, который и так использовался бы при записи данных. И в статье описано, и в комментах вам отвечал.
Время записи, физической записи, в тактах SPI считать крайне неправильная идея. Вы учитываете лишь малую часть этого процесса.
Время на пересылку 260 байт (1 команда + 3 адрес + 256 данные) при ваших 10 МГц будет 26 мкс, что 4,5% (в лучшем случае) от всех временных затрат.
Взгляните на рисунок и будет понятно, что ни о каких 1.2 Мбайт/сек речи и быть не может.
От чего и выбраны магические константы w, e и r, которые от чипа к чипу меняются.
Если пишите один байт, то у вас будет только время записи байта, а вот если переписываете - время стирания и переписывания всего сектора: tse + tpp * n, где n - количество страниц в секторе (в примере было 8, в жизни 16).
Использование DMA немного помогло бы, тут я согласен, но не кардинально. В довесок мы бы получили отложенный возврат статуса операции и обработки ошибок. Можно использовать неблокирующий способ передачи, но нужно будет дополнительно усложнить логику уровнем выше.
Как раз за счет уменьшения этих операций и решает.
Там подлость не в чтении статуса, а выдержке с отпущенным чипселектом после операций записи.
В итоге либо делать магическую задержку, либо проверять статус.
Но проверять статус сразу после записи не удается из-за слишком малого времени выдержки.
Микросхем не винбонд, а ZD25Q64B. Она в принципе аналогична. Хотя не исключаю, что это именно её особенность с длинной выдержкой.
По первой части. Где и зачем может потребоваться сделать дополнительный return в функции инициализации? Странно и не нужно.
В других случаях - согласен. Подобный вариант может быть уместен.
По второй. Что-то вы выдумываете и приписываете мне чужие "заслуги" ?
Приведите примеры и аргументы правильности использования варианта, предложенного вами.
Реализация с кучей функций имеет право на существование, но в чем смысл плодить сущности, если и так понятно что происходит?
take/give по нескольким причинам:
Нет мнимого чувство что можно использовать счетный, как это может показаться с down/up
Так исторически сложилось. Самый тупой аргумент, но имеет место быть
Понятность куда важнее, а если имя функции может спровоцировать ошибку, то нафиг оно нужно?
Всеобщая практика показывает: кто как хочет, так и ... Делает.
Спор про мьютекс считаю завершенным.
При чем здесь uart?
Медленно будет если не использовать кэширование, так как будет по две страницы писаться.
Но если записывать только по смене сектора и по таймауту, то будет быстрее.
Вижу, что вы не особо внимательно прочли. 4 килобайта в любом случае выделять, так как стереть можно минимум сектор, а он как раз 4 килобайта. Либо их использовать как временный буфер, либо ещё и в качестве кэша.
Посмотрите как реализованы fatfs и stm USB msc, вызывается и пишется блоками по 512 байт. Вот и пример, а выделять отдельно по 4кб для USB и fat глупо, особенно если в чипе всего 20 килобайт оперативы.
Я привел хоть и синтетический пример, но не такой уж и далекий от реального положения вещей
Согласен, будет выглядеть аккуратнее.
Не готов согласиться, down/up не совсем отражает суть действия и сходу понятны куда меньше.
take/give тоже не идеал, но имхо ближе к сути, и для знакомых с freeRTOS намного яснее отражает суть. lock/unlock - тоже было бы норм, но...
Напишите понятнее, что имеется ввиду? Все функции для работы с spi: прижатие чип селекта, приём и передача определены в другом модуле, здесь им делать нечего.
Подробнее, про какой кусок кода идёт речь?
Метод без прерываний требует прерываний ?
То есть либо тратим такты на бесполезную обработку в основном цикле, либо такты в бесполезной обработке таймера, даже если энкодер не двигается.
Уж лучше в прерывании от ноги все это делать
Для индикаторных светодиодов внутри помещения для уменьшения номенклатуры резисторов можно пренебречь небольшим отличием светимости, главное, что бы опознавалось нормально.