linux 中斷子系統 層級中斷編程

虛擬中斷控制器代碼:

#include<linux/kernel.h>
#include<linux/module.h>
#include<linux/clk.h>
#include<linux/err.h>
#include<linux/init.h>
#include<linux/interrupt.h>
#include<linux/io.h>
#include<linux/irq.h>
#include<linux/irqdomain.h>
#include<linux/of.h>
#include<linux/gpio.h>
#include<linux/platform_device.h>
#include<linux/of_device.h>
#include<linux/irqchip/chained_irq.h>
#include<linux/of_irq.h>static struct irq_domain *virt_intc_domain;
static u32 upper_hwirq_base;static void virt_intc_irq_ack(struct irq_data *d)
{printk("%s %d\n", __FUNCTION__, __LINE__);irq_chip_ack_parent(d);
}static void virt_intc_irq_mask(struct irq_data *d)
{printk("%s %d\n", __FUNCTION__, __LINE__);irq_chip_mask_parent(d);
}static void virt_intc_irq_mask_ack(struct irq_data *d)
{printk("%s %d\n", __FUNCTION__, __LINE__);
}static void virt_intc_unmask(struct irq_data *d)
{printk("%s %d\n", __FUNCTION__, __LINE__);irq_chip_unmask_parent(d);
}static void virt_intc_irq_eoi(struct irq_data *d)
{printk("%s %d\n", __FUNCTION__, __LINE__);irq_chip_eoi_parent(d);
}/*在回調函數里加打印觀察調用順序,理解調用過程*/
static struct irq_chip virt_intc_irq_chip = {.name = "virt_intc",.irq_ack = virt_intc_irq_ack,.irq_mask = virt_intc_irq_mask,.irq_mask_ack = virt_intc_irq_mask_ack,.irq_unmask = virt_intc_unmask,.irq_eoi = 	virt_intc_irq_eoi,
};//利用改函數解析設備樹
static int virt_intc_domain_translate(struct irq_domain *d, struct irq_fwspec *fwspec,unsigned long *out_hwirq, unsigned int *out_type)
{if(is_of_node(fwspec->fwnode)) {if(fwspec->param_count != 2)return -EINVAL;*out_hwirq = fwspec->param[0]; //硬件中斷號*out_type = fwspec->param[1]; //觸發類型printk("param[0] = %d, param[1] = %d\n", fwspec->param[0], fwspec->param[1]);return 0;}return -EINVAL;
}//這個虛擬中斷控制器的alloc函數主要設置irq_domain里的啥?
static int virt_intc_domain_alloc(struct irq_domain *domain, unsigned int virq,unsigned int nr_irqs, void *data)
{struct irq_fwspec *fwspec = data;struct irq_fwspec parent_fwspec;irq_hw_number_t hwirq;int i;//這里的參數domain指的是virt_intc_domainhwirq = fwspec->param[0];printk("virq = %d, hwirq = %ld, nr_irqs = %d, domain = %px\n", virq, hwirq, nr_irqs, domain);for(i = 0; i < nr_irqs; i++)//設置irq_desc[virq].irq_data的相關變量. handle_irq不設置嗎?(不需要)irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i, &virt_intc_irq_chip, NULL);//virt的domain的父domainparent_fwspec.fwnode = domain->parent->fwnode; //gic中斷信息parent_fwspec.param_count = 3;//描述層級關系是如何對應的parent_fwspec.param[0] = GIC_SPI;parent_fwspec.param[1] = fwspec->param[0] + upper_hwirq_base;parent_fwspec.param[2] = fwspec->param[1];/*1:函數會根據傳入的參數,找到對應的父中斷控制器,并在父中斷控制器中為這些中斷分配irq號2:配置父控制器的irq_desc(包括handle_irq和irq_chip)3:完成中斷鏈路的配置(子控制器中斷能夠通過父控制器進行處理)//調用domain->parent的alloc函數繼續設置*/return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, &parent_fwspec);
}static const struct irq_domain_ops virt_intc_domain_ops = {.translate = virt_intc_domain_translate, .alloc = virt_intc_domain_alloc,
};static int virt_intc_probe(struct platform_device *pdev)
{struct device_node *parent_node;struct irq_domain *parent_domain;of_property_read_u32(node, "upper_hwirq_base", &upper_hwirq_base);printk("%s %d upper_hwirq_base = %d\n", __FUNCTION__, __LINE__, upper_hwirq_base);parent_node = of_irq_find_parent(pdev->dev.of_node);parent_domain = irq_find_host(parent_node);virt_intc_domain = irq_domain_add_hierarchy(parent_domain, 0, 4, pdev->dev.of_node, &virt_intc_domain_ops, NULL);printk("parent_domain = %px, virt_intc_domain = %px\n", parent_domain, virt_intc_domain);return 0;
}static void virt_intc_remove(struct platform_device *pdev)
{printk("%s %d\n", __FUNCTION__, __LINE__);
}static const struct of_device_id virt_intc_of_match[] = {{ .compatible = "hvirt_intc", },{ },
};static struct platform_driver virt_intc_driver = {.probe = virt_intc_probe,.remove = virt_intc_remove,.driver = {.name = "virt_intc",.of_match_table = of_match_ptr(virt_intc_of_match),}
};static int __init virt_intc_init(void)
{printk("%s %d\n", __FUNCTION__, __LINE__);return platform_driver_register(&virt_intc_driver);
}static void __exit virt_intc_exit(void)
{printk("%s %d\n", __FUNCTION__, __LINE__);platform_driver_unregister(&virt_intc_driver);
}module_init(virt_intc_init);
module_exit(virt_intc_exit);MODULE_AUTHOR("Tan xujia");
MODULE_LICENSE("Dual BSD/GPL");
/*
//虛擬中斷控制器設備樹(層級)
virt_intc:virt_intc {compatible = "hvirt_intc";interrupt-controller;#interrupt-cells = <2>;interrupt-parent = <&gic>; //intc有irq_domainupper_hwirq_base = <210>;
};參考:gpc.c arch\arm\mach-imx
*/

虛擬按鍵代碼

#include<linux/module.h>
#include<linux/fs.h>
#include<linux/errno.h>
#include<linux/init.h>
#include<linux/major.h>
#include<linux/irq.h>
#include<linux/interrupt.h>
#include<linux/kernel.h>
#include<linux/of_irq.h>
#include<linux/of_gpio.h>
#include<linux/gpio/consumer.h>
#include<linux/platform_device.h>
#include<linux/slab.h>struct gpio_key {int irq;int cnt;char name[20];
};static struct gpio_key gpio_keys[4];static irqreturn_t gpio_key_isr(int irq, void *dev_id)
{struct gpio_key *g_key = dev_id;printk("%s %d name = %s, cnt = %d\n", __FUNCTION__, __LINE__, g_key->name, g_key->cnt++);return IRQ_HANDLED;
}static int gpio_key_probe(struct platform_device *pdev)
{//struct device_node *node = pdev->dev.of_node;int irq, err, i = 0;while(1) {//根據設備樹這里能獲取到4個虛擬中斷號irq = platform_get_irq(pdev, i); //0-3, i等于4時退出if(irq < 0)break;//將虛擬中斷號保存在這里gpio_keys[i].irq = irq;sprintf(gpio_keys[i].name, "gpio_key-%d", i);//注冊中斷err = devm_request_irq(&pdev->dev, gpio_keys[i].irq, gpio_key_isr, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, gpio_keys[i].name, &gpio_keys[i]);printk("err = %d, irq = %d\n", err, irq); /*16-19*/i++;}printk("%s %d\n", __FUNCTION__, __LINE__);return 0;
}static void gpio_key_remove(struct platform_device *pdev)
{printk("%s %d\n", __FUNCTION__, __LINE__);
}static const struct of_device_id gpio_key_of_match[] = {{ .compatible = "gpio_key", },{ },
};static struct platform_driver gpio_key_driver = {.probe = gpio_key_probe,.remove = gpio_key_remove,.driver = {.name = "gpio_key",.of_match_table = of_match_ptr(gpio_key_of_match),}
};static int __init gpio_key_init(void)
{printk("%s %d\n", __FUNCTION__, __LINE__);return platform_driver_register(&gpio_key_driver);
}static void __exit gpio_key_exit(void)
{printk("%s %d\n", __FUNCTION__, __LINE__);platform_driver_unregister(&gpio_key_driver);
}module_init(gpio_key_init);
module_exit(gpio_key_exit);MODULE_AUTHOR("Tan xujia");
MODULE_LICENSE("Dual BSD/GPL");//虛擬按鍵設備樹(鏈式和層級)
/*
gpio_keys:gpio_keys {compatible = "gpio_key";interrupt-parent = <&virt_intc>; //virt_intc有irq_domaininterrupts = <0 IRQ_TYPE_LEVEL_HIGH>,<1 IRQ_TYPE_LEVEL_HIGH>,<2 IRQ_TYPE_LEVEL_HIGH>,<3 IRQ_TYPE_LEVEL_HIGH>;
};
*/

參考:https://blog.csdn.net/caiji0169/article/details/143862261

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/80337.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/80337.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/80337.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

蝦皮(Shopee)商品詳情 API 接口概述及 JSON 數據返回參考

前言 一、接口概述 Shopee 商品詳情 API 接口是 Shopee 平臺為開發者提供的&#xff0c;用于獲取商品詳細信息的接口服務。通過該接口&#xff0c;開發者可以獲取商品的標題、價格、庫存、描述、圖片、規格參數、銷量、評價等詳細信息。這些數據為電商數據分析、商品比價工具…

three.js中的instancedMesh類優化渲染多個同網格材質的模型

three.js小白的學習之路。 在上上一篇博客中&#xff0c;簡單驗證了一下three.js中的網格共享。寫的時候就有一些想法&#xff0c;如果說某個場景中有一萬棵樹&#xff0c;這些樹共享一個geometry和material&#xff0c;有沒有好的辦法將其進行一定程度上的渲染優化&#xff0…

MySQL-自定義函數

自定義函數 函數的作用 mysql數據庫中已經提供了內置的函數&#xff0c;比如&#xff1a;sum&#xff0c;avg&#xff0c;concat等等&#xff0c;方便我們日常的使用&#xff0c;當需要時mysql支持定義自定義的函數&#xff0c;方便與我們對于需用復用的功能進行封裝。 基本…

ESP32上C語言實現JSON對象的創建和解析

在ESP32上使用C語言實現JSON對象的創建和解析&#xff0c;同樣可以借助cJSON庫。ESP-IDF&#xff08;Espressif IoT Development Framework&#xff09;本身已經集成了cJSON庫&#xff0c;你可以直接使用。以下是詳細的步驟和示例代碼。 1. 創建一個新的ESP-IDF項目 首先&…

【FAQ】PCoIP 會話后物理工作站本地顯示器黑屏

# 問題 工作人員從家里建立了到辦公室工作站的 PCoIP 連接&#xff0c;該工作站安裝了 HP Anyware Graphics Agent&#xff0c;并且還連接了本地顯示器。然后&#xff0c;遠程用戶決定去辦公室進行本地工作&#xff0c;工作站顯示器顯示黑屏&#xff08;有時沒有信號&#xff…

el-table 目錄樹列表本地實現模糊查詢

table目錄樹結構實現模糊查詢 <el-form :model"queryParams" ref"queryForm" size"small" :inline"true" v-show"showSearch"><el-form-item label"名稱:" prop"Name"><el-input v-mode…

力扣hot100 LeetCode 熱題 100 Java 哈希篇

兩數之和 1. 兩數之和 - 力扣&#xff08;LeetCode&#xff09; 直接暴力 class Solution {public int[] twoSum(int[] nums, int target) {for(int i0;i<nums.length;i){for(int ji1;j<nums.length;j){long ans nums[i]nums[j];if(ans>target)continue;if(anstarg…

前后端部署

#在學習JavaWeb之后&#xff0c;進行了蒼穹外賣的學習。在進行蒼穹外賣的部署的時候&#xff0c;作者遇到了下面的問題# 1.前端工程nginx無法啟動&#xff1a; 當我雙擊已經部署好的nginx工程中nginx.exe文件的時候&#xff0c;在服務中&#xff0c;并沒有找到ngnix成功運行。…

基于 EFISH-SBC-RK3588 的無人機環境感知與數據采集方案

一、核心硬件架構設計? ?高性能算力引擎&#xff08;RK3588 處理器&#xff09;? ?異構計算架構?&#xff1a;集成 8 核 CPU&#xff08;4Cortex-A762.4GHz 4Cortex-A551.8GHz&#xff09;&#xff0c;支持動態調頻與多任務并行處理&#xff0c;單線程性能較傳統四核方案…

什么是Maven

Maven的概念 Maven是一個一鍵式的自動化的構建工具。Maven 是 Apache 軟件基金會組織維護的一款自動化構建工具&#xff0c;專注服務于Java 平臺的項目構建和依賴管理。Maven 這個單詞的本意是&#xff1a;專家&#xff0c;內行。Maven 是目前最流行的自動化構建工具&#xff0…

mongo客戶端操作mongodb記錄

背景&#xff1a; 長時間不操作mongodb數據庫&#xff0c;已經遺忘了命令&#xff0c;今天正好用到&#xff0c;溫習一下 直接上命令 #進入mongodb數據庫安裝bin目錄cd /opt/mongodb/bin#連接mongodb ./mongo #查看所有的數據庫 show dbs; #選擇數據庫 use xx; #查看表 show …

rocky9.4部署k8s群集v1.28.2版本(containerd)(純命令)

文章目錄 前言三個節點的主機名 所有節點操作主機名和ip解析關閉交換分區&#xff0c;關閉防火墻&#xff0c;關閉selinux更換阿里云yum源時間同步修改內核參數修改系統最大打開文件數開啟bridge網橋過濾&#xff0c;加載br_netfilter模塊&#xff0c;加載配置文件安裝ipset及i…

解析塔能科技:綠色低碳智慧節能一站式破局之匙

在能源問題日益凸顯的當下&#xff0c;綠色低碳、高效節能成為全球發展的重要課題。對各類節能方案進行深入剖析后&#xff0c;可以發現塔能科技的綠色低碳智慧節能一站式解決方案極具創新性與實用性&#xff0c;切實為眾多行業面臨的能源困境提供了有效解決路徑。 直面行業痛點…

精選面試題

1、js中set和map的作用和區別? 在 JavaScript 中&#xff0c;Set 和 Map 是兩種非常重要的集合類型 1、Set 是一種集合數據結構&#xff0c;用于存儲唯一值。它類似于數組&#xff0c;但成員的值都是唯一的&#xff0c;沒有重復的值。Set 中的值只能是唯一的&#xff0c;任何…

Flutter之路由和導航

目錄&#xff1a; 1、flutter路由和導航簡介2、路由的使用2.1、使用 Navigator2.2、使用命名路由2.3、使用路由器 3、應用中添加Tab導航4、頁面跳轉一個新頁面和回退5、傳遞數據到新頁面6、使用 RouteSettings 傳遞參數 1、flutter路由和導航簡介 Flutter 提供了一個完整的系統…

KMS工作原理及其安全性分析

在當今數字化時代&#xff0c;數據安全已經成為企業和個人最為關注的話題之一。隨著云計算和大數據的快速發展&#xff0c;如何安全地管理密鑰成為了一個重要的挑戰。KMS&#xff08;Key Management Service&#xff0c;密鑰管理服務&#xff09;作為一種專業的密鑰管理解決方案…

機器學習在網絡安全中的應用:守護數字世界的防線

一、引言 隨著信息技術的飛速發展&#xff0c;網絡安全問題日益凸顯&#xff0c;成為全球關注的焦點。傳統的網絡安全防護手段&#xff0c;如防火墻、入侵檢測系統&#xff08;IDS&#xff09;和防病毒軟件&#xff0c;雖然在一定程度上能夠抵御攻擊&#xff0c;但在面對復雜多…

Java在excel中導出動態曲線圖DEMO

1、環境 JDK8 POI 5.2.3 Springboot2.7 2、DEMO pom <dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>5.2.3</version></dependency><dependency><groupId>commons…

Android APP 爬蟲操作

工具 夜神模擬器、charles、mitm 等 mitm的使用參考:Mitmproxy對Android進行抓包&#xff08;真機&#xff09;_mitmproxy 安卓-CSDN博客 charles的使用參考&#xff1a;【全網最詳細】手把手教學Charles抓包工具詳細自學教程&#xff0c;完整版安裝教程&#xff0c;詳細介紹…

Redis的LFU策略具體怎么工作?

Redis的LFU&#xff08;Least Frequently Used&#xff09;策略通過動態跟蹤鍵的訪問頻率實現淘汰決策&#xff0c;其核心工作邏輯可分為以下四個部分&#xff1a; 數據結構設計? 字段拆分?&#xff1a;每個Redis對象&#xff08;redisObject&#xff09;的lru字段&#xff…