Pull to refresh
26

Схемотехник/программист МК

6
Subscribers
Send message

Точно-точно, прошу прощения, потерял восьмёрку в расчетах. Однако это не сильно меняет ситуацию. А наоборот показывает, что операция длится ещё дольше и хорошо бы свести лишние записи к минимуму.

 А теперь рассказываете про выделение кеш. Что не так?

Кэш не выделяется, а используется уже готовый буфер, который и так использовался бы при записи данных. И в статье описано, и в комментах вам отвечал.

Время записи, физической записи, в тактах 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 килобайт оперативы.

Я привел хоть и синтетический пример, но не такой уж и далекий от реального положения вещей

Вместо bool write enum будет выглядеть лучше.

Согласен, будет выглядеть аккуратнее.

Для 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.

Подробнее, про какой кусок кода идёт речь?

Второй метод использует код Грея. В этом случае нам не нужны никакие прерывания вообще.

чтобы запускать эту процедуру в прерывании каждый раз, когда счётчик переполняется

Метод без прерываний требует прерываний ?

То есть либо тратим такты на бесполезную обработку в основном цикле, либо такты в бесполезной обработке таймера, даже если энкодер не двигается.

Уж лучше в прерывании от ноги все это делать

Для индикаторных светодиодов внутри помещения для уменьшения номенклатуры резисторов можно пренебречь небольшим отличием светимости, главное, что бы опознавалось нормально.

На странице в википедии куда больше информации и куда лучше все это описано ?

Кстати и сам clang нормально собирает под arm bare metal, только нужно ему библиотеки сишные подсунуть во время линковки хоть даже от гцц или же собрать себе из исходников ллвмные.

И где тут тематика разработки под андроид, программирование микроконтроллеров?

Только ссылки на репы? Ну так не интересно.

Лучше напишите какие сложности были, как с этим боролись, примеры схем, исходников.

Пока это похоже на "я парюсь"

У вас же калибровка идет с участием большого брата(ПК) соответственно нет сложностей писать сразу все изменения за раз, а не по одному параметру?

Даже в таком случае можно подцепиться какой нибудь ide или же с помощью vscodе и cortex debug?

Да ладно, а вы посмотрите в другом месте

https://developer.arm.com/downloads/-/gnu-rm

Я ни на что не намекаю, но может нужно в более надежных источниках софт искать?

В ответственных применениях типа авиа, авто и мед техники применяются специфические стандарты и требования к коду, где при хорошем подходе нельзя просто так взять и подсунуть левую либу, но это в идеальном мире...

Интересно, а почему бы не взять гцц еще старее?

Всё это, конечно, синтакический сахар. Но почему бы не написать цикл while или поднять это условие в for. Количество вопросов уменьшиться, а если ещё и магическое число скрыть за осмысленным именем макроса или константы, то и читаемость кода повысится. Можно хотя бы i назвать как timeout, вы же не перебираете массив по индексам, а ждёте.

На самом то деле, что мешает держать счётчик в ОЗУ и при событии снижения питания (детектирование любым удобным способом) или просто с более длительным периодом записывать в ПЗУ?

Переменную можно разместить в неинициализируемой области (настраиваем скрипт для линкера) и перезагрузки не страшны.

Нужна лишь ёмкость по питанию чуть больше чем обычно. Можно сказать почти бесплатное решение.

Information

Rating
4,992-nd
Location
Москва, Москва и Московская обл., Россия
Date of birth
Registered
Activity