Linux駆動プラットドライブ


#プラットフォームドライバ
Linuxのすべてのデバイスドライバはplatform_によってシステムプラットフォームに登録する必要があります.device.hで定義関数のセットが完了する.まずstruct platformを見てみましょうdriverという構造体:
   
struct platform_driver {
       int (*probe)(struct platform_device *);
       int (*remove)(struct platform_device *);
       void (*shutdown)(struct platform_device *);
       int (*suspend)(struct platform_device *, pm_message_t state);
       int (*resume)(struct platform_device *);  
       struct device_driver driver;  
       const struct platform_device_id *id_table;
};

この構造には、操作関数のセットとstruct device_が含まれています.driverの対像私たち自身の駆動でまずしなければならないのはplatformを定義することです.driverの関数を作成し、この構造のオブジェクトインスタンスを作成し、init()関数でplatform_を呼び出します.driver_register()はシステムに私たちのドライバを登録します.
kernel-3.0のleds-s 3 c 24 xxのように.cのplatform_driverの定義は次のとおりです.
static struct platform_driver s3c24xx_led_driver = {
    .probe        = s3c24xx_led_probe,
    .remove        = s3c24xx_led_remove,
    .driver        = {
        .name        = "s3c24xx_led",
        .owner        = THIS_MODULE,
    },
};

その他で指定する.driverの名前と所有者platformを呼び出すdriver_register()ドライバを登録するとplatformはまずデバイスがシステム内のplatform_であることを指定するbusメインバスの下では、これは仮想バス駆動にすぎない.次にplatformドライバがdriverを呼び出すregister(), driver_register呼び出しbus_add_driver()は、システムバスマネージャにドライバを登録する.デバイススキャンが正常に行われた場合、dd.cのdriver_attach()で行う.実際に呼び出されます_driver_attach()は、driver_を呼び出す関数です.probe_device(), driver_probe_デバイス()は、ドライバ登録時に指定したバスprobeとドライバ独自のprobe関数、すなわち、上に登録したs 3 c 24 xx_をそれぞれ呼び出します.led_probe()関数、バスprobe関数platform_driver_register()に設定、デフォルトのDriverの操作関数も設定.
我々のprobe関数では主に装置の検出と初期化を行い、ここで2410のledはgpioに接続されているので常に存在するが、usbのような周辺機器であれば、まず外部の周辺機器が存在するかどうかを検出する必要がある.sc 324 xx_led_probeでは主に以下の3つのことをした.
    1.プライベート・データ・オブジェクトを作成しplatform_を呼び出すset_drvdata()は、デバイスオブジェクトに付着する.Probe関数に渡されるパラメータはstruct platformです.デバイスのプラットフォームデバイス対像(そこで作成されたものは?)
       struct platform_デバイスは次のように定義されています.
struct platform_device {
	const char	* name;
	int		id;
	struct device	dev;
	u32		num_resources;
	struct resource	* resource;

	const struct platform_device_id	*id_entry;

	/* MFD cell pointer */
	struct mfd_cell *mfd_cell;

	/* arch specific additions */
	struct pdev_archdata	archdata;
};

システム内の特定のデバイスに関する情報を保存するstructデバイスオブジェクトがある.ここでdriver_Dataは、一般に、struct s 3 c 24 xx_を保存するために、デバイスに関連するプライベート情報を保存するために使用される.gpio_ledインスタンスですが、直接操作するのではなくplatformを使用します.set_drvdata()関数
    2. 具体的なgpioを初期化する
    3. 呼び出しled_classdev_registerカーネルにledクラスドライバを登録
小節:このプロセスでは、ドライバで行う必要があることと、基本的なプロセスを見ることができます.
       1.platformを定義する必要がありますドライバのオブジェクトは、駆動に関する情報を記述する.
       2.実装platform_driverで定義する必要な関数
       3.プラットフォームドライバマネージャにドライバを登録する.
       4.ドライバマネージャが呼び出す.probe関数はデバイスを検出するために、ここでデバイスの初期化を行う必要がある.
       5.カーネルは、open、closeなどの操作要求に基づいて駆動する対応する関数を呼び出す.
       
#プラットフォームデバイス
platform driverでカーネルが登録を呼び出します.probe関数、パラメータはplatform_デバイスのオブジェクトポインタですが、これはそこから来ています.s 3 c 2410 smdkボードを例にとると、対応するmachはmach-s 3 c 2410です.具体的に使うのは、カーネルを構成するときにどのプラットフォームとmachを選択したか、具体的にどのようにmachを構成したり増やしたりするかによって決まります.arch/arm/mach-s 3 c 2410/mach-smdk 2410を開きます.cファイルの最後にMACHINEがあります.STARTの構造体:
MACHINE_START(SMDK2410, "SMDK2410")
    .phys_io    = S3C2410_PA_UART,
    .io_pg_offst    = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
    .boot_params    = S3C2410_SDRAM_PA + 0x100,
    .map_io        = smdk2410_map_io,
    .init_irq    = s3c24xx_init_irq,
    .init_machine    = smdk_machine_init,
    .timer        = &s3c24xx_timer,
MACHINE_END 

この構造体は、machに関するシステムリソースを記述する、カーネルは、初期化時に、その構造体の内容に基づいて初期化動作を行う.指定したsmdk_を見つけます.machine_Init関数、この関数の内容は多くありません.今はただ関心を持っています.
   platform_add_devices(smdk_devs, ARRAY_SIZE(smdk_devs));
この呼び出しはplatformに入りますadd_devicesでは、devsパラメータ内のplatform_を巡回するためにこの関数にforループがあることがわかります.デバイスを呼び出しplatform_を呼び出しますdevice_register登録デバイス前のs 3 c 24 xx_を生成しますled_probeが受け取ったplatform_device.
主なdevsはどこから来たのか、前の階に戻ると、静的に定義されたplatformが伝わってくるのが見えます.デバイスの配列、この中は私たちのmachによって定義したいくつかの設定の構成情報に基づいて、少し良いpcのbiosです.ハードウェアの構成を変更するには、ここから始める必要がある.