在NanoPi-NEO上試驗dts和平臺總線機制

   學習了linux的dts和platform總線機制,自己畫圖概括了一下dts文件,設備,總線和驅動之間的相互關係.



   爲了證實一下,在NanoPi-NEO上進行了如下試驗, NanoPi-NEO上已經預裝了Ubuntu-Core Linux_4.11 固件:

1. 將friendlyarm官方源碼linux_4.11.2_20170531.tar.gz 解壓到NanoPi-NEO的 /works 目錄下,並按照說明完成編譯。

2. 在 /works/linux/arch/arm/boot/dts 目錄下建立一個midas.dtsi文件,添加一個midas節點,內容如下:

/{
        midas {
                compatible = "midas,dts_test";

reg=<0x12344321 0x1>;

                midas_value=<555>;
                label = "Midas_Label";
        };
};

  然後將它引用到 sun8i-h3-nanopi-neo.dts 文件中 #include "midas.dtsi"  

 3. 在/works/linux 目錄下執行 make dtbs 命令,成功後會生成dtb文件 /works/linux/arch/arm/boot/dts/sun8i-h3-nanopi-neo.dtb,將它複製到/boot下覆蓋原來的同名文件, 然後重啓linux,內核加載新的dtb.

 4. 編輯一個platf_test.c文件, 內容如下:

#include <linux/module.h>
#include <linux/init.h>
#include <linux/of_platform.h>

static struct of_device_id my_match_table[] = {
        { .compatible = "midas,dts_test",     },
        { },
};

static int my_probe(struct platform_device *dev)
{

    struct resource *res_mem;

    struct device_node *node_midas;
    int value;
    char *label;

  
    if( dev && (dev->name))
    {
        printk("--- dts_test: a compatibale device is found! -----");
        printk("matched platform_device:   name=%s    id=%d  num_resources=%d\n",dev->name,dev->id,dev->num_resources);

        res_mem = platform_get_resource(dev,IORESOURCE_MEM,0);
        printk("get MEM resource: name=%s, start=0x%08x, end=0x%08x\n",res_mem->name,res_mem->start,res_mem->end);

        //----- get node -----

        node_midas = dev->dev.of_node;
        //----- get u32 value of a property -----
        if(!of_property_read_u32(node_midas,"midas_value",&value))
                printk("value: %d ",value);
        else
                printk("no property with name 'midas_value' \n");

        //----- get property of a label string -----
        label=(char *)of_get_property(node_midas,"label",NULL); /* return void  */
        if(label)
                printk("label: %s \n",label);
        else
                printk("no property with name 'label' \n");
    }

    else
        printk("name unknwon \n");
    return 0;
}

static struct platform_driver my_driver = {
        .probe          = my_probe,
        .driver         = {
                .owner  = THIS_MODULE,
                .name   = "midas",
                .of_match_table = my_match_table, //platform_bus will try to match .of_match_table first, and then .name
        },
};

static int __init platf_test_init(void)
{
  printk("------  dts v.s. platform driver start -----\n");
  return platform_driver_register(&my_driver);
}

static void __exit platf_test_exit(void)
{

  platform_driver_unregister(&my_driver);
  printk("------ dts v.s. platform driver exit -----\n");
}

module_init(platf_test_init);
module_exit(platf_test_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Midas");
MODULE_DESCRIPTION("platf_test");


並編輯一個對應的Makefile如下:

obj-m := platf_test.o
PWD   := $(shell pwd)
K_DIR := /works/linux
all:
        $(MAKE) -C $(K_DIR) M=$(PWD) modules
clean:
        $(MAKE) -C $(K_DIR) M=$(PWD) clean


5. make 一下, 在當前目錄下會生成 platf_test.ko


6. insmod platf_test.ko 加載內核模塊,觀察運行結果:


注意到 /sys/bus/platform/devices下生成的設備名:



(水平所限,如有錯誤還請斧正.)


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章