(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连…...
Hutool CronUtil实战:5分钟搞定Spring Boot定时任务(含动态任务配置)
Hutool CronUtil实战:5分钟搞定Spring Boot定时任务(含动态任务配置) 在Java开发领域,定时任务几乎是每个项目都绕不开的基础需求。传统方案如Spring Scheduler虽然简单易用,但在动态任务管理和细粒度控制方面往往力不…...
高通平台USB充电背后的秘密:从SBL1阶段到Kernel的电池ID识别全解析
高通平台USB充电与电池ID识别的深度技术解析 在Android设备开发中,电源管理系统的稳定性直接影响用户体验。作为底层驱动工程师,理解高通平台从硬件到软件的完整充电流程至关重要。本文将深入剖析从XBL阶段到Kernel层的电池识别机制,揭示BATT…...
9大核心优势!Outfit字体全方位应用指南:从安装到精通
9大核心优势!Outfit字体全方位应用指南:从安装到精通 【免费下载链接】Outfit-Fonts The most on-brand typeface 项目地址: https://gitcode.com/gh_mirrors/ou/Outfit-Fonts Outfit字体作为一款专业开源无衬线字体,凭借9种完整字重体…...
ChatBI 开源产品实战解析:从语义层到Agent,如何选择你的AI数据助手?
1. 为什么企业需要AI数据助手? 想象一下这个场景:市场部的小王需要统计上季度各区域的销售数据,他对着Excel表格里密密麻麻的数字发愁,不得不找IT部门帮忙写SQL查询。三天后拿到数据时,业务窗口期已经错过——这是很多…...
Qwen3-14B-Int4-AWQ助力运维智能化:日志分析与故障排查实战
Qwen3-14B-Int4-AWQ助力运维智能化:日志分析与故障排查实战 1. 运维工程师的日常痛点 凌晨三点,你的手机突然响起。系统告警显示某核心服务出现异常,你需要立即登录服务器查看日志。面对几十GB的日志文件,你不得不用grep、awk等…...
当Navicat密码遗忘时:开源解密工具如何重建数据库连接通路
当Navicat密码遗忘时:开源解密工具如何重建数据库连接通路 【免费下载链接】navicat_password_decrypt 忘记navicat密码时,此工具可以帮您查看密码 项目地址: https://gitcode.com/gh_mirrors/na/navicat_password_decrypt 数据库连接中断的三大痛点场景 场…...
比较好的金线包封胶制造商推荐几家
嘿,朋友们!在半导体封装领域,金线包封胶就像是芯片的“贴身保镖”,保护着纤细的金线,让芯片能够稳定工作。今天咱们就来聊聊比较好的金线包封胶制造商,看看哪家更值得你选择。一、东莞市汉思新材料科技有限…...
acjscsdbhvusfd
一、yolo v1是什么? YOLO(You Only Look Once)算法 是一种目标检测算法,是经典的one-stage方法。YOLO v1 开创了单阶段目标检测的先河,其简洁的架构 和高效的推理为后续版本奠定了基础。尽管存在小目标检测和定位精度的…...
如何解决3D视频无法在普通设备播放的难题?VR-Reversal让转换更简单
如何解决3D视频无法在普通设备播放的难题?VR-Reversal让转换更简单 【免费下载链接】VR-reversal VR-Reversal - Player for conversion of 3D video to 2D with optional saving of head tracking data and rendering out of 2D copies. 项目地址: https://gitco…...
WarcraftHelper终极指南:5大核心功能让魔兽争霸3在现代系统完美运行
WarcraftHelper终极指南:5大核心功能让魔兽争霸3在现代系统完美运行 【免费下载链接】WarcraftHelper Warcraft III Helper , support 1.20e, 1.24e, 1.26a, 1.27a, 1.27b 项目地址: https://gitcode.com/gh_mirrors/wa/WarcraftHelper WarcraftHelper是一款…...
