[網站] 好站連結 (七) Android, javascript, Css, PHP, Perl, FreeBSD, Linux

Windows C# html apache javascript CSS php MySQL Perl FreeBSD MSSQL Android Linux C/C++ Network

[PHP] GoEz Framework

[Kernel Driver] 撰寫簡易 Timer 機制

在底層 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。 首先宣告:
#ifdef CONFIG_BMA150_TIMER
#include 
#endif
/* 定義 timer_list struct */
#ifdef CONFIG_BMA150_TIMER
struct timer_list bma150_report_timer;
#endif
在 Driver 內的 bma150_probe 裡面 call function:
#ifdef CONFIG_BMA150_TIMER
  bma150_init_timer();
#endif
撰寫 bma150_init_timer 函式:
#ifdef CONFIG_BMA150_TIMER
static void bma150_init_timer(void)
{  
  D("BMA150 init_timer start\n");
  /* Timer 初始化 */
  init_timer(&bma150_report_timer);
  /* 定義 timer 所執行之函式 */
  bma150_report_timer.function = bma150_report;
  /* 定義 timer 傳入函式之 Data */
  bma150_report_timer.data = ((unsigned long) 0);
  /* 定義 timer Delay 時間 */
  bma150_report_timer.expires = jiffies + BMA150_REPORT_DELAY_1;
  /* 啟動 Timer*/
  add_timer(&bma150_report_timer); 
}
#endif 
上述 add_timer 執行之後,會在一秒後執行 bma150_report 函式,執行之後就會停止,所以如果要一直產生迴圈,就必須在 bma150_report 裡面繼續加入 add_timer,改寫如下:
static int bma150_report(void)
{
  D("appleboy: test timer. \n");
#ifdef CONFIG_BMA150_TIMER
  bma150_report_timer.expires = jiffies + BMA150_REPORT_DELAY_2;
  add_timer(&bma150_report_timer);
#endif 
  return 0;
}
我們可以重新定義 expires 時間 jiffies + BMA150_REPORT_DELAY_2,就可以一直循環了,要離開 Timer 可以在最後加入 deltimer(&bma150_report_timer),最後就完成簡易的 Timer 功能。 參考: add_timer的使用方法 Linux Kernel: 簡介HZ, tick and jiffies

[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("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 "Goodbye\n");
}
MODULE_DESCRIPTION("Hello World !!");/* 此程式介紹與描述*/
MODULE_AUTHOR("Bo-Yi Wu ");/* 此程式作者*/
MODULE_LICENSE("GPL");/* 程式 License*/
module_init(hello_init);
module_exit(hello_exit);
在 linux/module.h 裡頭,可以找到 MODULE_LICENSE 可定義的 License
/*
 * The following license idents are currently accepted as indicating free
 * software modules
 *
 *	"GPL"				[GNU Public License v2 or later]
 *	"GPL v2"			[GNU Public License v2]
 *	"GPL and additional rights"	[GNU Public License v2 rights and more]
 *	"Dual BSD/GPL"			[GNU Public License v2
 *					 or BSD license choice]
 *	"Dual MIT/GPL"			[GNU Public License v2
 *					 or MIT license choice]
 *	"Dual MPL/GPL"			[GNU Public License v2
 *					 or Mozilla license choice]
 *
 * The following other idents are available
 *
 *	"Proprietary"			[Non free products]
 *
 * There are dual licensed components, but when running with Linux it is the
 * GPL that is relevant so this is a non issue. Similarly LGPL linked with GPL
 * is a GPL combined work.
 *
 * This exists for several reasons
 * 1.	So modinfo can show license info for users wanting to vet their setup 
 *	is free
 * 2.	So the community can ignore bug reports including proprietary modules
 * 3.	So vendors can do likewise based on their own policies
 */
巨集 define:
#define MODULE_LICENSE(_license) MODULE_INFO(license, _license)

/*
 * Author(s), use "Name " or just "Name", for multiple
 * authors use multiple MODULE_AUTHOR() statements/lines.
 */
#define MODULE_AUTHOR(_author) MODULE_INFO(author, _author)

/* What your module does. */
#define MODULE_DESCRIPTION(_description) MODULE_INFO(description, _description)

[高雄美食]道明中學武廟路好吃愛嬌姨臭豆腐

IMG_1290

我相信在高雄要吃到好吃的臭豆腐,無非就是豪記臭豆腐,大家可以參考懶喵兒滴窩:『[高雄-三民]豪記臭豆腐王【港式臭豆腐專賣店】 (新址)』,但是這次要來介紹也許在高雄比較少人知道的路邊攤臭豆腐,它位於高雄市武廟路上一間不起眼的臭豆腐,道明中學對面巷子走進去接到武廟路就可以吃到了,營業時間是下午15:30~19:40,時間不長,但是大排長龍阿,想要去吃的,最好不要挑晚餐時間,因為自己那個時間去吃,至少等了半小時。

Continue reading “[高雄美食]道明中學武廟路好吃愛嬌姨臭豆腐”

[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 "Goodbye\n");
}

module_init(hello_init);
module_exit(hello_exit);
編譯過程,可以自行修改 Makefile,可以打開 kernel/android-2.6.29/drivers/i2c/chips/Makefile 參考範例,您會發現很多類似底下寫法:
obj-$(CONFIG_TWL4030_POWEROFF)  += twl4030-poweroff.o
obj-$(CONFIG_TWL4030_MADC)  += twl4030-madc.o
obj-$(CONFIG_RTC_X1205_I2C) += x1205.o
obj-$(CONFIG_SENSORS_BOSCH_BMA150)  += bma150.o
如果要編譯成 module 可以設定成 obj-m += bma150.o,編譯到 Kernel image,則會寫成 obj-y += bma150.o,然而 $(CONFIG_SENSORS_BOSCH_BMA150) 是從 make menuconfig 設定,當然為什麼 menuconfig 會出現此設定,那就要從 kernel/android-2.6.29/drivers/i2c/chips/Kconfig 裡面加入 CONFIG_SENSORS_BOSCH_BMA150 設定, 選好之後,觀看 Kernel 資料夾底下的 .config 內容,看到 CONFIG_SENSORS_BOSCH_BMA150=y,這樣就正確了。

What is different of __init and __exit?

在寫 G-Senser Driver 時候,您會發現 static int __init BMA150_init(void) 跟 static void __exit BMA150_exit(void),跟平常寫 C 語言宣告函式不一樣吧,這兩個巨集分別有不同意義喔,當然也可以將 span style=”color:red”>__init 跟 __exit 拿掉,這不會影響 Driver 的編譯,但是會影響記憶體的優化,Driver 啟動時會呼叫 BMA150_init 函式,如果有加上 __init,當此 init function 執行完,會將記憶體 Release 給系統,這是針對 built-in 的方式才適用,如果是編譯成模組方式,則不會有此功能,然而 __exit 是 Driver 結束後會呼叫的 function,但是跟 __init 剛好功能相反,在 built-in 的 Kernel 映像檔並不會執行到 __exit,編譯成模組才會有釋放記憶體效果,這兩巨集可以參考 linux/init.h 檔案。

ProFTPD UseEncoding 繁體中文亂碼解決 Localization

Proftpd ProFTPD 一直都是我最喜歡使用的 FTP 伺服器,設定方式簡單淺顯易懂,最近在用 PSPad 寫程式,發現使用內建 FTP 功能時候,連不上 FreeBSD 架設的 ProFTPD,連線過程出現許多亂碼,所以造成 PSPad 斷線出現錯誤,解決方式就是利用 mod_lang 模組,設定 UseEncoding 讓系統可以顯示 Big5 中文編碼,FreeBSD Ports 請勾選
[X] NLSUOTA Use nls (builds mod_lang)
自行編譯請按照底下步驟
./configure --enable-nls
make
make install 

UseEncoding 設定

Syntax: UseEncoding on|off|local-charset client-charset
Default: None
Context: "server config", , 
Module: mod_lang
Compatibility: 1.3.2rc1
在 1.3.2rc1 版本之後才有支援,請複製底下設定,貼到 proftpd.conf
# 简体中文環境
UseEncoding UTF-8 GBK
# 繁体中文環境
UseEncoding UTF-8 Big5
Reference: ProFTPD module mod_lang centos上解決proftp中文亂碼問題