驱动开发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 逻辑运算符的用…...
最牛逼的程序员出生了
编程学习之路 我是河南某大学计算机专业的。目前主攻C语言与后端开发,每周投入14小时系统学习。计划通过《C Primer Plus》打牢基础,结合项目实战掌握后端技术。未来希望加入科大讯飞,参与AI相关研发。期待与各位共勉!...
计及阴影遮挡效应的光伏阵列拓扑 PSO 重构优化研究(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...
Jetson Nano + 镭神16线雷达:手把手教你将TARE自主探索算法部署到阿克曼机器人
Jetson Nano与镭神16线雷达:TARE算法在阿克曼机器人上的实战部署指南 硬件选型与系统架构设计 当我们需要将TARE自主探索算法部署到真实机器人平台时,硬件选型直接决定了后续开发流程的顺畅程度。经过多次项目实践,我发现Jetson Nano开发板与…...
使用小龙虾来操作猿编程的遥控车钾
一、什么是 Q 饱和运算? 1. 核心痛点:普通运算的 “数值回绕” 普通算术运算(如 ADD/SUB)溢出时,数值会按补码规则 “回绕”,导致结果完全错误: 示例:int8_t 类型最大值 127 1 → 结…...
软件SLA介绍(Service Level Agreement,服务等级协议)(可签约SLA:服务提供方(厂商)与客户之间,就服务质量达成的可量化承诺协议)SLO服务目标、SLI服务指标、吞吐量
文章目录软件 SLA 是什么?一文讲清“可签约 SLA”的本质与落地一、什么是 SLA?二、什么是“可签约 SLA”?1️⃣ 指标可量化2️⃣ 有明确统计口径3️⃣ 有违约责任(关键!)三、SLA vs SLO vs SLI(…...
TimescaleDB 2.26.2 发布,修复多项错误
开源数据库 TimescaleDB 发布 2.26.2 版本,该版本修复了自 2.26.1 版本以来存在的多个错误,官方建议用户尽快升级。 TimescaleDB 简介 TimescaleDB 是基于 PostgreSQL 构建的开源数据库,旨在让 SQL 可扩展到时间序列数据。它被打包为 Postgre…...
手把手教你用QT设计FPGA图像接收器:从UDP数据包到实时显示窗口的完整流程
QTUDP实现FPGA图像接收器的工程实践指南 在工业视觉检测、医疗影像传输等实时性要求较高的场景中,FPGA与PC端的高效图像传输一直是开发者面临的挑战。本文将分享一个基于QT框架的UDP图像接收器完整实现方案,重点解决网络流媒体处理中的三个核心问题&…...
NaViL-9B多场景落地:已支撑12家企业完成图文理解AI能力内嵌上线
NaViL-9B多场景落地:已支撑12家企业完成图文理解AI能力内嵌上线 1. 多模态AI新标杆 在当今企业数字化转型浪潮中,能够同时理解文本和图像的多模态AI正成为刚需。NaViL-9B作为原生多模态大语言模型,已经成功帮助12家不同行业的企业实现了图文…...
DEM、DSM、DTM、DOM、TIN:地理空间数据模型的本质区别与应用场景解析
1. 地理空间数据模型的核心概念解析 第一次接触DEM、DSM这些术语时,我也被绕得头晕。直到参与了一个城市规划项目,才真正理解它们的区别。简单来说,这些模型就像给地球表面拍不同类型的"照片":有的只拍地形,…...
哥本哈士奇(aspnetx)固
简介 langchain中提供的chain链组件,能够帮助我门快速的实现各个组件的流水线式的调用,和模型的问答 Chain链的组成 根据查阅的资料,langchain的chain链结构如下: $$Input \rightarrow Prompt \rightarrow Model \rightarrow …...
