Как отключить/включить HDMI на Raspberry Pi?

Таким образом, я могу использовать «tvservice -o», чтобы отключить HDMI на Raspberry Pi, и «tvservice -p», чтобы снова включить его. После повторного включения мне, по-видимому, нужно выполнить «fbset -depth 8 && fbset -depth 16», чтобы снова включить буфер кадров, а затем принудительно перерисовать X11.

Мой вопрос в том, как мне это сделать в C? У меня есть приложение X11, и я могу без проблем управлять перерисовкой X11, но как отключить/повторно включить HDMI в C и как снова включить буфер кадров после повторного включения HDMI?

Чтобы дать представление, у меня есть безголовое приложение, работающее как своего рода медиа-сервер, управляемый приложением Android. В настоящее время я постоянно отключаю отключение HDMI после тайм-аута. Однако для экономии энергии я хотел бы отключить HDMI, когда приложение не используется, а затем снова включить его и отобразить приложение RPi на экране с помощью libcec, чтобы определить, когда телевизор использует соединение HDMI RPi для включения HDMI и выключенный.


person AlastairG    schedule 30.03.2015    source источник


Ответы (5)


Если вы хотите перейти на чистый C, посмотрите исходный код tvservice, который является программой C. Его можно найти на github. Похоже, он использует функцию vc_tv_hdmi_power_on_preferred();, определенную в #include "interface/vmcs_host/vc_tvservice.h".

Если вы решите вызвать программу tvservice, как в ответе @moffeltje, вы можете использовать execl(), это немного безопаснее - вы должны указать полный путь к двоичному файлу. (С помощью execlp вы также можете контролировать переменные среды):

pid_t pid;


pid = fork();
if (0 == pid) {
    execl("/opt/vc/bin/tvservice", "-p", NULL);
}
if (-1 == pid) {
    // Handle error here, close program?
}
person Prof. Falken    schedule 30.03.2015
comment
Мило, спасибо. Любая идея, где найти исходный код для fbset? Я подозреваю, что он использует ioctl, и без документации или примера кода на устройстве кадрового буфера я немного застрял. - person AlastairG; 30.03.2015
comment
@AlastairG, да, это должно быть в пакете util-linux: kernel.org/pub/linux/utils/util-linux, но если нет, просто погуглите, там тоже есть реализация busybox. - person Prof. Falken; 30.03.2015

Вы можете использовать команду system() для использования тех команд, которые вы описали.

int main(){

   //some code before disable hdmi
   system("tvservice -o");

   //do somethings when HDMI is disabled

   //turn HDMI back on
   system("tvservice -p");
   system("fbset -depth 8 && fbset -depth 16");

   return 0;

}
person moffeltje    schedule 30.03.2015
comment
Как правило, я избегаю системы. Я предпочитаю execl() и т. д., но для предпочтения я бы предпочел встроить функциональность в свою собственную программу. - person AlastairG; 30.03.2015

Из https://gist.github.com/AGWA/9874925 я нашел полезность chvt . Поэтому я предлагаю вызывать команды оболочки

hdmioff() { tvservice -o; }
hdmion() { tvservice -p; sudo chvt 1; sudo chvt 7; }

с системой().

person Frank Breitling    schedule 26.03.2017
comment
В моей текущей конфигурации мне нужно изменить команды chvt: hdmion() { tvservice -p; судо чвт 7; судо чвт 1; } - person alvaropg; 10.10.2018

Я нашел

xset dpms force on

чтобы обновить материал xorg после выполнения tvservice -o и вернуть его с помощью tvservice -p. Выполнение этого с помощью fbset у меня не очень хорошо сработало.

person Entrabiter    schedule 08.05.2015

У меня были лучшие результаты с cec-client.

sudo apt install cec-utils

Выключить монитор:

echo "standby 0" | cec-client -s -d 1

Включите монитор:

echo "on 0" | cec-client -s -d 1

person Roberto Focosi    schedule 04.07.2016
comment
Я спросил, как это сделать на C, а не в сценариях/командной строке. Более того, это просто отправляет команды CEC и фактически не меняет состояние физического порта HDMI (AFAIK). - person AlastairG; 10.08.2016