题目:应用层采取ioctl命令控制,驱动代码用GPIO子系统,实现开发板6盏灯的循环亮灭

头文件程序:

#ifndef __LED_H__
#define __LED_H__typedef enum{LED1,LED2,LED3,LED4,LED5,LED6,
}led_t;//编写命令码
#define LED_ON _IOW('a',1,int)
#define LED_OFF _IOW('a',0,int)
#endif

应用层程序:

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include "led.h"
char buf[128]={""};
int main(int argc,char const *argv[])
{int whitch,i;int fd;fd = open("/dev/myled0",O_RDWR);while(1){whitch = LED1;ioctl(fd,LED_ON,&whitch);sleep(1);ioctl(fd,LED_OFF,&whitch);sleep(1);whitch = LED2;ioctl(fd,LED_ON,&whitch);sleep(1);ioctl(fd,LED_OFF,&whitch);sleep(1);whitch = LED3;ioctl(fd,LED_ON,&whitch);sleep(1);ioctl(fd,LED_OFF,&whitch);sleep(1);whitch = LED4;ioctl(fd,LED_ON,&whitch);sleep(1);ioctl(fd,LED_OFF,&whitch);sleep(1);whitch = LED5;ioctl(fd,LED_ON,&whitch);sleep(1);ioctl(fd,LED_OFF,&whitch);sleep(1);whitch = LED6;ioctl(fd,LED_ON,&whitch);sleep(1);ioctl(fd,LED_OFF,&whitch);sleep(1);}close(fd);return 0;
}

驱动程序:

#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/of.h>
#include <linux/gpio.h>
#include <linux/of_gpio.h>
#include <linux/uaccess.h>
#include "led.h"#define CNAME "myled"
struct class *cls;
struct device *dev;
struct cdev *mycdev;
struct device_node *node;
struct gpio_desc* gpiono1;
struct gpio_desc* gpiono2;
struct gpio_desc* gpiono3;
struct gpio_desc* gpiono4;
struct gpio_desc* gpiono5;
struct gpio_desc* gpiono6;
int ret;
#if 1
unsigned int major = 0;
#else
unsigned int major = 500;
#endif
int minor =0;
const int count = 1;
int mycdev_open(struct inode *inode,struct file *file)
{printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);return 0;
}
ssize_t mycdev_read(struct file* file,char __user *ubuf,size_t size,loff_t *loffs)
{printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);return 0;
}
ssize_t mycdev_write(struct file* file,const char __user *ubuf,size_t size,loff_t *loffs)
{printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);return 0;
}
int mycdev_close(struct inode *inode,struct file *file)
{printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);return 0;
}
long mycdev_ioctl(struct file* file,unsigned int cmd,unsigned long arg)
{int whitch;switch (cmd){case LED_ON:ret = copy_from_user(&whitch,(void*)arg,4);printk("whitch = %d\n",whitch);switch (whitch) //判断是哪个灯需要被点亮{case LED1:{//点亮led1gpiod_set_value(gpiono1,1);break;}case LED2:{gpiod_set_value(gpiono2,1);break;}case LED3:{//点亮ledgpiod_set_value(gpiono3,1);break;}case LED4:{//点亮ledgpiod_set_value(gpiono4,1);break;}case LED5:{//点亮ledgpiod_set_value(gpiono5,1);break;}case LED6:{//点亮ledgpiod_set_value(gpiono6,1);break;}}break;case LED_OFF:ret = copy_from_user(&whitch,(void*)arg,4);switch (whitch) //判断是哪个灯需要被点亮{ case LED1:{//熄灭led1gpiod_set_value(gpiono1,0);break;}case LED2:{//熄灭led2gpiod_set_value(gpiono2,0);break;}case LED3:{//熄灭led3gpiod_set_value(gpiono3,0);break;}case LED4:{//熄灭led4gpiod_set_value(gpiono4,0);break;}case LED5:{//熄灭led5gpiod_set_value(gpiono5,0);break;}case LED6:{//熄灭led6gpiod_set_value(gpiono6,0);break;}}break;}return 0;
}
const struct file_operations fops ={.open = mycdev_open,.read = mycdev_read,.write = mycdev_write,.release = mycdev_close,.unlocked_ioctl = mycdev_ioctl,
};
static int __init demo_init(void)
{int ret = 0;dev_t devno;int i;//分配cdev结构体空间mycdev = cdev_alloc();if(NULL == mycdev){printk("cdev alloc error\n");ret = -EIO;goto ERR1;}//初始化结构体cdev_init(mycdev,&fops);//申请设备号if(major >0){//静态申请设备号ret = register_chrdev_region(MKDEV(major,minor),count,CNAME);if(ret){printk("register chrdev regin error\n");ret = -ENOMEM;goto ERR2;}}else {//动态申请设备号ret = alloc_chrdev_region(&devno,0,count,CNAME);if(ret){printk("alloc_chrdev error\n");ret = -ENOMEM; goto ERR2;}major = MAJOR(devno);minor = MINOR(devno);}//驱动注册ret = cdev_add(mycdev,MKDEV(major,minor),count);if(ret){printk("cdev add error\n");ret = -EIO;goto ERR3;}//自动创建设备节点//提交目录信息cls = class_create(THIS_MODULE,CNAME);if(IS_ERR(cls)){printk("class create error\n");ret = PTR_ERR(cls);goto ERR4;}//提交设备节点信息for(i=0;i<count;i++){dev = device_create(cls,NULL,MKDEV(major,i),NULL,"myled%d",i);if(IS_ERR(dev)){printk("device create error\n");ret = PTR_ERR(dev);goto ERR5;}}//通过名字获取设备树节点信息node=of_find_node_by_name(NULL,"myleds");if(node==NULL){printk("通过名字解析设备树节点失败\n");return -EFAULT;}printk("成功解析到设备树节点\n");gpiono1 = gpiod_get_from_of_node(node,"myled1",0,GPIOD_OUT_LOW,NULL);if(IS_ERR(gpiono1)){printk("获取gpio编号1失败\n");return PTR_ERR(gpiono1);}//设置输出模式gpiod_direction_output(gpiono1,0);gpiono2 = gpiod_get_from_of_node(node,"myled2",0,GPIOD_OUT_LOW,NULL);if(IS_ERR(gpiono2)){printk("获取gpio编号2失败\n");return PTR_ERR(gpiono2);}//设置输出模式gpiod_direction_output(gpiono2,0);gpiono3 = gpiod_get_from_of_node(node,"myled3",0,GPIOD_OUT_LOW,NULL);if(IS_ERR(gpiono3)){printk("获取gpio编号3失败\n");return PTR_ERR(gpiono3);}//设置输出模式gpiod_direction_output(gpiono3,0);gpiono4 = gpiod_get_from_of_node(node,"myled4",0,GPIOD_OUT_LOW,NULL);if(IS_ERR(gpiono4)){printk("获取gpio编号4失败\n");return PTR_ERR(gpiono4);}//设置输出模式gpiod_direction_output(gpiono4,0);gpiono5 = gpiod_get_from_of_node(node,"myled5",0,GPIOD_OUT_LOW,NULL);if(IS_ERR(gpiono5)){printk("获取gpio编号5失败\n");return PTR_ERR(gpiono5);}//设置输出模式gpiod_direction_output(gpiono5,0);gpiono6 = gpiod_get_from_of_node(node,"myled6",0,GPIOD_OUT_LOW,NULL);if(IS_ERR(gpiono6)){printk("获取gpio编号6失败\n");return PTR_ERR(gpiono6);}//设置输出模式gpiod_direction_output(gpiono6,0);return 0;
ERR5:for(--i;i>=0;i--){device_destroy(cls,MKDEV(major,i));}class_destroy(cls);ERR4:cdev_del(mycdev);
ERR3:unregister_chrdev_region(MKDEV(major,minor),count);
ERR2:kfree(mycdev);
ERR1:return -EIO;
}
static void __exit demo_exit(void)
{int i = 0;gpiod_put(gpiono1);gpiod_put(gpiono2);gpiod_put(gpiono3);gpiod_put(gpiono4);gpiod_put(gpiono5);gpiod_put(gpiono6);//销毁设备节点信息for(i=0;i<count;i++){device_destroy(cls,MKDEV(major,i));}//销毁目录信息class_destroy(cls);//驱动注销cdev_del(mycdev);//注销设备号unregister_chrdev_region(MKDEV(major,minor),count);//释放结构体指针kfree(mycdev);
}module_init(demo_init);
module_exit(demo_exit);
MODULE_LICENSE("GPL");

测试结果:

华清远见上海中心22071班--11.24作业相关推荐

  1. 华清远见上海中心22071班--11.19作业

    题目:实现开发板点灯操作 程序要求: 1)分部实现注册字符设备驱动 2)自动创建设备节点 3)通过结构体对led灯地址进行映射 4)次设备号完成私有数据传参 5)在open函数中获取到次设备号,用私有 ...

  2. 华清远见上海中心22071班--11.28作业

    题目:三个按键实现按键中断,key1>>led1,key2>>led2, key3>>led3.按键按一下灯亮,再按一下灯灭 . #include <linu ...

  3. 华清远见上海中心22071班--11.29作业

    题目:paltform总线中通过名字.名字列表和设备树三种方式实现driver和device匹配 方式一>>>名字: #include <linux/init.h> #i ...

  4. 华清远见上海中心22071班 8.24作业

    1.单向链表按位置修改 void list_update_pos(linklist *L,int pos,datatype e) {if(NULL==L||list_empty(L)||pos< ...

  5. 华清远见上海中心22071班 8.25作业

    目录 1.用无头结点的循环链表实现约瑟夫环问题 头文件: 功能函数: 主函数: 终端输出: 2.顺序栈实现进制转换问题 头文件: 功能函数: 主函数: 终端输出: 1.用无头结点的循环链表实现约瑟夫环 ...

  6. 华清远见上海中心22071班 9.2作业

    1.用父子进程拷贝一张图片,其中子进程先拷贝后半部分,父进程后拷贝前半部分.要求用文件IO实现. 函数: #include <stdio.h> #include <fcntl.h&g ...

  7. 华清远见上海中心22071班 9.7作业

    目录 1.创建两个线程 A.B,要求A线程读取文件中的数据,B线程将读取到的数据打印到终端上,类似shell命令cat. 2.编写一个程序,开启3个线程,这3个线程的ID分别为A.B.C,每个线程将自 ...

  8. 华清远见上海中心22071班 9.30作业

    电子词典: 登录注册功能,不能重复登录,重复注册 单词查询功能 历史记录功能,存储单词,意思,以及查询时间 基于TCP,支持多客户端连接 采用数据库保存用户信息与历史记录 将dict.txt的数据导入 ...

  9. 华清远见上海中心22071班 9.21作业

    1.完成数据库的插入.删除.修改,插入选择全字段插入.删除.修改选择用id的方式 代码: #include <stdio.h> #include <sqlite3.h> #in ...

最新文章

  1. 秋季4类疾病患者忌吃螃蟹
  2. Sql Server 连接池
  3. win8 html文件怎么打开,技术员研习win8系统html文件图标变成空白的技巧
  4. mac 安装nvm和nvm常见的命令
  5. 使用简介EntityFramework6.0
  6. 复旦大学计算机科学院夏令营,2020年复旦大学计算机科学技术学院夏令营接收推免生条件...
  7. 红旗河最早设计计算机的目的,论红旗河的利弊及其替代方案
  8. [html] 编写html时,你有没有用过Emmet插件呢?说说它的优点及规则有哪些?
  9. Spring Boot Initilizr - 使用Spring Boot CLI
  10. dtree 后台管理例子_产品的后台设计整理与总结
  11. pthread库进行多线程编程 - 组件工厂 - C++博客
  12. 自定义Android TabHost的背景及文字
  13. 用Java发起HTTP请求与获取状态码(含状态码列表)
  14. el-table 树形表格 自定义展开图标_目前比较满意的安卓桌面启动器:非线性动画 + 精美图标包...
  15. 作死!研究生用实验室里的烧杯冲咖啡,喝完就进了医院抢救
  16. 国外LEAD赚钱提现到WMZ,附赚钱项目
  17. 麦子学院字符设备驱动201126
  18. 飞入菜花无处寻的上一句是什么,飞入菜花无处寻是什么意思
  19. linux如何进入文件编辑,Linux 文件编辑工具
  20. 在kubernetes集群用helm离线安装harbor

热门文章

  1. 利用WPS工具检查身份证号码的正确性
  2. Java官网下载JDK17版本详细教程(下载、安装、环境变量配置)
  3. 明日计划 - 2017.03.15
  4. 3DSlicer导入锥束CT图像
  5. 10.模型层与ORM
  6. centos卸载不必要的程序_Centos 利用yum安装卸载软件常用命令[转载]
  7. Linux内存管理(四十六):内核OOM机制详解
  8. 从零打造视频播放网站(3)-前端设计篇
  9. MongoDB设置登录账号,密码及权限
  10. navicat还需要下载mysql_navicat for mysql的下载、安装与基本使用