Раньше мы запускали на stm32f4-discovery в 192 Кб RAM, 1 Мб ROM — habr.com/ru/company/embox/blog/259721. Там все очень впритык, но ответ по звонку сработает. Если нет цели максимально ужиматься и оптимизировать, то лучше брать stm32f7, у нас эта версия лучше поддерживается в плане pjsip'а, да и запас по памяти хоть какой-то останется. Например, STM32F746NGH6 с 320 Кб RAM. 1 Мб ROM.
Нет, не пробовали, посчитали что SSE проще будет для полу-дуплесного соединения. В плане WebSocket'ов немного смотрели со стороны поддержки в Embox WebThings от Mozilla.
Да, хорошо выглядит :) Если полная пересовка тормозит, то тут приходит в голову либо битность цвета уменьшить типа RGBA8888 -> RGB565, либо какие-то оптимизации включать типа кешей если есть, ну и конечно оптимизации компилятора. Плюс может что-то с этой памятью в параллель работает с графикой (но это вряд ли, я так понял здесь только графика). Плюс я не знаю как там работа с самим фреймбуфером организована, могут пригодиться двойная (а может и тройная) буферизации. Я это в другой статье немного разбирал.
Да, про энеропотребление сложный вопрос. Как раз этим занимаемся в последнее время — не на уровне SIP, а на уровне ОС. Я думаю приложение может проснуться если есть входящий сетевой пакет (ethernet, в нашем случае), к примеру INVITE. То есть, по сути, по прерыванию. Но на деле, конечно, все сложней.
Под блокировкой имеется ввиду блокировка экрана? Если да, то это не поддерживается, демонстрацию делали минимальной — поэтому только звук + ответ/сброс звонка по кнопкам.
Правда, есть некоторые сомнения в том, что на реальных «микроконтроллерных» проектах задействование кеша приведет к настолько сильному увеличению производительности, что перекроет издержки. Впрочем, задачи бываю разные.
Согласен, все зависит от задачи. Я, кстати, хоть и рассказываю про микроконтроллеры ARM, а забыл упомянуть в каких сериях из линейки Cortex-M вообще есть кэш. Восполню это в комментарии. На сайте ARM есть сравнительная таблица «Cortex-M comparison table». Из нее видно, что D-Cache может быть только у Cortex-M7 и Cortex-M55, а у Cortex-M35P только I-Cache. А это же самые старшие процессоры из Cortex-M. У остальных моделей кэшей нет. Так что если кто-то выбирает какой-нибудь Cortex-M7 под свою задачу (а не Cortex-M0 или Cortex-M4), наверное что-то немаленькое запустить хочет, а там уже и кэш подключить можно.
И еще (в качестве пожелания) — не увидел в статье есть ли (и если есть, то какая именно и как проявляется) зависимость включенного режима кеширования и применения инструкций эксклюзивного доступа (LDREX/STREX).
Спасибо, действительно, в статье про это нет. Думаю что либо в комментарии, либо в будущем в статьях постараемся этот вопрос затронуть.
насчет RGB565 сейчас вдобавок обнаружил и на ресурсе «narodstream», в его уроках про 746-ую Дискавери, аналогичный подход в предлагаемом драйвере для LCD дисплея — он тоже там почему-то RGB565 применил:
RGB565 лучше и в плане FPS и в плане расхода памяти. Хуже только в плане цвета, но для такого экрана вполне годится. Единственная причина, по которой мы делали RGBA8888 — это то что Nuklear rawfb только в таком формате уже подготавливает кадр в памяти, а конвертировать не хотелось (об этом писал выше). То есть если можно RGB565 применить, то я бы тоже его посоветовал. А можно и вообще палитру, как выше предложили. Но сути не меняет, наверное зависит от качества картинки.
Сложно сказать, там про разводку плат обсуждение в основном… Да и непонятно по какой причине он RGB565 использует — вполне возможно что просто из соображений производительности.
По сути да, с точки зрения программиста это обычный регион памяти (memory-mapped i/o). При записи в этот регион данные попадают не напрямую в SDRAM, а проходят через FMC. Если шина данных 16 бит, то да — 32битное число выставится на нее не за раз, а за два. Это примерно как и с SPI-флэшкой — пишем по адресам в memory-mapped режиме, а данные реально передаются по одной линии данных (или по 4ем, если QSPI-флэшка).
Может вы имеете ввиду, что физически у этой SDRAM 32 data линии, но подключена она через первые 16 линий? Если да, то там же FMC настраивается в 16 битный режим, и тогда не имеет значения, что старшие 16 data линии «в воздухе висят», как вы выразились.
Большое спасибо за ссылки! Уже просмотрел (пока по диагонали). На первый взгляд будет. Сейчас там про write-back vs write-through + write-allocate + как можно управлять кэшируемостью памяти через MPU (т.е. помечать как некэшируюмую память под DMA, например, для сетевой карты), а когда стоит применить clean/inval (например, для той же видеопамяти). Да и упор хочется сделать, опять же, с точки зрения программиста — что, зачем и как использовать. Но как я сказал, статья пока очень сырая, там просто лежат те заметки о вещах, с которыми мы лично столкнулись. Еще надо pjsip и другие вещи с кэшем проверить. Но спешить, конечно, не буду. Да и как-то не в наших правилах анонсы статей делать, так как очень много работы, и статьи пишутся только по факту какого-то, пусть и небольшого, осмысленного успеха, а не ради статей. Это я наверное погорячился про анонс, отвечая товарищу выше…
да, не относится к оптимизации, а относится к невнимательности или непониманию принципов формирования кадров.
Да, так и оказалось :) Была ошибка в коде в том моменте когда nukear отрисовывал очередной кадр и запрашивает смену буфера. Я понимаю, что смотреть вероятно не будете, но на всякий случай оставляю ссылку на правку.
Про кэш вы тоже мало что знаете, но про это вы пока еще, похоже, не знаете — об этом я вам расскажу в следующем сообщении к концу недели.
Конечно пишите, мне будет интересно чего я не знаю.
p.s.
Кстати, я тоже хотел в относительно недалеком будущем отдельную статью про кэши написать, как раз потому что это вышло за рамки текущей статьи про графику, даже черновик уже есть (но очень-очень сырой). Так что если вдруг не хотите мне «подсказывать», то можете ее дождаться и раскритиковать в пух и прах :)))
Во-вторых, вот вы написали сейчас полотно, которое просто вышло бы за рамки статьи — соответствнно, объяснять все это было бы нерезонно (да, признаю, часть для меня новое, но 70% того что вы написали я знаю). Про FMC я знаю тоже. Знаете почему? А вы посмотрите на каком адресе расположена память SDRAM — 0x60000000. Мы ее переключаем с 0xc0000000 на 0x60000000 через SWP_FMC, это было нужно для выравнивания на 4 байта. Далее, я не утверждал я что DMA генерирует команды к SDRAM в обход FMC. Но почему я обязан о всех этих деталях с FMC рассказывать в статье?
Единственное, я бы может просто заменил мою неточную формулировку в статье на вашу:
Проблема в особенностях работы SDRAM — причем не конкретной микросхемы, а SDRAM как таковой. Но об этом вы, явно, мало что знаете. SDRAM очень даже шустрая, если читать или писать большой объем данных, расположенных последовательно. Как только начинается произвольный доступ скорость катастрофически падает. Поэтому, если бы вместо SDRAM к FMC подключили SRAM ситуация была бы иной.
Да, тут более четко сказано про особенность SDRAM. И этой особенностью, действительно, много объясняется. И этого было бы достаточно. Но нет же…
В остальном, серьезно, вот зачем это все в статье про детали с FMC и Bus Matrix? Вот вы похоже железом занимаетесь (аппаратчик, верилог, FPGA наверное), но к примеру, зачем вам в статье по железу рассказывать как устроены workqueue или timer wheel в Линукс. Могу вам точно так же сказать, если вы этого не знаете, то железячник из вас никудышний.
тройная буферизация используется когда идет непрерывный поток формирования кадров (например, камера или Ваш случай, где пытаетесь достичь много fps)
да, я читал выше про тройную буферизацию. там за бланками следить не надо, только контролеру видео сообщить, с какого адреса начинать следующий кадр.
почитайте как делается тройная буферизация, там не сложно. главное, не запутаться какой буфер на вывод, какой в очереди, а какой свободный.
Спасибо, попробую! Из любопытсва, вы тройную буферизацию на практике реализовывали, или разбирали в теории?
Я хочу сказать, что главное преимущество тройной буферизации — это повышение FPS. И если даже отрисовка происходит всегда быстрее загрузки кадра в экран, система может просто «перерисовывать» один из двух буферов, и уже, например, по v-sync или еще как-то отдаст в контроллер дисплея наиболее свежий отрисованный кадр. То есть тут важный момент, что вместо ожидания v-sync, всегда можно перерисовать буфер, в котором находится наиболее старый кадр. А вот в двойной же буферизации, перерисовывать самый старый кадр (он же текущий) — нельзя.
Благодаря этим обсуждениям здесь и выше, я лучше понял тройную буферизацию, признаю, спасибо :)
Но еще раз, та фраза, на которую вы сосласись:
Обсудив ситуацию, мы решили отложить унификацию до более глубокой проработки графического стека.
Попробуйте сделать тройной буфер, как рекомендовали выше. Это классика. Тогда не будет проблем с маленькими или большими разрешениями. И не надо ловить «обратный ход луча» или как принято сейчас называть — «вертикальный бланк».
Разве тройная буферизация всегда исключает необходимость проверки вертикального бланка? Если у вас ЦПУ отрисовывает кадр всегда быстрее, чем контроллер дисплея грузит кадр в экран, то тройная буферизация теряет смысл перед двойной буферизацией. Ну и, собственно, когда контроллер дисплея всегда быстрее грузит кадр нежели система его отрисовывает та же история. При этом, я понимаю как это может помочь «в среднем». Вы же читали обсуждения про тройную буферизацию выше (случаи когда кто-то из ЦПУ или LTDC быстрей)? Было бы интересно вас выслушать.
Ваш первый способ (с переключением слоев) работает только, когда скорость формирования кадра выше скорости вывода, второй (переключение буферов) — наоборот.
Можете пояснить? Казалось бы, ни один их этих способов не должен зависеть от соотношения скоростей формирования кадра/отображения кадра. При любом соотношении, оба способа должны давать адекватную картинку (без дрожания), ведь переключение буферов в обоих методах происходит исключительно внутри VBLANK.
Возможно, это мое мнение, но fps замерять не очень корректно, более правдиво — время, затраченное на формирование кадра. Тогда можно оценить свободное процессорное время для других задач.
У нас в этом примере только графическое приложение исполнялось. Помимо этого разве что системный таймер. Поэтому полученные 85 FPS это когда система только графикой и занимается. Если экран 60 Гц, то можно прикинуть какая часть свободного времени остается.
LVGL, кстати, выглядит интересным, у нас даже задача по портированию висит в репозитории. Просто Nuklear уже был портирован, вот и взяли его.
Согласен, все зависит от задачи. Я, кстати, хоть и рассказываю про микроконтроллеры ARM, а забыл упомянуть в каких сериях из линейки Cortex-M вообще есть кэш. Восполню это в комментарии. На сайте ARM есть сравнительная таблица «Cortex-M comparison table». Из нее видно, что D-Cache может быть только у Cortex-M7 и Cortex-M55, а у Cortex-M35P только I-Cache. А это же самые старшие процессоры из Cortex-M. У остальных моделей кэшей нет. Так что если кто-то выбирает какой-нибудь Cortex-M7 под свою задачу (а не Cortex-M0 или Cortex-M4), наверное что-то немаленькое запустить хочет, а там уже и кэш подключить можно.
Спасибо, действительно, в статье про это нет. Думаю что либо в комментарии, либо в будущем в статьях постараемся этот вопрос затронуть.
RGB565 лучше и в плане FPS и в плане расхода памяти. Хуже только в плане цвета, но для такого экрана вполне годится. Единственная причина, по которой мы делали RGBA8888 — это то что Nuklear rawfb только в таком формате уже подготавливает кадр в памяти, а конвертировать не хотелось (об этом писал выше). То есть если можно RGB565 применить, то я бы тоже его посоветовал. А можно и вообще палитру, как выше предложили. Но сути не меняет, наверное зависит от качества картинки.
Сложно сказать, там про разводку плат обсуждение в основном… Да и непонятно по какой причине он RGB565 использует — вполне возможно что просто из соображений производительности.
Да, так и оказалось :) Была ошибка в коде в том моменте когда nukear отрисовывал очередной кадр и запрашивает смену буфера. Я понимаю, что смотреть вероятно не будете, но на всякий случай оставляю ссылку на правку.
Конечно пишите, мне будет интересно чего я не знаю.
p.s.
Кстати, я тоже хотел в относительно недалеком будущем отдельную статью про кэши написать, как раз потому что это вышло за рамки текущей статьи про графику, даже черновик уже есть (но очень-очень сырой). Так что если вдруг не хотите мне «подсказывать», то можете ее дождаться и раскритиковать в пух и прах :)))
Во-вторых, вот вы написали сейчас полотно, которое просто вышло бы за рамки статьи — соответствнно, объяснять все это было бы нерезонно (да, признаю, часть для меня новое, но 70% того что вы написали я знаю). Про FMC я знаю тоже. Знаете почему? А вы посмотрите на каком адресе расположена память SDRAM — 0x60000000. Мы ее переключаем с 0xc0000000 на 0x60000000 через SWP_FMC, это было нужно для выравнивания на 4 байта. Далее, я не утверждал я что DMA генерирует команды к SDRAM в обход FMC. Но почему я обязан о всех этих деталях с FMC рассказывать в статье?
Единственное, я бы может просто заменил мою неточную формулировку в статье на вашу:
Да, тут более четко сказано про особенность SDRAM. И этой особенностью, действительно, много объясняется. И этого было бы достаточно. Но нет же…
В остальном, серьезно, вот зачем это все в статье про детали с FMC и Bus Matrix? Вот вы похоже железом занимаетесь (аппаратчик, верилог, FPGA наверное), но к примеру, зачем вам в статье по железу рассказывать как устроены workqueue или timer wheel в Линукс. Могу вам точно так же сказать, если вы этого не знаете, то железячник из вас никудышний.
Спасибо, попробую! Из любопытсва, вы тройную буферизацию на практике реализовывали, или разбирали в теории?
Благодаря этим обсуждениям здесь и выше, я лучше понял тройную буферизацию, признаю, спасибо :)
Но еще раз, та фраза, на которую вы сосласись:
не относится к оптимизации FPS.
Разве тройная буферизация всегда исключает необходимость проверки вертикального бланка? Если у вас ЦПУ отрисовывает кадр всегда быстрее, чем контроллер дисплея грузит кадр в экран, то тройная буферизация теряет смысл перед двойной буферизацией. Ну и, собственно, когда контроллер дисплея всегда быстрее грузит кадр нежели система его отрисовывает та же история. При этом, я понимаю как это может помочь «в среднем». Вы же читали обсуждения про тройную буферизацию выше (случаи когда кто-то из ЦПУ или LTDC быстрей)? Было бы интересно вас выслушать.
Можете пояснить? Казалось бы, ни один их этих способов не должен зависеть от соотношения скоростей формирования кадра/отображения кадра. При любом соотношении, оба способа должны давать адекватную картинку (без дрожания), ведь переключение буферов в обоих методах происходит исключительно внутри VBLANK.
У нас в этом примере только графическое приложение исполнялось. Помимо этого разве что системный таймер. Поэтому полученные 85 FPS это когда система только графикой и занимается. Если экран 60 Гц, то можно прикинуть какая часть свободного времени остается.