裝置驅動程式一向被認為是高深莫測的領域。或許是因為寫作的人需要了解作業系統、裝置硬體、界面規範、資料結構 …… 編譯環境建立以及編譯工具等等。洋洋灑灑五花八門,以至於繁雜生煩難,就難以掌握的了!讀者如果試著閱讀 notro 先生寫的
Examples on how to build various modules 之
【Hello World example】
Classic Hello World example for a loadable kernel module (LKM).
# 建立來源檔目錄且進入該目錄
mkdir hello && cd hello
# 建立 Makefile 編譯描述檔,內容為
obj-m := hello.o
# 寫作 hello.c 裝置原始碼,內容是
#include <linux/module.h>
#include <linux/kernel.h>
int hello_init(void)
{
pr_alert(“Hello World :)\n”);
return 0;
}
void hello_exit(void)
{
pr_alert(“Goodbye World!\n”);
}
module_init(hello_init);
module_exit(hello_exit);
# 執行編譯
make -C /lib/modules/$(uname -r)/build M=$(pwd) modules
# 將模組加入
sudo insmod hello.ko
# 檢查核心輸出訊息
dmesg | tail -1
[58728.008906] Hello World 🙂
# 把模組移除
sudo rmmod hello
# 檢查核心輸出訊息
dmesg | tail -1
[58732.440677] Goodbye World!
也許會覺得還好嘛!事實上程式就是程式,雖有領域與繁難之分,真的能有什麼其它不同的嗎!?比方說,
Adafruit 編譯的 PiTFT 核心版本上有一個『rpi_power_switch』︰
Extras!
Tactile switch as power button
Its a good idea to safely turn off your Pi with a good sudo shutdown -h now but that often means pulling out a keyboard or connecting to the console. With our kernel we added a cool module that will let you turn any GPIO into a power button. Since there’s a couple of tactile switches right there on the front, lets turn one into a power button. Press once to properly turn off the pi, press again to start it up. Isn’t that nice?
We’ll be using GPIO #23, the left-most button on a PiTFT 2.8″, on the 2.4″ HAT, #16 is a good choice since its on a tactile button. But, you can use any GPIO you want, really!
You will have to grab a pack of slim tactile switches or otherwise solder in a button
Add rpi_power_switch to /etc/modules and save
Now create a new conf file or edit our existing one with
sudo nano /etc/modprobe.d/adafruit.conf
and enter in the line
options rpi_power_switch gpio_pin=23 mode=0
Of course, change the gpio_pin setting to some other # if you wish. mode=0 means its a pushbutton not a switch. If you happen to install an on/off switch, use mode=1
這個模組在樹莓派基金會官方版 raspbian 上面沒有,雖然講 notro 先生的範例上也有,但是編譯後恐安裝不起來。作者隨興瀏覽網路文章時,曾聞有些人滿鍾情於這個模組,何不略為說說,也算對『驅動程式實務』有點交代的吧!假使能夠激發讀者的興趣,將來為自己打開一扇門,誠所願矣!!
其實當用『rpi-source』取得原始碼時,模組的『編譯環境』就已經建立完成。所欠的只是『適當版本』 gcc/g++ 而已。目前『jessie』repo 上的 gcc 版本是 4.8.4 ,依據作者實測,沒有什麼問題。茲將 notro 先生安裝與設定方法移譯如下︰
※ 註︰ gcc/g++ 更新至 4.9
【建立 jessie 程式庫來源】
建立 apt-get 『jessie.list』之來源檔
sudo nano /etc/apt/sources.list.d/jessie.list
內容為一行
deb http://mirrordirector.raspbian.org/raspbian/ jessie main contrib non-free rpi
【安裝】
# 更新資料庫快取
sudo apt-get update
# 安裝
sudo apt-get install -y gcc-4.8 g++-4.8
# 當執行安裝設定,問到『重啟服務』時,回答『Yes』。
# Package configuration
# Configuring libc6:armhf
# Restart services during package upgrades without asking?
# <Yes>
※ 需補裝 ncurses-devel
sudo apt-get install libncurses5-dev
【gcc/g++ 多重選擇環境設定】
可用
sudo update-alternatives –config gcc
選擇所要的 gcc/g++ 編譯環境。
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.6 20 sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.8 50 sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.6 20 sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.8 50
如是就將『編輯工具』建制完成了。
pi@raspberrypi ~ sudo update-alternatives --config gcc 替代項目 gcc(提供 /usr/bin/gcc)有 2 個選擇。 選項 路徑 優先權 狀態 ------------------------------------------------------------ * 0 /usr/bin/gcc-4.8 50 自動模式 1 /usr/bin/gcc-4.6 20 手動模式 2 /usr/bin/gcc-4.8 50 手動模式 按 [enter] 保留目前選項 [*],或輸入選項編號: pi@raspberrypi ~ cd cd fbtft_tools/rpi_power_switch/ sudo make install make -C /lib/modules/3.12.18+/build M=/home/pi/fbtft_tools/rpi_power_switch modules_install make[1]: Entering directory `/home/pi/linux-b09a27249d61475e4423607f7632a5aa6e7b3a53' INSTALL /home/pi/fbtft_tools/rpi_power_switch/rpi_power_switch.ko DEPMOD 3.12.18+ make[1]: Leaving directory `/home/pi/linux-b09a27249d61475e4423607f7632a5aa6e7b3a53'
先將 rpi_power_switch 模組編譯好。然後手動安裝
sudo cp rpi_power_switch.ko /lib/modules/4.1.4-v7+/kernel/drivers/power/ sudo depmod
這樣你就可以如前面 Adafruit PiTFT 文件所說的,將按鍵當成電源開關來使用。
sudo modprobe rpi_power_switch gpio_pin=17 mode=0
最後就讓我們再次回到『DS18B20』數位環境溫度感測器,當我們已經設定了『w1-gpio』的 dtoverlay ,也安裝了感測器,我們怎麼知道裝置正確工作了呢?也許可以用
pi@raspberrypi ~ cd /sys/bus/w1/devices/ # 28-021463ab43ff 某個『DS18B20』數位環境溫度感測器 pi@raspberrypi /sys/bus/w1/devices cd 28-021463ab43ff pi@raspberrypi /sys/bus/w1/devices/28-021463ab43ff cat name 28-021463ab43ff # 第一行的 YES 代表第二行溫度取得正確,若是 NO 代表溫度取得錯誤。 # 讀取溫度, t=35937 意味 35937/1000 = 35.937 °C pi@raspberrypi /sys/bus/w1/devices/28-021463ab43ff $ cat w1_slave 3f 02 55 00 7f ff 0c 10 89 : crc=89 YES 3f 02 55 00 7f ff 0c 10 89 t=35937
這個古怪的『類檔案裝置界面』顯然不怎麼對『使用者友善』 user friendly ,要是想一想所謂的『API』,指應用程式界面,原本就是設計給『程式』用的,自然就可以釋懷的了。即使是『程式』應用 ,『界面』也有使用上方便與否的問題,所以為『界面』再寫個易使用的『程式庫』,包裹成易記易讀的『新界面』也是常有的事。《 M♪o 之學習筆記本《巳》文章︰【䷡】藩決不羸》文本裡的 《W1ThermSensor》 就是這一類的『程式庫』。建議讀者閱讀它的『原始碼』《core.py》,思索設備『應用』以及『管理』方法,或將能夠對『程式實務』有更深的認識耶!!