C語言開源軟件Triggerhappy
想學習單片機的同學可以關注、私信我或者在評論區回覆我要入門。每個剛入門的嵌入式的朋友都想多找一些功能小巧、代碼質量高,可讀性好的開放性的小項目進行觀看和學習,主要的目的是錘鍊自己的知識,提高編程語言水平。
Triggerhappy (簡稱 thd)是一個輕量級的熱鍵守護程序 ( lightweight hotkey daemon )。它比較適合小型的嵌入式系統,例如基於 Linux的路由器。
Triggerhappy提供了系統級的熱鍵處理功能。它會監控指定的輸入設備文件,解析接收到的事件數據並根據配置文件執行用戶指定的操作 (user command)。例如你的設備的 UI是由 2個不同的程序分別處理前後端的,那麼你可以使用 Triggerhappy來處理 Home鍵以返回到前端 UI。
它會根據配置文件的內容,監測 /dev/input/event*設備,然後執行用戶預先配置的命令。
例如你的板子上有一個紅外接收器,你可以很輕鬆地使用 Triggerhappy來實現響應紅外遙控器的按鍵事件。
Triggerhappy非常的小巧,大約只有 80K,非常適合嵌入式場景。
Triggerhappy的代碼特點:
Triggerhappy的整體代碼風格和 Linux設備驅動的代碼風格很像,會用一個結構體來描述對象,然後用一個鏈表將多個對象管理起來。
功能劃分很清晰,大約有7、8個功能模塊,每一個模塊的實現都非常的乾淨利索,代碼一般情況下不超過 300行,而且比較統一。
綜合來看,符合 UNIX的設計哲學:簡單實用,且內容豐富,是一個非常適合練習 Linux應用編程的開源項目。
Triggerhappy怎麼用?
Triggerhappy的用法很簡單。
$ thd --dump /dev/input/event2
EV_KEY KEY_A 1 /dev/input/event2
EV_KEY KEY_A 0 /dev/input/event2
EV_KEY KEY_B 1 /dev/input/event2
EV_KEY KEY_B 0 /dev/input/event2
上面的命令會從 /dev/input/event2中讀取輸入事件,並打印出來。
另外,還可以通過配置文件設置事件處理器:
$ cat /etc/triggerhappy.d/triggerhappy.conf#
KEY_VOLUMEUP 1 /usr/bin/amixer set Master 5%+
KEY_VOLUMEUP 2 /usr/bin/amixer set Master 5%+
KEY_VOLUMEDOWN 1 /usr/bin/amixer set Master 5%-
KEY_VOLUMEDOWN 2 /usr/bin/amixer set Master 5%-
1表示 pressing,2表示 holding。
$ thd --triggers /etc/triggerhappy.d/triggerhappy.conf /dev/input/event*
這樣運行後,我們就可以通過 KEY_VOLUMEUP、KEY_VOLUMEDOWN控制音量了。
最後,Triggerhappy還支持通過 socket通訊進行命令行控制:
$ thd --socket /var/run/triggerhappy.socket --triggers /etc/triggerhappy.d/ /dev/input/event*
#動態添加或移除設備
$ th-cmd --socket /var/run/triggerhappy.socket --add /dev/input/event0
th-cmd --socket /var/run/triggerhappy.socket --remove /dev/input/event3
這是一種很實用的設計,工作裡,很多時候我發現自己都需要在不重新啓動程序的情況動態地通知程序做某些事情。
Triggerhappy怎麼實現?
Triggerhappy大致做了下面這些事情。
1、解析配置文件。
根據配置文件創建相應的 trigger,一個 1 trigger代表一條事件觸發規則,trigger都掛在鏈表 trigger_list上:
typedefstructtrigger{
inttype;//類型intcode;//鍵碼intvalue;//鍵值[...]
char*action;//事件發生時應執行的命令structtrigger*next;}trigger;
解析過程大致是使用 getline()讀取一行數據,然後用 strdup()複製出來,最後再用 strtok_r切割出按鍵、鍵值、執行命令。
2、創建 socket通訊、信號處理等輔助設施。
這些都是非核心功能,只是讓 Triggerhappy變得更易用。
intbind_cmdsocket(char*name);structcommand*read_command(intcmd_fd);intsend_command(intcmd_fd,enumcommand_typetype,char*param,intpassfd,intexclusive,char*tag);intconnect_cmdsocket(char*name);
Triggherhappy包含 2個可執行程序:後臺服務程序 thd,命令行工具 thd-cmd。
thd會調用 bind_cmdsocket()創建一個 local socket,thd-cmd通過 connect_cmdsocket()連接它。接着 thd-cmd可以通過 send_command()發送命令,thd則通過 read_command()接收命令。
3、根據命令行參數創建 devices。
1個 device代表 1個輸入設備,所有的 device都會掛在鏈表 device_list上。
typedefstructdevice{
intfd;
char*devname;
structdevice*next;}device;
voidadd_device(char*dev,intfd,intexcl,char*tag);intremove_device(char*dev);voidclear_devices(void);
add_device()會構造一個 device,並且 open()設備以得到文件描述符 fd。
4、不斷循環從所有 devices中讀取數據。
這個步驟是 Triggerhappy的核心功能,是一個基於 select()的eventloop。
這個 eventloop很簡單,就是用 select()檢測所有 devices,當有數據可讀時,對所有 devices都調用 read_event()讀取數據:
讀到數據後,會根據鍵值找到相應的 trigger,並執行 trigger對應的命令,實現方法就是 fork() + system():
到這裡Triggerhappy的核心部分我們就說完了。
本期先分享到這裡,想要進羣學習單片機編程的同學可以私信我,回覆“我要入門”,與我們一起成長,喜歡的可以點個贊關注我們!綜合來看,Triggerhappy符合 UNIX的設計哲學。它簡單實用,內容豐富,代碼清晰,是一個非常適合剛入門的嵌入式開發人員練習 Linux應用編程的開源項目。