1、 linux的幾個狀態
freeze
standby
mem
disk
可在/sys/power中查看狀態
cd到/sys/power之後可以“cat state”查看支持的狀態
以root權限使用“echo xxx > /sys/power/state”來改變狀態。其中xxx可以是standby,freeze,mem,disk等
2、 選擇gpio
orange pi 3使用的是allwinner H6 CPU。它所有代喚醒(wakeup)功能的引腳都在PL口上。不同於PA、PB,PC,PD...等端口。這個端口在設備樹中的表示也是不同的:
PA~PK口分別用0~10表示。在設備樹中通常是這樣表示的 :
gpios = <&pio 0 11 GPIO_ACTIVE_HIGH>; // PA11
gpios = <&pio 3 9 GPIO_ACTIVE_HIGH>; // PD9
而PL口上通常這樣表示
gpios = <&r_pio 0 8 GPIO_ACTIVE_HIGH>; // PL8
可以看出分別PL口的獨特性.另外似乎PM也支持wakeup功能。
再有一個相關的問題就是gpio-keys的鍵碼可參考https://github.com/torvalds/linux/blob/master/include/uapi/linux/input-event-codes.h
這裏面定義了KEY_POWER,KEY_WAKEUP等的code。
4、 配置設備樹
4.1 編寫
編寫支持gpio-keys的dts文件.不妨叫做gpio-pin-wakeup.dts:
/dts-v1/;
/plugin/;
/ {
compatible = "allwinner,sun8i-h3";
fragment@0 {
target = <&pio>;
__overlay__ {
poweroff_pins:poweroff_pins {
allwinner,pins = "PA13";
allwinner,function = "gpio_out";
};
};
};
fragment@1 {
target-path = "/";
__overlay__ {
poweroff: poweroff {
compatible = "gpio-poweroff";
gpios = <&pio 0 13 1>;
};
};
};
};
注意PL10暫不能使用,因爲它已經被分配給了BT-WIFI-ON,具體可以查看原理圖。事實上如果不改動系統文件,目前只有PL8是可自由使用的。另外似乎PM也可用於喚醒源。但是它也已經被完全佔用了。
同時不妨再分配一個sleep按鈕,設備樹如下:
/dts-v1/;
/plugin/;
/ {
compatible = "allwinner,sun50i-h6";
/*
* This fragment is needed only for the internal pull-up activation,
* external pull-up resistor is highly recommended if using long wires
*/
fragment@0 {
target = <&pio>;
__overlay__ {
gpio_but_sleep: gpio_but_sleep {
pins = "PH3";
function = "gpio_in";
bias-pull-up;
};
};
};
fragment@1 {
target-path = "/";
__overlay__ {
gpio-keys-user {
/*
* Use "gpio-keys" for EINT capable pins, "gpio-keys-polled" for other pins
* add "poll-interval" property if using "gpio-keys-polled"
*/
compatible = "gpio-keys";
autorepeat;
pinctrl-names = "default";
pinctrl-0 = <&gpio_but_sleep>;
sleep_button {
label = "KEY_SLEEP";
linux,code = <142>; /* KEY_SLEEP, see include/uapi/linux/input-event-codes.h */
linux,input-type = <1>; // EV_KEY
gpios = <&pio 7 3 1>; /* PD15 GPIO_ACTIVE_LOW */
gpio-key;
};
};
};
};
};
將這個設備樹文件叫做gpio-key-sleep.dts
4.2 編譯
armbian支持arrmbian-add-overlay,但不幸的是它恰恰不支持H6.現需要自己編寫完成dts之後用dtc命令編譯成dtbo文件。
dtc -@ -q -I dts -O dtb -o gpio-key-wakeup.dtbo gpio-key-wakeup.dts
dtc -@ -q -I dts -O dtb -o gpio-key-sleep.dtbo gpio-key-sleep.dts
4.3 配置armbianEnv.txt
在其中添加一行:
user_overlays=gpio-key-wakeup gpio-key-sleep
5、測試
可進入root權限後使用
cat /sys/power來獲取當前支持的幾種sleep模式
使用echo xxx > /sys/power/state來進入想要的狀態
另外在配置之後還可以使用evtest來測試中斷源是否正常.
6、 流程歸納
首先選擇具有中斷可作爲喚醒源的按鍵,然後編寫設備樹dts源文件,編譯設備樹overlay的dtbo文件,接着將編譯好的dtbo文件放到/boot/overlay-user文件夾中。最後修改armbianEnv.txt文件,重啓系統。
儘管看似流程簡單,中間設計很多細節。竟然搞了兩天時間。總在細枝末節上折騰,什麼時候才能遊刃有餘?