#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define MY_DEVICE_NAME "my_LED_device"

// 获取到设备树中到节点

static int gpio = -1;

int get_irqno_from_node(void)

{

struct gpio_config config;

struct device_node *np = of_find_node_by_path("/leds");

IF(np){

printk("find node ok\n");

}

else{

printk("find node failed\n");

}

gpio = of_get_named_gpio_flags(nd, "gpios", i, (enum of_gpio_flags *)&config);// 从设备树中读取gpios的GPIO配置编号和标志

if(!gpio_is_valid(gpio)){

//判断该 GPIO 编号是否有效,有效gpio_request 则申请占用该 GPIO。如果初始化过程出错,需要调用 gpio_free 来释放之前申请过且成功的 GPIO

printk("gpio isn't valid\n");

return -1;

}

if(gpio_request(gpio, "leds") < 0)

printk("gpio request failed %d\n", gpio);

gpio_direction_output(gpio, 1); //关灯

return 0;

}

static int my_open (struct inode *node, struct file *filp)

{

if(gpio)

{

printk("open ok\n");

}

else

{

return -EINVAL;

}

return 0;

}

static ssize_t my_write (struct file *filp, const char __user *buf, size_t size, loff_t *off)

{

unsigned char val;

copy_from_user(&val, buf, 1);

printk(" gpl_dat address   0x%x\n",gpl_dat);

if (val)

{

gpio_direction_output(gpio, 0); //关灯

printk("led on\n");

}

else

{

gpio_direction_output(gpio, 1); //关灯

printk("led off\n");

}

return 1;

}

static const struct file_operations my_led_fops = {

//step 1 :定义file_operations结构体

.open = my_open,

.write = my_write,

};

//step 1 :

static struct class *led_class;

static struct cdev *pcdev;      //定义一个cdev指针

static dev_t n_dev;            //第一个设备号(包含了主和次)

static int __init led_device_init(void)

{//step 2 :注册

int ret = -1;

pcdev = cdev_alloc();//分配cdev结构空间

if(pcdev == NULL) {

printk(KERN_EMERG" cdev_alloc  error\n");

ret = -ENOMEM;   /* 分配失败 */

return ret;

}

//2. 动态申请设备号

ret = alloc_chrdev_region(&n_dev, 0 , 2, MY_DEVICE_NAME);

if(ret < 0 ) {

//释放前面成功的资源

kfree(pcdev);                              /*释放cdev结构空间 */

printk(KERN_EMERG"alloc_chrdev_region  error\n");

return ret;

}

cdev_init(pcdev, &my_led_fops);     //初始化cdev结构           /* 建立cdev和file_operations之间的连接 */

/*

或这样初始化cdev结构

pcdev->owner = THIS_MODULE;

pcdev->ops = &my_led_fops;

*/

ret = cdev_add(pcdev, n_dev, 2) ;// 向内核里面添加一个驱动,注册驱动

if(ret < 0 ) {

//释放前面成功的资源

unregister_chrdev_region(n_dev,  2);       /*  释放前面申请的调和号*/

kfree(pcdev);                               /* 释放cdev结构空间 */

printk(KERN_EMERG"alloc_chrdev_region  error\n");

return ret;

}

/*自动创建设备节点/dev/SinlinxA64_LED*/

led_class = class_create(THIS_MODULE, "myled");

device_create(led_class, NULL, n_dev, NULL, "SinlinxA64_LED");

get_irqno_from_node();

printk(KERN_EMERG"cdev ok\n");

return 0;

}

static void __exit led_device_exit(void)

{    //step 2 :注销

//注销cdev结构

cdev_del(pcdev);

//释放设备号

unregister_chrdev_region(n_dev, 2); /*起始设备号(主、次) 连续的次设备号数量*/

//释放cdev结构空间

kfree(pcdev);

device_destroy(led_class, n_dev);

class_destroy(led_class);

gpio_free(gpio);

printk(KERN_EMERG"cdev_del ok\n");

}

module_init(led_device_init);

module_exit(led_device_exit);

MODULE_LICENSE("GPL");

全志linux led驱动程序,芯灵思Sinlinx A64 linux通过设备树写LED驱动(附参考代码,未测试)...相关推荐

  1. 全志a64linux内核编译,芯灵思Sinlinx A64 Linuxqt编译安装

    开发平台 芯灵思Sinlinx A64 内存: 1GB 存储: 4GB 开发板交流 641395230 前提条件搭建好CentOS环境 光盘目录 :芯灵思SIN-A64光盘资料\Linux & ...

  2. 芯灵思Sinlinx A64开发板 Linux内核等待队列p

    阻塞:阻塞调用是指调用结果返回之前,当前进程程会被挂起(休眠).函数只有在得到结果之后才会返回.默认情况下,文件都是以这种方式打开. 非阻塞:指在不能立刻得到结果之前,该函数不会阻塞当前进程程,而会立 ...

  3. Linux设备树led,linux设备树下LED灯控制

    linux设备树下LED灯控制 linux设备树下LED灯控制 原理图: 所以在设备树下子节点下插入gpioled节点: gpioled { #address-cells = <1>; # ...

  4. Linux驱动_设备树下LED驱动

    前言 学习完设备树基础知识后,完成设备树下LED驱动实验 一.修改设备树文件 在设备书根/节点下添加子节点led信息: alphaled {status = "okay";comp ...

  5. 【基于Linux系统设备树的SPI驱动编写方法】

    文章目录 前言 一.SPI驱动编写 1.修改设备树  a.设备树文件是什么?  b.设备树怎么改? 2.编写驱动 二.完善和测试 1.编译和应用程序  a.编译 && 拷贝到开发板命令 ...

  6. Linux利用platform_driver和设备树实现PWM驱动

    Linux利用platform_driver和设备树实现PWM驱动 字符设备PWM驱动 一.PWM驱动的硬件资源 1.PWM工作原理 2.PWM电路原理 3.PWM内部结构 二.具体代码 1.设备树 ...

  7. Linux dts设备树和platform驱动详解

    概念 小麦大叔 2019-05-06 22:56:31 12603 收藏 135 什么是设备树 dts(device tree)? 设备树(Device Tree)是描述计算机的特定硬件设备信息的数据 ...

  8. linux设备和驱动匹配的方法,Linux使用设备树的i2c驱动与设备匹配方式

    Linux使用设备树的i2c驱动与设备匹配有3种方式: of_driver_match_device acpi_driver_match_device i2c_match_id 源码: static ...

  9. linux u 驱动程序,在uClinux中增加自己的设备驱动程序

    驱动程序的使用可以按照两种方式编译,一种是静态编译进内核,另一种是编译成模块以供动态加载.由于 uClinux不支持模块动态加载,而且嵌入式Linux不能够象桌面Linux那样灵活的使用insmod/ ...

最新文章

  1. 搜索引擎中的URL散列
  2. 【解决方法】java.lang.ClassNotFoundException:
  3. python decorator ssh_Python库现后门 可窃取用户SSH信息
  4. 2016福州大学软件工程第四次团队作业-系统设计成绩汇总
  5. 时隔一年俺又回来了..
  6. Nutanix企业云助力嘉里大通提升核心竞争力
  7. FreeEIM 是班级的学习委员
  8. (7)UART接收verilog与Systemverilog编码
  9. Excel如何批量根据身份证号码查询出地址
  10. NX的尺寸控制与半径补偿(重要)
  11. 用Cocos Creator 模拟书本翻页效果
  12. 计算机应用技术一班班徽,1班班徽设计图片大全欣赏
  13. ClickHouse表引擎到底怎么选
  14. 移动端自动轮播可滑动轮播图
  15. 颜色综述何为三原色?配色原理?
  16. meshgrid()函数
  17. python实现md5和sha1加密
  18. 干货分享:智慧工厂时代下大数据 + 智能的深度实践
  19. gson线上环境解析日期时报错JsonSyntaxException
  20. oracle创建带blob字段的表,ORACLE 还有BLOB及CLOB等类型字段的表的导出导入

热门文章

  1. windows平台一个高性能、通用型的C++生产者/消费者架构模板
  2. 论文笔记:PRIN: Pointwise Rotation-Invariant Networks
  3. 论文笔记:Image Caption(Show and Tell)
  4. html 设置视频尺寸,如何使用CSS控制视频的宽高?
  5. 团队作业第二次—项目选题报告(追光的人)
  6. Nginx 实现AJAX跨域请求
  7. CSS Dock Menu:JS+CSS 仿苹果MAC机桌面导航菜单
  8. Oh-My-Zsh 操作 Git 的快捷键
  9. Leaflet实现地图分屏联动
  10. U盘安装openSuse