国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

linux驅(qū)動學(xué)習(xí)3-外部中斷

這篇具有很好參考價值的文章主要介紹了linux驅(qū)動學(xué)習(xí)3-外部中斷。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報違法"按鈕提交疑問。

在做中斷試驗時,發(fā)現(xiàn)中斷驅(qū)動總是insmod失敗,之后定位到 gpio_request 失敗,之后是想到使用的野火做好的系統(tǒng),在uEnv.txt中會加載大量設(shè)備樹插件,將key相關(guān)的設(shè)備樹插件屏蔽即可。

linux中斷API函數(shù)

中斷號

每個中斷都有一個中斷號,通過中斷號即可區(qū)分不同的中斷,在 Linux 內(nèi)核中使用一個 int 變量表示中斷號

request_irq函數(shù)

在 Linux 內(nèi)核中要想使用某個中斷是需要申請的, request_irq 函數(shù)用于申請中斷, request_irq函數(shù)可能會導(dǎo)致睡眠,因此不能在中斷上下文或者其他禁止睡眠的代碼段中使用 request_irq 函數(shù)。 request_irq 函數(shù)會激活(使能)中斷,所以不需要我們手動去使能中斷, request_irq 函數(shù)原型如下:

int request_irq(unsigned int irq,irq_handler_t handler,unsigned long flags,const char *name,void *dev)

irq:要申請中斷的中斷號。
handler:中斷處理函數(shù),當(dāng)中斷發(fā)生以后就會執(zhí)行此中斷處理函數(shù)。
flags:中斷標(biāo)志,可以在文件 include/linux/interrupt.h 里面查看所有的中斷標(biāo)志,這些標(biāo)志可以通過“|”來實現(xiàn)多種組合。
linux驅(qū)動學(xué)習(xí)3-外部中斷,linux
name:中斷名字,設(shè)置以后可以在/proc/interrupts 文件中看到對應(yīng)的中斷名字。
dev: 如果將 flags 設(shè)置為 IRQF_SHARED 的話, dev 用來區(qū)分不同的中斷,一般情況下將dev 設(shè)置為設(shè)備結(jié)構(gòu)體, dev 會傳遞給中斷處理函數(shù) irq_handler_t 的第二個參數(shù)。

free_irq函數(shù)

使用中斷的時候需要通過 request_irq 函數(shù)申請,使用完成以后就要通過 free_irq 函數(shù)釋放掉相應(yīng)的中斷。

void free_irq(unsigned int irq,void *dev)

irq: 要釋放的中斷。
dev:如果中斷設(shè)置為共享(IRQF_SHARED)的話,此參數(shù)用來區(qū)分具體的中斷。共享中斷只有在釋放最后中斷處理函數(shù)的時候才會被禁止掉。

中斷處理函數(shù)

使用 request_irq 函數(shù)申請中斷的時候需要設(shè)置中斷處理函數(shù),中斷處理函數(shù)格式如下所示:

irqreturn_t (*irq_handler_t) (int, void *)

第一個參數(shù)是要中斷處理函數(shù)要相應(yīng)的中斷號。第二個參數(shù)是一個指向 void 的指針,也就是個通用指針,需要與 request_irq 函數(shù)的 dev 參數(shù)保持一致。用于區(qū)分共享中斷的不同設(shè)備,dev 也可以指向設(shè)備數(shù)據(jù)結(jié)構(gòu)。中斷處理函數(shù)的返回值為 irqreturn_t 類型, irqreturn_t 類型定義
如下所示:

 enum irqreturn {
 IRQ_NONE = (0 << 0),
 IRQ_HANDLED = (1 << 0),
 IRQ_WAKE_THREAD = (1 << 1),
 };

 typedef enum irqreturn irqreturn_t;

可以看出 irqreturn_t 是個枚舉類型,一共有三種返回值。一般中斷服務(wù)函數(shù)返回值使用如下形式:

return IRQ_RETVAL(IRQ_HANDLED)

中斷使能和禁止函數(shù)

void enable_irq(unsigned int irq)
void disable_irq(unsigned int irq)

disable_irq函數(shù)要等到當(dāng)前正在執(zhí)行的中斷處理函數(shù)執(zhí)行完才返回,因此使用者需要保證不會產(chǎn)生新的中斷,并且確保所有已經(jīng)開始執(zhí)行的中斷處理程序已經(jīng)全部退出。在這種情況下,可以使用另外一個中斷禁止函數(shù):

void disable_irq_nosync(unsigned int irq)

關(guān)閉全局中斷可以使用如下函數(shù):

local_irq_save(flags)   //禁止中斷
local_irq_restore(flags)  //恢復(fù)中斷

上半部與下半部

上半部:上半部就是中斷處理函數(shù),那些處理過程比較快,不會占用很長時間的處理就可以放在上半部完成
下半部:如果中斷處理過程比較耗時,那么就將這些比較耗時的代碼提出來,交給下半部去執(zhí)行,這樣中斷處理函數(shù)就會快進(jìn)快出。

tasklet

tasklet 是利用軟中斷來實現(xiàn)的另外一種下半部機(jī)制,在軟中斷和 tasklet 之間,建議大家使用 tasklet。 Linux 內(nèi)核使用 tasklet_struct 結(jié)構(gòu)體來表示 tasklet:

struct tasklet_struct
{
struct tasklet_struct *next; /* 下一個 tasklet */
unsigned long state; /* tasklet 狀態(tài) */
atomic_t count; /* 計數(shù)器,記錄對 tasklet 的引用數(shù) */
void (*func)(unsigned long); /* tasklet 執(zhí)行的函數(shù) */
unsigned long data; /* 函數(shù) func 的參數(shù) */
};
void tasklet_init(struct tasklet_struct *t,void (*func)(unsigned long),unsigned long data);

t:要初始化的 tasklet
func: tasklet 的處理函數(shù)。
data: 要傳遞給 func 函數(shù)的參數(shù)
也 可 以 使 用 宏 DECLARE_TASKLET 來 一 次 性 完 成 tasklet 的 定 義 和 初 始 化 ,DECLARE_TASKLET 定義在 include/linux/interrupt.h 文件中,定義如下:

DECLARE_TASKLET(name, func, data)

其中 name 為要定義的 tasklet 名字,這個名字就是一個 tasklet_struct 類型的時候變量, func就是 tasklet 的處理函數(shù), data 是傳遞給 func 函數(shù)的參數(shù)。
在上半部,也就是中斷處理函數(shù)中調(diào)用 tasklet_schedule 函數(shù)就能使 tasklet 在合適的時間運(yùn)行, tasklet_schedule 函數(shù)原型如下:

void tasklet_schedule(struct tasklet_struct *t)

t:要調(diào)度的 tasklet,也就是 DECLARE_TASKLET 宏里面的 name。
關(guān)于 tasklet 的參考使用示例如下所示:

/* 定義 taselet */
struct tasklet_struct testtasklet;
/* tasklet 處理函數(shù) */
void testtasklet_func(unsigned long data)
{
/* tasklet 具體處理內(nèi)容 */
}
/* 中斷處理函數(shù) */
irqreturn_t test_handler(int irq, void *dev_id)
{
......
/* 調(diào)度 tasklet */
tasklet_schedule(&testtasklet);
......
}
/* 驅(qū)動入口函數(shù) */
static int __init xxxx_init(void)
{
......
/* 初始化 tasklet */
tasklet_init(&testtasklet, testtasklet_func, data);
/* 注冊中斷處理函數(shù) */
request_irq(xxx_irq, test_handler, 0, "xxx", &xxx_dev);
......
}

工作隊列

工作隊列是另外一種下半部執(zhí)行方式,工作隊列在進(jìn)程上下文執(zhí)行,工作隊列將要推后的工作交給一個內(nèi)核線程去執(zhí)行,因為工作隊列工作在進(jìn)程上下文,因此工作隊列允許睡眠或重新調(diào)度。因此如果你要推后的工作可以睡眠那么就可以選擇工作隊列,否則的話就只能選擇軟中斷或 tasklet。
Linux 內(nèi)核使用 work_struct 結(jié)構(gòu)體表示一個工作,內(nèi)容如下(省略掉條件編譯):

struct work_struct {
atomic_long_t data;
struct list_head entry;
work_func_t func; /* 工作隊列處理函數(shù) */
};

簡單創(chuàng)建工作很簡單,直接定義一個 work_struct 結(jié)構(gòu)體
變量即可,然后使用 INIT_WORK 宏來初始化工作, INIT_WORK 宏定義如下:

#define INIT_WORK(_work, _func)

_work 表示要初始化的工作, _func 是工作對應(yīng)的處理函數(shù)。
也可以使用 DECLARE_WORK 宏一次性完成工作的創(chuàng)建和初始化,宏定義如下:

#define DECLARE_WORK(n, f)

n 表示定義的工作(work_struct), f 表示工作對應(yīng)的處理函數(shù)。
和 tasklet 一樣,工作也是需要調(diào)度才能運(yùn)行的,工作的調(diào)度函數(shù)為 schedule_work,函數(shù)原型如下所示:

bool schedule_work(struct work_struct *work)

函數(shù)參數(shù)和返回值含義如下:
work: 要調(diào)度的工作。
返回值: 0 成功,其他值 失敗。

/* 定義工作(work) */
struct work_struct testwork;
/* work 處理函數(shù) */
void testwork_func_t(struct work_struct *work);
{
/* work 具體處理內(nèi)容 */
}
/* 中斷處理函數(shù) */
irqreturn_t test_handler(int irq, void *dev_id)
{
......
/* 調(diào)度 work */
schedule_work(&testwork);
......
}
/* 驅(qū)動入口函數(shù) */
static int __init xxxx_init(void)
{
......
/* 初始化 work */
INIT_WORK(&testwork, testwork_func_t);
/* 注冊中斷處理函數(shù) */
request_irq(xxx_irq, test_handler, 0, "xxx", &xxx_dev);
......
}

設(shè)備樹修改

設(shè)備樹修改如下:

key{
    #address-cells = <1>;
		#size-cells = <1>;
		compatible = "fire,key";
		pinctrl-names = "default";
		pinctrl-0 = <&pinctrl_key>;
		key_gpio = <&gpio5 1 GPIO_ACTIVE_LOW>;
		interrupt-parent = <&gpio5>;
		interrupts = <1 IRQ_TYPE_EDGE_FALLING>;  //1表示使用gpio5_io01
		status = "okay";
	};

IRQ_TYPE_EDGE_FALLING 定義在文件 include/linux/irq.h 中,定義如下:

enum {
IRQ_TYPE_NONE = 0x00000000,
IRQ_TYPE_EDGE_RISING = 0x00000001,
IRQ_TYPE_EDGE_FALLING = 0x00000002,
IRQ_TYPE_EDGE_BOTH = (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING),
IRQ_TYPE_LEVEL_HIGH = 0x00000004,
IRQ_TYPE_LEVEL_LOW = 0x00000008,
IRQ_TYPE_LEVEL_MASK = (IRQ_TYPE_LEVEL_LOW |
IRQ_TYPE_LEVEL_HIGH),
......
}

獲取中斷號

編寫驅(qū)動的時候需要用到中斷號,我們用到中斷號,中斷信息已經(jīng)寫到了設(shè)備樹里面,因此可以通過 irq_of_parse_and_map 函數(shù)從 interupts 屬性中提取到對應(yīng)的設(shè)備號,函數(shù)原型如下:
unsigned int irq_of_parse_and_map(struct device_node *dev, int index)
函數(shù)參數(shù)和返回值含義如下:
dev: 設(shè)備節(jié)點(diǎn)。
index:索引號, interrupts 屬性可能包含多條中斷信息,通過 index 指定要獲取的信息。
返回值:中斷號。
如果使用 GPIO 的話,可以使用 gpio_to_irq 函數(shù)來獲取 gpio 對應(yīng)的中斷號,函數(shù)原型如
下:

int gpio_to_irq(unsigned int gpio)

函數(shù)參數(shù)和返回值含義如下:
gpio: 要獲取的 GPIO 編號。
返回值: GPIO 對應(yīng)的中斷號。文章來源地址http://www.zghlxwxcb.cn/news/detail-667949.html

到了這里,關(guān)于linux驅(qū)動學(xué)習(xí)3-外部中斷的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點(diǎn)擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • MSP432學(xué)習(xí)筆記5——外部中斷

    所用單片機(jī)型號:MSP432P401r 今日繼續(xù)我的MSP432電賽速通之路。 外部中斷是個很有用的配置 STM32幾乎每個I/O口都能配置復(fù)用為外部中斷 但MSP432并不是這樣。 我經(jīng)過查閱數(shù)據(jù)手冊發(fā)現(xiàn) 支持中斷的引腳 為: P1^0~ P1^7??????? P3^0~ P3^7???? P5^0~ P5^7 P2^0~ P2^7??????? P4^0~ P4^7??

    2024年02月07日
    瀏覽(26)
  • 51單片機(jī)——中斷系統(tǒng)之外部中斷實驗,小白講解,相互學(xué)習(xí)

    51單片機(jī)——中斷系統(tǒng)之外部中斷實驗,小白講解,相互學(xué)習(xí)

    ?中斷介紹 ????????中斷是為使單片機(jī)具有對外部或內(nèi)部隨機(jī)發(fā)生的事件實時處理而設(shè)置的,中斷功能的存在,很大程度上提高了單片機(jī)處理外部或內(nèi)部事件的能力。它也是單片機(jī)最重要的功能之一,是我們學(xué)些單片機(jī)必須要掌握的。 ????????為了更容易的理解中斷概

    2024年02月07日
    瀏覽(27)
  • 單片機(jī)學(xué)習(xí)筆記---紅外遙控(外部中斷)

    單片機(jī)學(xué)習(xí)筆記---紅外遙控(外部中斷)

    目錄 紅外遙控簡介 硬件電路 基本發(fā)送與接收 NEC編碼??????? 遙控器鍵碼 復(fù)習(xí)外部中斷和定時器 紅外遙控是利用紅外光進(jìn)行通信的設(shè)備,由紅外LED將調(diào)制后的信號發(fā)出,由專用的紅外接收頭進(jìn)行解調(diào)輸出 通信方式:單工,異步 紅外LED波長:940nm 通信協(xié)議標(biāo)準(zhǔn):NEC標(biāo)

    2024年02月22日
    瀏覽(21)
  • 【STM32學(xué)習(xí)筆記】(13)——外部中斷詳解

    【STM32學(xué)習(xí)筆記】(13)——外部中斷詳解

    ????????EXTI(External interrupt/event controller)—外部中斷/事件控制器 ,管理了控制器的 20 個中斷/事件線。每個輸入線可以獨(dú)立地配置輸入類型(脈沖 或掛起)和對應(yīng)的觸發(fā)事件(上升沿或下降沿或者雙邊沿都觸發(fā))。EXTI 可以實現(xiàn)對每個中斷/事件線進(jìn)行單獨(dú)配置,可以單獨(dú)配置

    2024年02月05日
    瀏覽(23)
  • STM32CubeMX學(xué)習(xí)三 之外部中斷

    STM32CubeMX學(xué)習(xí)三 之外部中斷

    記錄一下STM32CubeMX的學(xué)習(xí)筆記,同時分享給初學(xué)的小白,希望一起進(jìn)步。 如何使用STM32CubeMX以及工程創(chuàng)建在之前的博客有提到,這里就直接從外部中斷講起。 編譯環(huán)境:KEIL 代碼生成:STM32CubeMX 庫:HAL MCU:STM32F072 假設(shè)你的cubeMX工程已經(jīng)建好,這里我們配置KEY1、KEY2、KEY3三個按

    2023年04月08日
    瀏覽(26)
  • stm32學(xué)習(xí)筆記-5EXIT外部中斷

    stm32學(xué)習(xí)筆記-5EXIT外部中斷

    注:筆記主要參考B站 江科大自化協(xié) 教學(xué)視頻“STM32入門教程-2023持續(xù)更新中”。 注:工程及代碼文件放在了本人的Github倉庫。 圖5-1 中斷及中斷嵌套示意圖 中斷 是指在主程序運(yùn)行過程中,出現(xiàn)了特定的中斷觸發(fā)條件(中斷源),使得CPU暫停當(dāng)前正在運(yùn)行的程序,轉(zhuǎn)而去處理

    2024年02月09日
    瀏覽(15)
  • stm32——hal庫學(xué)習(xí)筆記(外部中斷)

    stm32——hal庫學(xué)習(xí)筆記(外部中斷)

    一、什么是中斷?(了解) 打斷CPU執(zhí)行正常的程序,轉(zhuǎn)而處理緊急程序,然后返回原暫停的程序繼續(xù)運(yùn)行,就叫中斷 中斷的作用和意義 中斷的意義:高效處理緊急程序,不會一直占用CPU資源 STM32 GPIO外部中斷簡圖 二、NVIC(熟悉) 2.1,NVIC基本概念 2.2,NVIC相關(guān)寄存器介紹

    2024年02月22日
    瀏覽(23)
  • 【STM32F407學(xué)習(xí)筆記】中斷優(yōu)先級管理與外部中斷

    【STM32F407學(xué)習(xí)筆記】中斷優(yōu)先級管理與外部中斷

    計算機(jī)系統(tǒng)中中斷占有極其重要的地位,在嵌入式系統(tǒng)中更是如此。中斷機(jī)制能讓計算機(jī)有效合理的發(fā)揮效能和提高效率。 涉及外設(shè) :EXIT外部中斷,NVIC內(nèi)嵌向量中斷控制器。 計算機(jī)在執(zhí)行程序的過程中,當(dāng)出現(xiàn)異常情況或特殊情況時,計算機(jī)停止現(xiàn)在程序的運(yùn)行,轉(zhuǎn)向?qū)?/p>

    2024年02月02日
    瀏覽(32)
  • STC15系列單片機(jī)學(xué)習(xí)6:外部中斷

    STC15系列單片機(jī)學(xué)習(xí)6:外部中斷

    外部中斷,就是通過單片機(jī)IO引腳電平的變化觸發(fā)的中斷。 STC15系列單片機(jī)的外部中斷源一共有5個,分別是外部中斷0(INT0)、外部中斷1(INT1)、外部中斷2(INT2)、外部中斷3(INT3)、外部中斷4(INT4);當(dāng)然不是所有的STC15系列單片機(jī)都有著5個外部中斷。 中斷源 觸發(fā)行為

    2024年03月12日
    瀏覽(78)
  • 【STM32】STM32學(xué)習(xí)筆記-EXTI外部中斷(11)

    【STM32】STM32學(xué)習(xí)筆記-EXTI外部中斷(11)

    中斷 :在主程序運(yùn)行過程中,出現(xiàn)了特定的中斷觸發(fā)條件(中斷源),使得CPU暫停當(dāng)前正在運(yùn)行的程序,轉(zhuǎn)而去處理中斷程序,處理完成后又返回原來被暫停的位置繼續(xù)運(yùn)行 中斷優(yōu)先級 :當(dāng)有多個中斷源同時申請中斷時,CPU會根據(jù)中斷源的輕重緩急進(jìn)行裁決,優(yōu)先響應(yīng)更加

    2024年02月04日
    瀏覽(21)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包