基於fs210平台的dm9000原理及移植

來源:互聯網
上載者:User

標籤:fs210   dm9000   dm9000原理   嵌入式   

dm9000的原理圖如下:

650) this.width=650;" src="http://s3.51cto.com/wyfs02/M00/38/40/wKioL1OzmQGAEEtZAAL59MpEn5M140.jpg" title="Column871.jpg" alt="wKioL1OzmQGAEEtZAAL59MpEn5M140.jpg" />

網卡的移植工作很簡單,首先是需要添加目標版的平台裝置資訊,就可以實現網卡的移植工作,平台裝置資訊如何添加很重要

添加平台資訊的第一步是添加一個platform_device裝置資訊

首先在arch/arm/mach-s5pv210/mach-smdkv210.c

添加標頭檔:

#include <linux/dm9000.h>
             #include <linux/irq.h>
             添加platform_device平台裝置資訊
             struct platform_device {
                     const char * name; // 平台裝置名稱
                     int id; // 裝置的ID 如果是唯一裝置,ID = -1,如果裝置不是唯一的,ID = 0,1,2,3,4,5
                     struct device dev; //
                     u32 num_resources; //所擁有資源結構體的個數
                     struct resource * resource; //資源結構體指標
                     const struct platform_device_id *id_entry;
                     struct pdev_archdata archdata;
             };
             例如:
             static struct platform_device s5pc100_device_dm9000 = {
                     .name = "dm9000",
                     .id = -1,
                     .num_resources = ARRAY_SIZE(dm9000_resources),
                     .resource = dm9000_resources,
                     .dev = {
                     .        platform_data = &s5pc100_dm9000_platdata,
                     }
             };

struct device 在  include/linux/device.h中的platform_data只是一個指標,可以傳送一個地址

用這個地址可以給驅動傳動一些特殊的資料,對於dm9000這個網卡晶片需要傳送dm9000_plat_data

在網卡驅動中使用了如下的定義:   struct dm9000_plat_data *pdata = pdev->dev.platform_data;

因此我們要傳遞這個這個platform_data結構體,結構體的定義如下:

/* platform data for platform device structure‘s platform_data field */
             struct dm9000_plat_data {
                     unsigned int flags;
                     unsigned char dev_addr[6]; // 網卡的mac地址 ,可以不寫,如果不寫的話,是隨機產生一個
                     /* allow replacement IO routines */
                     void (*inblk)(void __iomem *reg, void *data, int len);
                     void (*outblk)(void __iomem *reg, void *data, int len);
                     void (*dumpblk)(void __iomem *reg, int len);
             };

這個是網卡驅動使用的結構體

flags = DM9000_PLATF_16BITONLY, 表示dm9000工作在16位的模式下

在這個檔案中定義  include/linux/dm9000.h

/* IO control flags */
             #define DM9000_PLATF_8BITONLY (0x0001)
             #define DM9000_PLATF_16BITONLY (0x0002)
             #define DM9000_PLATF_32BITONLY (0x0004)
             #define DM9000_PLATF_EXT_PHY (0x0008)
             #define DM9000_PLATF_NO_EEPROM (0x0010)
             #define DM9000_PLATF_SIMPLE_PHY (0x0020) /* Use NSR to find LinkStatus */
             dev_addr是網卡的mac地址,
             .dev_addr[0] = 0x00,
             .dev_addr[1] = 0x00,
             .dev_addr[2] = 0x3e,
             .dev_addr[3] = 0x26,
             .dev_addr[4] = 0x0a,
             .dev_addr[5] = 0x00,
             例如:.dev = {
                     .platform_data = & s5pc100_dm9000_plat data,  //表示驅動中要用的資料
             }
             struct resource {
                     resource_size_t start; // 表示資源的開始值
                     resource_size_t end; // 表示資源的結束值
                     const char *name;
                     unsigned long flags; // 資源的類型
                     struct resource *parent, *sibling, *child;
             };
             我們一般只關心這3個欄位 start ,end ,flags
             flags:
             /*
             * IO resources have these defined flags.
             */
             #define IORESOURCE_BITS 0x000000ff /* Bus-specific bits */
             #define IORESOURCE_TYPE_BITS 0x00001f00 /* Resource type */
             #define IORESOURCE_IO 0x00000100
             #define IORESOURCE_MEM 0x00000200 //記憶體資源
             #define IORESOURCE_IRQ 0x00000400 //中斷資源
             #define IORESOURCE_DMA 0x00000800
             #define IORESOURCE_BUS 0x00001000
             因為在驅動中使用了如下的函數:
             db->addr_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
             db->data_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
             db->irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
             因此我們必須要對成員設定如下:
             static struct resource dm9000_resources[] = {
                     [0] = {
                             .start = 0x88000000,
                             .end = 0x88000000+0x3,
                             .flags = IORESOURCE_MEM,
                     },
                     [1] = {
                             .start = 0x88000000+0x4,
                             .end = 0x88000000+0x4+0x3,
                             .flags = IORESOURCE_MEM,
                     },
                     [2] = {
                             .start = IRQ_EINT(10),
                             .end = IRQ_EINT(10),
                             .flags = IORESOURCE_IRQ|IRQ_TYPE_LEVEL_HIGH,
                     },
             };

為什麼驅動要這樣設定呢?

因為網卡dm9000這個裝置有一個介面, 是dm9000的cmd引腳, 如果cmd = 0 表示的是地址,  cmd=1 表示的資料

cmd這個引腳接到了addr2 ,接到了地址匯流排, 也就是說我們只需要對addr2的地址產生影響就可以了,因此addr2 =0 表示是index是地址,

addr2 =1 表示對index索引指向的寄存器的內的值data ,因此我們只需要對這兩個寄存器設定就可以實現網卡的驅動.

int platform_device_register(struct platform_device *pdev); //註冊一個裝置

int platform_add_devices(struct platform_device **pdevs, int ndev); //註冊多個裝置

pdevs: platform_device類型的指標

ndev : 一共有多少個裝置


本文出自 “嵌入式學習天地” 部落格,請務必保留此出處http://farsight.blog.51cto.com/1821374/1433472

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.