靠腰~~~
是我自己不知道的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月2日 星期三
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);
訂閱:
文章 (Atom)