linux有 设备树 LED 驱动开发

————————————————————————————

在设备树中添加节点信息节点属性:设备节点最好添加在好区分的地方 如一级节点处

在设备树中最重要的节点信息是设备的地址信息

    /*用设备树操作 获取设备树属性内容  一般在加载驱动的时候读取设备树节点信息*/
    alphaled {
        #address-cells = <1>;
        #size-cells =<1>;
        status = "okay";
        compatible = "alientek,alphaled";
        //地址 地址长度 
        reg = < 0X020C406C 0X04    /* CCM_CCGR1_BASE */
                0X020E0068 0X04 /* SW_MUX_GPIO1_IO03_BASE */
                0X020E02F4 0X04 /* SW_PAD_GPIO1_IO03_BASE */
                0X0209C000 0X04 /* GPIO1_DR_BASE */
             0X0209C004 0X04 >; /* GPIO1_GDIR_BASE */

};

———————————————————添加节点信息后使用:make dtbs

编译设备树 将用新的设备树启动内核

使用cat /proc/device-tree 命令可以查看根节点的下的节点信息

——————————————————————————————————————————

LED驱动的编写 (一般用一个结构体描述一个设备里面所需要的各种信息)

/*dtsled设备结构体*/
struct dtsled_dev
{
  
    dev_t devid; //设备号
    int major; //主设备号
    int minor;//次设备号
    struct cdev cdev ;//包含了操作函数集 与app.C进行联系
    struct class *class;//创建类
    struct device *device;//创建设备

    struct device_node *nd;//设备节点
};
struct dtsled_dev dtsled; //设备

——————————————————————————————————

/*入口 -注册字符设备*/中注册设备号 向内核添加字符设备 自动创建设备节点 不变

新添加

————————————————————

    /*1——————获取节点*/
    dtsled.nd = of_find_node_by_path("/alphaled");//从全路径中找
    if(dtsled.nd == NULL)
    {
        ret = -EINVAL ; //查找节点失败
        goto failed_findnd;
    }

   /*2———————获取节点各个属性信息*/
    //status 字符串
    ret = of_property_read_string(dtsled.nd, "status",&str);
   if(ret < 0)
   {
       goto faield_rs;
   }
   else
   {
        printk("status = %s \r\n", str);
   }

   // compatible 字符串
    ret = of_property_read_string(dtsled.nd, "compatible",&str);
   if(ret < 0)
   {
       goto faield_rs;
   }
   else
   {
        printk("compatible = %s \r\n", str);
   }

——————————————获取地址属性 reg

第一种方法 由于需要灯的内存映射

/*存在虚拟映射*/
/*地址映射后打虚拟地址指针*/
//#include <asm/io.h>
static void __iomem *IMX6U_CCM_CCGR1;
static void __iomem *SW_MUX_GPIO1_IO03;
static void __iomem *SW_PAD_GPIO1_IO03;
static void __iomem *GPIO1_DR;
static void __iomem *GPIO1_GDIR;

   /*获取reg属性 数组*/
    ret = of_property_read_u32_array(dtsled.nd,"reg", regdate ,10);// 节点 名称 保存到哪里 几个元素
    if(ret < 0)
    {
        ret = -EINVAL;
       goto faield_read32array;
    }
    else
    { 
        printk("reg date :\r\n");
        for( i = 0 ; i < 10 ; i++ )
        printk("%#X  ",regdate[i]);
        printk("\r\n");
    }

    IMX6U_CCM_CCGR1 = ioremap(regdate[0], regdate[1]); //该函数用于虚拟地址映射 物理地址加大小 32bit =4 byte
    SW_MUX_GPIO1_IO03 = ioremap(regdate[2], regdate[3]);
    SW_PAD_GPIO1_IO03 = ioremap(regdate[4], regdate[5]);
    GPIO1_DR = ioremap(regdate[6], regdate[7]);
    GPIO1_GDIR = ioremap(regdate[8], regdate[9]);

第二种方法 内存映射和读取一体函数

    //在设备树中 由读取属性值和内存映射同时进行的函数 of_iomap 函数  获得的是reg属性
    //index 起始地址加内存段长度是一个index 
    IMX6U_CCM_CCGR1 = of_iomap(dtsled.nd, 0);
	SW_MUX_GPIO1_IO03 = of_iomap(dtsled.nd, 1);
  	SW_PAD_GPIO1_IO03 = of_iomap(dtsled.nd, 2);
	GPIO1_DR = of_iomap(dtsled.nd, 3);
	GPIO1_GDIR = of_iomap(dtsled.nd, 4);

————————————————————————————————————————————之后 //初始化时钟      //初始化IO复用 //初始化电气属性 //初始化GPIO 设置输入还是输出 led是输出灯    //初始化高低电平控制led 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值