(RK3566驱动开发 - 1).pinctrl和gpio子系统
一.设备树
pinctrl部分可以参考 rockchip 官方的绑定文档 :kernel/Documentation/devicetree/bindings/pinctrl
PIN_BANK:引脚所属的组 - 本次例程使用的是 GPIO3_A1 这个引脚,所以所属的组为 3;
PIN_BANK_IDX:引脚的索引号,可在 kernel/include/dt-bindings/pinctrl/rockchip.h 中查看到 PA1 的宏定义;
MUX:引脚的复位功能,同样在绑定文档中的 pinctrl 中可以看到,当 MUX 为 0 的时候表示复用为 gpio ,其余表示其他的复用功能。也可在 rockchip.h 中使用宏 RK_FUNC_GPIO
&phandle:电器属性,可在泰山派的 .tspi-rk3566-user-v10-linux.dtb.dts.tmp 中查看
pcfg_pull_none 为无上下拉
(1).流程图
(2).设备树代码
二.驱动部分
(1).流程图
(2).驱动代码
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/ide.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/gpio.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_gpio.h>
// #include <asm/mach/map.h>
#include <asm/uaccess.h>
#include <asm/io.h>#define BEEP_CNT 1 /* 设备号个数 */
#define BEEP_NAME "beep" /* 名字 */
#define BEEPOFF 0 /* 关 */
#define BEEPON 1 /* 开 *//* beep设备结构体 */
struct beep_dev
{dev_t devid; /* 设备号 */struct cdev cdev; /* cdev */struct class *class; /* 类 */struct device *device; /* 设备 */int major; /* 主设备号 */int minor; /* 次设备号 */struct device_node *nd; /* 设备结点 */int beep_gpio; /* beep所使用的 gpio 编号 */
};/* led设备 */
struct beep_dev beepdev;/*** @description: 打开设备* @param - inode : 传递给驱动的inode* @param - filp : 设备文件* @return : 0 成功,其他 失败
*/
static int beep_open(struct inode *inode,struct file *filp)
{/* 设置私有属性 */filp->private_data = &beepdev; return 0;
}/*** @description: 从设备读取数据* @param - filp : 要打开的设备文件(文件描述符)* @param - buf : 返回给用户空间的数据缓冲区* @param - cnt : 要读取的数据长度* @param - offt : 相对于文件首地址的偏移* @return : 读取的字节数,如果为负值,则为失败
*/
static ssize_t beep_read(struct file *filp,char __user *buf,size_t cnt,loff_t *offt)
{return 0;
}/*** @description: 向设备写数据* @param - filp : 设备文件,表示打开的文件描述符* @param - buf : 要写给设备的数据* @param - cnt : 要写入的数据长度* @param - offt : 写入的字节数,如果为负值,则为失败
*/
static ssize_t beep_write(struct file *filp,const char __user *buf,size_t cnt,loff_t *offt)
{int retvalue;unsigned char databuf[1];unsigned char beepstat;struct beep_dev *dev = filp->private_data;retvalue = copy_from_user(databuf,buf,cnt);if(0 > retvalue){printk("kernel write failed!\r\n");return -EFAULT;}beepstat = databuf[0];printk("beepstat : %d\r\n",beepstat);if(beepstat == BEEPON){gpio_set_value(dev->beep_gpio,1); //打开LED灯}else if(beepstat == BEEPOFF){gpio_set_value(dev->beep_gpio,0); //关闭LED}return 0;
}/*** @description: 关闭/释放设备* @param - filp : 要关闭的设备文件(文件描述符)* @return : 0 成功,其他 失败
*/
static int beep_release(struct inode *inode,struct file *filp)
{return 0 ;
}/* 绑定设备操作函数 */
static struct file_operations beep_fops =
{.owner = THIS_MODULE,.open = beep_open,.read = beep_read,.write = beep_write,.release = beep_release,
};/*** @description: 驱动入口函数* @param : 无* @return : 无
*/
static int __init beep_init(void)
{int ret = 0;printk("enter beep_init\r\n");/* 设置LED所使用的beep *//* 1.从设备数中获取设备节点:beep */beepdev.nd = of_find_node_by_path("/beep");if(NULL == beepdev.nd){printk("beep node can not found!\r\n");}else{printk("beep node has been found!\r\n");}/* 2.获取设备数中的beep属性,得到LED所使用的LED编号 */beepdev.beep_gpio = of_get_named_gpio(beepdev.nd,"beep-gpio",0);if(0 > beepdev.beep_gpio){printk("can not get gpio-beep");return -EINVAL;}printk("gpio-beep num = %d\r\n",beepdev.beep_gpio);/* 3.初始化beep,默认关闭LED */ret = gpio_direction_output(beepdev.beep_gpio,0);if(0 > ret){printk("can not init beep!\r\n");}/* 注册字符设备驱动 *//* 1.创建设备号 */if(beepdev.major) //若定义了设备号{beepdev.devid = MKDEV(beepdev.major,0);register_chrdev_region(beepdev.devid,BEEP_CNT,BEEP_NAME);}else //没有定义设备号{alloc_chrdev_region(&beepdev.devid,0,BEEP_CNT,BEEP_NAME); //申请设备号beepdev.major = MAJOR(beepdev.devid); //获取主设备号beepdev.minor = MINOR(beepdev.devid); //获取次设备号}printk("beep major = %d,minor = %d",beepdev.major,beepdev.minor);/* 2.初始化cdev */beepdev.cdev.owner = THIS_MODULE;cdev_init(&beepdev.cdev,&beep_fops);/* 3.添加一个cdev */cdev_add(&beepdev.cdev,beepdev.devid,BEEP_CNT);/* 4.创建类 */beepdev.class = class_create(THIS_MODULE,BEEP_NAME);if(IS_ERR(beepdev.class)){return PTR_ERR(beepdev.class);}/* 5.创建设备 */beepdev.device = device_create(beepdev.class,NULL,beepdev.devid,NULL,BEEP_NAME);if(IS_ERR(beepdev.device)){return PTR_ERR(beepdev.device);}return 0;
}/*** @description: 驱动出口函数* @param : 无* @return : 无
*/
static void __exit beep_exit(void)
{printk("enter beep_exit");/* 注销字符设备驱动 */cdev_del(&beepdev.cdev); //删除cdevunregister_chrdev_region(beepdev.devid,BEEP_CNT); //注销device_destroy(beepdev.class,beepdev.devid);class_destroy(beepdev.class);
}module_init(beep_init);
module_exit(beep_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("kaneki");
(3).Makefile
PWD ?= $(shell pwd)KERNELDIR := /home/linux/RK3566/rk3566_sdk/kernel
CROSS_COMPILE := /home/linux/RK3566/rk3566_sdk/prebuilts/gcc/linux-x86/aarch64/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-obj-m += beep.oCC := $(CROSS_COMPILE)gccmodule:make -C $(KERNELDIR) M=$(PWD) ARCH=arm64 modules@# -C $(KERNELDIR) 从当前目录切换到内核源码下 借助内核源码 makefile 进行 makefile@# M=$(PWD) 只编译当前目录下的驱动文件@# ARCH=arm64 指定编译架构# $(CC) beep.c -o beep
clean:make -C $(KERNELDIR) M=$(PWD) ARCH=arm64 clean
三.应用程序
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>#define BEEP_ON 1
#define BEEP_OFF 0int main(int argc, char *argv[])
{char *filename;char databuf[1];int fd,ret;if(3 != argc){printf("usage : ./%s <dev_path> <1 / 0>\n",argv[0]);return -1;}filename = argv[1];databuf[0] = atoi(argv[2]);fd = open(filename,O_WRONLY);if(0 > fd){perror("open failed");return -1;}write(fd,databuf,1);return 0;
}
相关文章:

(RK3566驱动开发 - 1).pinctrl和gpio子系统
一.设备树 pinctrl部分可以参考 rockchip 官方的绑定文档 :kernel/Documentation/devicetree/bindings/pinctrl PIN_BANK:引脚所属的组 - 本次例程使用的是 GPIO3_A1 这个引脚,所以所属的组为 3; PIN_BANK_IDX:引脚的…...

css三角制作(二十课)
代码: <style>/* 边框原理 */.box1 {width: 0;height: 0;border-top: 100px solid pink;border-bottom: 100px solid blue;border-left: 100px solid yellow;border-right: 100px solid greenyellow;}/* 三角制作 */.box2 {width: 0;height: 0;border: 100px …...

C++_priority_queue(优先级队列)
✨✨ 欢迎大家来到小伞的大讲堂✨✨ 🎈🎈养成好习惯,先赞后看哦~🎈🎈 所属专栏:C学习 小伞的主页:xiaosan_blog 1. priority_queue的介绍和使用 priority_queue文档介绍 优先级队列的实现的关键…...

微信小程序——01开发前的准备和开发工具
文章目录 一、开发前的准备1注册小程序账号2安装开发者工具 二、开发者工具的使用1创建项目2 工具的使用3目录结构4各个页面之间的关系5 权限管理6提交审核和发布 一、开发前的准备 开发前需要进行以下准备: 1 注册小程序账号2激活邮箱3 信息登记4 登录小程序管理后…...
MySQL 的主从复制数据同步
一、什么是 MySQL 的主从复制 MySQL 的主从复制(Master-Slave Replication)是一种将数据从一个主数据库服务器(主库)复制到一个或多个从数据库服务器(从库)的技术。主库负责所有的数据写操作,从…...

python——面向对象
一、面向对象编程 1.1 面向过程与面向对象 面向过程和面向对象都是一种编程方式,只不过再设计上有区别。 1.1.1 面向过程pop: 举例:孩子上学 1. 妈妈起床 2. 妈妈洗漱 3. 妈妈做饭 4. 妈妈把孩子叫起来 5. 孩子起床 6. 孩子洗漱 7. 孩子吃…...

Microsoft 365 Exchange如何设置可信发件IP白名单
1、 进入到 Microsoft 365 admin center 管理中心 ,点击 管理中心 下的 安全 在弹出的新页面中,依次点击 策略和规则 – 威胁策略 – 反垃圾邮件 再单击 连接筛选器策略(默认) – 编辑连接筛选器策略 2、在 IP 允许列表 中添加可信邮件 IP 段࿰…...

LM27313典型电路之升压电路
下图为升压芯片LM27313典型电路图: 从图中可以看出:系统电压VSYS3.7伏,通过C26与C27两个滤波电容后,到达升压芯片的VIN输入脚pin5。 其中电源芯片的电压输出由下式子决定: VOUT1.23*(1R17/R21) 其中VOUT是图中的V5D…...

嵌入式面试八股文(七)·#ifndef#define#endif的作用、以及内存分区(全局区、堆区、栈区、代码区)
目录 1. 头文件中的#ifndef / #define / #endif的作用是什么? 2. 内存分区:全局区、堆区、栈区、代码区简单描述? 2.1 代码区(Text Segment): 2.2 全局区(Data Segment)&…...

【弱监督视频异常检测】2024-ESWA-基于扩散的弱监督视频异常检测常态预训练
2024-ESWA-Diffusion-based normality pre-training for weakly supervised video anomaly detection 基于扩散的弱监督视频异常检测常态预训练摘要1. 引言2. 相关工作3. 方法论3.1. 使用扩散自动编码器进行常态学习3.2. 全局-局部特征编码器3.2.1 局部块3.2.2 全局块3.2.3 协同…...
Android 13 实现屏幕熄屏一段时候后关闭 Wi-Fi 和清空多任务列表
明白了,您这个补丁的功能是当设备屏幕关闭一段时间后,自动关闭 Wi-Fi 连接并清空多任务菜单。以下是更新后的博客内容,包含了对功能的详细解释和代码实现: 修改 PowerManagerService.java 以实现屏幕灭屏后关闭 Wi-Fi 和清空多任务菜单功能 在本篇博客中,我们将介绍一个针…...
Elasticsearch磁盘占用大于95%时将所有索引置为只读
在一个稳定运行的功能中,突然收到报错。经查明,是在向 Elasticsearch 中插入文档时出现了错误: AuthorizationException: AuthorizationException(403, ucluster_block_exception, ublocked by: [FORBIDDEN/12/index read-only / allow delete (api)];) 网上也有其他人报出类…...
删除 git config 保存的密码
要从 Git 中删除保存的密码,你可以根据你之前使用的保存方法来操作。以下是一些常见的方法来删除 Git 中保存的密码: 删除 credential.helper 中的密码 如果你之前使用 store 或 cache 作为 credential.helper,你可以执行以下步骤来删除保存…...
Springboot环境搭建详解
springboot学习视频记录: 笔记: a:Springboot maven常见依赖、配置文件笔记-CSDN博客 b:Springboot环境搭建详解-CSDN博客 day01 6:springboot的parent和starter依赖- a 7:启动类的位置配置- b 8&am…...

SpringCloud框架学习(第三部分:Resilience4j 与 Micrometer)
目录 九、CircuitBreaker断路器 1.前言(Hystrix) 2.服务雪崩 3.Circuit Breaker 4. Resilience4j 5.案例实战 (1)熔断(服务熔断 服务降级) Ⅰ. 按照 COUNT_BASED(计数的滑动窗口…...
Scala的Map集合(不可变)
package gxy//类型:不可变,可变 //操作:添加元素,删除元素,查询元素,移除元素,遍历 object map {def main(args: Array[String]): Unit {//不可变mapval map1 Map("鄂" -> "…...
深入剖析:Spring MVC与Struts的较量
标题:深入剖析:Spring MVC与Struts的较量 引言 在Java Web开发领域,Spring MVC和Struts是两个非常流行的框架。它们各自拥有不同的特点,适用于不同的应用场景。本文将深入探讨Spring MVC和Struts的区别,从底层机制、…...

4.Mybatis中,在Mapper的SQL映射文件中,使用<choose><when>无法识别参数的情况
正确结果 <?xml version"1.0" encoding"UTF-8" ?> <!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace"com.itheima.mapper.Bra…...
antd proFromSelect 懒加载+模糊查询
antd proFromSelect 懒加载模糊查询 场景 查询用户的时候数量特别大,有10w条数据,不可能直接全部查询用来展示 所以本文章将讲解如何使用懒加载模糊查询,解决数量过大的问题 后端代码就不用展示了,很简单的分页查询,主…...

Spring Boot 牛刀小试 org.springframework.boot:spring-boot-maven-plugin:找不到类错误
今天看了下书翻了下Spring Boot的用法,下载idea后, 反复出现org.springframework.boot:spring-boot-maven-plugin:找不到类错误,后来看了下调试窗口,发现是连不上maven的网站443错误,解决思路很简单,把ide连…...
Android Wi-Fi 连接失败日志分析
1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分: 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析: CTR…...

AI Agent与Agentic AI:原理、应用、挑战与未来展望
文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例:使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例:使用OpenAI GPT-3进…...

基于Flask实现的医疗保险欺诈识别监测模型
基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施,由雇主和个人按一定比例缴纳保险费,建立社会医疗保险基金,支付雇员医疗费用的一种医疗保险制度, 它是促进社会文明和进步的…...

ElasticSearch搜索引擎之倒排索引及其底层算法
文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...
汇编常见指令
汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX(不访问内存)XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...

IT供电系统绝缘监测及故障定位解决方案
随着新能源的快速发展,光伏电站、储能系统及充电设备已广泛应用于现代能源网络。在光伏领域,IT供电系统凭借其持续供电性好、安全性高等优势成为光伏首选,但在长期运行中,例如老化、潮湿、隐裂、机械损伤等问题会影响光伏板绝缘层…...

深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南
🚀 C extern 关键字深度解析:跨文件编程的终极指南 📅 更新时间:2025年6月5日 🏷️ 标签:C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言🔥一、extern 是什么?&…...
css3笔记 (1) 自用
outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size:0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格ÿ…...

ArcGIS Pro制作水平横向图例+多级标注
今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作:ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等(ArcGIS出图图例8大技巧),那这次我们看看ArcGIS Pro如何更加快捷的操作。…...

【JVM】Java虚拟机(二)——垃圾回收
目录 一、如何判断对象可以回收 (一)引用计数法 (二)可达性分析算法 二、垃圾回收算法 (一)标记清除 (二)标记整理 (三)复制 (四ÿ…...