Jump to content

    

Организация интерфейса к объекту внутри таска

1 час назад, topor_topor сказал:

 Но зачем другим полезним функциям MAIN  липнуть? Например можно продолжать реагировать на кнопки,  усреднять измерения АЦП итд. 

Я не знаю зачем. Я не предлагаю вам вешать остальные потоки. Я вам говорю, что если вы вынесете LCD/I2c в другой поток и сделаете реализацию как у haker_fox, то эффекта не получите. О чем вам haker_fox написал - "Другие в это время, да, курят бамбук". Если вы сделаете как у haker_fox, то при вызове MeasCore::sendMsg(), у вас MAIN  залипнет.

Share this post


Link to post
Share on other sites

А почему обязательно рисовать непосредственно на этом экране, т.е. напрямую?

Я уже давным-давно пошел по пути упрощения это задачи: выделяю ОЗУ (некое видео ОЗУ) для LCD, даже графического (монохромное).

Все потоки "рисуют" прямо в это ОЗУ. Отдельный поток периодически перерисовывает картинку из этого видео ОЗУ непосредственно в экран, ВСЮ картинку. Для таких LCD достаточно периодичности примерно до 5 раз в сек. Приоритет его низкий.

Саму функцию рисования в это ОЗУ желательно защитить внутри мьютексом (он не всегда требуется, это зависит от проекта).

Никаких очередей, списков, буферов, критических секций и т.п. анархизма. Все получается предельно просто и главное - функция рисования работает ооочень быстро и за прогнозируемое время (рисуем в ОЗУ).

Фактически нужно лишь отделить "мух от котлет" - рисование от отображения.

При желании можно использовать ДВА видео-озу, чтобы картинка не "рассыпалась", но это нужнее для TFT, а не LCD.

 

Для адептов экономии ОЗУ: монохромный графический LCD 320х240 в таком построении требует всего лишь ~10кБ ОЗУ. Не говорю уже про символьные LCD ...

Да, безусловно есть минус - перерисовывается весь LCD независимо от того, менялось на нем что-то или нет.

Но если провести замеры в реальном проекте заранее - замерить загрузку CPU при работающей только задаче перерисовки ЖК, то можно заранее эти данные учесть в проекте.

У меня в проектах работа с ЖК, построенным по описанной схеме, отъедает от даже убогого тщедушного проца от силы 1..2% процессорного времени.

 

Share this post


Link to post
Share on other sites
3 minutes ago, Forger said:

Саму функцию рисования в это ОЗУ желательно защитить внутри мьютексом (необязательно).

А если не обязательно, то что будет, если при перерисовке дисплея из ОЗУ какая-либо другая приоритетная задача напишет что-то? Не будет "муара" или "помех" на дисплее?

Share this post


Link to post
Share on other sites
13 minutes ago, haker_fox said:

А если не обязательно, то что будет, если при перерисовке дисплея из ОЗУ какая-либо другая приоритетная задача напишет что-то? Не будет "муара" или "помех" на дисплее?

 

17 minutes ago, Forger said:

При желании можно использовать ДВА видео-озу, чтобы картинка не "рассыпалась"

 

Но чаще, где есть LCD, использую вот такое решение: рисовать только в одной задаче, а уже ей сообщать данные для отрисовки, данные по текущему пункту меню (если оно предусмотрено проектом).

Задача, которая занимается отображением, никуда не девается.

Share this post


Link to post
Share on other sites
4 часа назад, Forger сказал:

Да, безусловно есть минус - перерисовывается весь LCD независимо от того, менялось на нем что-то или нет.

А зачем перерисовывать весь LCD (отправлять видеобуфер в LCD), если на нём ничего не меняется? Достаточно предусмотреть флаг "содержимое видеоОЗУ" модифицировано.И после каждой отправки на экран ещё запускать таймер (скажем на 30мс) и пока он не истечёт - не отправлять видеоОЗУ в LCD даже если этот флаг установился.

Кроме самого флага, можно завести некую инфу, говорящую - какая именно область экрана менялась. Чтобы отправлять на LCD меньше данных. Если это даст какой-то выигрыш.

4 часа назад, Forger сказал:

Но чаще, где есть LCD, использую вот такое решение: рисовать только в одной задаче, а уже ей сообщать данные для отрисовки,

Именно так. Лучше отделять мух от котлет: получение и вычисление данных, от их отображения в видеоОЗУ. Многие задачи могут эти данные вычислять. И просто класть в ОЗУ. И ставить флажок: "такой-то блок данных изменился" и пинать задачу GUI. А уже одна единственная задача отрисовки пользовательского GUI будет эти данные переводить в картинку в видеоОЗУ.

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

Share this post


Link to post
Share on other sites
1 hour ago, jcxz said:

. Если это даст какой-то выигрыш.

Вот именно: "если"!

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

Quote

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

У меня RefreshRate для таких медленных LCD не бывает выше 5 Гц, поскольку опытным путем уже установил, что этого вполне хватает.

 

 

1 hour ago, jcxz said:

Лучше отделять мух от котлет: получение и вычисление данных, от их отображения в видеоОЗУ. Многие задачи могут эти данные вычислять.

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

Другими словами: снимаешь деньги с банкомата (в очереди), заранее приготовь пластик, чтобы не заставлять всю очередь ждать, пока его достанешь из своих закромов ;)

 

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now