Linux驱动认知简明导论③ —— 修改树莓派引脚文件pin4Driver.c操作IO口
原创首发于CSDN,转载请注明出处,谢谢!https://blog.csdn.net/weixin_46959681/article/details/118150759
文章目录
- 前言
- 修改引脚驱动文件 pin4Driver.c(GPIO)
- 修改上层应用的测试代码 pin4Test2.c
- IO口驱动代码调式与测试
- 参考资料
- 文章更新时间记录
前言
该篇博文不同于上一篇,上一篇博文笔者仅仅只记录了从上层空间到底层内核驱动的逻辑调用,并没有结合实际的硬件部分,故该篇博文笔者以树莓派的引脚电平操作为演练的实战记录。相比于其他几位朋友的同课题笔记,笔者也将整个系列做出了拆分,避免全文下来过于臃肿,这也是个人对于技术博客的一贯理解。
修改引脚驱动文件 pin4Driver.c(GPIO)
演示代码: raspberryGPIO.c
/* raspberryGPIO.c */
#include <linux/fs.h> //file_operations 声明
#include <linux/module.h> //module_init module_exit 声明
#include <linux/init.h> //__init __exit 宏定义声明
#include <linux/device.h> //class devise 声明
#include <linux/uaccess.h> //copy_from_user 的头文件
#include <linux/types.h> //设备号 dev_t 类型声明
#include <asm/io.h> //ioremap iounmap 的头文件static struct class *pin4_class;
static struct device *pin4_class_dev;static dev_t devno; //设备号
static int major = 231; //主设备号
static int minor = 0; //次设备号
static char *module_name= "pin4"; //模块名//函数volatil确保指令不被编译器优化,且要求每次直接读取寄存器里的器。
volatile unsigned int* GPFSEL0 = NULL;
volatile unsigned int* GPSET0 = NULL;
volatile unsigned int* GPCLR0 = NULL;//函数pin4_open
static int pin4_open(struct inode *inode,struct file *file)
{printk("pin4_open\n");*GPFSEL0 &= ~(0x6 << 12); *GPFSEL0 |= (0x1 << 12);return 0;
}//函数pin4_write
static ssize_t pin4_write(struct file *file1,const char __user *buf,size_t count, loff_t *ppos)
{int cmd;printk("pin4_write\n");//函数copy_from_user —— 获取上层应用空间的数据。copy_from_user(&cmd,buf,count);if(cmd == 1){printk("set 1.\n");*GPSET0 |= 0x1 << 4;//将引脚4设置为1}else if(cmd == 0){printk("set 0.\n");*GPCLR0 |= 0x1 << 4;//将引脚4设置为0}else{printk("error.\n");}printk("%d\n",cmd);return 0;
}static struct file_operations pin4_fops = {.owner = THIS_MODULE,.open = pin4_open,.write = pin4_write,
};int __init pin4_drv_init(void)
{int ret;printk("insmod driver pi4 success.\n");//1.创建设备号(主设备、次设备号)。devno = MKDEV(major,minor); printk("drive init succeed\n");//2.注册驱动:通知内核,将该驱动加入到驱动链表。ret = register_chrdev(major,module_name,&pin4_fops); //3.加载驱动代码文件时自动操作路径“/root/dev”下生成驱动设备。pin4_class = class_create(THIS_MODULE,"myfirstdriver");//4.创建设备文件pin4_class_dev = device_create(pin4_class,NULL,devno,NULL,module_name); //函数 ioremap —— 将IO的物理地址映射内存的虚拟地址。GPFSEL0 = (volatile unsigned int *)ioremap(0x3f200000,4);GPSET0 = (volatile unsigned int *)ioremap(0x3f20001C,4);GPCLR0 = (volatile unsigned int *)ioremap(0x3f200028,4);return 0;
}void __exit pin4_drv_exit(void)
{ //函数iounmap —— 与装载驱动的IO映射相对应,卸载驱动时必须解除映射。iounmap(GPFSEL0);iounmap(GPSET0);iounmap(GPCLR0);//1.销毁设备device_destroy(pin4_class,devno);//2.销毁类文件class_destroy(pin4_class);//3.卸载驱动unregister_chrdev(major, module_name);
}module_init(pin4_drv_init);
module_exit(pin4_drv_exit);
MODULE_LICENSE("GPL v2");
代码中微小的细节请读者自己细细品味。
修改上层应用的测试代码 pin4Test2.c
上层测试代码: pin4Test2.c
/* pin4Test2.c */
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>int main()
{int fd;int cmd;fd = open("/dev/pin4",O_RDWR);if(fd < 0){perror("Open failed:");}else{printf("Open success.\n");}printf("Please input number 0/1, 0 - Low Level, 1 - high Level.\n");scanf("%d\n",&cmd);if(cmd == 0){printf("pin4 is low level.\n");}if(cmd == 1){printf("pin4 is high level.\n");}write(fd,&cmd,4);return 0;
}
IO口驱动代码调式与测试
对于这两个文件的操作与笔者上一篇的驱动博文一样:交叉编译传送至树莓派 与 在树莓派内加载驱动以及测试,具体的步骤请看翻阅那篇博文的对应章节(重复写出来也无必要且过于繁琐)。
在树莓派上层试运行测试文件后输入 gpio readall,若发现的GPIO显示图里BCM“4”一栏对应部分反复切换0、1则说明操作成功。
参考资料
- 位运算(按位与、按位或、异或)
- 详细到吐血 —— 树莓派驱动开发入门:从读懂框架到自己写驱动
- 树莓派简单驱动编写
- 树莓派LED驱动编写
文章更新时间记录
- 文章框架初步搭好。 「2021.6.24 11:44」
- “修改上层应用的测试代码 pin4Test2.c”一节完成。 「2021.7.6 22:35」
- “IO口驱动代码调式与测试 ”一节完成。 「2021.7.6 23:00」
P.S.1 生活里负面情绪上来了不及时开导,一个人真的能溺在里面好久。「2021.7.6 23:34」
Linux驱动认知简明导论③ —— 修改树莓派引脚文件pin4Driver.c操作IO口相关推荐
- Linux驱动开发(十)---树莓派输入子系统学习(红外接收)
前文回顾 <Linux驱动开发(一)-环境搭建与hello world> <Linux驱动开发(二)-驱动与设备的分离设计> <Linux驱动开发(三)-设备树> ...
- linux按照更改时间查看文件,Linux查看特定时间段内修改过的文件
Linux查看特定时间段内修改过的文件 一.Linux系统日志的一些信息,日志配置文件syslog.conf 系统日志一般都存在/var/log下 常用的系统日志如下: 核心启动日志:/var/log ...
- 【Linux 驱动】下编写和加载 .ko 文件(驱动模块文件)
一..ko 文件介绍 .ko文件是kernel object文件(内核模块),该文件的意义就是把内核的一些功能移动到内核外边, 需要的时候插入内核,不需要时卸载. 二.优点 (1)这样可以缩小内核体积 ...
- Linux查看时间段文件,Linux查看特定时间段内修改过的文件
一.Linux系统日志的一些信息,日志配置文件syslog.conf 系统日志一般都存在/var/log下 常用的系统日志如下: 核心启动日志:/var/log/dmesg 系统报错日志:/var/l ...
- linux下pip换源——修改pip.conf文件
本文转至:linux下更换pip源 在linux对pip进行换源,直接修改pip.conf文件即可. 该文件路径:/home/[用户]/.config/pip/ 终端:gedit /home/wjl/ ...
- Linux系统下查找最近修改过的文件
Linux的终端上,没有windows的搜索那样好用的图形界面工具,但find命令确是很强大的. 比如按名字查找一个文件,可以用 find / -name targetfilename . 唉,如果只 ...
- RIFFA之LINUX驱动学习之二:riffa.c文件
因为riffa.c包含进来了riffa.h和riffa_driver.h,我们分别贴出来这三个文件: riffa_driver.h // ------------------------------- ...
- linux shell中怎样批量修改文件名为 文件夹_文件名
如何将 多个目录下的文件 批量修改文件名 比如 abc目录下的test1.txt,text2.txt ... 修改为 abc_test.txt abc_test2.txt ... def目录下的tes ...
- linux查找指定修改时间的文件夹,linux 查找某个日期以后修改过哪些文件 shell脚本...
今天有一个需求,就是程序在 2019-10-16以后有哪些文件被修改过,在百度也找了好久,可以使用find的方式去搞定,但是需要使用-newermt的参数,也是第一次使用该参数.并在此记录一下.分享出 ...
- linux查找修改时间在三天前,ECS linux 中查找最近一次修改过的文件的具体操作
1.find dir/ -type f -mtime +1 -atime : 指定时间曾被存取过的文件,意思是文件被读取过 -ctime : 指定时间曾被更改过的文件,意思是文件权限被更改过 -mti ...
最新文章
- 采用编码器-解码器匹配语义分割的图像压缩
- IT行业HR:我们很缺人...
- Pandas to_json() 中文乱码,转化为json数组
- java简单小程序_Java简易登录注册小程序
- VTK:可视化算法之ColoredAnnotatedCube
- 《集体智慧编程》笔记(1 / 12):集体智慧导言
- TCP协议的一些认识及实践
- Monkey测试执行指导
- (转)淘淘商城系列——商品搜索功能Dao实现
- 蓝桥杯 ADV-126 算法提高 扫雷
- [深度学习]什么叫激活函数
- 新出炉的面试题,了解一下?
- 《Spring 5官方文档》11集成测试 (二)
- android 空气质量代码,Android-Json数据解析之空气质量检测
- unity物体移动的几种常用方式
- OpenCV IplImage图片结构
- nuxt.js项目打包上传服务器pm2启动各种问题
- VBA基础语法:类型转换函数
- 迪文屏幕的学习和开发
- Outlook 2007对于不同(Gmail.Sina.Sohu.126.163.Yahoo.Hotmail)Email账号设置
热门文章
- Tomcat怎么重启 tomcat重启命令
- 2020年实验室安全准入考试
- Java 实体对象转Map
- Hive报错记录——林子雨教材
- STC8H开发(十二): I2C驱动AT24C08,AT24C32系列EEPROM存储
- Linux的NFS(net file systen)
- win10安装steam有损计算机,Win10专业版无法安装steam软件怎么办?
- 结合LayoutIt学习Bootstrap的探索
- 电机精密运动控制专家电机驱动芯片TMC260
- 尔雅网络选课 大学计算机知识,2017-2018学年第1学期超星尔雅网络课程选课指南.PDF...