用gpio來休眠與喚醒orange pi 3(armbian)

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文件,重啓系統。

儘管看似流程簡單,中間設計很多細節。竟然搞了兩天時間。總在細枝末節上折騰,什麼時候才能遊刃有餘?

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章