设备树下的 LED 驱动实验 您所在的位置:网站首页 驱动精灵有必要安装吗 设备树下的 LED 驱动实验

设备树下的 LED 驱动实验

2023-05-18 14:58| 来源: 网络整理| 查看: 265

修改设备树文件

在根节点“/”下创建一个名为“alphaled”的子节点,打开 imx6ull-alientek-emmc.dts 文件, 在根节点“/”最后面输入如下所示内容:

alphaled { #address-cells = ; #size-cells = ; compatible = "atkalpha-led"; status = "okay"; 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 */ }; /* 第 2、3 行,属性#address-cells 和#size-cells 都为 1,表示 reg 属性中起始地址占用一个字长 (cell),地址长度也占用一个字长(cell)。 第 4 行,属性 compatbile 设置 alphaled 节点兼容性为“atkalpha-led”。 第 5 行,属性 status 设置状态为“okay”。 第 6~10 行,reg 属性,非常重要!reg 属性设置了驱动里面所要使用的寄存器物理地址,比 如第 6 行的“0X020C406C 0X04”表示 I.MX6ULL 的 CCM_CCGR1 寄存器,其中寄存器首地 址为 0X020C406C,长度为 4 个字节。 */

设备树修改完成以后输入如下命令重新编译一下 imx6ull-alientek-emmc.dts:  make dtbs

编译完成以后得到 imx6ull-alientek-emmc.dtb,使用新的 imx6ull-alientek-emmc.dtb 启动 Linux 内核。Linux 启动成功以后进入到/proc/device-tree/目录中查看是否有“alphaled”这个节 点,如图

 如果没有“alphaled”节点的话请重点查看下面两点:

①、检查设备树修改是否成功,也就是 alphaled 节点是否为根节点“/”的子节点。

②、检查是否使用新的设备树启动的 Linux 内核。

可以进入到alphaled 目录中,查看一下都有哪些属性文件,

LED 灯驱动程序编写

#include #include #include #include #include #include #include #include #define LEDOFF 0 //关闭 #define LEDON 1 //打开 #define DTSLED_NAME "dts_led" //设备名字 #define DTSLED_CONUT 1 //设备号个数 /*地址映射后的虚拟地址指针*/ 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; /*dtsled设备结构体*/ struct dtsled_dev { struct cdev cde; //字符设备 struct class *class; //类 struct device *device; //设备 dev_t devid; //设备号 int major; //主设备号 int minor; //次设备号 struct device_node *bl_nd; //设备节点 }; struct dtsled_dev dtsled; /*led设备*/ /*LED灯打开/关闭*/ static void led_switch(u8 sta) { u32 val = 0; if(sta == LEDON) { val = readl(GPIO1_DR); val &= ~(1 private_data; return 0; } static ssize_t dtsled_write(struct file *filp, const char __user *buf, size_t count, loff_t *ppos) { struct dtsled_dev *dev = (struct dtsled_dev *)filp -> private_data; int retvalue; unsigned char databuf[1]; retvalue = copy_from_user(databuf,buf,count); if(retvalue < 0) { return -EFAULT; } /*判断是开灯还是关灯*/ led_switch(databuf[0]); return 0; } //dtsled字符设备操作集 const struct file_operations dtsled_fops = { .owner = THIS_MODULE, .write = dtsled_write, .open = dtsled_open, .release = dtsled_close, }; /*入口*/ static int __init dtsled_init(void) { int ret = 0; const char *str; //u32 brival[10]; //u8 i = 0; unsigned int val = 0; /*1.申请设备号*/ dtsled.major = 0; //设备号由内核分配 if(dtsled.major) //定义了设备号 { dtsled.devid = MKDEV(dtsled.major,0); ret = register_chrdev_region(dtsled.devid,DTSLED_CONUT,DTSLED_NAME); }else //没有定义设备号 { ret = alloc_chrdev_region(&dtsled.devid,0,DTSLED_CONUT,DTSLED_NAME); dtsled.major = MAJOR(dtsled.devid); dtsled.minor = MINOR(dtsled.devid); if (ret < 0) { printk("dtsled chardev_region err\r\n"); return -1; } } /*2.添加字符设备*/ dtsled.cde.owner = THIS_MODULE; cdev_init(&dtsled.cde,&dtsled_fops); ret = cdev_add(&dtsled.cde,dtsled.devid,DTSLED_CONUT); if (ret < 0) { goto fail_cdev; } /*3.自动创建设备节点*/ dtsled.class = class_create(THIS_MODULE,DTSLED_NAME); if (IS_ERR(dtsled.class)) { ret = PTR_ERR(dtsled.class); goto fail_class; } /*4.创建设备*/ dtsled.device = device_create(dtsled.class,NULL,dtsled.devid,NULL,DTSLED_NAME); if(IS_ERR(dtsled.device)) { ret = PTR_ERR(dtsled.device); goto fail_device; } /*获取设备树属性内容*/ dtsled.bl_nd = of_find_node_by_path("/alphaled"); if (dtsled.bl_nd == NULL) { ret = -EINVAL; goto fail_findnd; } /*获取属性*/ ret = of_property_read_string(dtsled.bl_nd,"status",&str); if (ret < 0) { goto fail_rs; }else { printk("status = %s\r\n",str); } ret = of_property_read_string(dtsled.bl_nd,"compatible",&str); if (ret < 0) { goto fail_rs; }else { printk("compatible = %s\r\n",str); } #if 0 ret = of_property_read_u32_array(dtsled.bl_nd,"reg",brival,10); if (ret


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有