在底層 Linux Kernel 提供了時序(timing)機制,方便驅動程式設計者所使用,核心是依據硬體發出的『計時器中斷』來追蹤時間的流動狀況。我們可以依據 HZ 的值來設計 Delay 機制,讓驅動程式可以每隔固定一段時間啟動或者是發出訊號,也可以利用 Timer 來讓 LED 閃爍變化,在介紹 Timer API 之前,可以先參考 Linux Kernel: 簡介HZ, tick and jiffies 這篇文章,瞭解一些相關名詞,舉例:如果想知道一秒後的 jiffies 時間,可以寫成底下:
#ifdef CONFIG_BMA150_TIMER
#include #endif
j = jiffies;
/* 一秒之後 */
stamp_1 = j + HZ;
/* 半秒之後 */
stamp_1 = j + HZ/2; /* 20秒之後 */
stamp_1 = j + 20*HZ; Timer API 用法 筆記一下自己在寫 BOSCH Sensortec 三軸加速偵測器(BMA150 Sensor) Driver 的時候,遇到底層要回報 input event X,Y,Z 到 Android HAL(Hardware abstraction layer),所以利用 Timer 的機制定時 report 給 Android。 首先宣告:
[Read More]
[Linux Kernel] 簡單 hello world: License and Module 介紹(part 3)
在 Kernel 2.4 或以上版本,在編譯模組完成,要進行 load module 之前,你會發現底下訊息:
# insmod hello-3.o
Warning: loading hello-3.o will taint the kernel: no license
See http://www.tux.org/lkml/#export-tainted for information about tainted modules 很顯然這訊息是要您在 kernel module 裡面加上版權宣告,例如:"GPL","GPL v2"…等來宣告您的 module 並非 open source,利用 MODULE_LICENSE() 巨集來宣告程式 License,同樣的,可以用 MODULE_DESCRIPTION() 來描述此模組或者是 Driver 的功用跟簡介,以及用 MODULE_AUTHOR() 來定義此模組作者,這些巨集都可以在 linux/module.h 裡找到,但是這些並非用於 Kernel 本身,如果大家想看範例程式,可以到 drivers/ 資料夾底下觀看每一個 Driver 程式,底下是簡單 hello world 範例:
#include /* pr_info所需 include 檔案*/
#include #include /* 所有 module 巨集需要檔案*/
#include static int __init hello_init(void)
{
pr_info("
[Read More]
[Linux Kernel] 撰寫 Hello, World module: The __init and __exit Macros (part 2).
再看此篇之前,可以先閱讀作者先前寫的:『[Linux Kernel Driver] 撰寫簡單 Hello, World module (part 1).』,今天要介紹 Driver 的 init module 區別,在 Kernel 2.4 版本,您可以自行定義 init 跟 cleanup 函式,他們不再被個別稱為 init_module() 和 cleanup_module(),現在都使用 module_init() 和 module_exit() 兩大巨集,這兩函式被定義在 linux/init.h 檔案裡面,所以在寫程式務必將其 include 喔,另外一個核心模組(MODULE_LICENSE),用於讓核心知道此模組遵守自由授權條款,若沒這項宣告,核心會跟您抱怨的喔,底下為範例:
#include /* pr_info所需 include 檔案*/
#include #include /* 所有 module 需要檔案*/
#include MODULE_DESCRIPTION("Hello World !!");
MODULE_AUTHOR("Bo-Yi Wu ");
MODULE_LICENSE("GPL");
static int __init hello_init(void)
{
pr_info("Hello, world appleboy\n");
pr_info("The process is \"%s\" (pid %i)\n", current->comm, current->pid);
return 0;
}
static void __exit hello_exit(void)
{
printk(KERN_INFO "
[Read More]
[Linux Kernel] 撰寫簡單 Hello, World module (part 1).
來筆記如何在 Kernel 撰寫 hello world! module,在 Ubuntu Kernel 2.6.31-14 環境下撰寫,其實不難啦,首先先進入 Kernel 目錄,請在 /usr/src 底下看自己的系統版本,或者是利用 uname -r 來知道 Kernel 版本,底下是在 Ubuntu Kernel 2.6.31-14 Kernel 實做:
進入 Kernel 目錄 #
# cd Kernel directory
#
cd /usr/src/linux-headers-2.6.31-14-generic-pae 建立 hello 目錄 #
# mkdir directory
#
mkdir hello 建立 Makfile 以及 hello.c hello.c: #include /* pr_info 所需 include 檔案*/
#include #include /* 所有 module 需要檔案*/
#include MODULE_DESCRIPTION("Hello World !!");
MODULE_AUTHOR("Bo-Yi Wu ");
MODULE_LICENSE("GPL");
static int __init hello_init(void)
{
pr_info("
[Read More]
[Linux Kernel] built-in vs. module
在編譯 Android Linux Kernel 2.6.29 Driver,常常遇到該把 Driver 用 built-in 或者是編譯成 module 呢?這其實看人習慣,就跟問你編輯器是用 Vim 或者是 emacs 是同樣意思,這兩者是有很大的差異,built-in 用在開機自動讀取載入,所以直接編譯成 uImage 檔案給嵌入式系統,像是 SCSI 或者是 SATA Driver 都建議編譯成 built-in 的方式,反而是一些音效驅動程式,可以編譯成 module,NTFS 就是可以編譯成 module,等您需要的時候在動態載入就可以,這樣可以減少 Kernel Image 的使用空間。 如果不想用 built-in 編譯,開機又需要驅動程式,那就需要透過 initrd 方式來啟動。底下整理兩者差異:
built-in:
開機自動載入,不可移除 Linux Kernel Image 大 需要重新 Compile
module:
可動態載入 Linux Kernel Image 小 不需要重新 Compile reference: [gentoo-user] kernel: built-in vs. module