juvf 17 26 апреля, 2019 Опубликовано 26 апреля, 2019 · Жалоба 1 час назад, topor_topor сказал: Но зачем другим полезним функциям MAIN липнуть? Например можно продолжать реагировать на кнопки, усреднять измерения АЦП итд. Я не знаю зачем. Я не предлагаю вам вешать остальные потоки. Я вам говорю, что если вы вынесете LCD/I2c в другой поток и сделаете реализацию как у haker_fox, то эффекта не получите. О чем вам haker_fox написал - "Другие в это время, да, курят бамбук". Если вы сделаете как у haker_fox, то при вызове MeasCore::sendMsg(), у вас MAIN залипнет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 26 28 апреля, 2019 Опубликовано 28 апреля, 2019 · Жалоба А почему обязательно рисовать непосредственно на этом экране, т.е. напрямую? Я уже давным-давно пошел по пути упрощения это задачи: выделяю ОЗУ (некое видео ОЗУ) для LCD, даже графического (монохромное). Все потоки "рисуют" прямо в это ОЗУ. Отдельный поток периодически перерисовывает картинку из этого видео ОЗУ непосредственно в экран, ВСЮ картинку. Для таких LCD достаточно периодичности примерно до 5 раз в сек. Приоритет его низкий. Саму функцию рисования в это ОЗУ желательно защитить внутри мьютексом (он не всегда требуется, это зависит от проекта). Никаких очередей, списков, буферов, критических секций и т.п. анархизма. Все получается предельно просто и главное - функция рисования работает ооочень быстро и за прогнозируемое время (рисуем в ОЗУ). Фактически нужно лишь отделить "мух от котлет" - рисование от отображения. При желании можно использовать ДВА видео-озу, чтобы картинка не "рассыпалась", но это нужнее для TFT, а не LCD. Для адептов экономии ОЗУ: монохромный графический LCD 320х240 в таком построении требует всего лишь ~10кБ ОЗУ. Не говорю уже про символьные LCD ... Да, безусловно есть минус - перерисовывается весь LCD независимо от того, менялось на нем что-то или нет. Но если провести замеры в реальном проекте заранее - замерить загрузку CPU при работающей только задаче перерисовки ЖК, то можно заранее эти данные учесть в проекте. У меня в проектах работа с ЖК, построенным по описанной схеме, отъедает от даже убогого тщедушного проца от силы 1..2% процессорного времени. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
haker_fox 61 28 апреля, 2019 Опубликовано 28 апреля, 2019 · Жалоба 3 minutes ago, Forger said: Саму функцию рисования в это ОЗУ желательно защитить внутри мьютексом (необязательно). А если не обязательно, то что будет, если при перерисовке дисплея из ОЗУ какая-либо другая приоритетная задача напишет что-то? Не будет "муара" или "помех" на дисплее? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 26 28 апреля, 2019 Опубликовано 28 апреля, 2019 · Жалоба 13 minutes ago, haker_fox said: А если не обязательно, то что будет, если при перерисовке дисплея из ОЗУ какая-либо другая приоритетная задача напишет что-то? Не будет "муара" или "помех" на дисплее? 17 minutes ago, Forger said: При желании можно использовать ДВА видео-озу, чтобы картинка не "рассыпалась" Но чаще, где есть LCD, использую вот такое решение: рисовать только в одной задаче, а уже ей сообщать данные для отрисовки, данные по текущему пункту меню (если оно предусмотрено проектом). Задача, которая занимается отображением, никуда не девается. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 236 28 апреля, 2019 Опубликовано 28 апреля, 2019 · Жалоба 4 часа назад, Forger сказал: Да, безусловно есть минус - перерисовывается весь LCD независимо от того, менялось на нем что-то или нет. А зачем перерисовывать весь LCD (отправлять видеобуфер в LCD), если на нём ничего не меняется? Достаточно предусмотреть флаг "содержимое видеоОЗУ" модифицировано.И после каждой отправки на экран ещё запускать таймер (скажем на 30мс) и пока он не истечёт - не отправлять видеоОЗУ в LCD даже если этот флаг установился. Кроме самого флага, можно завести некую инфу, говорящую - какая именно область экрана менялась. Чтобы отправлять на LCD меньше данных. Если это даст какой-то выигрыш. 4 часа назад, Forger сказал: Но чаще, где есть LCD, использую вот такое решение: рисовать только в одной задаче, а уже ей сообщать данные для отрисовки, Именно так. Лучше отделять мух от котлет: получение и вычисление данных, от их отображения в видеоОЗУ. Многие задачи могут эти данные вычислять. И просто класть в ОЗУ. И ставить флажок: "такой-то блок данных изменился" и пинать задачу GUI. А уже одна единственная задача отрисовки пользовательского GUI будет эти данные переводить в картинку в видеоОЗУ. Этой же задаче легко завести таймаут от последней отрисовки, в течение которого она не будет реагировать на "пинания". Ведь нет смысла рисовать на экране чаще, чем пользователь способен воспринимать эти экранные изменения. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 26 28 апреля, 2019 Опубликовано 28 апреля, 2019 · Жалоба 1 hour ago, jcxz said: . Если это даст какой-то выигрыш. Вот именно: "если"! Но тут все легко посчитать. Для простых LCD мне проще все перерисовать, для TFT - там уже все совсем иначе, хотя можно поступить также "в лоб" как и с LCD, если производительность выбранного камня избыточна. Quote Ведь нет смысла рисовать на экране чаще, чем пользователь способен воспринимать эти экранные изменения. У меня RefreshRate для таких медленных LCD не бывает выше 5 Гц, поскольку опытным путем уже установил, что этого вполне хватает. 1 hour ago, jcxz said: Лучше отделять мух от котлет: получение и вычисление данных, от их отображения в видеоОЗУ. Многие задачи могут эти данные вычислять. Именно так и делаю, ибо нефик все в один котел складывать - пусть каждый, кому нужно что-то отобразить, потрудится и заранее подготовит число или даже готовую строку, вызвав заранее свой printf. Другими словами: снимаешь деньги с банкомата (в очереди), заранее приготовь пластик, чтобы не заставлять всю очередь ждать, пока его достанешь из своих закромов ;) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться