【Linux驱动】【手把手配置3568寄存器】点亮RK3568的一颗LED

2024-06-07 15:44

本文主要是介绍【Linux驱动】【手把手配置3568寄存器】点亮RK3568的一颗LED,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

【硬件】

3568的LED9 :引脚 GPIO0 B7

【配置GPIO的复用】

 找配置复用关系的寄存器基地址、偏移地址、对应配置的GPIO。

查找:io -r -4 0xfdc2000c 系统设置的默认值

结果为1,意思是只有bit 0是1,其他全都为0。所以系统默认就是配置GPIO功能,所以可以不用设置复用GPIO。

【配置GPIO的方向 Direction Register】

查找对应IO配置:io -r -4 0xfdd60008 的默认值(GPIO基地址为0xfdd60000,GPIOB地址偏移8位:0xfdd60008

结果为:0000c064

二进制 : 1100 0000 0110 0010

bit 15为1 ,所以默认已经配置为输出了

【配置GPIO数据寄存器】

查找对应IO配置:io -r -4 0xfdd60000 的默认值

结果为:8000c040

可知bit15 默认为1

PB7写1对应的数据寄存器地址:   8000c040

【问】B7的写使能位是哪一位?

bit31。

PB7写0对应的数据寄存器地址:80004040

PS   :   bit15设置为0(PB7写0),B7对应控制位bit31必须使能1(写使能) 

【驱动】 

#define GPIO_DR 0xFDD60000struct device_test{dev_t dev_num;static int major = 0;static int minor = 0;struct cdev cdev_test;struct class *class;struct device *device;char kbuf[32];  //模拟内核寄存器的数据/************************/unsigned int *vir_gpio_dr; //保存GPIO寄存器虚拟地址用的
};/* 然后定义结构体变量 */
struct device_test dev1;static int moduleparam_init()
{int ret;ret = alloc_chrdev_region(&dev1.dev_num,0,1,"HELLO");  if(ret<0){goto err_chrdev;}printk("alloc_chrdev_region ok\n");  dev1.major_num =MAJOR(dev1.dev_num); //将主设备号取出来dev1.minor_num = MINOR(dev1.dev_num);//将次设备号取出来printk("major_num = %d\n", dev1.major_num);//打印传入进来的主设备号printk("minor_num = %d\n", dev1.minor_num);//打印传入进来的次设备号dev1.cdev_test.owner = THIS_MODULE;cdev_init(dev1.cdev_test, &cdev_file_operations);ret = cdev_add(&dev1.cdev_test, dev1.dev_num, 1);if(ret<0){goto err_chradd;}dev1.class = class_creat(THIS_MODULE, "test");/* 判断创建类有没有失败 */if(IS_ERR(dev1,device)){ret = PTR_ERR(dev1,device);goto err_class_creat;           }dev1.device = device_creat( dev1.class,NULL, dev1.dev_num,,NULL,"test")  /* 判断创建类有没有失败 */if(IS_ERR(dev1.device)){ret = PTR_ERR(dev1,device);goto err_device_creat;           }                    return 0;dev1.vir_gpio_dr = ioremap(GPIO_DR, 4);if(IS_ERR(dev1.vir_gpio_dr)){ret = PTR_ERR(dev1.vir_gpio_dr);goto err_ioremap;           }                    err_ioremap:iounmap(GPIO_DR); //要取消虚拟映射的地址err_device_creat:  //设备添加失败,意味着设备类添加成功,就要把这个类删掉class_destroy( dev1.class);
err_class_creat: //类添加失败,意味着字符设备添加成功,就要把这个字符设备删掉cdev_del(& dev1.cdev_test);  //销毁字符设备        
err_chradd: //添加cdev失败,意味着添加设备号成功,就要释放这个设备号unregister_chrdev_region( dev1.dev_num,DEVICE_NUMBER);//注销设备号
err_chrdev:return ret;
}

关键:

static ssize_t cdev_write(struct file *filp, const char __user *buf, size_t cnt, loff_t *offt)
{struct device_test *test_dev = (struct device_test *)file->private_data;test_dev->kbuf = {0};if(copy_from_user( test_dev->kbuf, buf ,sizeof(buf))!= 0);{printk("copy_from_user error !\n");return -1;}if(test_dev -> kbuf[0] == 1){*(test_dev->vir_gpio_dr) = 0x8000c040;else if{*(test_dev->vir_gpio_dr) = 0x80004040;        }   }return 0;            
}static void hello_exit(void)
{unregister_chrdev_region( dev1.dev_num,DEVICE_NUMBER);//注销设备号cdev_del(& dev1.cdev_test);  //销毁字符设备device_destroy( dev1.class, dev1.dev_num);class_destroy( dev1.class);iounmap(GPIO_DR);printk("gooodbye! \n");
}

【APP】

int main(int argc, char *argv[])
{int fd;char buf[32] = {0};fd1 = open("/dev/test", HELLO);  /* 打开设备节点1 */if(fd < 0){perror("open error \n");return fd;   }   buf[0] = atoi(argv[1]);write(fd, buf, sizeof(buf));close(fd);  return 0;  
}

【实验效果】

./a.out 1 可以实现点灯

./a.out 0 可以实现灭灯

这篇关于【Linux驱动】【手把手配置3568寄存器】点亮RK3568的一颗LED的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


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

相关文章

Linux进程CPU绑定优化与实践过程

《Linux进程CPU绑定优化与实践过程》Linux支持进程绑定至特定CPU核心,通过sched_setaffinity系统调用和taskset工具实现,优化缓存效率与上下文切换,提升多核计算性能,适... 目录1. 多核处理器及并行计算概念1.1 多核处理器架构概述1.2 并行计算的含义及重要性1.3 并

nginx 负载均衡配置及如何解决重复登录问题

《nginx负载均衡配置及如何解决重复登录问题》文章详解Nginx源码安装与Docker部署,介绍四层/七层代理区别及负载均衡策略,通过ip_hash解决重复登录问题,对nginx负载均衡配置及如何... 目录一:源码安装:1.配置编译参数2.编译3.编译安装 二,四层代理和七层代理区别1.二者混合使用举例

Java JDK1.8 安装和环境配置教程详解

《JavaJDK1.8安装和环境配置教程详解》文章简要介绍了JDK1.8的安装流程,包括官网下载对应系统版本、安装时选择非系统盘路径、配置JAVA_HOME、CLASSPATH和Path环境变量,... 目录1.下载JDK2.安装JDK3.配置环境变量4.检验JDK官网下载地址:Java Downloads

Linux线程之线程的创建、属性、回收、退出、取消方式

《Linux线程之线程的创建、属性、回收、退出、取消方式》文章总结了线程管理核心知识:线程号唯一、创建方式、属性设置(如分离状态与栈大小)、回收机制(join/detach)、退出方法(返回/pthr... 目录1. 线程号2. 线程的创建3. 线程属性4. 线程的回收5. 线程的退出6. 线程的取消7.

Linux下进程的CPU配置与线程绑定过程

《Linux下进程的CPU配置与线程绑定过程》本文介绍Linux系统中基于进程和线程的CPU配置方法,通过taskset命令和pthread库调整亲和力,将进程/线程绑定到特定CPU核心以优化资源分配... 目录1 基于进程的CPU配置1.1 对CPU亲和力的配置1.2 绑定进程到指定CPU核上运行2 基于

golang程序打包成脚本部署到Linux系统方式

《golang程序打包成脚本部署到Linux系统方式》Golang程序通过本地编译(设置GOOS为linux生成无后缀二进制文件),上传至Linux服务器后赋权执行,使用nohup命令实现后台运行,完... 目录本地编译golang程序上传Golang二进制文件到linux服务器总结本地编译Golang程序

Linux下删除乱码文件和目录的实现方式

《Linux下删除乱码文件和目录的实现方式》:本文主要介绍Linux下删除乱码文件和目录的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录linux下删除乱码文件和目录方法1方法2总结Linux下删除乱码文件和目录方法1使用ls -i命令找到文件或目录

Spring Boot spring-boot-maven-plugin 参数配置详解(最新推荐)

《SpringBootspring-boot-maven-plugin参数配置详解(最新推荐)》文章介绍了SpringBootMaven插件的5个核心目标(repackage、run、start... 目录一 spring-boot-maven-plugin 插件的5个Goals二 应用场景1 重新打包应用

Linux在线解压jar包的实现方式

《Linux在线解压jar包的实现方式》:本文主要介绍Linux在线解压jar包的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录linux在线解压jar包解压 jar包的步骤总结Linux在线解压jar包在 Centos 中解压 jar 包可以使用 u

Java中读取YAML文件配置信息常见问题及解决方法

《Java中读取YAML文件配置信息常见问题及解决方法》:本文主要介绍Java中读取YAML文件配置信息常见问题及解决方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要... 目录1 使用Spring Boot的@ConfigurationProperties2. 使用@Valu