最近在處理driver 效率問題,要很在乎每個宣告實際的大小,還有type的大小
sizeof 就常常用,還好arm 板子上跟pc 的沒差太多...
但!!! 還是得小心用阿 囧>
以下是用sizeof 在系統上求出
--
首先
int 是 4 bytes (32bits)
char 是 1
--
常常用sizeof 不只求位元大小還可以用來求長度
筆記幾個要小心的地方:
char *str = "0123456789"
sizeof(str) ==>4
sizeof(*str) ==> 1
<<不要對指標亂來取來這招 囧!!!>>
char str[] = "0123456789"
sizeof(str) ==>11個(\0)
sizeof(*str) ==> 1
但是
char str[100] = "0123456789"
sizeof(str) ==>100
<<亂來沒好處阿!!! 那可不是字串大小!!!>>
int value[100];
value[0] = 10;
sizeof(value) ==>400 (4*100)
因為char 是1 int 是4
---
所以sizeof 是用來算記憶體大小,在complier時期就會知道的數字,要找長度
還是乖乖用strlen()唷~~~
那個... 執行期間的sizeof是邪魔歪道(誤
2010年12月1日 星期三
[Linux] vim 加速上班的心情
Vim 有多好用就不用說了,(其實也沒多好用,就編輯器而已 = =)
記錄一下。
以下操作都在
編輯 /etc/vim/vimrc
if has("autocmd")
au BufReadPost * if line("'\"") > 0 && line("'\"") <= line("$")
\| exe "normal! g'\"" | endif
endif
map <F8> :set hls!<BAR>set hls?<CR>
map <f9> :Tlist<CR>
a: 全部模式都可以用滑鼠
v: Visual mode
n: Normal mode
i: insert mode
其他模式就不列了。
不用a的話可以用
set mouse=vn
把各種模式串起來
記錄一下。
以下操作都在
編輯 /etc/vim/vimrc
- 讓你的vim 看得懂C 語言的特徵!!!
- 每次開啟檔案都會自動跳到上一次停留的地方(這太重要了~讓你工作馬上回神)
if has("autocmd")
au BufReadPost * if line("'\"") > 0 && line("'\"") <= line("$")
\| exe "normal! g'\"" | endif
endif
- 讓找的字便亮一點啊
- 自訂熱鍵
map <F8> :set hls!<BAR>set hls?<CR>
map <f9> :Tlist<CR>
- 打開滑鼠支援(我還沒適應用滑鼠 囧>)
a: 全部模式都可以用滑鼠
v: Visual mode
n: Normal mode
i: insert mode
其他模式就不列了。
不用a的話可以用
set mouse=vn
把各種模式串起來
2010年10月4日 星期一
[Linux] 不聽使喚的Proxy for APT
如果在特殊的環境裡面(如:學校,公司)
使用APT常常會需要proxy來幫忙下載軟體包,可是有時候明明已經修好改proxy路徑,卻不聽使喚。APT有時候很搞怪阿。
通常更換APT的proxy有
/etc/apt/apt.conf
裡面填寫:
Acquire::http::proxy "http://XXX.XXX.XXX:3128/";
即可。
不過有時候不會動。(棍!
或是去GUI填寫
Network proxy
然後按下去"apply System-wide"
即可
不過有時候也不會動。(幹!!
執行之後會噴
"111 Connection refused"
也就是說他還是讀取舊的或是不正確的proxy,原因在於apt讀取的是
$http_proxy <--這個全域變數
echo $http_proxy
可以看到。
修改法
export http_proxy=http://XXX.XXX.XXX:3128
增加到全域去即可。
當然重新開terminal會不見
可以考慮寫進去
/.bashrc
裡
使用APT常常會需要proxy來幫忙下載軟體包,可是有時候明明已經修好改proxy路徑,卻不聽使喚。APT有時候很搞怪阿。
通常更換APT的proxy有
/etc/apt/apt.conf
裡面填寫:
Acquire::http::proxy "http://XXX.XXX.XXX:3128/";
即可。
不過有時候不會動。(棍!
或是去GUI填寫
Network proxy
然後按下去"apply System-wide"
即可
不過有時候也不會動。(幹!!
執行之後會噴
"111 Connection refused"
也就是說他還是讀取舊的或是不正確的proxy,原因在於apt讀取的是
$http_proxy <--這個全域變數
echo $http_proxy
可以看到。
修改法
export http_proxy=http://XXX.XXX.XXX:3128
增加到全域去即可。
當然重新開terminal會不見
可以考慮寫進去
/.bashrc
裡
2010年6月2日 星期三
[Linux] 你不知道的 echo
靠腰~~~
是我自己不知道的echo.... T__T
感覺有個小BUG死在這個小細節.... 而且還不是我弄的
code 裡面用system call 的echo 跟 console 下面手打的反應竟然不同....
Orz... 用男人問了一下echo 才知道 囧>
通常echo就是拿來回呼你打入的字串,或者是把字串傳入某個目的檔
如: echo "bejo" > bejo.txt
(題外話: 還搞不清楚 " " 符號 跟 ' ' 在echo 使用上有差別嗎?)
echo command 也是有參數的
-e: 允許用跳脫符號 ( \ )
-n: 結束不要自動換行(預設會)
-E: 不允許用跳脫符號(預設)
看起來沒啥問題就出在一些tty dev用echo 餵參數的時候會卡在換行,特殊符號等等
所以應該要
echo -ne "bejo is \"8787\"\n" > /dev/ttyXXX
要加上參數... 嗚~~真痛O__Q
紀錄幾個跳脫常用的
\n 換行
\a 發出逼逼聲
\b 往前刪除一個字( backspace)
\r 往前整行刪掉
特別的是
\0NNN NNN是十進位 可以echo 出 ascii 上的字元
例如:
echo -e "\0100" 印出 @
\xHH HH 是16進位
echo -e "\x40" 效果跟上面的一樣 印出@
詳細對照可以
man ascii 查詢
------------------------
echo 也可以改變console顏色
分為前景跟背景
echo -e "\E[31;42mBEJO\n"
m後面就是跟著你想顯示的文字內容
前景是紅 31
背景是綠 42
數字對調沒差,因為定義不重疊
我用烏幫兔玩一下然後...console 變的很噁心,可以用
echo -ne \E[0m
加在字尾也可
echo -e "\E[31;42mBEJO\E[0m"
復原
下面是網路查到對應表:
-------------------------------
前 背
黑 30 40
紅 31 41
綠 32 42
黃 33 43
藍 34 44
青 36 46
白 37 47
聽說不是每個終端機都一樣,阿災~
是我自己不知道的echo.... T__T
感覺有個小BUG死在這個小細節.... 而且還不是我弄的
code 裡面用system call 的echo 跟 console 下面手打的反應竟然不同....
Orz... 用男人問了一下echo 才知道 囧>
通常echo就是拿來回呼你打入的字串,或者是把字串傳入某個目的檔
如: echo "bejo" > bejo.txt
(題外話: 還搞不清楚 " " 符號 跟 ' ' 在echo 使用上有差別嗎?)
echo command 也是有參數的
-e: 允許用跳脫符號 ( \ )
-n: 結束不要自動換行(預設會)
-E: 不允許用跳脫符號(預設)
看起來沒啥問題就出在一些tty dev用echo 餵參數的時候會卡在換行,特殊符號等等
所以應該要
echo -ne "bejo is \"8787\"\n" > /dev/ttyXXX
要加上參數... 嗚~~真痛O__Q
紀錄幾個跳脫常用的
\n 換行
\a 發出逼逼聲
\b 往前刪除一個字( backspace)
\r 往前整行刪掉
特別的是
\0NNN NNN是十進位 可以echo 出 ascii 上的字元
例如:
echo -e "\0100" 印出 @
\xHH HH 是16進位
echo -e "\x40" 效果跟上面的一樣 印出@
詳細對照可以
man ascii 查詢
------------------------
echo 也可以改變console顏色
分為前景跟背景
echo -e "\E[31;42mBEJO\n"
m後面就是跟著你想顯示的文字內容
前景是紅 31
背景是綠 42
數字對調沒差,因為定義不重疊
我用烏幫兔玩一下然後...console 變的很噁心,可以用
echo -ne \E[0m
加在字尾也可
echo -e "\E[31;42mBEJO\E[0m"
復原
下面是網路查到對應表:
-------------------------------
前 背
黑 30 40
紅 31 41
綠 32 42
黃 33 43
藍 34 44
青 36 46
白 37 47
聽說不是每個終端機都一樣,阿災~
2010年6月1日 星期二
[Linux] Ethernet driver 骨架
算一算已經自願調到driver team 好一陣子了,從user space 寫到kernel space感覺上似乎沒改變太多,每天還是看code,需要動手大改的機會都不多,大概這就是系統廠的宿命。
不過誰說工作要求才能寫,XD 最近邊debug ethernet driver,乾脆就動手自己寫一個註冊net device...
這樣就更清楚了整個flow了。
底下附上的code都是拿掉硬體IO reg 等等相關,一來只是要紀錄如果從無到有寫一個,二來硬體資料百百款跟vendor拿到spec 在接上就可以,有空再補哩。
net device 的註冊已經是很普遍了,只要自己建好下面幾個function 就可以動了。
當然
不包含NAPI,沒寫 poll,沒有ioctl (通常拿來改MAC), device status, config 等等都沒有XD
-----------------
static void do_bth_tx(u_char *buffer, u_short len)
static void do_bth_rx(void)
static irqreturn_t bth_interrupt(int irq, void *dev_id, struct pt_regs *regs)
static int bth_open(struct net_device *dev)
static int bth_stop(struct net_device *dev)
static int bth_xmit(struct sk_buff *skb, struct net_device *dev)
void bth_tx_timeout(struct net_device *dev)
int bth_init(struct net_device *dev)
static int __init bth_dev_init(void)
static void __exit bth_dev_exit(void)
-----------------------------------------------------------------------------
#include <linux/module.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <asm/irq.h>
#include <asm/io.h>
struct bth{
spinlock_t lock;
}; // 裡面要建構硬體私有的宣告,不需要的都拿掉了。
static struct net_device *bth_dev = NULL;
static void do_bth_tx(u_char *buffer, u_short len)
{
//接硬體的部份拿掉了
char shortpkt[ETH_ZLEN];
if(len < ETH_ZLEN)
{
memset(shortpkt, 0X0, ETH_ZLEN);
memcpy(shortpkt, buffer, len);
len = ETH_ZLEN;
buffer = shortpkt;
}
printk("%x\n", buffer);
printk("bth_tx_done the bth dev! \n");
}
static void do_bth_rx(void)
{
struct net_device *dev = bth_dev;
// struct bth *bthx = (struct bth *)dev->priv;
struct sk_buff *skb;
int frame_len = 1500; // it needs read form phy
skb = dev_alloc_skb(frame_len + 2);
skb_reserve(skb, 2);
skb->dev = dev;
skb_put(skb, frame_len);
skb->protocol = eth_type_trans(skb, dev);
netif_rx(skb);
dev->trans_start = jiffies;
printk("bth_packet_receive the bth dev!\n");
}
static irqreturn_t bth_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
//中斷產生時呼叫,內容化簡
do_bth_rx();
return IRQ_HANDLED;
}
static int bth_open(struct net_device *dev)
{
// ifconfig up 會呼叫
if(request_irq(dev->irq, &bth_interrupt, 0, dev->name, dev))
return -EAGAIN;
netif_start_queue(dev);
printk("open the bth dev! \n");
return 0;
}
static int bth_stop(struct net_device *dev)
{
//ifconfig down 會呼叫
netif_stop_queue(dev);
free_irq(dev->irq, dev);
printk("bth dev STOP!!! \n");
return 0;
}
static int bth_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct bth *bthx = (struct bth *)dev->priv;
unsigned long flags;
spin_lock_irqsave(&bthx->lock, flags);
dev->stats.tx_bytes += skb->len;
dev->stats.tx_packets++;
do_bth_tx(skb->data,skb->len);
dev->trans_start = jiffies;
spin_unlock_irqrestore(&bthx->lock, flags);
printk("hard start xmit the bth dev! \n");
return 0;
}
void bth_tx_timeout(struct net_device *dev)
{
//tx timeout 的時候呼叫
printk("TIMEOUT the bth dev! \n");
dev->trans_start = jiffies;
netif_wake_queue(dev);
}
int bth_init(struct net_device *dev)
{
//這裡接上,基本上就可以看到interface了
struct bth *bthx;
int i;
unsigned char mac_addr[6] = {0x00, 0x11, 0x22, 0x33, 0x99, 0x99}; // 通常是從REG或另外的記憶體讀出,這裡寫死
bthx = (void *)kmalloc(sizeof(struct bth), GFP_KERNEL);
memset(bthx, 0, sizeof (struct bth));
if (!dev)
{
printk(": unable to allocate etherdev\n");
return 1;
}
ether_setup(dev);
dev->priv = bthx;
dev->open = bth_open;
dev->stop = bth_stop;
dev->hard_start_xmit = bth_xmit;
dev->tx_timeout = bth_tx_timeout;
for (i = 0; i < 6; i++)
dev->dev_addr[i] = mac_addr[i];
return 0;
}
static int __init bth_dev_init(void)
{
bth_dev = alloc_netdev(sizeof(struct bth), "bth%d", bth_init);
register_netdev(bth_dev);
printk("init the bth dev! \n");
return 0;
}
static void __exit bth_dev_exit(void)
{
unregister_netdev(bth_dev);
free_netdev(bth_dev);
kfree(bth_dev->priv);
printk("bth dev exit!! \n");
}
module_init(bth_dev_init);
module_exit(bth_dev_exit);
不過誰說工作要求才能寫,XD 最近邊debug ethernet driver,乾脆就動手自己寫一個註冊net device...
這樣就更清楚了整個flow了。
底下附上的code都是拿掉硬體IO reg 等等相關,一來只是要紀錄如果從無到有寫一個,二來硬體資料百百款跟vendor拿到spec 在接上就可以,有空再補哩。
net device 的註冊已經是很普遍了,只要自己建好下面幾個function 就可以動了。
當然
不包含NAPI,沒寫 poll,沒有ioctl (通常拿來改MAC), device status, config 等等都沒有XD
-----------------
static void do_bth_tx(u_char *buffer, u_short len)
static void do_bth_rx(void)
static irqreturn_t bth_interrupt(int irq, void *dev_id, struct pt_regs *regs)
static int bth_open(struct net_device *dev)
static int bth_stop(struct net_device *dev)
static int bth_xmit(struct sk_buff *skb, struct net_device *dev)
void bth_tx_timeout(struct net_device *dev)
int bth_init(struct net_device *dev)
static int __init bth_dev_init(void)
static void __exit bth_dev_exit(void)
-----------------------------------------------------------------------------
#include <linux/module.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <asm/irq.h>
#include <asm/io.h>
struct bth{
spinlock_t lock;
}; // 裡面要建構硬體私有的宣告,不需要的都拿掉了。
static struct net_device *bth_dev = NULL;
static void do_bth_tx(u_char *buffer, u_short len)
{
//接硬體的部份拿掉了
char shortpkt[ETH_ZLEN];
if(len < ETH_ZLEN)
{
memset(shortpkt, 0X0, ETH_ZLEN);
memcpy(shortpkt, buffer, len);
len = ETH_ZLEN;
buffer = shortpkt;
}
printk("%x\n", buffer);
printk("bth_tx_done the bth dev! \n");
}
static void do_bth_rx(void)
{
struct net_device *dev = bth_dev;
// struct bth *bthx = (struct bth *)dev->priv;
struct sk_buff *skb;
int frame_len = 1500; // it needs read form phy
skb = dev_alloc_skb(frame_len + 2);
skb_reserve(skb, 2);
skb->dev = dev;
skb_put(skb, frame_len);
skb->protocol = eth_type_trans(skb, dev);
netif_rx(skb);
dev->trans_start = jiffies;
printk("bth_packet_receive the bth dev!\n");
}
static irqreturn_t bth_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
//中斷產生時呼叫,內容化簡
do_bth_rx();
return IRQ_HANDLED;
}
static int bth_open(struct net_device *dev)
{
// ifconfig up 會呼叫
if(request_irq(dev->irq, &bth_interrupt, 0, dev->name, dev))
return -EAGAIN;
netif_start_queue(dev);
printk("open the bth dev! \n");
return 0;
}
static int bth_stop(struct net_device *dev)
{
//ifconfig down 會呼叫
netif_stop_queue(dev);
free_irq(dev->irq, dev);
printk("bth dev STOP!!! \n");
return 0;
}
static int bth_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct bth *bthx = (struct bth *)dev->priv;
unsigned long flags;
spin_lock_irqsave(&bthx->lock, flags);
dev->stats.tx_bytes += skb->len;
dev->stats.tx_packets++;
do_bth_tx(skb->data,skb->len);
dev->trans_start = jiffies;
spin_unlock_irqrestore(&bthx->lock, flags);
printk("hard start xmit the bth dev! \n");
return 0;
}
void bth_tx_timeout(struct net_device *dev)
{
//tx timeout 的時候呼叫
printk("TIMEOUT the bth dev! \n");
dev->trans_start = jiffies;
netif_wake_queue(dev);
}
int bth_init(struct net_device *dev)
{
//這裡接上,基本上就可以看到interface了
struct bth *bthx;
int i;
unsigned char mac_addr[6] = {0x00, 0x11, 0x22, 0x33, 0x99, 0x99}; // 通常是從REG或另外的記憶體讀出,這裡寫死
bthx = (void *)kmalloc(sizeof(struct bth), GFP_KERNEL);
memset(bthx, 0, sizeof (struct bth));
if (!dev)
{
printk(": unable to allocate etherdev\n");
return 1;
}
ether_setup(dev);
dev->priv = bthx;
dev->open = bth_open;
dev->stop = bth_stop;
dev->hard_start_xmit = bth_xmit;
dev->tx_timeout = bth_tx_timeout;
for (i = 0; i < 6; i++)
dev->dev_addr[i] = mac_addr[i];
return 0;
}
static int __init bth_dev_init(void)
{
bth_dev = alloc_netdev(sizeof(struct bth), "bth%d", bth_init);
register_netdev(bth_dev);
printk("init the bth dev! \n");
return 0;
}
static void __exit bth_dev_exit(void)
{
unregister_netdev(bth_dev);
free_netdev(bth_dev);
kfree(bth_dev->priv);
printk("bth dev exit!! \n");
}
module_init(bth_dev_init);
module_exit(bth_dev_exit);
2010年4月30日 星期五
[Linux] 少用但是你被卡住時好用的指令 fuser and lsof
小微微常常刪檔或是改檔的時候會跟你靠腰說"檔案正在使用中...",讓你不能刪除檔案,但有時候還是不知道誰在用,linux下面也有。
fuser
Show which processes use the named files, sockets, or filesystems
lsof
list open files
多好用?
欲哭無淚的時候,很好用.....
紀錄幾個常用用法
fuser -v -mu /home/bejo
fuser -v -mu /proc
-v: 不加沒辦法閱讀啦
查看目錄或是檔案被誰用。查proc妙用無窮(疑?
也可以用來砍掉再用的process,不過...
lsof -i
-i 查哪些程式在用網路資源...(上次TFTP就是這樣找出來的 囧>)
lsof -u root
查root用了哪些東西
組合起來就可以用
lsof -u root -a -i
查root開了哪些網路程式
-a: 用來組合其他條件,例如 -i
有程式亂活動馬上就知道@__@!!!
fuser
Show which processes use the named files, sockets, or filesystems
lsof
list open files
多好用?
欲哭無淚的時候,很好用.....
紀錄幾個常用用法
fuser -v -mu /home/bejo
fuser -v -mu /proc
-v: 不加沒辦法閱讀啦
查看目錄或是檔案被誰用。查proc妙用無窮(疑?
也可以用來砍掉再用的process,不過...
lsof -i
-i 查哪些程式在用網路資源...(上次TFTP就是這樣找出來的 囧>)
lsof -u root
查root用了哪些東西
組合起來就可以用
lsof -u root -a -i
查root開了哪些網路程式
-a: 用來組合其他條件,例如 -i
有程式亂活動馬上就知道@__@!!!
2010年4月28日 星期三
[小微微]開機指令檔/關機指令檔
最近想放棄WINXP換系統.....
可是發現我一窮二白...買不起W7
只好整理開機流程加快一下系統O__Q
XP系統如果想在登入帳號之前執行使用者想要執行的動作,如COPY檔案、檢查檔案、撥PPPoE連線等等
埋在"啟動"資料夾、排程、系統服務都不適當
應該要放在
開始=>執行=>gpedit.msc (就是群組原則啦)
電腦設定=>windows設定=>將 [開機指令檔] 指向 想執行的程式(*.BAT也可)。
這也提供[關機指令檔] (用新增的) 可以在關機的時候做。
類似linux的S60_XXX,S99_XXX 開機執行,跟rc file的執行階段不大一樣。
會在Windowns登入使用者之前就執行。
看來想換DX10來打電動要再久一點了.....(哭哭
可是發現我一窮二白...買不起W7
只好整理開機流程加快一下系統O__Q
XP系統如果想在登入帳號之前執行使用者想要執行的動作,如COPY檔案、檢查檔案、撥PPPoE連線等等
埋在"啟動"資料夾、排程、系統服務都不適當
應該要放在
開始=>執行=>gpedit.msc (就是群組原則啦)
電腦設定=>windows設定=>將 [開機指令檔] 指向 想執行的程式(*.BAT也可)。
這也提供[關機指令檔] (用新增的) 可以在關機的時候做。
類似linux的S60_XXX,S99_XXX 開機執行,跟rc file的執行階段不大一樣。
會在Windowns登入使用者之前就執行。
看來想換DX10來打電動要再久一點了.....(哭哭
2010年4月26日 星期一
[語言] 沒營養的 - do{} while(0)
看code 有時候會看到沒營養的
do{ XXX } while(0)
直覺上會覺得很北七... 顯然北七的只是表面...
這種寫法常見在
#define
如
#define BEJO(x) {a(x-2);b(x);} while(0)
#define a(x) printf("%d\n", x)
#define b(x) printf("%d\n", x)
如果這樣寫
#define BEJO(x) a(x-2);b(x);
那
if(x >0 )
BEJO(x);
else
.....
會被展開成
if(x >0 )
a(x-2);b(x);;
else
.....
當場就b(x)爆炸了.....
那如果這樣寫
#define BEJO(x) {a(x-2);b(x)}
就...
if(x >0 )
{a(x-2);b(x)};
else
.....
那如果這樣寫
#define BEJO(x) {a(x-2);b(x);}
就...
if(x >0 )
{a(x-2);b(x);};
else
.....
不管怎麼寫~~都有可能會被呼叫者誤用到爆炸
按照
本來BEJO(x); <-- 會加分號的習性
do{} while(0)
剛剛好...
if(x >0 )
BEJO(x);
else
.....
會被展開成
if(x >0 )
{a(x-2);b(x);} while(0);
else
.....
很安全.....
do{ XXX } while(0)
直覺上會覺得很北七... 顯然北七的只是表面...
這種寫法常見在
#define
如
#define BEJO(x) {a(x-2);b(x);} while(0)
#define a(x) printf("%d\n", x)
#define b(x) printf("%d\n", x)
如果這樣寫
#define BEJO(x) a(x-2);b(x);
那
if(x >0 )
BEJO(x);
else
.....
會被展開成
if(x >0 )
a(x-2);b(x);;
else
.....
當場就b(x)爆炸了.....
那如果這樣寫
#define BEJO(x) {a(x-2);b(x)}
就...
if(x >0 )
{a(x-2);b(x)};
else
.....
那如果這樣寫
#define BEJO(x) {a(x-2);b(x);}
就...
if(x >0 )
{a(x-2);b(x);};
else
.....
不管怎麼寫~~都有可能會被呼叫者誤用到爆炸
按照
本來BEJO(x); <-- 會加分號的習性
do{} while(0)
剛剛好...
if(x >0 )
BEJO(x);
else
.....
會被展開成
if(x >0 )
{a(x-2);b(x);} while(0);
else
.....
很安全.....
2010年3月23日 星期二
[語言] Select 小紀末
select()
最近碰到一點小小厘清。
select 時間塞給他NULL跟0的差別。
什麼? 0 跟 NULL 不是ㄧ樣嗎?不ㄧ樣就是不ㄧ樣,筆畫還差很多咧。
如果資料一直在進FD倒是沒差太多,如果資料斷斷續續你又擺了個while LOOP,
那就會有很討厭的現象了,最近差點被dev沒回應搞死Orz
從"函式庫辭典挖ㄧ段"來寫程式證明:
--
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
int main(void)
{
fd_set rfds;
struct timeval tv;
int retval;
char buf[1024];
bzero(buf, sizeof(buf));
while(1)
{
FD_ZERO(&rfds);
FD_SET(0, &rfds);
tv.tv_sec = 0;
tv.tv_usec = 0;
retval = select(1, &rfds, NULL, NULL, &tv);
if(retval == -1)
perror("select error !!!\n");
else if(retval)
printf("Data is available NOW!!\n");
if(FD_ISSET(0, &rfds))
{
read(0, buf, sizeof(buf));
printf("Message: %s \n", buf);
break;
}else
printf("No date\n");
}
return 0;
}
--
給0的時候馬上就回報FD沒有資料可以讀取
--
retval = select(1, &rfds, NULL, NULL, NULL);
給NULL的時候會select會停住直到FD有資料可用。
是有一點點差別的。
PS.
通常都會這樣寫,另外弄一個*tvp增加彈性
(sec, usec 秒數是相加)
struct timeval tv, *tvp;
if(XXX)
tvp = NULL;
else
tvp = &tv
tv.tv_sec = secs;
tv.tv_usec = tv.tv_sec/1000000;
tv.tv_usec %= 1000000;
retval = select(1, &rfds, NULL, NULL, tvp);
最近碰到一點小小厘清。
select 時間塞給他NULL跟0的差別。
什麼? 0 跟 NULL 不是ㄧ樣嗎?不ㄧ樣就是不ㄧ樣,筆畫還差很多咧。
如果資料一直在進FD倒是沒差太多,如果資料斷斷續續你又擺了個while LOOP,
那就會有很討厭的現象了,最近差點被dev沒回應搞死Orz
從"函式庫辭典挖ㄧ段"來寫程式證明:
--
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
int main(void)
{
fd_set rfds;
struct timeval tv;
int retval;
char buf[1024];
bzero(buf, sizeof(buf));
while(1)
{
FD_ZERO(&rfds);
FD_SET(0, &rfds);
tv.tv_sec = 0;
tv.tv_usec = 0;
retval = select(1, &rfds, NULL, NULL, &tv);
if(retval == -1)
perror("select error !!!\n");
else if(retval)
printf("Data is available NOW!!\n");
if(FD_ISSET(0, &rfds))
{
read(0, buf, sizeof(buf));
printf("Message: %s \n", buf);
break;
}else
printf("No date\n");
}
return 0;
}
--
給0的時候馬上就回報FD沒有資料可以讀取
--
retval = select(1, &rfds, NULL, NULL, NULL);
給NULL的時候會select會停住直到FD有資料可用。
是有一點點差別的。
PS.
通常都會這樣寫,另外弄一個*tvp增加彈性
(sec, usec 秒數是相加)
struct timeval tv, *tvp;
if(XXX)
tvp = NULL;
else
tvp = &tv
tv.tv_sec = secs;
tv.tv_usec = tv.tv_sec/1000000;
tv.tv_usec %= 1000000;
retval = select(1, &rfds, NULL, NULL, tvp);
2010年1月27日 星期三
[語言] __attribute__
這東西的用法很特別,來自GNU C,挑幾個我看過
OR用過的做ㄧ下筆記
會用跟搞清楚~~還真的有點距離。
用來檢查函數的格式:
可以叫complier幫你檢查如果你的函數長的像printf 或scanf 等等
example:
#include <stdio.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
int bbprintf(int i, const char *fmt, ...) __attribute__((format(printf,2,3)));
int bbprintf(int i, const char *fmt, ...)
{
va_list args;
printf("i = %d \n", i);
va_start(args, fmt);
return vfprintf(stdout, fmt, args);
}
int main()
{
bbprintf(10 ,"num = %d \n", 5);
}
這樣他就會幫你把bbprintf()用printf檢查一番
例如: 故意把%d 換成%s
warning: format '%s' expects type 'char *', but argument 3 has type 'int'
指令說明:
format(printf,2,3)
第一格:printf -> 依照printf的樣子檢查
第二格:2 -> const char *fmt 這是第二欄
第三格:3 -> ... 這是第三欄
之前有遇過類似的問題,如果可以這個檢查應該可以避掉
--
這個也可以避掉void function 的呼叫被放在有return 的位置,
避免 complier 跟你靠腰。
void myexit(void) __attribute__ ((__noreturn__));
void myexit()
{
printf("YA \n");
exit(1); <--- 不能省 不然你會看到更奇怪的靠腰,原因是程式需要在這裡終止。
}
int main()
{
int n = 1;
if( n > 0 )
{
myexit();
}else
return 0;
}
是意思是告訴complier myexit是沒有回傳的function 就算他放在需要回傳的function裡,也請睜ㄧ隻眼閉一隻眼。
abort() 就是用同樣的方式宣告。
否則你會看到以下的訊息
warning: control reaches end of non-void function
以上在complier時記得加上 -Wall 才看到的
當然還有
const
aligned
packed
使用該屬性可以使得變量或者結構體成員使用最小的對齊方式
還很多,packed有看過,沒用到就先不記錄了。
OR用過的做ㄧ下筆記
會用跟搞清楚~~還真的有點距離。
用來檢查函數的格式:
可以叫complier幫你檢查如果你的函數長的像printf 或scanf 等等
example:
#include <stdio.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
int bbprintf(int i, const char *fmt, ...) __attribute__((format(printf,2,3)));
int bbprintf(int i, const char *fmt, ...)
{
va_list args;
printf("i = %d \n", i);
va_start(args, fmt);
return vfprintf(stdout, fmt, args);
}
int main()
{
bbprintf(10 ,"num = %d \n", 5);
}
這樣他就會幫你把bbprintf()用printf檢查一番
例如: 故意把%d 換成%s
warning: format '%s' expects type 'char *', but argument 3 has type 'int'
指令說明:
format(printf,2,3)
第一格:printf -> 依照printf的樣子檢查
第二格:2 -> const char *fmt 這是第二欄
第三格:3 -> ... 這是第三欄
之前有遇過類似的問題,如果可以這個檢查應該可以避掉
--
這個也可以避掉void function 的呼叫被放在有return 的位置,
避免 complier 跟你靠腰。
void myexit(void) __attribute__ ((__noreturn__));
void myexit()
{
printf("YA \n");
exit(1); <--- 不能省 不然你會看到更奇怪的靠腰,原因是程式需要在這裡終止。
}
int main()
{
int n = 1;
if( n > 0 )
{
myexit();
}else
return 0;
}
是意思是告訴complier myexit是沒有回傳的function 就算他放在需要回傳的function裡,也請睜ㄧ隻眼閉一隻眼。
abort() 就是用同樣的方式宣告。
否則你會看到以下的訊息
warning: control reaches end of non-void function
以上在complier時記得加上 -Wall 才看到的
當然還有
const
aligned
packed
使用該屬性可以使得變量或者結構體成員使用最小的對齊方式
還很多,packed有看過,沒用到就先不記錄了。
2010年1月22日 星期五
[Linux] 麗娜思小妹妹幫你換心臟囉
小妹妹要有強壯的心靈,才不會被奇怪的大哥哥拐走!!!
又可以幫她脫光光了 YA
最近想弄點東西,抓了kernel source 來幫麗納思小妹妹換個強壯的心靈!!!
按照慣例
這是神級的官網
http://www.kernel.org/
版本這次用的是
2.6.32.4
雖然工作機是Unbuntu不過這次要換的是Debian小B機~
首先準備
解開linux source 需要bzip2 (debian 預設沒有裝)
make menuconfig 需要ncurses-devel,ncurses-devel 需要叫做libncurses5-dev (靠~debian 預設還是沒有裝,不過我就是喜歡她這點>////////< 不穿比較好)
make help <-- Makefile 有寫了哪些目標可以被make
就會發現下面很有用的訊息:
make mrproper <-- 清光設定檔包跨 .config + make clean
make clean <-- 就是 clean
make menuconfig <-- 選菜
make oldconfig <-- 只有列出新的來選
make all <-- 等於make vmlinux, make modules, make bzImage
make vmlinux <-- 作出沒有壓縮的核心,在source 根目錄會看到
make modules <-- 作出核心用的模組,以後可以insmod
make bzImage <-- 作出壓縮過的核心,在arch/i386/boot/bzImage,或是arch/i386/boot/bzImage -> ../../x86/boot/bzImage
make module_install <--會幫忙拷貝module到目錄/lib/modules... 玩玩而已可以不用才怪 囧>
littleB:/home/bejo/code# uname -a
Linux littleB 2.6.32.4 #1 Fri Jan 22 07:00:51 CST 2010 i686 GNU/Linux
YES~
-----
總結來說,核心就是一個檔案,開機之後bootloader指到那邊去執行,initrd.img是為瞭解決巧妙的驅動問題,就是前人沒想到sata會出現嘛... 還是一個小小的kernel唷,bootloader之後就是交給initrd.img再交給vmliunz
檔案說明
System.map <--記得拷貝到 /boot/
What Is The System.map File?
There are 2 files that are used as a symbol table:
1. /proc/ksyms (在ubuntu 是 /proc/kallsyms,媽的~我開始覺得這東西流著debianㄧ樣GY的血液是真的)
2. System.map
這個檔案會紀錄module應該插入的symbol記憶體位置,如果模組有問題的話,可以確認一下。
vmlinux <-- 沒壓縮的核心檔
vmlinuz <-- 有壓縮的核心檔
bzImage <-- 有壓縮的核心檔,用bzip壓縮,把這個檔案拷貝到 /boot 下,然後更改成vmlinuxz
zImage <-- 有壓縮的核心檔,用gzip壓縮
.config <-- 系統原本的設定檔,如果要升級現有kernel可以在/boot 下面找到類似config-2.6.27-16-generic之前的前一份檔
所以可以把它拷貝出來餵給現在的核心吃,這樣就不會不知道選啥Kernel菜了,所以記得換過核心要順便把新的config塞進去,守規矩。
mkinitramfs 這東西製造出新的initrd.img
mkinitramfs -o initrd.img-版號 版號
(在這之前ㄧ定要make modules_install 因為它會吃/lib/module/板號)
(如果編譯端不是安裝端,可以用Makefile 改路徑騙過他)
修改開機的kernel選擇
/boot/grub/menu.lst
增加
title BeJo GNU/Linux, kernel 2.6.32.4
root (hd0,0)
kernel /boot/vmlinuz-2.6.32.4 root=/dev/hda1 ro
initrd /boot/initrd.img-2.6.32.4
savedefault
下面是Unbuntu的,有uuid跟debian不大ㄧ樣,照換也可以。
title linux kernel 2.6.27.7
uuid bdce929d-3c0b-4f10-aeb7-76b0fb8b62cd
kernel /vmlinuz-2.6.27.7 root=UUID=1d668bc0-d6b1-4798-8173-b05b65e925e7 ro quiet splash
initrd /initrd.img-2.6.27.7
quie
最近想弄點東西,抓了kernel source 來幫麗納思小妹妹換個強壯的心靈!!!
按照慣例
這是神級的官網
http://www.kernel.org/
版本這次用的是
2.6.32.4
雖然工作機是Unbuntu不過這次要換的是Debian小B機~
首先準備
解開linux source 需要bzip2 (debian 預設沒有裝)
make menuconfig 需要ncurses-devel,ncurses-devel 需要叫做libncurses5-dev (靠~debian 預設還是沒有裝,不過我就是喜歡她這點>////////< 不穿比較好)
- 編譯步驟
make help <-- Makefile 有寫了哪些目標可以被make
就會發現下面很有用的訊息:
make mrproper <-- 清光設定檔包跨 .config + make clean
make clean <-- 就是 clean
make menuconfig <-- 選菜
make oldconfig <-- 只有列出新的來選
make all <-- 等於make vmlinux, make modules, make bzImage
make vmlinux <-- 作出沒有壓縮的核心,在source 根目錄會看到
make modules <-- 作出核心用的模組,以後可以insmod
make bzImage <-- 作出壓縮過的核心,在arch/i386/boot/bzImage,或是arch/i386/boot/bzImage -> ../../x86/boot/bzImage
make module_install <--會幫忙拷貝module到目錄/lib/modules... 玩玩而已可以不用
- make menuconfig (記得拷貝舊的來用,在/boot/下面有)
- make all
- make moudule_install (用來做initrd.img) copy 檔案到系統/boot下,需要vmlinuz、initrd.img、System.map、新config
- 修改/boot/grub/menu.lst
- 重開機
littleB:/home/bejo/code# uname -a
Linux littleB 2.6.32.4 #1 Fri Jan 22 07:00:51 CST 2010 i686 GNU/Linux
YES~
-----
總結來說,核心就是一個檔案,開機之後bootloader指到那邊去執行,initrd.img是為瞭解決巧妙的驅動問題,
檔案說明
System.map <--記得拷貝到 /boot/
What Is The System.map File?
There are 2 files that are used as a symbol table:
1. /proc/ksyms (在ubuntu 是 /proc/kallsyms,媽的~我開始覺得這東西流著debianㄧ樣GY的血液是真的)
2. System.map
這個檔案會紀錄module應該插入的symbol記憶體位置,如果模組有問題的話,可以確認一下。
vmlinux <-- 沒壓縮的核心檔
vmlinuz <-- 有壓縮的核心檔
bzImage <-- 有壓縮的核心檔,用bzip壓縮,把這個檔案拷貝到 /boot 下,然後更改成vmlinuxz
zImage <-- 有壓縮的核心檔,用gzip壓縮
.config <-- 系統原本的設定檔,如果要升級現有kernel可以在/boot 下面找到類似config-2.6.27-16-generic之前的前一份檔
所以可以把它拷貝出來餵給現在的核心吃,這樣就不會不知道選啥Kernel菜了,所以記得換過核心要順便把新的config塞進去,守規矩。
mkinitramfs 這東西製造出新的initrd.img
mkinitramfs -o initrd.img-版號 版號
(在這之前ㄧ定要make modules_install 因為它會吃/lib/module/板號)
(如果編譯端不是安裝端,可以用Makefile 改路徑騙過他)
修改開機的kernel選擇
/boot/grub/menu.lst
增加
title BeJo GNU/Linux, kernel 2.6.32.4
root (hd0,0)
kernel /boot/vmlinuz-2.6.32.4 root=/dev/hda1 ro
initrd /boot/initrd.img-2.6.32.4
savedefault
下面是Unbuntu的,有uuid跟debian不大ㄧ樣,照換也可以。
title linux kernel 2.6.27.7
uuid bdce929d-3c0b-4f10-aeb7-76b0fb8b62cd
kernel /vmlinuz-2.6.27.7 root=UUID=1d668bc0-d6b1-4798-8173-b05b65e925e7 ro quiet splash
initrd /initrd.img-2.6.27.7
quie
2010年1月21日 星期四
[語言] __FILE__, __LINE__
上次在神人那看到....他說:我就是要挺慣C,
恩...
可以交到這麼多正妹的慣C,我也很挺XD
看過
__FILE__, __LINE__ 沒?
C語言常常有那種知道的不要問,不知道的不要說的詭異(取自某討論區的黑暗氣氛...這根本是死結嘛)
其實這是GCC complier 預先就定義好的變數,不只這兩個,只要符合C99的標準有以下七個
__LlNE__
__FILE__
__FUNCTION__
__TIME__
__DATE__
__STDC__ (是否遵守ISO C )
__STDC_HOSTED__ (是不是HOST,非寄居)
__STDC_VERSION__ (版本)
用GCC的話並不完全符合上面的定義
__STDC_VERSION__ 就變成 __VERSION__
__func__ 等同於__FUNCTION__ 不過聽說GCC建議使用前者。
另外complier,我用GCC試過存在
__TIMESTAMP__
寫個程式印一下就知道了
printf("line: %d \n", __LINE__);
printf("file: %s \n", __FILE__);
printf("function: %s \n", __FUNCTION__);
printf("function: %s \n", __func__);
printf("time: %s \n", __TIME__);
printf("date: %s \n", __DATE__);
printf("STDC: %d \n", __STDC__);
printf("STDC_HOSTED: %d \n", __STDC_HOSTED__);
printf("VERSION: %s \n", __VERSION__);
printf("TIMESTAMP: %s \n", __TIMESTAMP__);
輸出:
line: 150
file: test.c
function: main
function: main
time: 15:13:28
date: Jan 21 2010
STDC: 1
STDC_HOSTED: 1
VERSION: 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)
TIMESTAMP: Thu Jan 21 15:13:26 2010
這東西就可以視情況取用,很方便。
多方便?
例如我們要重新定義一個DBG()函數來幫忙debug好了
#define DBG(msg, arg...) printf("%s:%s(%d): " msg, __FILE__, __FUNCTION__, __LINE__, ##arg)
這樣我們就可以把DBG()當作printf()使用還多增加function name 行數等等可以查詢。
如
DBG("index:%d str = %s\n", index, str);
輸出: test.c:main(146): index:2147483647 str = bejo
--
那define 看起來十分詭異對吧 XD
其實那也只是置換的意思,把置換ㄧ下就很清楚了
DBG("index:%d str = %s\n", index, str);
被置換成
printf("%s%s(%d): " "index:%d str = %s\n", __FILE__, __FUNCTION__, __LINE__, index, str);
DBG --> printf
msg --> "index:%d str = %s\n"
arg --> index, str
就ㄧ點都不奇怪了...
補充一下假指令#line 的用法
這用法可以在openl2tp這包open source看到,用在bison paswer相關
例如當
testA.c 是由bejo.c 自動產生時,run testA.c包好的檔案去debug會產生一些困擾,這時候我們可以這樣做
#line 888 "bejo.c"
printf("%s line: %d\n", __FILE__, __LINE__);
printf("line: %d\n", __LINE__);
輸出
bejo.c line:888
line:889
就會知道該去看該死的bejo.c 第888行
---
自動產生的code聽起好夢幻XD
恩...
可以交到這麼多正妹的慣C,我也很挺XD
看過
__FILE__, __LINE__ 沒?
C語言常常有那種知道的不要問,不知道的不要說的詭異(取自某討論區的黑暗氣氛...這根本是死結嘛)
其實這是GCC complier 預先就定義好的變數,不只這兩個,只要符合C99的標準有以下七個
__LlNE__
__FILE__
__FUNCTION__
__TIME__
__DATE__
__STDC__ (是否遵守ISO C )
__STDC_HOSTED__ (是不是HOST,非寄居)
__STDC_VERSION__ (版本)
用GCC的話並不完全符合上面的定義
__STDC_VERSION__ 就變成 __VERSION__
__func__ 等同於__FUNCTION__ 不過聽說GCC建議使用前者。
另外complier,我用GCC試過存在
__TIMESTAMP__
寫個程式印一下就知道了
printf("line: %d \n", __LINE__);
printf("file: %s \n", __FILE__);
printf("function: %s \n", __FUNCTION__);
printf("function: %s \n", __func__);
printf("time: %s \n", __TIME__);
printf("date: %s \n", __DATE__);
printf("STDC: %d \n", __STDC__);
printf("STDC_HOSTED: %d \n", __STDC_HOSTED__);
printf("VERSION: %s \n", __VERSION__);
printf("TIMESTAMP: %s \n", __TIMESTAMP__);
輸出:
line: 150
file: test.c
function: main
function: main
time: 15:13:28
date: Jan 21 2010
STDC: 1
STDC_HOSTED: 1
VERSION: 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)
TIMESTAMP: Thu Jan 21 15:13:26 2010
這東西就可以視情況取用,很方便。
多方便?
例如我們要重新定義一個DBG()函數來幫忙debug好了
#define DBG(msg, arg...) printf("%s:%s(%d): " msg, __FILE__, __FUNCTION__, __LINE__, ##arg)
這樣我們就可以把DBG()當作printf()使用還多增加function name 行數等等可以查詢。
如
DBG("index:%d str = %s\n", index, str);
輸出: test.c:main(146): index:2147483647 str = bejo
--
那define 看起來十分詭異對吧 XD
其實那也只是置換的意思,把置換ㄧ下就很清楚了
DBG("index:%d str = %s\n", index, str);
被置換成
printf("%s%s(%d): " "index:%d str = %s\n", __FILE__, __FUNCTION__, __LINE__, index, str);
DBG --> printf
msg --> "index:%d str = %s\n"
arg --> index, str
就ㄧ點都不奇怪了...
補充一下假指令#line 的用法
這用法可以在openl2tp這包open source看到,用在bison paswer相關
例如當
testA.c 是由bejo.c 自動產生時,run testA.c包好的檔案去debug會產生一些困擾,這時候我們可以這樣做
#line 888 "bejo.c"
printf("%s line: %d\n", __FILE__, __LINE__);
printf("line: %d\n", __LINE__);
輸出
bejo.c line:888
line:889
就會知道該去看該死的bejo.c 第888行
---
自動產生的code聽起好夢幻XD
2010年1月12日 星期二
[Ubuntu] SCIM - 輸入法
SCIM - 整合性的輸入法伺服 平常屋邦兔都是拿來工作,很少會打到中文,這次要裝上注音輸入法,哪有那種裝scim會動,裝gcin會動,等一下通通不會動這種鳥事阿,還真的有點稿死我 囧>
照慣例這是官網:
http://www.scim-im.org/
這篇是用SCIM的酷注音完成...... 很不順手 =___=
首先安裝好Ubuntu之後應該會有scim,但因為我是英文環境所以安裝上有點問題。
執行
im-switch -s scim
會發現
Cannot find alternative `/e tc/X11/xinit/xinput.d/scim'
原因:
scim沒有被加入到alternatives列表中
解法:
update-alternatives --install /etc/X11/xinit/xinput.d/all_ALL xinput-all_ALL /etc/X11/xinit/xinput.d/scim 30
另外用im-switch -c 也可以用表單來切換輸入法。
#pkill scim
#scim -d
重新執行
不過..... 我還是登出登入才可以用,真他x的奇怪阿 囧>
ps. 新酷音還是很不順手...某後用
照慣例這是官網:
http://www.scim-im.org/
這篇是用SCIM的酷注音完成...... 很不順手 =___=
首先安裝好Ubuntu之後應該會有scim,但因為我是英文環境所以安裝上有點問題。
- 確認language support 裝上中文包
- 安裝scim- chewing
- 需要一個工具:im-switch
執行
im-switch -s scim
會發現
Cannot find alternative `/e tc/X11/xinit/xinput.d/scim'
原因:
scim沒有被加入到alternatives列表中
解法:
update-alternatives --install /etc/X11/xinit/xinput.d/all_ALL xinput-all_ALL /etc/X11/xinit/xinput.d/scim 30
另外用im-switch -c 也可以用表單來切換輸入法。
#pkill scim
#scim -d
重新執行
不過..... 我還是登出登入才可以用,真他x的奇怪阿 囧>
ps. 新酷音還是很不順手...某後用
訂閱:
文章 (Atom)