2023/10/30-LED灯驱动开发

news/2024/5/19 4:51:59/文章来源:https://blog.csdn.net/ainitjq1314/article/details/133953669

 k1.c

#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/io.h>
#include "head.h"
char kbuf[128] = {};
unsigned int major;
//定义三个指针指向映射后的虚拟内存
unsigned int *vir_rcc;
unsigned int *vir_moder_led1;
unsigned int *vir_odr_led1;
unsigned int *vir_moder_led2;
unsigned int *vir_odr_led2;
unsigned int *vir_moder_led3;
unsigned int *vir_odr_led3;
// 封装操作方法
int mycdev_open(struct inode *inode, struct file *file)
{printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);return 0;
}
ssize_t mycdev_read(struct file *file, char *ubuf, size_t size, loff_t *lof)
{printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);int ret=0;ret = copy_to_user(ubuf,kbuf,size);if(ret = 0){printk("copy_to_user 内核->用户 filed!\n");return -EIO;}//printk("copy_to_user 内核->用户 success!,ubuf=%s\n",ubuf);printk("copy_to_user 内核->用户 success!\n");return 0;
}
ssize_t mycdev_write(struct file *file, const char *ubuf, size_t size, loff_t *lof)
{printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);int ret=0;ret = copy_from_user(kbuf,ubuf,size);if(ret = 0){printk("copy_from_user 用户->内核 filed!\n");return -EIO;}//printk("copy_from_user 用户->内核 success!,ubuf=%s\n",ubuf);printk("copy_from_user 用户->内核 success!\n");if(kbuf[0] == '0') //关灯{(*vir_odr_led1) &= (~(0x1 << 10));(*vir_odr_led2) &= (~(0x1 << 10));(*vir_odr_led3) &= (~(0x1 << 8));}else if(kbuf[0] == '1') //开灯{(*vir_odr_led1) |= (0x1 << 10);(*vir_odr_led2) |= (0x1 << 10);(*vir_odr_led3) |= (0x1 << 8);}return 0;
}
int mycdev_close(struct inode *inode, struct file *file)
{printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);return 0;
}
//定义操作方法结构体对象
struct file_operations fops={.open=mycdev_open,.read=mycdev_read,.write=mycdev_write,.release=mycdev_close,
};
static int __init mycdev_init(void)
{//注册字符设备驱动major=register_chrdev(0,"mychrdev",&fops);if (major < 0){printk("字符设备驱动注册失败\n");return major;}printk("注册字符设备驱动成功major=%d\n", major);//进行寄存器的地址映射vir_rcc = ioremap(PHY_RCC,4);if(vir_rcc == NULL){printk("物理内存映射filed! %d\n",__LINE__);return -EFAULT;}vir_moder_led1 = ioremap(PHY_LED1_MODER,4);if(vir_moder_led1 == NULL){printk("物理内存映射filed! %d\n",__LINE__);return -EFAULT;}vir_odr_led1 = ioremap(PHY_LED1_ODR,4);if(vir_odr_led1 == NULL){printk("物理内存映射filed! %d\n",__LINE__);return -EFAULT;}vir_moder_led2 = ioremap(PHY_LED2_MODER,4);if(vir_moder_led2 == NULL){printk("物理内存映射filed! %d\n",__LINE__);return -EFAULT;}vir_odr_led2 = ioremap(PHY_LED2_ODR,4);if(vir_odr_led2 == NULL){printk("物理内存映射filed! %d\n",__LINE__);return -EFAULT;}vir_moder_led3 = ioremap(PHY_LED3_MODER,4);if(vir_moder_led3 == NULL){printk("物理内存映射filed! %d\n",__LINE__);return -EFAULT;}vir_odr_led3 = ioremap(PHY_LED3_ODR,4);if(vir_odr_led3 == NULL){printk("物理内存映射filed! %d\n",__LINE__);return -EFAULT;}printk("物理内存映射成功!\n");//LED1寄存器初始化(*vir_rcc) |= (0x3 << 4);         //GPIOE控制器时钟使能(*vir_moder_led1) &= (~(0x3 << 20));   //MODER[21:20] => 00(*vir_moder_led1) |= (0x1 << 20);      //MODER[21:20] => 01(*vir_odr_led1) &= (~(0x1 << 10));     //默认为关灯(*vir_moder_led2) &= (~(0x3 << 20));   //MODER[21:20] => 00(*vir_moder_led2) |= (0x1 << 20);      //MODER[21:20] => 01(*vir_odr_led2) &= (~(0x1 << 10));     //默认为关灯(*vir_moder_led3) &= (~(0x3 << 16));   //MODER[17:16] => 00(*vir_moder_led3) |= (0x1 << 16);      //MODER[17:16] => 01(*vir_odr_led3) &= (~(0x1 << 8));     //默认为关灯return 0;
}
static void __exit mycdev_exit(void)
{//取消内存映射iounmap(vir_rcc);iounmap(vir_moder_led1);iounmap(vir_odr_led1);iounmap(vir_moder_led2);iounmap(vir_odr_led2);iounmap(vir_moder_led3);iounmap(vir_odr_led3);//注销字符设备驱动unregister_chrdev(major,"mychrdev");}
module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");

test.c

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
int main(int argc,const char * argv[])
{char buf[128] = {0};int fd = open("/dev/mychrdev",O_RDWR);if(fd < 0){printf("文件/dev/mychrdev打开失败\n");return -1;}printf("文件/dev/mychrdev打开成功\n");while(1){printf("输入要进行的操作=> 0(关灯) <-> 1(开灯) :  ");fgets(buf,sizeof(buf),stdin);buf[strlen(buf)-1] = '\0';//User -> 内核write(fd,buf,sizeof(buf));}/*//User -> 内核write(fd,buf,sizeof(buf));//内核 -> Userread(fd,buf,sizeof(buf));*/close(fd);return 0;
}

head.h

#ifndef __HEAD_H__
#define __HEAD_H__
#define PHY_RCC        0x50000A28#define PHY_LED1_MODER 0x50006000
#define PHY_LED1_ODR   0x50006014#define PHY_LED2_MODER 0x50007000
#define PHY_LED2_ODR   0x50007014#define PHY_LED3_MODER 0x50006000
#define PHY_LED3_ODR   0x50006014#endif

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

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

STM32:TIM通道输入捕获

本文主要讲解如何使用TIMER通道的输入脉冲捕获功能。基于STM32F7的Timer2 Channel3来进行讲解。 配置时钟 Timer2的时钟频率&#xff0c;对应APB1 Timer。 分频设置为96-1&#xff0c;这样设置每次count计数&#xff0c;对应的时间为1us。Counter设置为最大即可&#xff0c;默…

VMware Workstation里面安装ubuntu20.04的流程

文章目录 前言一、获取 desktop ubuntu20.04 安装镜像二、VMware Workstation下安装ubuntu20.041. VMware Workstation 创建一个新的虚拟机2. ubuntu20.04的安装过程3. 登录ubuntu20.044. 移除 ubuntu20.04 安装镜像总结参考资料前言 本文主要介绍如何在PC上的虚拟机(VMware W…

使用Spyder进行动态网页爬取:实战指南

导语 知乎数据的攀爬价值在于获取用户观点、知识和需求&#xff0c;进行市场调查、用户画像分析&#xff0c;以及发现热门话题和可能的新兴领域。同时&#xff0c;知乎上的问题并回答也是宝贵的学习资源&#xff0c;用于知识图谱构建和自然语言处理研究。爬取知乎数据为决策和…

SolidWorks2021 安装教程(亲测可用)

1.安装教程&#xff1a;&#xff08;断网进行&#xff0c;否则安装了后还是无法用&#xff09; 1.运行sw2021_network_serials_licensing 2. 注册表编辑器确定 3.成功添加到注册表中 4.复制SolidWorks_Flexnet_Server文件夹 5.运行SolidWorks_Flexnet_Server下的lserver_insta…

测试Android webview 加载本地html

最近开发一个需要未联网功能的App, 不熟悉使用Java原生开发界面&#xff0c;于是想使用本地H5做界面&#xff0c;本文测试了使用本地html加载远程数据。直接上代码&#xff1a; MainActivity.java package com.alex.webviewlocal;import androidx.appcompat.app.AppCompatAct…

UE4 UltrDynamicSky与场景物体进行交互

找到材质 找到其最父类的材质 把这个拖过去连上即可

OSI笔记

由7层组成&#xff0c;由下自上分别为&#xff1a; 物理层&#xff08;硬件方面&#xff0c;例如物理网络设备、布线电缆、光纤等&#xff09;&#xff0c; 传输数据主要是比特流0 1 、电信号数据链路层&#xff08;确定了0 1 的分组方式&#xff0c;通过广播的方式&#xff0…

VTK8.0.0编译+QT5.9.2+VS2017

背景 VTK网上资料较多并且使用较多的版本可能是VTK8.2.0&#xff0c;但是由于之前先配置了QT 5.9.2 msvc2017 PCL1.8.1 VTK8.0.0环境&#xff0c;听说有人PCL1.8.1配置VTK8.2.0实测版本不兼容&#xff0c;需修改源码调试&#xff0c;比较麻烦&#xff0c;所以之前就使用的VT…

元梦之星内测上线,如何在B站打响声量?

元梦之星是腾讯天美工作室群研发的超开星乐园派对手游&#xff0c;于2023年1月17日通过审批。该游戏风格可爱软萌&#xff0c;带有社交属性&#xff0c;又是一款开黑聚会的手游&#xff0c;备受年轻人关注。 飞瓜数据&#xff08;B站版&#xff09;显示&#xff0c;元梦之星在…

迅为RK3588开发板Android12单摄方案设备树修改

打开 3588-android12/kernel-5.10/arch/arm64/boot/dts/rockchip/topeet_camera_config.dtsi 设备树&#xff0c;此设备树中对底板上的摄像头接口进行了配置&#xff0c;如下图所示&#xff1a; 如果想要使用 J1 接口打开摄像头 OV5695 或者 摄像头 OV13850&#xff0c;只需要在…

在 Windows Server RDS 服务器 上重置 120 天宽限期

如果您出于测试目的安装了 RDS Server 2016/2019/2022&#xff0c;并且 RDS 许可宽限期已过期&#xff0c;请继续阅读下面的内容以了解如何重置 120 天宽限期。您可能知道&#xff0c;在安装 RDS Server 2016 时&#xff0c;您有 120 天的时间来安装 RD 客户端访问许可证 &…

nginx负载均衡(动静分离)

nginx负载均衡&#xff08;动静分离&#xff09; 文章目录 nginx负载均衡&#xff08;动静分离&#xff09;工作原理&#xff1a;环境说明&#xff1a;部署nginx负载均衡步骤&#xff1a;在负载均衡&#xff08;NGINX&#xff09;主机上做配置&#xff1a;测试&#xff1a;在浏…

驱动编写应用程序控制三盏灯亮灭

应用程序 #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <string.h> int main(int argc, char const *argv[]) {char buf[128] {0};int fd open("/dev/mych…

点云平面拟合新国标怎么应对?

文章目录 一、应用背景二、算法原理三、代码实现首先我们看一下平面度的概念: 平面度:测量点集合中,在平面上方且距离基准平面最远的点到平面的距离+在平面下方且距离基准平面最远的点到平面的距离。 一、应用背景 在旧标准中,使用最小二乘法去拟合全部点,以拟合平面作为…

QT的QStringList的使用

初始 化 默认构造函数创建一个空列表。可以使用初始值设定项列表构造函数创建包含元素的列表&#xff1a; QStringList fonts { "Arial", "Helvetica", "Times" }; 添加字符串 可以使用insert 、append&#xff08;&#xff09; 和 operator…

RK3568驱动指南|第七期-设备树-第57章 实例分析:中断

瑞芯微RK3568芯片是一款定位中高端的通用型SOC&#xff0c;采用22nm制程工艺&#xff0c;搭载一颗四核Cortex-A55处理器和Mali G52 2EE 图形处理器。RK3568 支持4K 解码和 1080P 编码&#xff0c;支持SATA/PCIE/USB3.0 外围接口。RK3568内置独立NPU&#xff0c;可用于轻量级人工…

操作系统【OS】微内核

基本概念 微内核结构将操作系统划分为两大部分&#xff1a;微内核多个服务器微内核包含&#xff1a; 与硬件处理紧密相关的部分一些较基本的功能客户和服务器间的通信客户与服务器之间是借助微内核提供的消息传递机制来实现交互的 基本功能 进程管理 进程的通信、切换、调度…

攻防世界web篇-get_post

打开给出的地址 将浏览器上的地址http://61.147.171.105:58937/改为http://61.147.171.105:58937/?a1 输入?a1是完成了第一步&#xff0c;get请求&#xff0c;接下来要完成post的请求 这里&#xff0c;我使用的backbar quantum插件 得出flag值

SystemVerilog学习(1)——验证导论

写在最前 选课不慎&#xff0c;选修课选了个SystemVerilog&#xff0c;事情比必修还多&#xff0c;上课老师讲的一点用没有&#xff0c;但是学分还得修&#xff0c;只能自学了&#xff0c;既来之则安之。 一、什么是SystemVerilog SystemVerilog简称为SV语言&#xff0c;是一种…

使用socket对http站点的访问

使用socket对http站点的访问 步骤&#xff1a; 1、实现TCP客户端 2、设置访问的网站地址 3、创建发送的请求报文 4、连接和发送报文到百度 5、显示百度回复的内容 import socket # 建立TCP连接 s socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 与服务器建立连接 host …