Linux内核驱动开发-001字符设备开发-003独立按键杂项驱动

1驱动程序

/*************************************************************************> File Name: key_misc.c> Author: yas> Mail: rage_yas@hotmail.com> Created Time: 2024年04月22日 星期一 17时20分42秒************************************************************************/#if 1
/*=========================The key_misc driver=========================*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/miscdevice.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
#include <asm/io.h>/*寄存器地址映射*/
#define GPGCON (0x56000060)
#define GPGUP (0x56000068)
#define GPGDAT (0x56000064)/*保存寄存器地址映射*/
unsigned int *regGPGCON;
unsigned int *regGPGUP;
unsigned int *regGPGDAT;/*接收返回的键值*/
u8 key=0;/*key函数声明*/
void key_init(void);
u8 key_press(void);
void delay_nms(u32 t);/*驱动函数声明*/
void ioremap_r(void);
static int __init key_driver_init(void);static int key_driver_open(struct inode *node, struct file *fp);
static ssize_t key_driver_read(struct file *fp, char __user *user_buffer, size_t len, loff_t *offset);
static ssize_t key_driver_write(struct file *fp, const char __user *user_buffer, size_t len, loff_t *offset);
static int key_driver_close(struct inode *node, struct file *fp);void iounmap_r(void);
static void __exit key_driver_exit(void);/*定义字符设备文件操作结构体变量*/
static struct file_operations fops = 
{.owner = THIS_MODULE,.open = key_driver_open,.read = key_driver_read,.write = key_driver_write,.release = key_driver_close
};static struct miscdevice key_dev =
{.minor = MISC_DYNAMIC_MINOR,.name = "key_r",.fops = &fops
};#if 1
/*******************************************************************************
* 函 数 名	: ioremap_r
* 函数功能	: 寄存器映射
* 输    入  :无 							
* 输    出  :无
*******************************************************************************/
void ioremap_r(void)
{/*寄存器映射*/regGPGCON = ioremap(GPGCON, 4);//【源地址】【需要映射的地址大小】<返回目标地址>regGPGUP = ioremap(GPGUP,4);regGPGDAT = ioremap(GPGDAT, 4);
}
#endif#if 1
/*******************************************************************************
* 函 数 名	: key_driver_init
* 函数功能	: key驱动初始化
* 输    入  :无 							
* 输    出  :无
*******************************************************************************/
static int __init key_driver_init(void)
{int ret=0;ret=misc_register(&key_dev);if(ret<0){printk("misc_register is failed\n");goto misc_register_err;}/*寄存器映射*/ioremap_r();/*key初始化*/key_init();printk("key_driver_init OK\n");return 0;misc_register_err:return -1;
}
#endif#if 1
static int key_driver_open(struct inode *node, struct file *fp)
{return 0;
}
#endif#if 1
static ssize_t key_driver_read(struct file *fp, char __user *user_buffer, size_t len, loff_t *offset)
{key_press();copy_to_user(user_buffer,&key,4);
//    key=0;return sizeof(key);
}
#endif#if 1
/*******************************************************************************
* 函 数 名 : key_driver_write
* 函数功能 : key驱动写数据
* 输    入 :
*               fp:
*      user_buffer:
*           offset:
* 输    出 :无
*******************************************************************************/
static ssize_t key_driver_write(struct file *fp, const char __user *user_buffer, size_t len, loff_t *offset)
{return 0;
}
#endif#if 1
static int key_driver_close(struct inode *node, struct file *fp)
{return 0;
}
#endif#if 1
/*******************************************************************************
* 函 数 名	: ioremap_r
* 函数功能	: 寄存器反映射
* 输    入  :无 							
* 输    出  :无
*******************************************************************************/
void iounmap_r(void)
{/*寄存器反映射*/iounmap(regGPGCON);iounmap(regGPGUP);iounmap(regGPGDAT);
}
#endif#if 1
/*******************************************************************************
* 函 数 名 : key_driver_exit
* 函数功能 : 退出key驱动
* 输    入 : 无
* 输    出 : 无
*******************************************************************************/
static void __exit key_driver_exit(void)
{iounmap_r();misc_deregister(&key_dev);printk("key_driver_exit OK\n");
}
#endif/*=========================key配置函数=========================*//*******************************************************************************
* 函 数 名	: key_init
* 函数功能	: 独立按键初始化
* 输    入  :无 							
* 输    出  :无
*******************************************************************************/
//K1-EINT8-GPG0,K2-EINT11-GPG3,K3-EINT13-GPG5,
//K4-EINT14-GPG6,K5-EINT15-GPG7,K6-EINT19-GPG11
void key_init(void)
{*regGPGCON&=~((0X03<<0)|(0X03<<6)|(0X03<<10)|(0X03<<12)|(0X03<<14)|(0X03<<22));//KEY控制引脚配置-输入状态*regGPGUP|=(0X01<<0)|(0X01<<11);//上拉使能寄存器-置位-禁止上拉//思考:为何要关闭K1和K6按键对应引脚内部的上拉电阻?(原理图)//这里和LED的区别是:不需要将按键的数据寄存器初始化,
//而LED是需要保证初始状态为关闭	
}
/*******************************************************************************
* 函 数 名         : key_press
* 函数功能		     : 检测按键按下
* 输    入         : 
*					 无
* 输    出         : 返回键值
*******************************************************************************/
u8 key_press(void)
{if((*regGPGDAT&(0X01<<0))==0)//问题1:【&】和【==】的优先级不确定,导致按键功能故障;解决:使用括号{key=1;}else if((*regGPGDAT&(1<<3))==0){key=2;}else if((*regGPGDAT&(1<<5))==0){key=3;}else if((*regGPGDAT&(1<<6))==0){key=4;}else if((*regGPGDAT&(1<<7))==0){key=5;}else if((*regGPGDAT&(1<<11))==0){key=6;}else{key=0;} return key;
}/*******************************************************************************
* 函 数 名         : delay_nms
* 函数功能		     : 延时nms
* 输    入         : 
*									 	t:延时时间
* 输    出         : 无
*******************************************************************************/
void delay_nms(u32 t)
{u32 i=0;u32 j=0;for(i=0;i<t;i++){for(j=0;j<100;j++);}
}module_init(key_driver_init);
module_exit(key_driver_exit);MODULE_LICENSE("GPL");
MODULE_AUTHOR("XXX");
/*=========================The key_misc driver=========================*/
#endif

2应用程序

/*************************************************************************> File Name: main.c> Author: yas> Mail: rage_yas@hotmail.com> Created Time: 2024年04月22日 星期一 17时20分42秒************************************************************************/#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>int main(void)
{
#if 1
/*====================key-r====================*/    int fd=0;int n=0;fd=open("dev/key_r",O_RDWR);//这里路径一定要对,尤其是手动创建设备结点的时候if(fd<0){printf("opening is failed\n");return -1;}while(1){read(fd,&n,4);printf("%d\n",n);sleep(1);}return 0;
/*========================================*/    
#endif
}

3运行结果

由运行结果可以看到,6颗独立按键的驱动全部正常。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/641535.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

DBA-现在应该刚刚入门吧

说来话长 在2023年以前&#xff0c;我的DBA生涯都是“孤独的”。成长路径除了毕业前的实习期有人带&#xff0c;后续几乎都是靠自学。如何自学&#xff0c;看视频、看文档、网上查阅资料、项目实战。 可能是学疏才浅 &#xff0c;一直都是在中小公司混&#xff0c;在中小公司通…

30V-STM32设计项目

30V-STM32设计 一、项目描述 (已验证) 基于STM32c8t6芯片设计的开发板&#xff0c;支持4-30V宽电压输入&#xff0c;串口模式自动下载功能&#xff0c;支持串口和STlink&#xff0c;方式下载程序 二、原理图介绍 电源电路采用了DCDCLDO电路&#xff0c;如果是外接DC头供电的话&…

GELU激活函数

Gaussian Error Linerar Units(GELUS) 论文链接&#xff1a;https://arxiv.org/abs/1606.08415 在激活函数领域&#xff0c;鄙视链应该是&#xff1a;Elus > Relu > Sigmoid &#xff0c;这些激活函数都有自身的缺陷&#xff0c; sigmoid容易饱和&#xff0c;Elus与Rel…

【Transformer】detr之encoder逐行梳理(二)

every blog every motto: You can do more than you think. https://blog.csdn.net/weixin_39190382?typeblog 0. 前言 detr之encoder逐行梳理 1. 整体 encoder由encoder layer构成 输入进encoder的特征shape:(hw,b,c)&#xff0c;后文将给出说明 class Transformer(nn.…

java-springmvc 01

MVC就是和Tomcat有关。 01.MVC启动的第一步&#xff0c;启动Tomcat 02.Tomcat会解析web-inf的web.xml文件

《架构风清扬-Java面试系列第23讲》如何理解Java的泛型檫除?

晚上好&#xff0c;给大家加个餐 来&#xff0c;思考片刻&#xff0c;说出你的答案 1&#xff0c;什么是泛型檫除&#xff1f; 泛型擦除是指编译器在处理泛型代码时&#xff0c;会在编译阶段移除&#xff08;擦除&#xff09;所有与泛型相关的类型参数信息&#xff0c;将其替换…

Java 网络编程之TCP(三):基于NIO实现服务端,BIO实现客户端

前面的文章&#xff0c;我们讲述了BIO的概念&#xff0c;以及编程模型&#xff0c;由于BIO中服务器端的一些阻塞的点&#xff0c;导致服务端对于每一个客户端连接&#xff0c;都要开辟一个线程来处理&#xff0c;导致资源浪费&#xff0c;效率低。 为此&#xff0c;Linux 内核…

VulBG: 构建行为图加强基于深度学习的漏洞检测模型

近年来&#xff0c;人们提出了基于深度学习&#xff08;DL&#xff09;的漏洞检测系统&#xff0c;用于从源代码中自动提取特征。这些方法在合成数据集上可以实现理想的性能&#xff0c;但在检测真实世界的漏洞数据集时&#xff0c;准确率却大幅下降。此外&#xff0c;这些方法…

数字时代的社交王者:探索Facebook的社交帝国

引言&#xff1a;社交媒体的霸主 在数字化浪潮席卷全球的当下&#xff0c;社交媒体已然成为人们日常生活中不可或缺的一部分&#xff0c;而Facebook则是这个领域的不二之选。作为全球最大的社交网络&#xff0c;Facebook不仅拥有庞大的用户群体&#xff0c;更在技术创新、社会…

EJB和Spring

1. EJB 1.1. 背景 功能日趋复杂的软件&#xff0c;如果把所有的功能实现都放在客户端&#xff0c;不仅代码没有安全性&#xff0c;部署及发布运维都会变的很复杂&#xff0c;所以将软件的功能实现分为客户端和服务端&#xff0c;服务端和客户端之间通过网络调用进行功能实现。…

要养生也要时尚,益百分满足你的所有需求

要养生也要时尚&#xff0c;益百分满足你的所有需求 艾灸是个好东西&#xff0c;尤其是在近几年的时候&#xff0c;艾灸就像一阵浪潮席卷进了人们的日常生活之中&#xff0c;我们可以在街边看到大大小小的艾灸馆&#xff0c;有些评价比较高的艾灸馆门前甚至还排起了长长的队伍…

Leetcode 118 杨辉三角

目录 一、问题描述二、示例及约束三、代码方法一&#xff1a;数学 四、总结 一、问题描述 给定一个非负整数 numRows&#xff0c;生成「杨辉三角」的前 numRows 行。   在「杨辉三角」中&#xff0c;每个数是它左上方和右上方的数的和。 二、示例及约束 示例 1&#xff1a…