日B视频 亚洲,啪啪啪网站一区二区,91色情精品久久,日日噜狠狠色综合久,超碰人妻少妇97在线,999青青视频,亚洲一区二卡,让本一区二区视频,日韩网站推荐

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

__disable_irq()和__enable_irq()函數(shù)的具體定義

TopSemic嵌入式 ? 來源:TopSemic嵌入式 ? 2024-08-29 10:06 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

前段時間一工程師向我咨詢了一個問題,問我為什么他的MCU KEIL工程代碼里沒有找到__disable_irq() 和 __enable_irq()的具體定義,是不是有問題。

wKgZombP18aAKIgJAACAC6ifUtA639.png

直接在工程里搜索,確實只能在cmsis_armcc.h文件里看到下面的兩處注釋說明,并沒有這倆函數(shù)的具體定義。

wKgaombP19iAKZCIAAAnqTdnJps986.png

可是如果直接去調用這倆函數(shù)的話,編譯又不會報錯,那么這倆函數(shù)的定義到底在哪呢?

__disable_irq() 和 __enable_irq() 是所謂的intrinsic函數(shù),編譯器自動識別并替換為相關的指令,它們其實是編譯器的一部分,實際的定義位于arm_compat.h 文件中(位于KEIL的安裝目錄里),

static__inline__unsignedint__attribute__((__always_inline__,__nodebug__))
__disable_irq(void){
unsignedintcpsr;
#if__ARM_ARCH>=6
#ifdefined(__ARM_ARCH_PROFILE)&&__ARM_ARCH_PROFILE=='M'
__asm____volatile__("mrs%[cpsr],primask
"
"cpsidi
"
:[cpsr]"=r"(cpsr));
returncpsr&0x1;
#else/*!defined(__ARM_ARCH_PROFILE)||__ARM_ARCH_PROFILE!='M'*/
__asm____volatile__("mrs%[cpsr],cpsr
"
"cpsidi
"
:[cpsr]"=r"(cpsr));
returncpsr&0x80;
#endif
#else/*__ARM_ARCH
#if(defined(__ARM_ARCH_PROFILE)&&__ARM_ARCH_PROFILE=='M'&&
__ARM_ARCH==6)||__ARM_ARCH_8M_BASE__
static__inline__void__attribute__((unavailable(
"intrinsicnotsupportedforthisarchitecture")))__enable_fiq(void);
#else//(!defined(__ARM_ARCH_PROFILE)||__ARM_ARCH_PROFILE!='M'||
//__ARM_ARCH!=6)&&!__ARM_ARCH_8M_BASE__
static__inline__void__attribute__((__always_inline__,__nodebug__))
__enable_fiq(void){
#if__ARM_ARCH>=6
__asm____volatile__("cpsief");
#else/*__ARM_ARCH

核心是 cpsie i 和 cpsid i 這兩個指令。

cps全稱change processor state,即改變PRIMASK這個寄存器

ie: interrupt enable. 中斷使能,即PRIMASK.PM設置為0

id: interrupt disable. 中斷關閉,即PRIMASK.PM設置為1

3dd39db1f6db39a0cd121d329fe74de5.png

3dd39db1f6db39a0cd121d329fe74de5.png

__enable_irq()函數(shù)調用cpsie i指令。

__disable_irq()函數(shù)除調用cpsid i 指令,同時返回了PRIMASK的值,即如果返回值為 0,則表示中斷在調用該函數(shù)之前是使能的;如果返回值為1,則表示中斷在調用函數(shù)之前是禁用的。

需要注意的是:如果之前開啟了相關外設的中斷功能,在調用__disable_irq()函數(shù)關中斷后,這時如果有中斷觸發(fā),那么不會去進行中斷響應。但是在調用__enable_irq()開啟中斷后,MCU會立即處理之前觸發(fā)的中斷。這說明__disable_irq()只是禁止CPU去響應中斷,沒有真正的去屏蔽中斷的觸發(fā),當中斷發(fā)生后,相應的寄存器會將中斷標志置位,在__enable_irq()開啟中斷后,由于相應的中斷標志沒有清空,因而還會觸發(fā)中斷。

以下述代碼為例,程序中使用了一個GPIO中斷,當按鍵按下時翻轉一次LED。實際測試如果在調用__disable_irq()后、__enable_irq()之前的這3s時間內按下按鍵,并不會進入中斷翻轉LED,雖然這時中斷標志位已經產生了。

e0ec29af41084f964c2f2593534e1382.png

但是調用__enable_irq()之后就會立刻進入到中斷服務函數(shù)中。

intmain(void)
{
/*配置系統(tǒng)時鐘*/
system_clock_config();

/*Systick初始化*/
std_delay_init();

/*LED初始化*/
led_init();

/*EXTI初始化*/
exti_init();

__disable_irq();

std_delayms(3000);

__enable_irq();

while(1)
{

}
}

/**
*@briefEXTI4_15中斷服務函數(shù)
*@retval無
*/
voidEXTI4_15_IRQHandler(void)
{
/*讀取EXTI通道中斷掛起狀態(tài)*/
if(std_exti_get_pending_status(EXTI_LINE_GPIO_PIN13))
{
/*清除EXTI通道中斷掛起狀態(tài)*/
std_exti_clear_pending(EXTI_LINE_GPIO_PIN13);
LED1_TOGGLE();
}
}

說到這里你可能還注意到還有__NVIC_DisableIRQ(IRQn_Type IRQn)、__NVIC_EnableIRQ(IRQn_Type IRQn) 這倆函數(shù)

/**
riefDisableInterrupt
detailsDisablesadevicespecificinterruptintheNVICinterruptcontroller.
param[in]IRQnDevicespecificinterruptnumber.

oteIRQnmustnotbenegative.
*/
__STATIC_INLINEvoid__NVIC_DisableIRQ(IRQn_TypeIRQn)
{
if((int32_t)(IRQn)>=0)
{
NVIC->ICER[0U]=(uint32_t)(1UL<
/**
riefEnableInterrupt
detailsEnablesadevicespecificinterruptintheNVICinterruptcontroller.
param[in]IRQnDevicespecificinterruptnumber.

oteIRQnmustnotbenegative.
*/
__STATIC_INLINEvoid__NVIC_EnableIRQ(IRQn_TypeIRQn)
{
if((int32_t)(IRQn)>=0)
{
NVIC->ISER[0U]=(uint32_t)(1UL<

這倆函數(shù)和上述函數(shù)的區(qū)別是,上面的兩個函數(shù)是開關全局的中斷,這倆函數(shù)是針對某特定的中斷。

但是有一點相同的是,如果在調用__NVIC_DisableIRQ之后發(fā)生了中斷事件,當調用__NVIC_EnableIRQ(IRQn_Type IRQn)之后還是會進入到中斷處理。

綜上disable函數(shù)只是不響應中斷,并不會影響中斷的產生,在disable狀態(tài)下如果發(fā)生中斷則會掛起,等到enable后滿足條件還是會被執(zhí)行。如果不希望此現(xiàn)象發(fā)生,那么需要再enable前清除掉相關外設模塊中斷掛起請求標志。

如果想真正禁止中斷的產生的話,還得從源頭上配置相關外設的寄存器關掉中斷才行。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • mcu
    mcu
    +關注

    關注

    147

    文章

    19160

    瀏覽量

    404830
  • 寄存器
    +關注

    關注

    31

    文章

    5620

    瀏覽量

    130455
  • 函數(shù)
    +關注

    關注

    3

    文章

    4422

    瀏覽量

    67873
  • 編譯器
    +關注

    關注

    1

    文章

    1673

    瀏覽量

    51963

原文標題:__disable_irq() 和 __enable_irq()定義在哪?

文章出處:【微信號:TopSemic,微信公眾號:TopSemic嵌入式】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    cmsis_armcc.h沒有實現(xiàn)__disable_irq函數(shù)接口,還有別的函數(shù)嗎?

    cmsis_armcc.h沒有實現(xiàn)__disable_irq函數(shù)接口,還有別的函數(shù)嗎?除了__NVIC_DisableIRQ
    發(fā)表于 04-02 08:25

    STM32F0 IAP進入APP后 __disable_irq() 失效了的原因?

    如題,STM32F030C8T6 做 IAP 現(xiàn)能正確的從 bootloader 中跳轉到 APP,在APP中也能正常的進入中斷,為什么在APP中使用 __disable_irq();無法關閉 所有中斷。 經測試 在bootloader中__disable_irq();是
    發(fā)表于 04-22 08:21

    stm32f0讀寫內部flash和刷新液晶屏時,禁止所有中斷,__disable_irq();不起作用,還會進入中斷響應函數(shù)為什么?

    讀寫內部flash和刷新液晶屏時,禁止所有中斷,__disable_irq();不起作用,還會進入中斷響應函數(shù)
    發(fā)表于 05-09 06:41

    TC387中有__disable_interrupts()關閉所有中斷和打開所有中斷的函數(shù)或宏嗎?

    TC387 芯片中有__disable_irq()和__enable_irq()關閉所有中斷和打開所有中斷的函數(shù)或宏嗎,請告知
    發(fā)表于 08-01 08:22

    stm32 Cortex M3內核 ,CPU調用__disable_irq函數(shù)關閉中斷后,為何還能接收到中斷????????

    Cortex M3內核 ,CPU調用__disable_irq函數(shù)關閉中斷后,進入睡眠模式,并且調用__WFI()函數(shù),等待中斷,結果當有外部中斷進入時,CPU喚醒。跪求大神指教這是什么原理,關閉中斷后,等待中斷,然后中斷來了,
    發(fā)表于 05-25 11:41

    請問除了__disable_irq();__enable_irq()之外還有其他暫時屏蔽中斷嗎?

    我在設計中要利用__disable_irq();__enable_irq()來實現(xiàn)原子操作,防止中斷與正常運行程序同時訪問數(shù)據(jù)造成不一致,但是這個是暫時屏蔽全局中斷的。我系統(tǒng)中有個最高優(yōu)先級的是不能
    發(fā)表于 08-27 10:15

    設備樹中GIC中斷控制器節(jié)點

    irq_handler_tirqreturn_t(2)flags2、free_irq()函數(shù)3、enable_irq()函數(shù)4、
    發(fā)表于 01-10 07:37

    請問ch32v103如何使用全局中斷?

    在使用arm芯片時有叫做__disable_irq();和__enable_irq();的全局中斷方法,請問riscv里面要如何使用這種全局中斷?
    發(fā)表于 06-02 07:14

    STM32使用__disable_irq()后就無法使用HAL_Delay(xx),這是為什么?

    __enable_irq();//打開所有中斷但實際應用中發(fā)現(xiàn),當使用__disable_irq(); 關閉所有中斷后,再用__enable_irq();打開所有中斷,就會出現(xiàn)HAL_Delay(xx)不能再使用,所以直接用上述
    發(fā)表于 12-03 09:09

    逐步認識中斷請求IRQ

    一、了解IRQ家族??IRQ全稱為Interrupt Request,即是“中斷請求”的意思(以下使用IRQ稱呼)。IRQ的作
    發(fā)表于 04-17 22:51 ?2668次閱讀

    Linux中斷(interrupt)子系統(tǒng)之一:驅動程序接口層和中斷通用邏輯層

    這兩個API應該配對使用,disable_irq可以被多次嵌套調用,要想重新打開irqenable_irq必須也要被調用同樣的次數(shù),為此,irq_desc結構中的depth字段專門用
    發(fā)表于 05-15 11:28 ?793次閱讀
    Linux中斷(interrupt)子系統(tǒng)之一:驅動程序接口層和中斷通用邏輯層

    6.分析request_irq和free_irq函數(shù)如何注冊注銷中斷(詳解)

    上一節(jié)講了如何實現(xiàn)運行中斷,這些都是系統(tǒng)給做好的,當我們想自己寫個中斷處理程序,去執(zhí)行自己的代碼,就需要寫irq_desc->action->handler,然后通過
    發(fā)表于 11-30 18:36 ?13次下載
    6.分析request_<b class='flag-5'>irq</b>和free_<b class='flag-5'>irq</b><b class='flag-5'>函數(shù)</b>如何注冊注銷中斷(詳解)

    2.單片機flash操作注意事項

    (); //關閉中斷//////////////////////if(a) __disable_irq(); else __enable_irq();2.創(chuàng)建備份區(qū)降低擦寫時掉電數(shù)據(jù)丟失的風險...
    發(fā)表于 12-01 20:51 ?9次下載
    2.單片機flash操作注意事項

    控制IRQ和FIQ中斷的編譯器內部函數(shù) - 基于Keil MDK

    編譯器內部函數(shù)__disable_irq、__enable_irq、__disable_fiq和__enable_fiq用于控制
    發(fā)表于 01-26 17:16 ?1次下載
    控制<b class='flag-5'>IRQ</b>和FIQ中斷的編譯器內部<b class='flag-5'>函數(shù)</b> - 基于Keil MDK

    IRQ domain支持幾種映射方式

    IRQ domain IRQ domain用于將硬件的中斷號,轉換成Linux系統(tǒng)中的中斷號(virtual irq, virq),來張圖: 每個中斷控制器都對應一個IRQ Domai
    的頭像 發(fā)表于 09-28 15:21 ?1747次閱讀
    <b class='flag-5'>IRQ</b> domain支持幾種映射方式
    洪洞县| 吉水县| 邮箱| 玛曲县| 大冶市| 吉木萨尔县| 呼玛县| 南安市| 龙山县| 饶阳县| 鹤峰县| 新巴尔虎右旗| 静宁县| 公安县| 霍城县| 榆社县| 墨脱县| 巨鹿县| 石林| 锡林浩特市| 广宗县| 岚皋县| 荥经县| 娄底市| 金坛市| 宁强县| 小金县| 塔河县| 钟山县| 辽源市| 云龙县| 措美县| 炉霍县| 呼和浩特市| 吉木萨尔县| 惠来县| 偃师市| 沙湾县| 盐津县| 旺苍县| 定陶县|