驱动day4work
头文件
#ifndef __CKR_H__
#define __CKR_H__typedef struct
{unsigned int MODER; // 00unsigned int OTYPER; // 04unsigned int OSPEEDR; // 08unsigned int PUPDR; // 0Cunsigned int IDR; // 10unsigned int ODR; // 14
} gpio_t;// GPIO口
#define PHY_GPIOB 0X50003000
#define PHY_GPIOE 0X50006000
#define PHY_GPIOF 0X50007000
// RCC 总线
#define PHY_RCC 0X50000A28// LED
#define LED_ON _IO('l', 1)
#define LED_OFF _IO('l', 0)#endif
应用程序
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include "ckr.h"int main(int argc, char const *argv[])
{char buf[128] = {0};int led1 = open("/dev/myled0", O_RDWR);int led2 = open("/dev/myled1", O_RDWR);int led3 = open("/dev/myled2", O_RDWR);while (1){printf("\n请输入要操作的的灯(1-led1 2-led2 3-led3 4-退出)>>>");int a, b;scanf("%d", &a);if (a == 4){break;}printf("请输入操作指令(0-关灯 1-开灯)>>>");scanf("%d", &b);switch (a){case 1:if (b == 0){ioctl(led1, LED_OFF);}if (b == 1){ioctl(led1, LED_ON);}break;case 2:if (b == 0){ioctl(led2, LED_OFF);}if (b == 1){ioctl(led2, LED_ON);}break;case 3:if (b == 0){ioctl(led3, LED_OFF);}if (b == 1){ioctl(led3, LED_ON);}break;default:break;}}close(led1);close(led2);close(led3);return 0;
}
驱动程序
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/io.h>
#include <linux/device.h>
#include <linux/uaccess.h>
#include <linux/slab.h>
#include <linux/cdev.h>
#include "ckr.h"gpio_t *GPIOE;
gpio_t *GPIOF;
unsigned int *RCC;struct cdev *cdev;
struct class *cls;
struct device *dev;
unsigned int major = 500;
unsigned int minor = 0; // 次设备号的起始值
dev_t devno;char kbuf[128] = {0};
// 封装操作方法
int mycdev_open(struct inode *inode, struct file *file)
{int a = inode->i_rdev; // 获取当前设备文件对应的设备号file->private_data = (void *)MINOR(a); // 将次设备号保存到当前文件的file结构中printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);return 0;
}// ioctrl
long mycdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{unsigned int a = (unsigned int)file->private_data;switch (a){case 0:if (cmd == LED_ON){GPIOE->ODR |= (0x1 << 10);}else if (cmd == LED_OFF){GPIOE->ODR &= (~(0x1 << 10));}break;case 1:if (cmd == LED_ON){GPIOF->ODR |= (0x1 << 10);}else if (cmd == LED_OFF){GPIOF->ODR &= (~(0x1 << 10));}break;case 2:if (cmd == LED_ON){GPIOE->ODR |= (0x1 << 8);}else if (cmd == LED_OFF){GPIOE->ODR &= (~(0x1 << 8));}break;default:break;}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,.release = mycdev_close,.unlocked_ioctl = mycdev_ioctl,
};void myled_init(void)
{// 进行寄存器地址的映射-----------------------------------------------GPIOE = ioremap(PHY_GPIOE, 4);if (GPIOE == NULL){printk("映射物理内存失败%d\n", __LINE__);return -EFAULT;}GPIOF = ioremap(PHY_GPIOF, 4);if (GPIOF == NULL){printk("映射物理内存失败%d\n", __LINE__);return -EFAULT;}RCC = ioremap(PHY_RCC, 4);if (RCC == NULL){printk("映射物理内存失败%d\n", __LINE__);return -EFAULT;}printk("映射物理内存成功\n");// 硬件寄存器的初始化(*RCC) |= (0X3 << 4); // rcc使能GPIOE->MODER &= (~(0x3 << 20));GPIOE->MODER |= (0x1 << 20);GPIOE->ODR &= (~(0x1 << 10));GPIOF->MODER &= (~(0x3 << 20));GPIOF->MODER |= (0x1 << 20);GPIOF->ODR &= (~(0x1 << 10));GPIOE->MODER &= (~(0x3 << 16));GPIOE->MODER |= (0x1 << 16);GPIOE->ODR &= (~(0x1 << 8));
}static int __init mycdev_init(void)
{int ret;// 1.申请对象空间 cdev_alloccdev = cdev_alloc();if (cdev == NULL){printk("申请对象空间失败\n");ret = -EFAULT;goto OUT1;}// 2.初始化对象 cdev_initcdev_init(cdev, &fops);// 3.申请设备号 register_chrdev_region()/alloc_chrdev_region()if (major == 0) // 动态申请{ret = alloc_chrdev_region(&devno, minor, 3, "mycdev");if (ret){printk("动态申请设备号失败\n");goto OUT2;}// 统一后面的操作major = MAJOR(devno); // 根据设备号获取主设备号minor = MINOR(devno);}else{ret = register_chrdev_region(MKDEV(major, minor), 3, "mycdev");if (ret){printk("静态指定设备号失败\n");goto OUT2;}}printk("设备号申请成功\n");// 4.注册驱动对象 cdev_add()ret = cdev_add(cdev, MKDEV(major, minor), 3);if (ret){printk("注册设备驱动对象失败\n");goto OUT3;}// 5.向上提交目录 class_create()cls = class_create(THIS_MODULE, "mycdev");if (IS_ERR(cls)){printk("向上提交目录失败\n");ret = -PTR_ERR(cls);goto OUT4;}printk("向上提交目录成功\n");// 6.向上提交设备信息 device_create()int i;for (i = 0; i < 3; i++){dev = device_create(cls, NULL, MKDEV(major, i), NULL, "myled%d", i);if (IS_ERR(dev)){printk("向上提交设备节点失败\n");ret = -PTR_ERR(dev);goto OUT5;}}printk("向上提交设备信息成功\n");myled_init();printk("led初始化成功\n");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)
{// 1.销毁设备信息 device_destroyint i;for (i = 0; i < 3; i++){device_destroy(cls, MKDEV(major, i));}// 2.销毁目录 class_destroyclass_destroy(cls);// 3.注销驱动对象 cdev_delcdev_del(cdev);// 4.释放设备号 unregister_chrdev_region()unregister_chrdev_region(MKDEV(major, minor), 3);// 5.释放对象空间 kfree()kfree(cdev);
}module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");
相关文章:
驱动day4work
头文件 #ifndef __CKR_H__ #define __CKR_H__typedef struct {unsigned int MODER; // 00unsigned int OTYPER; // 04unsigned int OSPEEDR; // 08unsigned int PUPDR; // 0Cunsigned int IDR; // 10unsigned int ODR; // 14 } gpio_t;// GPIO口 #define PHY_GPI…...
[SQL挖掘机] - 字符串函数 - length
介绍: length函数是mysql中用于获取字符串长度的函数。它接受一个字符串作为参数,并返回该字符串的字符数量(包括空格和特殊字符)。 用法: 以下是length函数的语法: length(string)其中,string是要计算长度的字符串…...
「深度学习之优化算法」(十七)灰狼算法
1. 灰狼算法简介 (以下描述,均不是学术用语,仅供大家快乐的阅读) 灰狼算法(Grey Wolf Algorithm)是受灰狼群体捕猎行为启发而提出的算法。算法提出于2013年,仍是一个较新的算法。目前为止(2020)与之相关的论文也比较多,但多为算法的应用,应该仍有研究和改进的余…...
mysql主从复制(主-从-从)
文章目录 一、前期环境准备二、主库配置1.设置server-id值并开启binlog参数2.建立同步账户并给上权限3.查看主库状态4.锁表设置只读5.备份数据库数据 三、从库配置1.设置server-id值并开启binlog参数2.还原从主库备份数据3.设定从主库同步4.启动从库同步开关 四.测试1.在主库上…...
如何制定数据采集解决方案?
数据采集仍是人工智能(AI)构建团队的主要瓶颈。原因各不相同:用例数据可能不足,深度学习等新机器学习(ML)技术需要更多数据,或者团队并未建立获取所需数据的适当流程。但无论如何,对…...
RabbitMQ消息可靠性问题及解决
说明:在RabbitMQ消息传递过程中,有以下问题: 消息没发到交换机 消息没发到队列 MQ宕机,消息在队列中丢失 消息者接收到消息后,未能正常消费(程序报错),此时消息已在队列中移除 …...
2023河南萌新联赛第(三)场:郑州大学(两个题目)
1.入门mex 重点 一些数字的mex是从0往上枚举,第一个没出现的数字。请你回答选最多k个数字,mex最大是多少 既然从0开始枚举,那么应该是最小,那么最大是什么? 经过自己的考虑,给出一个样例,0 1 1…...
学生管理系统-07打包与上线
一、项目架构 vue的项目必须要进行打包,并部署在nginx服务器上的 二、vue的打包 1、修改vue.cofing.js文件 在该文件中添加publicPath属性,值为./ const { defineConfig } require(vue/cli-service) module.exports defineConfig({transpileDepen…...
day31贪心算法 用最少数量的箭引爆气球 和无重叠区间
题目描述 题目分析: x轴向上射箭,12一支,重叠的需要一支,3-8一支,7-16一支 返回2; 就是让重叠的气球尽量在一起,局部最优;用一支弓箭,全局最优就是最少弓箭;…...
AMEYA360报道:手机直连卫星通信发展的三个阶段
卫星通信的发展从过去、现在与规划,可以分为三个阶段。手机卫星通信的第一个阶段中,较为典型的有铱星公司、海事卫星电话、天通卫星通信等,终端设备方面已经可以做到手持设备直接通过自带的天线与卫星进行通信。 包括铱星、天通卫星等&#x…...
redis中缓存雪崩,缓存穿透,缓存击穿的原因以及解决方案
一 redis的缓存雪崩 1.1 缓存雪崩 在redis中,新,旧数据交替时候,旧数据进行了删除,新数据没有更新过来,造成在高并发环境下,大量请求查询redis没有数据,直接查询mysql,造成mysql的…...
ChatGPT火热之下的冷思考
作为一款基于人工智能的自然语言处理(NLP)聊天机器人程序,ChatGPT通过大量来自互联网的文本进行训练,并使用深度学习和机器学习算法来理解用户的问题并提供准确的回答。并且,ChatGPT还内置了情感分析、关键字提取和实体识别等功能&am…...
查看docker容器启动参数
查看docker启动参数 1、查看docker容器的自启动策略2、查看docker容器的日志滚动清理策略 以下配置命令以redis容器为例 1、查看docker容器的自启动策略 docker inspect --format{{json .HostConfig.RestartPolicy}} redis输出的name是always 表示此容器是开机自启动的&#x…...
对Webpack的理解
Webpack是目前比较物流的前端构建工具,它基于入口,用不同的Loader来处理不同的文件 Webpack的核心概念 Entry:入口,Webpack执行构建的第一步将从Entry开始,可抽象成输入。告诉Webpack要使用哪个模块作为构建项目的起…...
使用wxPython和pillow开发拼图小游戏(四)
上一篇介绍了使用本地图片来初始化游戏的方法,通过前边三篇,该小游戏的主要内容差不多介绍完了,最后这一篇来介绍下游戏用时的计算、重置游戏和关闭窗口事件处理 游戏用时的计算 对于游戏用时的记录,看过前几篇的小伙伴可能也发现…...
XGBoost实例——皮马印第安人糖尿病预测和特征筛选
利用皮马印第安人糖尿病数据集来预测皮马印第安人的糖尿病,以下是数据集的信息: Pregnancies:怀孕次数Glucose:葡萄糖BloodPressure:血压 (mm Hg)SkinThickness:皮层厚度 (mm)Insulin:胰岛素 2…...
使用MQ发送对象错误
说明:使用RabbitMQ发送消息,消息是对象,出现下面这样的错误; 错误信息:Caused by: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of com.hmall.item.pojo.Item (no Cr…...
安装和卸载docker,详细教程
安装docker ############################################################################# 安装: 1、Docker要求CentOS系统的内核版本高于 3.10 ,通过 uname -r 命令查看你当前的内核版本是否支持安账docker 2、更新yum包:sudo yum -y up…...
RabbitMQ的确认机制
RabbitMQ的确认机制 生产者确认 public class ProductionMessageConfirm {public static void Send(){ConnectionFactory factory new ConnectionFactory();factory.HostName "localhost";//RabbitMQ服务在本地运行factory.UserName "guest";//用户名…...
java项目之人才公寓管理系统(ssm+mysql+jsp)
风定落花生,歌声逐流水,大家好我是风歌,混迹在java圈的辛苦码农。今天要和大家聊的是一款基于ssm的人才公寓管理系统。技术交流和部署相关看文章末尾! 开发环境: 后端: 开发语言:Java 框架&…...
从WWDC看苹果产品发展的规律
WWDC 是苹果公司一年一度面向全球开发者的盛会,其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具,对过去十年 WWDC 主题演讲内容进行了系统化分析,形成了这份…...
《Playwright:微软的自动化测试工具详解》
Playwright 简介:声明内容来自网络,将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具,支持 Chrome、Firefox、Safari 等主流浏览器,提供多语言 API(Python、JavaScript、Java、.NET)。它的特点包括&a…...
iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版分享
平时用 iPhone 的时候,难免会碰到解锁的麻烦事。比如密码忘了、人脸识别 / 指纹识别突然不灵,或者买了二手 iPhone 却被原来的 iCloud 账号锁住,这时候就需要靠谱的解锁工具来帮忙了。Aiseesoft iPhone Unlocker 就是专门解决这些问题的软件&…...
Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...
DBAPI如何优雅的获取单条数据
API如何优雅的获取单条数据 案例一 对于查询类API,查询的是单条数据,比如根据主键ID查询用户信息,sql如下: select id, name, age from user where id #{id}API默认返回的数据格式是多条的,如下: {&qu…...
初学 pytest 记录
安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...
在Mathematica中实现Newton-Raphson迭代的收敛时间算法(一般三次多项式)
考察一般的三次多项式,以r为参数: p[z_, r_] : z^3 (r - 1) z - r; roots[r_] : z /. Solve[p[z, r] 0, z]; 此多项式的根为: 尽管看起来这个多项式是特殊的,其实一般的三次多项式都是可以通过线性变换化为这个形式…...
【Linux】Linux安装并配置RabbitMQ
目录 1. 安装 Erlang 2. 安装 RabbitMQ 2.1.添加 RabbitMQ 仓库 2.2.安装 RabbitMQ 3.配置 3.1.启动和管理服务 4. 访问管理界面 5.安装问题 6.修改密码 7.修改端口 7.1.找到文件 7.2.修改文件 1. 安装 Erlang 由于 RabbitMQ 是用 Erlang 编写的,需要先安…...
基于江科大stm32屏幕驱动,实现OLED多级菜单(动画效果),结构体链表实现(独创源码)
引言 在嵌入式系统中,用户界面的设计往往直接影响到用户体验。本文将以STM32微控制器和OLED显示屏为例,介绍如何实现一个多级菜单系统。该系统支持用户通过按键导航菜单,执行相应操作,并提供平滑的滚动动画效果。 本文设计了一个…...
__VUE_PROD_HYDRATION_MISMATCH_DETAILS__ is not explicitly defined.
这个警告表明您在使用Vue的esm-bundler构建版本时,未明确定义编译时特性标志。以下是详细解释和解决方案: 问题原因: 该标志是Vue 3.4引入的编译时特性标志,用于控制生产环境下SSR水合不匹配错误的详细报告1使用esm-bundler…...
