2011年9月8日星期四

timer using msleep

最近在改之前寫的slic driver,在送DTMF tone的時候會發生crash,如下:

To send DTMF CID sequence [A11111CR]
POL_FORWARD
getOffhook = 0
Freq1 : 13990
Freq2 : 4657
BUG: scheduling while atomic: ash/0x00000100/2020
Call Trace:
[<800074cc>] dump_stack+0x8/0x34
[<80219a04>] schedule+0x778/0x920
[<8021a7c4>] schedule_timeout+0x70/0xdc
[<80030a18>] msleep+0x24/0x34
[] playDtmfTone+0x148/0x6a4 [slic3217x]
[] playDtmfTone+0x598/0x6a4 [slic3217x]


看來root cause是因為在timer中用了msleep

造成它reschedule就crash

解決方式就是透過將timer的call時間拉長
讓Oscillators播放時間p_cid->dtmf_on_ms拉長一點

init_timer(&cid_dtmf_timer);
cid_dtmf_timer.function = cid_dtmf_do_timer;
cid_dtmf_timer.expires = jiffies + ms2jiffies(p_cid->dtmf_on_ms);
add_timer(&cid_dtmf_timer);


才不會造成dtmf signal lost

2010年9月15日星期三

取得 wifi parameters for linux kernel

想抓取wifi的資訊可利用linux kernel的struct netdev
所提供的struct iw_handler_def wireless_handlers來拿取
這是透過wireless_handlers內有個standard的指標函數,
可提供wireless device driver實作,
因此我們可透過standard指標函數來拿取wireless相關資訊

struct net_device
{
...
const struct iw_handler_def * wireless_handlers;
...
}


struct iw_handler_def
{
...
/* Array of handlers for standard ioctls
* We will call dev->wireless_handlers->standard[ioctl - SIOCSIWCOMMIT]
*/
const iw_handler * standard;
...
}


typedef int (*iw_handler)(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);


以zd1211rw driver為例:

#define WX(x) [(x)-SIOCIWFIRST]

static const iw_handler zd_standard_iw_handlers[] = {
WX(SIOCGIWNAME) = iw_get_name,
WX(SIOCGIWNICKN) = iw_get_nick,
WX(SIOCSIWFREQ) = iw_set_freq,
WX(SIOCGIWFREQ) = iw_get_freq,
...
};


可以看到這些Wireless Identification的定義:

/* Wireless Identification */
#define SIOCSIWCOMMIT 0x8B00
#define SIOCGIWNAME 0x8B01

#define SIOCSIWNWID 0x8B02 /* set network id (pre-802.11) */
#define SIOCGIWNWID 0x8B03 /* get network id (the cell) */
#define SIOCSIWFREQ 0x8B04 /* set channel/frequency (Hz) */
#define SIOCGIWFREQ 0x8B05 /* get channel/frequency (Hz) */
...
wireless.h:335:#define SIOCIWFIRSTPRIV 0x8BE0
wireless.h:351:#define SIOCIWFIRST 0x8B00


倘若我們想抓取frequency(channel) of current link ,

可直接call function
net_dev -> wireless_handlers ->
standard[SIOCGIWFREQ - SIOCSIWCOMMIT](net_dev, NULL, (void *) & my_freq, NULL);


然後透過my_freq.m就能抓取現在的freq

struct iw_freq my_freq;

struct iw_freq
{
__s32 m; /* Mantissa */
__s16 e; /* Exponent */
__u8 i; /* List index (when in range struct) */
__u8 flags; /* Flags (fixed/auto) */
};


進而推出wifi的rssi

2010年8月17日星期二

COSCUP 2010

今天的[COSCUP]在中研院舉辦,
去了第四年XD,還是一樣熱血,
而且今年參加人數大爆炸XD

今年的議程主要以Open Web and Mobile Technologies為主

以下為一些議程的心得:

Frontend Development Enviornment, josephj

這個議程滿有趣的,
透過將HTML/CSS/JavaScript 的模組化與自動化
可很嚴謹的制定模組policy
這個design pattern或許也可用於其他地方

Debugging: Linux Kernel by Ftrace, AceLan

Ftrace的工具, 可透過/proc的檔案系統來進行trace kernel function
但很可惜, 目前只僅次於function, 誰call誰, 誰被call

Be 「Android」, Tick Chen + Matt Hsu

很cool的機器人, 透過馬達 <-I2C-> ARM <-buletooth-> Android
來控制機器人, 可惜沒看到開全速的樣子XD

打造特製的 Android Toolchain, jserv

透過"搞系統程式絕對不是「不入流」"開場, 超high
jserv前輩很強~~
一路trace GNU Toolchain發展開發並發現android toolchain的git中無說明
無法自制android toolchain,因此開始打造從無到有的android toolchain,
超cool

2010年1月28日星期四

Add new system call

kernel版本:2.6.33-rc2

新增自行定義的system call步驟如下:

1. edit arch/x86/kernel/syscall_table_32.S, add

.long sys_mysystemcall /* 338 */

2. edit include/asm-i386/unistd.h, add

#define __NR_mysystemcall 338

3. create new file, arch/x86/kernel/systemcall.c
(defined filename yourself)

#include <linux/linkage.h>
#include <linux/kernel.h>

asmlinkage int sys_mysystemcall(void)
{
printk("mysystemcall\n");
return 0;
}


4. edit arch/x86/kernel/Makefile, add

obj-y += systemcall.o


5. compiler kernel

root@shulong-desktop:/home/shulong/linux-2.6.33-rc2# make clean && make


6. writing code for user mode, create new file test.c

#include <linux/unistd.h>
#include <sys/syscall.h>
#include <sys/types.h>

#define __NR_mysystemcall 338
#define mysystemcall() syscall(__NR_mysystemcall);

int main ()
{
mysystemcall();
return 0;
}


7. compiler test.c

root@shulong-desktop:~# gcc -Wall test.c -o systemcall

8. execute systemcall

root@shulong-desktop:~# ./systemcall
[ 39.289669] mysystemcall


就可順利加入自行定義的system call。

2009年10月30日星期五

GNU C Expand

1. __attribute__ ((variable attributes))

variable attributes:

• aligned
• deprecated
• mode
• nocommon
• packed
• section
• transparent_union
• unused
• vector_size
• weak

section ("section-name")'
extern void foobar (void) __attribute__ ((section ("bar")));
puts the function 『foobar' in the 『bar' section.


example:


#define subsys_initcall(fn) __define_initcall("4",fn,4)
//用來將指定的函數pointer fn放到initcall.init section
//是把fn放到.initcall.init的section.initcall4.init


initcall4.init defined in arch/i386/kernel/vmlinux.lds.S

.initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET)
{
*(.initcall1.init)
*(.initcall2.init)
*(.initcall3.init)
*(.initcall4.init)
*(.initcall5.init)
*(.initcall6.init)
*(.initcall7.init)
}


2. likely and unlikely

in include/linux/compiler.h

#define __builtin_expect(x, expected_value) (x)

#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)


example:

if(likely(value))
{
}
else
{
}


//看起來likely和unlikely是一樣的, 但事實上是有差異的
//likely表示value的值為true的可能性更大一些,那麼執行if的機會大;
//unlikely表示value的值為false的可能性大一些,執行else機會大一些。
//有了這種修飾,gcc編成組語後,
//會將likely使得if後面的執行語句緊跟著前面的;
//unlikely使得else後面的語句緊跟著前面的程序
//這樣就會可以讓cache預先讀取,
//目的是增加程序的執行速度

2009年10月6日星期二

Meld : Diff and merge tool

比較和合併code的工具,在windows上有[Araxis Merge],但它並非open source software,因此有[WinMerge]可以替代,而在linux上比較常見的是[KDiff3]和[Meld]。

而我最常用的是Meld,它的操作很容易就可上手。

2009年10月2日星期五

Coding tips, Vim顯示當前行

輸入":set cursorline".
或輸入":set cul".

取消當前行:
輸入":set no cursorline".
或輸入":set no cul"