【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生产者,消费者问题

pthread_cond_wait() :用于阻塞当前线程,等待别的线程使用pthread_cond_signal()或pthread_cond_broadcast来唤醒它。 pthread_cond_wait() 必须与pthread_mutex 配套使用。pthread_cond_wait()函数一进入wait状态就会自动release mutex。当其他线程通过pthread

Linux 安装、配置Tomcat 的HTTPS

Linux 安装 、配置Tomcat的HTTPS 安装Tomcat 这里选择的是 tomcat 10.X ,需要Java 11及更高版本 Binary Distributions ->Core->选择 tar.gz包 下载、上传到内网服务器 /opt 目录tar -xzf 解压将解压的根目录改名为 tomat-10 并移动到 /opt 下, 形成个人习惯的路径 /opt/tomcat-10

RedHat运维-Linux文本操作基础-AWK进阶

你不用整理,跟着敲一遍,有个印象,然后把它保存到本地,以后要用再去看,如果有了新东西,你自个再添加。这是我参考牛客上的shell编程专项题,只不过换成了问答的方式而已。不用背,就算是我自己亲自敲,我现在好多也记不住。 1. 输出nowcoder.txt文件第5行的内容 2. 输出nowcoder.txt文件第6行的内容 3. 输出nowcoder.txt文件第7行的内容 4. 输出nowcode

【Linux进阶】UNIX体系结构分解——操作系统,内核,shell

1.什么是操作系统? 从严格意义上说,可将操作系统定义为一种软件,它控制计算机硬件资源,提供程序运行环境。我们通常将这种软件称为内核(kerel),因为它相对较小,而且位于环境的核心。  从广义上说,操作系统包括了内核和一些其他软件,这些软件使得计算机能够发挥作用,并使计算机具有自己的特生。这里所说的其他软件包括系统实用程序(system utility)、应用程序、shell以及公用函数库等

一份LLM资源清单围观技术大佬的日常;手把手教你在美国搭建「百万卡」AI数据中心;为啥大模型做不好简单的数学计算? | ShowMeAI日报

👀日报&周刊合集 | 🎡ShowMeAI官网 | 🧡 点赞关注评论拜托啦! 1. 为啥大模型做不好简单的数学计算?从大模型高考数学成绩不及格说起 司南评测体系 OpenCompass 选取 7 个大模型 (6 个开源模型+ GPT-4o),组织参与了 2024 年高考「新课标I卷」的语文、数学、英语考试,然后由经验丰富的判卷老师评判得分。 结果如上图所

uniapp接入微信小程序原生代码配置方案(优化版)

uniapp项目需要把微信小程序原生语法的功能代码嵌套过来,无需把原生代码转换为uniapp,可以配置拷贝的方式集成过来 1、拷贝代码包到src目录 2、vue.config.js中配置原生代码包直接拷贝到编译目录中 3、pages.json中配置分包目录,原生入口组件的路径 4、manifest.json中配置分包,使用原生组件 5、需要把原生代码包里的页面修改成组件的方

IDEA配置Tomcat远程调试

因为不想把本地的Tomcat配置改乱或者多人开发项目想测试,本文主要是记录一下,IDEA使用Tomcat远程调试的配置过程,免得一段时间不去配置到时候忘记(毕竟这次是因为忘了,所以才打算记录的…) 首先在catalina.sh添加以下内容 JAVA_OPTS="-Dcom.sun.management.jmxremote=-Dcom.sun.management.jmxremote.port

Windows/macOS/Linux 安装 Redis 和 Redis Desktop Manager 可视化工具

本文所有安装都在macOS High Sierra 10.13.4进行,Windows安装相对容易些,Linux安装与macOS类似,文中会做区分讲解 1. Redis安装 1.下载Redis https://redis.io/download 把下载的源码更名为redis-4.0.9-source,我喜欢跟maven、Tomcat放在一起,就放到/Users/zhan/Documents

Linux系统稳定性的奥秘:探究其背后的机制与哲学

在计算机操作系统的世界里,Linux以其卓越的稳定性和可靠性著称,成为服务器、嵌入式系统乃至个人电脑用户的首选。那么,是什么造就了Linux如此之高的稳定性呢?本文将深入解析Linux系统稳定性的几个关键因素,揭示其背后的技术哲学与实践。 1. 开源协作的力量Linux是一个开源项目,意味着任何人都可以查看、修改和贡献其源代码。这种开放性吸引了全球成千上万的开发者参与到内核的维护与优化中,形成了

Steam邮件推送内容有哪些?配置教程详解!

Steam邮件推送功能是否安全?如何个性化邮件推送内容? Steam作为全球最大的数字游戏分发平台之一,不仅提供了海量的游戏资源,还通过邮件推送为用户提供最新的游戏信息、促销活动和个性化推荐。AokSend将详细介绍Steam邮件推送的主要内容。 Steam邮件推送:促销优惠 每当平台举办大型促销活动,如夏季促销、冬季促销、黑色星期五等,用户都会收到邮件通知。这些邮件详细列出了打折游戏、