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

news2024/10/6 12:23:51

【硬件】

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 0xFDD60000

struct 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 可以实现灭灯

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【面试干货】 非关系型数据库(NoSQL)与 关系型数据库(RDBMS)的比较

【面试干货】 非关系型数据库&#xff08;NoSQL&#xff09;与 关系型数据库&#xff08;RDBMS&#xff09;的比较 一、引言二、非关系型数据库&#xff08;NoSQL&#xff09;2.1 优势 三、关系型数据库&#xff08;RDBMS&#xff09;3.1 优势 四、结论 &#x1f496;The Begin…

论文合集整理推荐2024.6.4

论文合集整理推荐2024.6.4 原创 小王搬运工 时序课堂 2024-06-04 20:12 四川 ‍2012年论文合集&#xff1a;论文入口 ‍2019年论文合集&#xff1a;论文入口 2021年论文合集&#xff1a;论文入口 2022年论文合集&#xff1a;论文入口 2023年论文合集&#xff1a;论文入口…

数据结构---力扣 20.有效的括号 (C语言

1.链接&#xff1a; . - 力扣&#xff08;LeetCode&#xff09;【点击即可跳转】 思路&#xff1a; 使用 栈 来完成操作 1.左括号-- 入栈 2.右括号-- 判断出栈顶的左括号与右括号是否匹配 如果匹配-->继续 不匹配-->终止 代码中 栈 的基本实现&#xff0c;不在以下展示&…

两站图片滑动对比效果实现(VUE3)

像这种图片滑动对比的效果&#xff0c;网上还不少见吧&#xff0c;但是网上却不好找到完整现成的实现代码&#xff0c;我找到几个地方有类似的代码&#xff0c;但是都不好直接移植到代码里&#xff0c;因为很多都是使用原生htmlcssjs实现&#xff0c;太复杂了。反而不好应用到v…

【Python Cookbook】S02E04 文本模式的匹配和查找 match()、search()、findall() 以及 捕获组和 + 的含义

目录 问题解决方案讨论 问题 本文讨论一些按照特定的文本模式进行的查找和匹配。 解决方案 如果想要匹配的只是简单文字&#xff0c;通常我们使用一些内置的基本字符串方法即可&#xff0c;如&#xff1a;str.find()&#xff0c;str.startwith()&#xff0c;str.endswith() …

MySQL数据库数据恢复方案应对没有where误操作导致的大量数据更新或删除

&#x1f604; 19年之后由于某些原因断更了三年&#xff0c;23年重新扬帆起航&#xff0c;推出更多优质博文&#xff0c;希望大家多多支持&#xff5e; &#x1f337; 古之立大事者&#xff0c;不惟有超世之才&#xff0c;亦必有坚忍不拔之志 &#x1f390; 个人CSND主页——Mi…

二分答案-acwing-102. 最佳牛围栏

题目传送门&#xff1a;t​​​102. 最佳牛围栏 - AcWing题库高质量的算法题库https://www.acwing.com/problem/content/104/ 解题思路 整体解析 按照题目要求我们要找到一块连续的区域&#xff0c;使其里面每块地里面的平均值最大&#xff0c;且这块区域的长度要大于f 二分处理…

STM32——ADC篇(ADC的使用)

一、ADC的介绍 1.1什么是ADC ADC&#xff08;Analogto-Digital Converter&#xff09;模拟数字转换器&#xff0c;是将模拟信号转换成数字信号的一种外设。比如某一个电阻两端的是一个模拟信号&#xff0c;单片机无法直接采集&#xff0c;此时需要ADC先将短租两端的电…

免费获取云服务器

这几天刚入手了阿贝云的 “免费云服务器 ” &#xff0c;接下来给大家讲讲如何免费注册阿贝云的免费云服务器 如何获取免费云服务器 打开阿贝云官网&#xff0c;注册并认证 即可以领取免费云服务器 阿贝云地址&#xff1a;https://www.abeiyun.com/ 服务器优势 永久免费&…

单点登录(SSO)前端怎么做

单点登录&#xff08;SSO&#xff09;前端怎么做 本文介绍单点登录&#xff08;SSO&#xff09;是什么&#xff0c;还有就是前端怎么做。 单点登录&#xff08;SSO&#xff09;是什么 单点登录&#xff08;SSO&#xff0c;Single Sign On&#xff09;&#xff0c;是在企业内部…

【Java笔记】第9章:三个修饰符

前言1. abstract&#xff08;抽象的&#xff09;2. static&#xff08;静态的&#xff09;3. final&#xff08;最终的&#xff09;结语 上期回顾:【Java笔记】第8章&#xff1a;面向对象的三大特性&#xff08;封装、继承、多态&#xff09; 个人主页&#xff1a;C_GUIQU 归属…

瑞鑫RK3588 画中画 OSD 效果展示

这些功能本来在1126平台都实现过 但是迁移到3588平台之后 发现 API接口变化较大 主要开始的时候会比较费时间 需要找到变动接口对应的新接口 之后 就比较好操作了 经过几天的操作 已实现 效果如下

项目工具|git相关

本博客暂时只作为个人资料&#xff0c;后续会进行完善&#xff0c;主要内容来自&#xff1a; 【【Git第一讲】&#xff1a;git分区与两个盒子的故事】 理解暂存区和未暂存区 git为什么要多一个暂存区&#xff1f;难道不能我把代码写完后就是未暂存区&#xff0c;然后直接提交…

ROS2从入门到精通4-3:全局路径规划插件开发案例(以A*算法为例)

目录 0 专栏介绍1 路径规划插件的意义2 全局规划插件编写模板2.1 构造规划插件类2.2 注册并导出插件2.3 编译与使用插件 3 全局规划插件开发案例(A*算法)常见问题 0 专栏介绍 本专栏旨在通过对ROS2的系统学习&#xff0c;掌握ROS2底层基本分布式原理&#xff0c;并具有机器人建…

docker bash: vi: command not found 修改文件无法使用 vi yum的方法

如题&#xff0c;被入坑很多次。也参考了很多的修复docker 中的vi yum等方法。最终都未解决。 因为要修改 已安装容器中的各类配置信息。无法使用vi yum很麻烦。除去使用docker 挂载文件方法外&#xff0c;还可以使用如下方法直接修改对应的配置文件信息。 如: 修改 logstas…

通过抑制治疗上调的环氧化酶-2来改善光动力性能的肿瘤归巢嵌合肽菱形体

引用信息 文 章&#xff1a;Tumor Homing Chimeric Peptide Rhomboids to Improve Photodynamic Performance by Inhibiting Therapy‐Upregulated Cyclooxygenase-2. 期 刊&#xff1a;Smal&#xff08;影响因子&#xff1a;13.3&#xff09; 发表时间&#xff1a…

赢单有秘诀,大模型智能陪练更懂你

随着数字化技术在营销场景的加速应用&#xff0c;产品营销节奏不断加快&#xff0c;消费者需求日益多元化、个性化&#xff0c;市场竞争日趋激烈。面对复杂多变的市场环境&#xff0c;企业新产品、新服务的推出速度大幅提升&#xff0c;产品知识更新愈加频繁&#xff0c;传统的…

神经网络 torch.nn---优化器的使用

torch.optim - PyTorch中文文档 (pytorch-cn.readthedocs.io) torch.optim — PyTorch 2.3 documentation 反向传播可以求出神经网路中每个需要调节参数的梯度(grad)&#xff0c;优化器可以根据梯度进行调整&#xff0c;达到降低整体误差的作用。下面我们对优化器进行介绍。 …

通过龙讯旷腾PWmat发《The Journal of Chemical Physics》 :基于第一性原理分子动力学热力学积分的离子溶剂化自由能计算

背景导读 离子溶解是电化学中一个重要的过程。电化学反应中许多重要的参数&#xff0c;例如电化学还原电位、无限稀释活度系数、亨利定律溶解常数和离子溶解度等&#xff0c;都与离子的溶剂化能有关。然而&#xff0c;由于测量技术和数据处理的困难&#xff0c;离子溶剂化能的…

LabVIEW与Arm控制器之间的通讯

LabVIEW是一个强大的图形化编程环境&#xff0c;广泛应用于自动化控制、数据采集和测试测量等领域。而Arm控制器则是嵌入式系统中常用的处理器架构&#xff0c;广泛用于各种控制和计算任务。将LabVIEW与Arm控制器进行通讯控制&#xff0c;可以结合二者的优势&#xff0c;实现高…