platform平台总线实现LED字符设备驱动

参考内核中存在的字符设备驱动进行编写,如misc.c这个经典的字符设备驱动。

一、LED字符设备驱动平台设备实现

1、查看手册获取相关寄存器

寄存器宏定义:

#define  CCM_CCGR1               0x20C406C  //打开/关闭时钟的寄存器地址 : 使用一个模块前必须开发它的使用,默认是打开的
#define  MUX_PAD_GPIO1_IO04      0x20E006C    //GPIO复用寄存器地址 : 复用pin为GPIO功能还是其他功能
#define  GPIO1_DR                0x209C000    //GPIO输入输出寄存器地址
#define  GPIO1_GDIR              0x209C004    //GPIO方向寄存器 :设置GPIO为输入还是输出模式#define  REG_LEN                 4              //寄存器地址长度

对于GPIO的配置使用和STM32等单片机使用寄存器开发是一样的。

2、定义硬件资源描述struct resource

static struct resource red_led_resource[] = {[0] = {.start =  CCM_CCGR1,.end   = (CCM_CCGR1 + REG_LEN - 1),.flags = IORESOURCE_MEM,},[1] = {.start =  MUX_PAD_GPIO1_IO04,.end   = (MUX_PAD_GPIO1_IO04 + REG_LEN - 1),.flags = IORESOURCE_MEM,},[2] = {.start =  GPIO1_DR,.end   = (GPIO1_DR + REG_LEN - 1),.flags = IORESOURCE_MEM,},[3] = {.start =  GPIO1_GDIR,.end   = (GPIO1_GDIR + REG_LEN - 1),.flags = IORESOURCE_MEM,},
};

对于硬件的操作就是对寄存器的操作,而硬件的寄存器是映射到内存地址上的,所以就是操作内存。所以flags资源类型选择的是IORESOURCE_MEM,start - 寄存器的其实地址,end - 寄存器的结束地址。

3、定义平台设备

static void red_led_platform_release(struct device *dev)
{}static struct platform_device  red_led_device = {.name = "red_led",.id = -1,.resource = red_led_resource,              //注入硬件资源.num_resources = ARRAY_SIZE(red_led_resource),    //硬件资源数组大小.dev.release = red_led_platform_release,
};

4、平台设备入口函数

static int __init red_led_platform_device_init(void)
{printk("red_led_platform_device_init\r\n");int ret = platform_device_register(&red_led_device);return ret;
}module_init(red_led_platform_device_init);
  • platform_device_register - 注册平台设备

5、平台设备出口函数

static void __exit red_led_platform_device_exit(void)
{printk("red_led_platform_device_exit\r\n");platform_device_unregister(&red_led_device);
}
  • platform_device_unregister - 卸载平台设备驱动

二、LED字符设备平台驱动实现

平台设备的struct file_operations结构函数还是和传统方式一样的实现。

对于平台驱动方式实现的led驱动的变化:

1、定义平台驱动

static struct platform_driver red_led_platform_driver = {.probe = led_red_driver_probe,.remove = led_red_driver_remove,.driver.name = "red_led",
};
  • .driver.name 字段的值red_led和平台设备中的name字段一致,表示通过名字进行平台设备和驱动的匹配

2、在probe()函数中进行初始化工作

static int led_red_driver_probe(struct platform_device *dev)
{struct resource *ccm_ccgr1 = platform_get_resource(dev, IORESOURCE_MEM, 0);  //获取设备中定义的文件资源struct resource *mux_pad_gpio1_io4 = platform_get_resource(dev, IORESOURCE_MEM, 1);struct resource *gpio1_dr = platform_get_resource(dev, IORESOURCE_MEM, 2);struct resource *gpio1_gdir = platform_get_resource(dev, IORESOURCE_MEM, 3);if (ccm_ccgr1 == NULL || mux_pad_gpio1_io4 == NULL || gpio1_dr == NULL || gpio1_gdir == NULL)return -1;_CCM_CCGR1 = ioremap(ccm_ccgr1->start, resource_size(ccm_ccgr1)); //将寄存器物理地址映射为虚拟地址                    _MUX_PAD_GPIO1_IO04 = ioremap(mux_pad_gpio1_io4->start, resource_size(mux_pad_gpio1_io4));_GPIO1_DR = ioremap(gpio1_dr->start, resource_size(gpio1_dr));_GPIO1_GDIR = ioremap(gpio1_gdir->start, resource_size(gpio1_gdir));  int err;major = register_chrdev(0, "my_led", &led_drv);led_class = class_create(THIS_MODULE, "my_led_class");err = PTR_ERR(led_class);if (IS_ERR(led_class)) {unregister_chrdev(major, "my_led"); return -1;}device_create(led_class, NULL, MKDEV(major, 0), NULL, "my_led"); printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);return 0;
}
  • struct resource *ccm_ccgr1 = platform_get_resource(dev, IORESOURCE_MEM, 0) - 获取平台设备定义的硬件资源
  • _CCM_CCGR1 = ioremap(ccm_ccgr1->start, resource_size(ccm_ccgr1) - 将寄存器物理地址映射为虚拟地址

3、在remove()函数中做卸载/解初始化工作

int led_red_driver_remove(struct platform_device *dev)
{iounmap(_CCM_CCGR1);iounmap(_MUX_PAD_GPIO1_IO04);iounmap(_GPIO1_DR);iounmap(_GPIO1_GDIR);printk(" %s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);device_destroy(led_class, MKDEV(major, 0));class_destroy(led_class);unregister_chrdev(major, "my_led");return 0;
}

4、平台设备的注册/卸载

//平台设备入口函数
static int __init red_led_driver_init(void)
{printk(" %s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);int ret = platform_driver_register(&red_led_platform_driver);return ret;
}//平台设备出口函数
static void __exit red_led_driver_exit(void)
{printk(" %s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);platform_driver_unregister(&red_led_platform_driver);
}module_init(red_led_driver_init);
module_exit(red_led_driver_exit);MODULE_AUTHOR("Ares");
MODULE_LICENSE("GPL");

5、加载/卸载驱动

sudo insmod platform_led_device.ko     //安装led platform device
sudo insmod platform_led_driver.ko     //安装led platform driver

在加载设备和驱动匹配成功后,会在系统目录/sys/bus/platform/devices//sys/bus/platform/driver/*出现相应led deviceled driver的目录

Linux设备驱动 | LED字符设备驱动(platform平台总线)相关推荐

  1. <Linux开发>--驱动开发-- 字符设备驱动(3) 过程详细记录

    <Linux开发>–驱动开发-- 字符设备驱动(3) 过程详细记录 驱动开发是建立再系统之上的,前面作者也记录了系统移植的过程记录,如果有兴趣,可进入博主的主页查看相关文章,这里就不添加链 ...

  2. 【linux驱动之字符设备驱动基础】

    linux驱动之字符设备驱动基础 文章目录 linux驱动之字符设备驱动基础 前言 一.开启驱动学习之路 二.驱动预备知识 三.什么是驱动? 3.1 驱动概念 3.2 linux 体系架构 3.3 模 ...

  3. linux驱动之字符设备

    linux驱动之字符设备 linux驱动设备分类 linux驱动分为了三种驱动: 字符设备: 字符设备和应用程序之间是以字节进行进行数据交换的.在进行数据交换的时候数据是以一定顺序进行传输的,传输是实 ...

  4. Linux驱动之字符设备驱动

    系列文章目录 第一章 Linux入门之驱动框架 第二章 Linux驱动之字符设备驱动 文章目录 系列文章目录 前言 一.认识字符设备驱动 1.基本概念 2.基本概念 二.字符设备旧框架 1.注册和注销 ...

  5. linux用户空间flash驱动,全面掌握Linux驱动框架——字符设备驱动、I2C驱动、总线设备驱动、NAND FLASH驱动...

    原标题:全面掌握Linux驱动框架--字符设备驱动.I2C驱动.总线设备驱动.NAND FLASH驱动 字符设备驱动 哈~ 这几天都在发图,通过这种方式,我们希望能帮大家梳理学过的知识,全局的掌握Li ...

  6. 一起分析Linux系统设计思想——05字符设备驱动框架剖析(四)

    在学习资料满天飞的大环境下,知识变得非常零散,体系化的知识并不多,这就导致很多人每天都努力学习到感动自己,最终却收效甚微,甚至放弃学习.我的使命就是过滤掉大量的垃圾信息,将知识体系化,以短平快的方式直 ...

  7. linux的驱动开发——字符设备驱动

    1.字符设备驱动 \qquad字符设备驱动是最基本,最常用的设备.它将千差万别的硬件设备采用统一的接口封装起来,屏蔽了硬件的差异,简化了应用层的操作. 2.描述所有字符设备的结构体 \qquad描述所 ...

  8. linux PCI驱动调用字符设备驱动方式

    上一篇文章写了字符设备驱动的基本结构及访问方式,在实际应用时首先需要绑定自己的硬件设备.本篇主要描述字符设备驱动与PCI接口类型的设备访问方式(内核为2.6.24及以上的方法,测试内核为2.6.32) ...

  9. Linux内核学习-字符设备驱动学习(二)

    在Linux内核学习-字符设备驱动学习(一)中编写字符设备驱动的一种方法,但是需要手动创建设备节点. 有没有能够自动的创建设备节点的呢? 有!使用class_create()和device_creat ...

  10. Linux设备驱动模型之platform(平台)总线详解

    /********************************************************/ 内核版本:2.6.35.7 运行平台:三星s5pv210 /*********** ...

最新文章

  1. 1043 输出PATest
  2. ansys的kbc_ansys求解过程
  3. java 工厂模式 计算器_简单工厂模式实现简易计算器
  4. boost::sloan_ordering用法的测试程序
  5. php限制只能中文,php如何实现一个账号只能有一个人登录
  6. vue ---- 插槽
  7. 单一世界十万在线webgame的设计思路(五)-- 整体架构和总结
  8. ThinkPHP2.1 增加PHPCMS模板引擎,支持PC标签(get,json)
  9. python雷达信号处理,信号处理之功率谱原理与python实现
  10. 火狐扩展教程_5个Firefox扩展保护您的隐私
  11. feasycom蓝牙对接Android,蓝牙音频收发一体方案
  12. html控制萤石云摄像头转动,萤石云摄像头直播带云台控制代码
  13. 模糊提取器(Fuzzy Extractor)
  14. Android so库动态加载总结
  15. HEVC视频扩展解决方法
  16. 知识图谱构建:py2neo的实体关系以及节点显示图片
  17. 怎么编辑gif动态图片?gif动图编辑的操作步骤
  18. 100000行级别数据的 Excel 导入优化之路
  19. 宇宙学colossus库介绍
  20. nokia n1 android 6,到手的NOKIA 诺基亚 N1平板 — 王者归来?呵呵

热门文章

  1. matlab质心定位算法,一种改进的质心定位算法
  2. win10右键一直转圈_windows10为何鼠标右键一点桌面就一直转圈?
  3. 示波器电流探头应该怎么保养-PinTech品致
  4. 占鳌头。当雪花沁透着
  5. chrome regedit 崩溃_谷歌浏览器网页崩溃的解决方法
  6. bspline怎么使用 python_B-Spline曲线拟合
  7. AssertionError: Torch not compiled with CUDA enabled
  8. Python win8安装
  9. win7系统使用高版本node.js
  10. 十二平均律的数学描述