PCIe驱动开发(2)— 第一个简单驱动编写和测试
PCIe驱动开发(2)— 第一个简单驱动编写和测试
一、前言
教程参考:02_实战部分_PCIE设备测试
教程参考:03_PCIe设备驱动源码解析
二、驱动编写
新建hello_pcie.c文件
touch hello_pcie.c
然后编写内容如下所示:
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/init.h>#define HELLO_PCI_DEVICE_ID 0x11e8
#define HELLO_PCI_VENDOR_ID 0x1234
#define HELLO_PCI_REVISION_ID 0x10static struct pci_device_id ids[] = {{ PCI_DEVICE(HELLO_PCI_VENDOR_ID, HELLO_PCI_DEVICE_ID), },{ 0 , }
};static struct hello_pci_info_t {struct pci_dev *dev;void __iomem *address_bar0;
} hello_pci_info;MODULE_DEVICE_TABLE(pci, ids);static irqreturn_t hello_pci_irq_handler(int irq, void *dev_info)
{struct hello_pci_info_t *_pci_info = dev_info;uint32_t irq_status;// get irq_stutasirq_status = *((uint32_t *)(_pci_info->address_bar0 + 0x24));printk("hello_pcie: get irq status: 0x%0x\n", irq_status);// clean irq*((uint32_t *)(_pci_info->address_bar0 + 0x64)) = irq_status;// get irq_stutasirq_status = *((uint32_t *)(_pci_info->address_bar0 + 0x24));if(irq_status == 0x00){printk("hello_pcie: receive irq and clean success. \n");return IRQ_HANDLED;}else{printk("hello_pcie: receive irq but clean failed !!! \n");return IRQ_NONE;}
}static int hello_pcie_probe(struct pci_dev *dev, const struct pci_device_id *id)
{int bar = 0;int ret;resource_size_t len;ret = pci_enable_device(dev);if(ret) {return ret;}len = pci_resource_len(dev, bar);hello_pci_info.address_bar0 = pci_iomap(dev, bar, len);hello_pci_info.dev = dev;// register interruptret = request_irq(dev->irq, hello_pci_irq_handler, IRQF_SHARED, "hello_pci", &hello_pci_info);if(ret) {printk("request IRQ failed.\n");return ret;}// enable irq for finishing factorial computation*((uint32_t *)(hello_pci_info.address_bar0 + 0x20)) = 0x80;return 0;
}static void hello_pcie_remove(struct pci_dev *dev)
{// disable irq for finishing factorial computation*((uint32_t *)(hello_pci_info.address_bar0 + 0x20)) = 0x01;free_irq(dev->irq, &hello_pci_info);pci_iounmap(dev, hello_pci_info.address_bar0);pci_disable_device(dev);
}static struct pci_driver hello_pci_driver = {.name = "hello_pcie",.id_table = ids,.probe = hello_pcie_probe,.remove = hello_pcie_remove,
};static int __init hello_pci_init(void)
{return pci_register_driver(&hello_pci_driver);
}static void __exit hello_pci_exit(void)
{pci_unregister_driver(&hello_pci_driver);
}MODULE_LICENSE("GPL");
module_init(hello_pci_init);
module_exit(hello_pci_exit);
三、驱动编译
新建Makefile文件编写内容如下:
ifeq ($(KERNELRELEASE),)KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)all:$(MAKE) -C $(KERNELDIR) M=$(PWD) modules clean:rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions Module* modules*.PHONY: all cleanelseobj-m := hello_pcie.o
endif
然后执行 make命令进行编译

编译完成后可以得到驱动对应的 .ko文件

四、驱动加载及测试
驱动编译完成后使用如下命令加载即可:
sudo insmod hello_pcie.ko
然后使用lspci查看该pcie设备,可以看到驱动加载成功:

同时我们也可以看到其BAR0基地址为0xfea00000,我们使用devmem向其0x08编译地址写入数据进行阶乘运算:

使用详细说明可以查看查看qemu源码的docs/specs/edu.txt文件

然后我们使用dmesg命令可以查看驱动的相关打印:

相关文章:
PCIe驱动开发(2)— 第一个简单驱动编写和测试
PCIe驱动开发(2)— 第一个简单驱动编写和测试 一、前言 教程参考:02_实战部分_PCIE设备测试 教程参考:03_PCIe设备驱动源码解析 二、驱动编写 新建hello_pcie.c文件 touch hello_pcie.c然后编写内容如下所示: #i…...
k8s-第七节-ConfigMap Secret
ConfigMap & Secret ConfigMap 数据库连接地址,这种可能根据部署环境变化的或者其他容器配置选项的包括容器更新或者扩容时可以统一配置 Kubernetes 为我们提供了 ConfigMap,可以方便的配置一些变量。 https://kubernetes.io/zh/docs/concepts/c…...
MySQL架构和工作流程
引言:MySQL执行一条sql语句期间发生了什么? 想要搞清楚这个问题,我们必须了解MySQL的体系结构和工作流程 一、MySQL体系结构 MySQL由以下几个部分组成 一、server层 1.MySQL Connnectors连接器,MySQL的连接池组件,…...
java项目总结8
1.方法引用 1.方法引用概述 注意注意: 1.引用出必须是函数式接口 2.被引用的方法必须已经存在 3.被引用方法的型参和返回值需要跟抽象方法保持一致 4.被引方法的功能要满足当前需求 Arrays.sort(arr,Main::subtraction); Main是该类的名称,:…...
【Nvidia+AI相机】涂布视觉检测方案专注提高锂电池质量把控标准
锂电池单元的质量在多个生产制造领域都至关重要,特别是在新能源汽车、高端消费电子等行业。这些领域的产品高度依赖锂电池提供持续、稳定的能量供应。优质的锂电池单元不仅能提升产品的性能和用户体验,还能确保使用安全。因此,保证锂电池单元…...
Spring Cloud Alibaba - Sentinel 分布式系统流量哨兵
目录 概述特征基本概念 安装Sentinel微服务引入Sentinel案例流控规则(流量控制)流控模式-直接流控模式-关联流控模式-链路流控效果-快速失败流控效果-预热WarmUp流控效果-排队等候 流控规则(并发线程数控制)熔断规则(熔…...
文件存储的方法一
文章目录 概念介绍实现方法示例代码 我们在上一章回中介绍了"如何实现本地存储"相关的内容,本章回中将介绍如何实现文件存储.闲话休提,让我们一起Talk Flutter吧。 概念介绍 我们在上一章回中介绍的本地存储只能存储dart语言中基本类型的数值…...
数据结构/作业/2024/7/7
搭建个场景: 将学生的信息,以顺序表的方式存储(堆区),并且实现封装函数︰1】顺序表的创建, 2】判满、 3】判空、 4】往顺序表里增加学生、5】遍历、 6】任意位置插入学生、7】任意位置删除学生、8】修改、 9】查找(按学生的学号查…...
隔离级别-隔离级别中的锁协议、隔离级别类型、隔离级别的设置、隔离级别应用
一、引言 1、DBMS除了采用严格的两阶段封锁协议来保证并发事务的可串行化,实现事务的隔离性,也可允许用户选择一个可以保证应用程序正确执行并且能够使并发度最大的隔离性等级 2、通常用隔离级别来描述隔离性等级,以下将主要介绍ANSI 92标准…...
【数据结构与算法】希尔排序
💓 博客主页:倔强的石头的CSDN主页 📝Gitee主页:倔强的石头的gitee主页 ⏩ 文章专栏:《数据结构与算法》 期待您的关注 ...
【机器学习】(基础篇一) —— 什么是机器学习
什么是机器学习 本系列博客为你从机器学习的介绍开始,使用大量的代码实战和验证,最终帮助你完全掌握什么是机器学习 人工智能、机器学习和深度学习的关系 人工智能(Artificial Intelligence,AI):是一门研…...
VitePress安装部署
VitePress安装部署 VitePress安装步骤 安装 Node环境 官网下载:https://nodejs.org/zh-cn 傻瓜式安装到完成 npm环境 安装完Node环境之后,可以直接运行下面的命令安装npm npm install -g pnpm关于pnpm源: 有时候需要国内源,…...
Spring的事务传播机制和隔离级别
Spring 提供了强大的事务管理机制,通过 @Transactional 注解或程序化事务管理方式,开发者可以轻松地在应用中启用事务特性。事务传播机制和隔离级别是 Spring 事务管理中的两个重要方面,了解它们有助于更好地控制事务的行为,确保数据的一致性和完整性。 1. 事务传播机制(…...
华为路由器静态路由配置(eNSP模拟实验)
实验目标 如图下所示,让PC1ping通PC2 具体操作 配置PC设备ip 先配置PC1的ip、掩码、网关。PC2也做这样的配置 配置路由器ip 配置G0/0/0的ip信息 #进入系统 <Huawei>system-view #进入GigabitEthernet0/0/0接口 [Huawei]int G0/0/0 #设置接口的ip和掩码 […...
antd实现简易相册,zdppy+vue3+antd实现前后端分离相册
前端代码 <template><a-image:preview"{ visible: false }":width"200"src"http://localhost:8889/download/1.jpg"click"visible true"/><div style"display: none"><a-image-preview-group:previe…...
PIP换源的全面指南
##概述 在Python的世界里,pip是不可或缺的包管理工具,它帮助开发者安装和管理Python软件包。然而,由于网络条件或服务器位置等因素,直接使用默认的pip源有时会遇到下载速度慢或者连接不稳定的问题。这时,更换pip源到一…...
陶建辉当选 GDOS 全球数据库及开源峰会荣誉顾问
近日,第二十三届 GOPS 全球运维大会暨 XOps 技术创新峰会在北京正式召开。本次会议重点议题方向包括开源数据库落地思考、金融数据库自主可控、云原生时代下数据库、数据库智能运维、数据库安全与隐私、开源数据库与治理。大会深入探讨这些方向,促进了数…...
Drools开源业务规则引擎(二)- Drools规则语言(DRL)
文章目录 1.DRL文件的组成:2.package3.import4.function5.query6.declare7.global8.rule8.1.规则属性8.2.LHS8.2.1.语法格式8.2.2.运算符优先级8.2.3.特殊的运算符1.matches, not matches2.contains, not contains3.memberOf, not memberOf4.in, notin5.soundslike6…...
PTA甲级1005:Spell It Right
错误代码: #include<iostream> #include<vector> #include<unordered_map> using namespace std;int main() {unordered_map<int, string> map {{0, "zero"}, {1, "one"}, {2, "two"}, {3, "three&qu…...
Vue笔记11-Composition API的优势
Options API存在的问题 使用传统Options API中,新增或者修改一个需求,就需要分别在data,methods,computed里修改,而这些选项分布在代码的各个地方,中间还穿插着其他Optional API,如果代码量上来…...
基于FPGA的PID算法学习———实现PID比例控制算法
基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容:参考网站: PID算法控制 PID即:Proportional(比例)、Integral(积分&…...
Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动
一、前言说明 在2011版本的gb28181协议中,拉取视频流只要求udp方式,从2016开始要求新增支持tcp被动和tcp主动两种方式,udp理论上会丢包的,所以实际使用过程可能会出现画面花屏的情况,而tcp肯定不丢包,起码…...
【力扣数据库知识手册笔记】索引
索引 索引的优缺点 优点1. 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度(创建索引的主要原因)。3. 可以加速表和表之间的连接,实现数据的参考完整性。4. 可以在查询过程中,…...
使用分级同态加密防御梯度泄漏
抽象 联邦学习 (FL) 支持跨分布式客户端进行协作模型训练,而无需共享原始数据,这使其成为在互联和自动驾驶汽车 (CAV) 等领域保护隐私的机器学习的一种很有前途的方法。然而,最近的研究表明&…...
linux arm系统烧录
1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 (忘了有没有这步了 估计有) 刷机程序 和 镜像 就不提供了。要刷的时…...
第25节 Node.js 断言测试
Node.js的assert模块主要用于编写程序的单元测试时使用,通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试,通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...
Cinnamon修改面板小工具图标
Cinnamon开始菜单-CSDN博客 设置模块都是做好的,比GNOME简单得多! 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...
Spring AI 入门:Java 开发者的生成式 AI 实践之路
一、Spring AI 简介 在人工智能技术快速迭代的今天,Spring AI 作为 Spring 生态系统的新生力量,正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务(如 OpenAI、Anthropic)的无缝对接&…...
Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信
文章目录 Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket(服务端和客户端都要)2. 绑定本地地址和端口&#x…...
华为OD机考-机房布局
import java.util.*;public class DemoTest5 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseSystem.out.println(solve(in.nextLine()));}}priv…...
