Обновить
25
0

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

Отправить сообщение

Описания, как и сами неприятности два и три неверны. Вот кусок текста из даташита.

The last address byte (the 8 least significant address bits, A7-A0) should be set to 0 for 256 bytes page program. If A7-A0 are not all zero, transmitted data that exceed page length are programmed from the starting address (24-bit address that last 8 bit are all 0) of currently selected page. If the data bytes sent to the device exceeds 256, the last 256 data byte is programmed at the request page and previous data will be disregarded.

Младший байт адреса должен быть нулями только для записи страницы целиком. Если не нули, то количество байт не должно быть больше чем размер страницы + офсет.

Поясню на пальцах: внутри есть буфер на 256 байт, 8 битный счетчик принятых байтов. Когда передается адрес его младший байт устанавливает офсет внутри этого буфера. Соответственно если гнать поток байтов длиннее оставшегося места, то счетчик переполняется и считает с нуля, а данные пишутся в начало буфера.

Аналогично если попытаться записать сначала страницы больше 256 байт - данные перетрутся.

Можно городить ООП: по сути все эти статичные переменные запихнуть в структуру.

Несколько SPI флэшек еще не было нужно.

Если две, то продублировать не проблема: чипселект и буфер в зависимости от адреса выбрать и чуть-чуть усложнить логику. Три - чуть сложнее, но тоже почти так же

Очень круто, но есть подозрение, что ножки(крепления) где тензодатчик будет не просто отлить.

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

LOG_INFO(SYS,"GitSha: " GIT_SHA);

к тому же, без лишних вычислений.

Нечего в исходниках делать переменной информации.

А гит или что-то аналогичное использовать полезно ?

Можно сделать проще:

Используем make

GIT_SHA := $(shell git rev-parse --short HEAD)

# ...
DEFINES += GIT_SHA=0x0$(GIT_SHA) # можно сделатьстроку если надо
C_DEFS = $(addprefix -D,$(DEFINES))
# ...

Используем в коде

printf("FW version : %d.%d.%d (%08x)\n", FIRMWARE_VERSION_MAJOR, FIRMWARE_VERSION_MINOR, FIRMWARE_PATCH, GIT_SHA)

Для идентификации имя ветки избыточно, достаточно хэша комита

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

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

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

Всё это называется: "не читал, но осуждаю". Дело не в макросах и комментариях.

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

Так это доступно уровнем выше))

Пару ключиков для линкера, реализуем функции _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 килобайт оперативы.

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

Информация

В рейтинге
Не участвует
Откуда
Москва, Москва и Московская обл., Россия
Дата рождения
Зарегистрирован
Активность