分步注册方式 编写驱动
作业:通过分步注册方式,编写LED灯驱动:(驱动文件mycdev.c 测试文件test.c 头文件head.h)
mycdev.c
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/io.h>
#include <linux/device.h>
#include <linux/cdev.h>
#include <linux/slab.h>
#include "head.h"
struct cdev *cdev;
unsigned int major=0;
unsigned int minor=0;
dev_t devno;
int major;
char kbuf[128] = {0};
gpio_t *vir_led1;
gpio_t *vir_led2;
gpio_t *vir_led3;
unsigned int *vir_rcc;
struct class *cls;
struct device *dev;
int mycdev_open(struct inode *inode, struct file *file)
{
printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
return 0;
}
long mycdev_ioctl(struct file *file,unsigned int cmd, unsigned long arg)
{
int which;
int ret = copy_from_user(&which,(unsigned int *)arg,4);
if(ret)
{
printk("copy_from_user err\n");
return ret;
}
switch (cmd)
{
case LED_ON://which LED is turned on
switch(which)
{
case 1: //LED1
vir_led1->ODR |= (0x1 << 10);
break;
case 2: //LED2
vir_led2->ODR |= (0x1 << 10);
break;
case 3: //LED3
vir_led3->ODR |= (0x1 << 8);
break;
}
break;
case LED_OFF: //which LED is turned off
switch (which)
{
case 1:
vir_led1->ODR &= (~(0x1 << 10));
break;
case 2:
vir_led2->ODR &= (~(0X1 << 10));
break;
case 3:
vir_led3->ODR &= (~(0X1 << 8));
break;
}
break;
return 0;
}
}
int all_leds_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("ioremap success\n");
// init regestors
(*vir_rcc) |= (3 << 4);
vir_led1->MODER &= (~(3 << 20));
vir_led1->MODER |= (1 << 20);
vir_led1->ODR &= (~(1 << 10));
vir_led2->MODER &= (~(3 << 20));
vir_led2->MODER |= (1 << 20);
vir_led1->MODER &= (~(3 << 16));
vir_led1->MODER |= (1 << 16);
vir_led1->ODR &= (~(1 << 8));
printk("init regestors success\n");
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;
ret=copy_to_user(ubuf,kbuf,size);
if(ret)
{
printk("copy_to_user filad\n");
return ret;
}
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)
{
int ret;
//cdev allocate space
cdev=cdev_alloc();
if(cdev==NULL)
{
printk("cdev allocate space failed\n");
ret=-EFAULT;
goto OUT1;
}
printk("cdev allocate space success\n");
cdev_init(cdev,&fops);
if(major>0)
{
ret=register_chrdev_region(MKDEV(major,minor),3,"mycdev");
if(ret)
{
printk("apply for cdev Number failed\n");
goto OUT2;
}
}
else
{
ret=alloc_chrdev_region(&devno,minor,3,"mycdev");
if(ret)
{
printk("apply for cdev Number failed\n");
goto OUT2;
}
minor=MINOR(devno);//minor of cdev Number
major=MAJOR(devno);//major of cdev Number
}
printk("cdev Number:major=%d\n", major);
printk("apply for cdev Number success\n");
ret=cdev_add(cdev,MKDEV(major,minor),3);
if(ret)
{
printk("regest cdev failed\n");
goto OUT3;
}
printk("regest cdev sucess\n");
cls=class_create(THIS_MODULE,"mycdev");
if(IS_ERR(cls))
{
printk("submit catalog list failed\n");
ret=-PTR_ERR(cls);
goto OUT4;
}
printk("submit catalog list success\n");
int i;
for(i=0;i<3;i++)
{
dev=device_create(cls,NULL,MKDEV(major,i),NULL,"mycdev%d",i);
if(IS_ERR(dev))
{
printk("submit cdev inod failed\n");
ret=-PTR_ERR(dev);
goto OUT5;
}
}
printk("submit cdev inod success\n");
all_leds_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);
int i;
for(i=0;i<3;i++)
{
device_destroy(cls,MKDEV(major,i));
}
class_destroy(cls);
cdev_del(cdev);
unregister_chrdev_region(MKDEV(major,minor),3);
kfree(cdev);
}
module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");
test.c
#include<stdlib.h>
#include<stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include<unistd.h>
#include<string.h>
#include<sys/ioctl.h>
#include"head.h"
int main(int argc, char const *argv[])
{
char buf[128]={0};
int a,b;
int fd=open("/dev/mycdev0",O_RDWR);
if(fd<0)
{
printf("open cdev failed\n");
exit(-1);
}
while(1)
{
printf("turn on or turn off:1(on)0(off)>)");
scanf("%d",&a);
printf("select the LED:1(LED1) 2(LED2) 3(LED3)>");
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;
}
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;
}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
相关文章:
分步注册方式 编写驱动
作业:通过分步注册方式,编写LED灯驱动:(驱动文件mycdev.c 测试文件test.c 头文件head.h) mycdev.c #include <linux/init.h> #include <linux/module.h> #include <linux/fs.h> #include <linux/io.h> …...

repmgr出现双主,并且时间线分叉,删除了最新的时间线节点
遇到的问题如下: 2023-08-17 20:24:21.566 CST [1556001] LOG: database system was interrupted; last known up at 2023-08-17 20:21:41 CST 2023-08-17 20:24:21.770 CST [1556001] LOG: restored log file "00000009.history" from archive cp: 无法…...
ThinkPHP中实现IP地址定位
在网站开发中,我们经常需要获取用户的地理位置信息以提供个性化的服务。一种常见的方法是通过IP地址定位。在本文中,我们将介绍如何在ThinkPHP框架中实现IP地址定位。 一、IP地址定位的基本原理 IP地址是Internet上的设备在网络中的标识符。每个设备都有…...

使用Python批量将Word文件转为PDF文件
说明:在使用Minio服务器时,无法对word文件预览,如果有需要的话,可以将word文件转为pdf文件,再存储到Minio中,本文介绍如何批量将word文件,转为pdf格式的文件; 安装库 首先ÿ…...

XDR解决方案成为了新的安全趋势
和当今指数倍增长的安全数据相比,安全人才的短缺带来了潜在的风险。几乎所有的公司,无论规模大小,在安全资源能力上都有限,需要过滤各种告警才能将分析量保持在可接受范围。但这样一来,潜在的威胁线索就可能被埋没&…...

001-Nacos 服务注册
目录 Nacos介绍注册中心架构面临问题源码分析实例注册-接口实例注册-入口实例注册-创建一个(Nacos)Service实例注册-注册(Nacos)Service Nacos 介绍 Dynamic Naming and Configuration Service 动态的命名和配置服务 反正可以实现注册中心的功能 注册中心架构 服务提供者 …...

71 # 协商缓存的配置:通过内容
对比(协商)缓存 比较一下再去决定是用缓存还是重新获取数据,这样会减少网络请求,提高性能。 对比缓存的工作原理 客户端第一次请求服务器的时候,服务器会把数据进行缓存,同时会生成一个缓存标识符&#…...

【服务器】Strace显示后台进程输出
今天有小朋友遇到一个问题 她想把2331509和2854637这两个进程调到前台来,以便于在当前shell查看这两个python进程的实时输出 我第一反应是用jobs -l然后fg (参考这里) 但是发现jobs -l根本没有输出: 原因是jobs看的是当前ses…...
centos如何安装libssl-dev libsdl-dev libavcodec-dev libavutil-dev ffmpeg
在 CentOS 系统上安装这些包可以按照以下步骤进行: 打开终端,使用 root 或具有管理员权限的用户登录。 使用以下命令安装 libssl-dev 包: yum install openssl-devel使用以下命令安装 libsdl-dev 包: yum install SDL-devel使用以…...

2022年12月 C/C++(二级)真题解析#中国电子学会#全国青少年软件编程等级考试
第1题:数组逆序重放 将一个数组中的值按逆序重新存放。例如,原来的顺序为8,6,5,4,1。要求改为1,4,5,6,8。 输入 输入为两行:第一行数组中元素的个数n(1 输出 输出为一行:输出逆序后数组的整数,每两个整数之间用空格分隔。 样例输入 5 8 6 5 4 1 样例输出 1 4 5 6 8 以下是…...

详谈MongoDB的那些事
概念区分 什么是关系型数据库 关系型数据库(Relational Database)是一种基于关系模型的数据库管理系统(DBMS)。在关系型数据库中,数据以表格的形式存储,表格由行和列组成,行表示数据记录&…...

企业电子招投标采购系统源码之电子招投标的组成 tbms
功能模块: 待办消息,招标公告,中标公告,信息发布 描述: 全过程数字化采购管理,打造从供应商管理到采购招投标、采购合同、采购执行的全过程数字化管理。通供应商门户具备内外协同的能力,为…...
Android 13 添加自定义分区,恢复出厂设置不被清除
需求: 客户有些文件或数据,需要做得恢复出厂设置还存在,故需新增一个分区存储客户数据。 要求: a) 分区大小为50M b) 应用层可读可写 c) 恢复出厂设置后不会被清除 d) 不需要打包.img e) 不影响OTA升级 缺点: 1).通过代码在分区创建目录和文件,会涉及到SeLinux权限的修…...

改进YOLO系列:1.添加SE注意力机制
添加SE注意力机制 1. SE注意力机制论文2. SE注意力机制原理3. SE注意力机制的配置3.1common.py配置3.2yolo.py配置3.3yaml文件配置 1. SE注意力机制论文 论文题目:Squee…...

RP2040开发板自制树莓派逻辑分析仪
目录 前言 1 准备工作和前提条件 1.1 Raspberry Pi Pico RP2040板子一个 1.2 Firmware-LogicAnalyzer-5.0.0.0-PICO.uf2固件 1.3 LogicAnalyzer-5.0.0.0-win-x64软件 2 操作指南 2.1 按住Raspberry Pi Pico开发板的BOOTSEL按键,再接上USB接口到电脑 2.2 刷入…...
git clone -b与git pull origin <branch_name>的区别
git clone -b 和 git pull origin <branch_name> 都是用于在 Git 中操作分支的命令,但它们有不同的用途和行为。 git clone -b 这是在克隆仓库时指定要克隆的特定分支的命令。它用于在克隆一个仓库的同时指定要克隆的分支。例如,如果你只想克隆一…...

中期国际:MT4数据挖掘与分析方法:以数据为导向,制定有效的交易策略
在金融市场中,制定有效的交易策略是成功交易的关键。而要制定一份可靠的交易策略,数据挖掘与分析方法是不可或缺的工具。本文将介绍如何以数据为导向,利用MT4进行数据挖掘与分析,从而制定有效的交易策略。 首先,我们需…...
Linux命令(70)之bzip2
linux命令之bzip2 1.bzip2介绍 linux命令bzip2是用来压缩或解压缩文件名后缀为".bz2"的文件 2.bzip2用法 bzip2 [参数] filename bzip2常用参数 参数说明-d解压缩文件-t测试压缩文件是否正确-k压缩后,保留源文件-z强制压缩-f强制覆盖已存在的文件-v显…...

ubuntu下gif动态图片的制作
Gif图片比视频小, 比静态JPG图片形象生动, 更适用于产品展示和步骤演示等。各种各样的gif动图为大家交流提供很大的乐趣. 这里简单介绍ubuntu系统下gif图的制作。 一、工具安装: kazam和ffmpeg kazam是linux下的一款简单但是功能强大的屏幕录制工具. 它可录制声音并选择全屏录…...

56.linux 进程管理命令和用户管理命令
目录 一、进程管理命令 1.ps 2.pstree 3.kill 4.pkill 5.&后台运行程序 6.jobs 7.fg bg 8.top 二、用户管理命令 1.系统存储用户信息的文件 2.添加新用户 3.修改用户密码 4.删除用户 一、进程管理命令 1.ps 用于查看当前系统中运行的进程信息。它可以…...
Python|GIF 解析与构建(5):手搓截屏和帧率控制
目录 Python|GIF 解析与构建(5):手搓截屏和帧率控制 一、引言 二、技术实现:手搓截屏模块 2.1 核心原理 2.2 代码解析:ScreenshotData类 2.2.1 截图函数:capture_screen 三、技术实现&…...

React19源码系列之 事件插件系统
事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...

基于Docker Compose部署Java微服务项目
一. 创建根项目 根项目(父项目)主要用于依赖管理 一些需要注意的点: 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件,否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)
UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中,UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化…...

云原生玩法三问:构建自定义开发环境
云原生玩法三问:构建自定义开发环境 引言 临时运维一个古董项目,无文档,无环境,无交接人,俗称三无。 运行设备的环境老,本地环境版本高,ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...

深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用
文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么?1.1.2 感知机的工作原理 1.2 感知机的简单应用:基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...

MFC 抛体运动模拟:常见问题解决与界面美化
在 MFC 中开发抛体运动模拟程序时,我们常遇到 轨迹残留、无效刷新、视觉单调、物理逻辑瑕疵 等问题。本文将针对这些痛点,详细解析原因并提供解决方案,同时兼顾界面美化,让模拟效果更专业、更高效。 问题一:历史轨迹与小球残影残留 现象 小球运动后,历史位置的 “残影”…...

Chromium 136 编译指南 Windows篇:depot_tools 配置与源码获取(二)
引言 工欲善其事,必先利其器。在完成了 Visual Studio 2022 和 Windows SDK 的安装后,我们即将接触到 Chromium 开发生态中最核心的工具——depot_tools。这个由 Google 精心打造的工具集,就像是连接开发者与 Chromium 庞大代码库的智能桥梁…...
OD 算法题 B卷【正整数到Excel编号之间的转换】
文章目录 正整数到Excel编号之间的转换 正整数到Excel编号之间的转换 excel的列编号是这样的:a b c … z aa ab ac… az ba bb bc…yz za zb zc …zz aaa aab aac…; 分别代表以下的编号1 2 3 … 26 27 28 29… 52 53 54 55… 676 677 678 679 … 702 703 704 705;…...
Kubernetes 网络模型深度解析:Pod IP 与 Service 的负载均衡机制,Service到底是什么?
Pod IP 的本质与特性 Pod IP 的定位 纯端点地址:Pod IP 是分配给 Pod 网络命名空间的真实 IP 地址(如 10.244.1.2)无特殊名称:在 Kubernetes 中,它通常被称为 “Pod IP” 或 “容器 IP”生命周期:与 Pod …...