驱动开发LED灯绑定设备文件
头文件
#ifndef __HEAD_H__
#define __HEAD_H__typedef struct
{unsigned int MODER;unsigned int OTYPER;unsigned int OSPEEDR;unsigned int PUPDR;unsigned int IDR;unsigned int ODR;
}gpio_t;#define PHY_LED1_ADDR 0x50006000
#define PHY_LED2_ADDR 0x50007000
#define PHY_LED3_ADDR 0x50006000
#define PHY_RCC_ADDR 0x50000A28
#define LED_ON _IOW('l',1,int)
#define LED_OFF _IOW('l',0,int)#endif
应用程序
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include "head.h"
int main(int argc,char const *argv[])
{char buf[128]={0};int a,b;int fd=open("/dev/demo0",O_RDWR);if(fd<0){printf("打开设备文件失败\n");exit(-1);}while(1){//从终端读取printf("请输入要实现的功能 ");printf("0(关灯) 1(开灯)\n");printf("请输入>");scanf("%d",&a);printf("请选择要控制的灯:1(LED1)2(LED2) 3(LED3)\n");printf("请输入>");scanf("%d",&b);switch(a){case 1:ioctl(fd,LED_ON,&b);break;case 0:ioctl(fd,LED_OFF,&b);break;}}close(fd);return 0;
}
驱动程序
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/io.h>
#include <linux/device.h>
#include <linux/cdev.h>
#include <linux/slab.h>
#include "head.h"
unsigned int major=0;
unsigned int minor=0;
char kbuf[128]={};
gpio_t *vir_led1;
gpio_t *vir_led2;
gpio_t *vir_led3;
unsigned int *vir_rcc;
struct cdev *cdev;
dev_t devno;
struct class *cls;
struct device *dev;int mycdev_open(struct inode *inode, struct file *file)
{int min=MINOR(inode->i_rdev);file->private_data=(void *)min;printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);return 0;
}long mycdev_ioctl(struct file *file,unsigned int cmd,unsigned long arg)
{int min=(int)file->private_data;switch (min){case 0: // 操作LED1switch (cmd){case LED_ON: //开灯vir_led1->ODR |= (0x1<<10);break;case LED_OFF://关灯vir_led1->ODR &= (~(0x1<<10));break;}break;case 1: // 操作LED2switch (cmd){case LED_ON: //开灯vir_led2->ODR |= (0x1<<10);break;case LED_OFF://关灯vir_led2->ODR &= (~(0x1<<10));break;}break;case 2: // 操作LED3switch (cmd){case LED_ON: //开灯vir_led3->ODR |= (0x1<<8);break;case LED_OFF://关灯vir_led3->ODR &= (~(0x1<<8));break;}break;}printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);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,.unlocked_ioctl=mycdev_ioctl,.release=mycdev_close,
};int all_led_init(void)
{//寄存器地址的映射vir_led1=ioremap(PHY_LED1_ADDR,sizeof(gpio_t));if(vir_led1==NULL){printk("ioremap filed:%d\n",__LINE__);return -ENOMEM;}vir_led2=ioremap(PHY_LED2_ADDR,sizeof(gpio_t));if(vir_led2==NULL){printk("ioremap filed:%d\n",__LINE__);return -ENOMEM;}vir_led3=vir_led1;vir_rcc=ioremap(PHY_RCC_ADDR,4);if(vir_rcc==NULL){printk("ioremap filed:%d\n",__LINE__);return -ENOMEM;}printk("物理地址映射成功\n");//寄存器的初始化//rcc(*vir_rcc) |= (3<<4);//led1vir_led1->MODER &= (~(3<<20));vir_led1->MODER |= (1<<20);vir_led1->ODR &= (~(1<<10));//led2vir_led2->MODER &= (~(3<<20));vir_led2->MODER |= (1<<20);vir_led2->ODR &= (~(1<<10));//led3vir_led3->MODER &= (~(3<<16));vir_led1->MODER |= (1<<16);vir_led1->ODR &= (~(1<<8));printk("寄存器初始化成功\n");return 0;
}static int __init mycdev_init(void)
{//1.申请一个对象空间cdev_allocint ret;cdev= cdev_alloc();if(cdev==NULL){printk("申请字符设备驱动对象失败\n");ret=-EFAULT;goto out1;}printk("字符设备驱动对象申请成功\n");//2.初始化对象cdev_initcdev_init(cdev,&fops);//3.申请设备号 register_chrdev_region()/alloc_chrdev_region()if(major==0)//动态申请{ret=alloc_chrdev_region(&devno,minor,3,"demo");if(ret){printk("动态申请设备号失败\n");goto out2;}major=MAJOR(devno);//根据设备号获取主设备号minor=MINOR(devno);//根据设备号获取次设备号}else{ret=register_chrdev_region(MKDEV(major,minor),3,"demo");if(ret){printk("静态指定设备号失败\n");goto out2;}}printk("设备号申请成功\n");//4.注册驱动对象 cdev_addret=cdev_add(cdev,MKDEV(major,minor),3);if(ret){printk("注册字符设备驱动对象失败\n");goto out3;}printk("注册字符设备驱动对象成功\n");//5.向上提交目录 class_createcls=class_create(THIS_MODULE,"demo");if(IS_ERR(cls)){printk("向上提交目录失败\n");goto out4;}printk("向上提交目录成功\n");//6.向上提交设备节点信息 device_createint i;for(i=0;i<3;i++){dev=device_create(cls,NULL,MKDEV(major,i),NULL,"demo%d",i);if(IS_ERR(dev)){printk("向上提交设备节点失败\n");goto out5;}}printk("向上提交设备节点信息成功\n");all_led_init();return 0;
out5:
//将提交成功的节点信息释放for(--i;i>=0;i--){device_destroy(cls,MKDEV(major,i));}//销毁目录class_destroy(cls);
out4:cdev_del(cdev);
out3:unregister_chrdev_region(MKDEV(major,minor),3);
out2:kfree(cdev);
out1:return ret;}
static void __exit mycdev_exit(void)
{iounmap(vir_led1);iounmap(vir_led2);iounmap(vir_rcc);//1.销毁设备节点信息int i;for(i=0;i<3;i++){device_destroy(cls,MKDEV(major,i));}//2.销毁目录class_destroy(cls);//3.注销字符设备驱动对象cdev_del(cdev);//4.释放设备号unregister_chrdev_region(MKDEV(major,minor),3);//5.释放申请到的字符设备驱动对象空间kfree(cdev);
}module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");

相关文章:
驱动开发LED灯绑定设备文件
头文件 #ifndef __HEAD_H__ #define __HEAD_H__typedef struct {unsigned int MODER;unsigned int OTYPER;unsigned int OSPEEDR;unsigned int PUPDR;unsigned int IDR;unsigned int ODR; }gpio_t;#define PHY_LED1_ADDR 0x50006000 #define PHY_LED2_ADDR 0x50007000 #defin…...
MySql 数据库基础概念,基本简单操作及数据类型介绍
文章目录 数据库基础为什么需要数据库?创建数据库mysql架构SQL语句分类编码集修改数据库属性数据库备份 表的基本操作存在时更新,不存在时插入 数据类型日期类型enum和set 数据库基础 以特定的格式保存文件,叫做数据库,这是狭义上…...
异步加载 JavaScript
目录 编辑 前言:异步加载 JavaScript 的重要性 详解:异步加载 JavaScript 的方法 使用 使用动态创建标签: 使用模块引入(ES6模块): 解析:异步加载 JavaScript 的重要性和优势 实践和注…...
汽车屏类产品(四):仪表Cluster
###前言 仪表Cluster/仪表盘Dashboard,作为伴随汽车诞生就存在的一个主要零部件之一,从机械到电子到数字,可以说也是逐渐发展到现在的。 目前的主流框图如下,中间processor就是主控芯片,可能有buttons/switches,有display显示屏+backlight背光,有audio->speake…...
【GA-ELM】基于遗传算法优化极限学习机回归预测研究(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...
DFT和ATE岗位前景薪资对比,手把手教你如何选择岗位?
ATE测试和DFT可测性设计,虽然二者都对芯片测试至关重要,但是两个岗位的区别还是很大的。 两个岗位应该如何做选择? 先讲产业环节 我们知道芯片设计、芯片制造、芯片封测每个环节都是大工程,且每个环节都关键且重要。测试是芯片诞…...
驱动day4作业
通过字符设备驱动的分步实现编写LED驱动,另外实现特备文件和设备的绑定 head.h #ifndef __HEAD_H__ #define __HEAD_H__ typedef struct{unsigned int MODER;unsigned int OTYPER;unsigned int OSPEEDR;unsigned int PUPDR;unsigned int IDR;unsigned int ODR; }…...
【Oracle】VC6.0使用 odbc 访问 Oracle 存储过程
环境说明 系统环境 系统:Windows XP IDE: Microsoft Visual C 6.0 使用的对象 msado15.tlh _ConnectionPtr m_pConnection; HRESULT hr m_pConnection.CreateInstance(“ADODB.Connection”); _RecordsetPtr m_pRecordset; m_pRecordset.CreateInstan…...
QWidget快速美化-圆形蓝色单选框
将代码复制进QRadioButton的样式表 效果: 代码: QRadioButton{font:75 9pt "Arial";background:transparent;color:white;border:none; }QRadioButton:disabled{color:gray; }QRadioButton::indicator{width:12px;height:12px;border-radius:8px; }QRadioButton::i…...
adb 获取当前界面元素
adb配置正确,直接看6,pull的位置是你执行pull的目录下。 --------------------------------------------------------------------------------------------------------------------------------- 使用adb命令获取当前应用的元素需要先连接到手机或模…...
SpringSecurity源码学习四:会话管理
目录 1. 什么是会话管理2. springSecurity中的session管理怎么做的3. springSecurity源码中的session管理4. 代码示例5. 源码5.1 不同策略的含义 6. 集群模式session管理7. 总结 1. 什么是会话管理 会话管理是指在Java应用程序中管理用户会话状态的过程。在Spring框架中&#…...
Kotlin笔记(七):协程
1. 协程的定义 协程属于Kotlin中非常有特色的一项技术,因为大部分编程语言中是没有协程这个概念的。 什么是协程呢?它其实和线程是有点类似的,可以简单地将它理解成一种轻量级的线程。要知道,线程是非常重量级的,它需要…...
存储优化知识复习二详细版解析
存储优化 知识复习二 一、 选择题 1、 对数据库调优的方法中,最困难但是最有成效的是( )。 A、优化表的架构设计 B、添加内存 C、索引优化 D、查询语句优化 【参考答案】A2、 防止与处理死锁的方法有( )。 A、尽量避免或尽快处理阻塞 B、访…...
《持续交付:发布可靠软件的系统方法》- 读书笔记(七)
持续交付:发布可靠软件的系统方法(七) 第 7 章 提交阶段7.1 引言7.2 提交阶段的原则和实践7.2.1 提供快速有用的反馈7.2.2 何时令提交阶段失败7.2.3 精心对待提交阶段7.2.4 让开发人员也拥有所有权7.2.5 在超大项目团队中指定一个构建负责人 …...
Go源码实现使用多线程并发下载大文件的功能
摘要:Go语言编码实现了使用多线程并发下载文件的功能。 1. 代码流程介绍 1. 获取系统的CPU核心数量,并将其作为线程数的参考值,并打印出来。 2. 定义要下载的文件的URL、线程数和输出文件名。 3. 使用getFileSize()函数获取文件大小…...
Python基础入门例程1-NP1 Hello World!
描述 将字符串 Hello World! 存储到变量str中,再使用print语句将其打印出来。 输入描述: 无 输出描述: 一行输出字符串Hello World! 解答: str "Hello World!" print(str) 解释说明: 赋值变量&…...
前端面试题10.23
解决的最复杂的前端问题,介绍一下 最复杂的前端问题之一是浏览器兼容性,不同浏览器对网页的渲染方式存在差异,需要针对不同浏览器做兼容性处理。此外,前端性能优化也是一个复杂的问题,需要综合考虑网页加载速度、渲染…...
DYC算法开发与测试(基于ModelBase实现)
ModelBase是经纬恒润开发的车辆仿真软件,包含两个大版本:动力学版本、智能驾驶版本。动力学版包含高精度动力学模型,能很好地复现车辆在实际道路中运行的各种状态变化,可用于乘用车、商用车动力底盘系统算法开发、控制器仿真测试&…...
第四章 路由基础
目录 4.1 路由器概述 4.1.1 路由器定义 4.1.2 路由器工作原理 4.1.3 路由表的生成方式 (1)直连路由 (2)静态路由 (3)动态路由 4.1.4 路由器的接口 (1)配置接口 ࿰…...
Java逻辑运算符(、||和!),Java关系运算符
逻辑运算符把各个运算的关系表达式连接起来组成一个复杂的逻辑表达式,以判断程序中的表达式是否成立,判断的结果是 true 或 false。 逻辑运算符是对布尔型变量进行运算,其结果也是布尔型,具体如表 1 所示。 表 1 逻辑运算符的用…...
【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器
——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的一体化测试平台,覆盖应用全生命周期测试需求,主要提供五大核心能力: 测试类型检测目标关键指标功能体验基…...
连锁超市冷库节能解决方案:如何实现超市降本增效
在连锁超市冷库运营中,高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术,实现年省电费15%-60%,且不改动原有装备、安装快捷、…...
【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】
1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件(System Property Definition File),用于声明和管理 Bluetooth 模块相…...
解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错
出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上,所以报错,到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本,cu、torch、cp 的版本一定要对…...
Matlab | matlab常用命令总结
常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...
Map相关知识
数据结构 二叉树 二叉树,顾名思义,每个节点最多有两个“叉”,也就是两个子节点,分别是左子 节点和右子节点。不过,二叉树并不要求每个节点都有两个子节点,有的节点只 有左子节点,有的节点只有…...
以光量子为例,详解量子获取方式
光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学(silicon photonics)的光波导(optical waveguide)芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中,光既是波又是粒子。光子本…...
Linux离线(zip方式)安装docker
目录 基础信息操作系统信息docker信息 安装实例安装步骤示例 遇到的问题问题1:修改默认工作路径启动失败问题2 找不到对应组 基础信息 操作系统信息 OS版本:CentOS 7 64位 内核版本:3.10.0 相关命令: uname -rcat /etc/os-rele…...
七、数据库的完整性
七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...
Python+ZeroMQ实战:智能车辆状态监控与模拟模式自动切换
目录 关键点 技术实现1 技术实现2 摘要: 本文将介绍如何利用Python和ZeroMQ消息队列构建一个智能车辆状态监控系统。系统能够根据时间策略自动切换驾驶模式(自动驾驶、人工驾驶、远程驾驶、主动安全),并通过实时消息推送更新车…...
