<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      痞子衡嵌入式:嵌入式Cortex-M中斷向量表原理及其重定向方法


        大家好,我是痞子衡,是正經(jīng)搞技術(shù)的痞子。今天痞子衡給大家分享的是Cortex-M中斷向量表原理及其重定向方法

        接著前文 《嵌入式Cortex-M裸機(jī)環(huán)境下臨界區(qū)保護(hù)的三種實(shí)現(xiàn)》 繼續(xù)聊,嵌入式代碼設(shè)計(jì)里有時(shí)候一些特殊操作(比如 XIP 下 Flash 擦寫、低功耗模式切換)不能被隨意打斷,或者一些共享數(shù)據(jù)區(qū)不能被無序訪問(A 任務(wù)正在讀,B 任務(wù)卻要寫),這時(shí)候我們可以利用系統(tǒng)全局中斷開關(guān)控制來實(shí)現(xiàn)所謂的臨界區(qū)保護(hù)。

        但有些場(chǎng)景下開關(guān)系統(tǒng)全局中斷這種方法并不總是很湊效,比如 XIP 下 Flash 擦寫這種情況,如果項(xiàng)目里還有一個(gè)后臺(tái)定時(shí)器(比如SysTick)在實(shí)時(shí)運(yùn)行,擦除 Flash 期間(這個(gè)時(shí)間可能會(huì)很長(zhǎng))我們直接關(guān)閉系統(tǒng)全局中斷,會(huì)導(dǎo)致定時(shí)器中斷無法響應(yīng),系統(tǒng)計(jì)時(shí)會(huì)出偏差,對(duì)于這種情況,我們顯然不能關(guān)閉系統(tǒng)全局中斷。

        為了在 Flash 擦寫期間系統(tǒng)還能夠及時(shí)響應(yīng)定時(shí)器中斷(執(zhí)行中斷響應(yīng)函數(shù)),我們需要將定時(shí)器中斷響應(yīng)函數(shù)及其相關(guān)代碼像 Flash IAP 操作代碼一樣都鏈接到 RAM 里執(zhí)行,此外還需要將中斷向量表也重定向到 RAM 里才行。今天痞子衡就來聊一聊重定向中斷向量表的方法:

      一、Cortex-M中斷向量表簡(jiǎn)介

        熟悉 ARM Cortex-M 處理器的朋友應(yīng)該都對(duì)下面這張表有所了解,這就是中斷向量表,表中每個(gè)向量大小都是 4 字節(jié),除了第 0 個(gè)向量外,其余向量都是函數(shù)地址,這個(gè)表集中保存了系統(tǒng)全部的中斷處理函數(shù)(xxxIRQHandler)地址。

        對(duì)于內(nèi)嵌 Flash 的 MCU 來說,初始中斷向量表一般會(huì)被要求固定鏈接到 Flash 起始地址處,因?yàn)橄到y(tǒng)啟動(dòng)總是從 Flash 起始地址獲取第 0(初始棧)、1個(gè)向量(初始PC,復(fù)位函數(shù)ResetHandler)來開始應(yīng)用程序代碼的執(zhí)行。對(duì)于一些包含 BootROM 或者沒有內(nèi)部 Flash 的 MCU,初始中斷向量表也許可以放到 Flash 中的其他地址處,這要取決于具體芯片設(shè)計(jì)。

        當(dāng)應(yīng)用程序執(zhí)行起來后,如果發(fā)生了中斷,系統(tǒng)會(huì)根據(jù)發(fā)出請(qǐng)求的外設(shè)中斷號(hào)來中斷向量表里找到對(duì)應(yīng)的外設(shè)中斷響應(yīng)函數(shù)并去執(zhí)行。Cortex-M 內(nèi)核(除了CM0)模塊 SCB 里有個(gè)專門的 VTOR 寄存器用來控制中斷向量表首地址(注意,地址需要 128 字節(jié)對(duì)齊),程序運(yùn)行起來后用戶可以配置 SCB->VTOR 寄存器來重設(shè)中斷向量表地址。

      二、重定向中斷向量表的方法

        現(xiàn)在我們以恩智浦 i.MXRT1170 型號(hào)為例介紹重定向中斷向量表的方法,在 \SDK_2.9.1_MIMXRT1170-EVK\boards\evkmimxrt1170\demo_apps\led_blinky\cm7\iar 工程上示例。

      2.1 與中斷向量表相關(guān)的文件

        這個(gè) led_blinky 工程里跟中斷向量表有關(guān)的一共兩個(gè)文件,一是 startup_MIMXRT1176_cm7.s 啟動(dòng)文件,這里面存放了中斷向量表實(shí)體定義,以及復(fù)位函數(shù) ResetHandler(),從復(fù)位函數(shù)里你可以看到上來就先重置了一遍 SCB->VTOR 寄存器。

              THUMB
      
              PUBWEAK Reset_Handler
              SECTION .text:CODE:REORDER:NOROOT(2)
      Reset_Handler
              CPSID   I               ; Mask interrupts
              LDR     R0, =0xE000ED08      ; 即 SCB->VTOR
              LDR     R1, =__vector_table  ; section .intvec 段首地址
              STR     R1, [R0]
              LDR     R2, [R1]
              MSR     MSP, R2
              LDR     R0, =SystemInit
              BLX     R0
              CPSIE   I               ; Unmask interrupts
              LDR     R0, =__iar_program_start
              BX      R0
      

        復(fù)位函數(shù)里用到的 __vector_table 值取決于 MIMXRT1176xxxxx_cm7_flexspi_nor.icf 鏈接文件里如下語句設(shè)置。由于 i.MXRT1170 沒有內(nèi)部 Flash,分配給外部 NOR Flash (掛在 FlexSPI1 外設(shè)上)的系統(tǒng)映射起始地址是 0x30000000,而 0x30002000 是 BootROM 能支持的應(yīng)用程序初始中斷向量表地址之一(在 IVT 啟動(dòng)頭里指示)。

      define symbol m_interrupts_start       = 0x30002000;
      define symbol m_interrupts_end         = 0x300023FF;
      
      define exported symbol __VECTOR_TABLE          = m_interrupts_start;
      
      place at address mem: m_interrupts_start    { readonly section .intvec };
      

        編譯工程后在對(duì)應(yīng)生成的 iled_blinky_cm7.map 映射文件里可以找到初始中斷向量表最終鏈接地址。為了便于后續(xù)分析問題,我們將定時(shí)器中斷響應(yīng)函數(shù)地址也一并列出來:

      *******************************************************************************
      *** PLACEMENT SUMMARY
      ***
      
      "A0":  place at address 0x3000'2000 { ro section .intvec };
      
        Section              Kind         Address    Size  Object
        -------              ----         -------    ----  ------
      "A0":                                         0x400
        .intvec              ro code  0x3000'2000   0x400  startup_MIMXRT1176_cm7.o [1]
                                    - 0x3000'2400   0x400
      
      *******************************************************************************
      *** ENTRY LIST
      ***
      
      Entry                       Address   Size  Type      Object
        -----                       -------   ----  ----      ------
      SysTick_Handler         0x3000'5767   0x10  Code  Gb  led_blinky.o [1]
      __VECTOR_TABLE {Abs}    0x3000'2000         Data  Gb  <internal module>
      __Vectors               0x3000'2000          --   Gb  startup_MIMXRT1176_cm7.o [1]
      __Vectors_End           0x3000'2400         Data  Gb  startup_MIMXRT1176_cm7.o [1]
      __Vectors_Size {Abs}          0x400          --   Gb  startup_MIMXRT1176_cm7.o [1]
      __vector_table          0x3000'2000         Data  Gb  startup_MIMXRT1176_cm7.o [1]
      

      2.2 中斷重定向函數(shù)示例

        定時(shí)器中斷響應(yīng)函數(shù) SysTick_Handler() 鏈接在 Flash 里顯然是不行的,我們利用 IDE 特性(對(duì)于IAR,是 __ramfunc 修飾符)將其鏈接到 RAM 里(MIMXRT1176xxxxx_cm7_flexspi_nor.icf 里定義了 TEXT2_region: 0x0 - 0x3FFFF 空間存放 section .textrw 段), 重新編譯工程,查看映射文件可以看到新分配的地址是 0x1。

      __ramfunc void SysTick_Handler(void)
      {
          if (g_systickCounter != 0U)
          {
              g_systickCounter--;
          }
      }
      
      *******************************************************************************
      *** ENTRY LIST
      ***
      
      Entry                       Address   Size  Type      Object
        -----                       -------   ----  ----      ------
      SysTick_Handler                 0x1   0x14  Code  Gb  led_blinky.o [1]
      

        現(xiàn)在我們嘗試在代碼里純手工搬移中斷向量表,找一塊空閑的 RAM 區(qū)域(比如 0x20000000 - 0x200003FF),將中斷向量表內(nèi)容直接手工拷貝過去即可,示例代碼如下。主函數(shù)里一開始就調(diào)用一下這個(gè) relocate_vector_table() 函數(shù)即可,修改后的工程下載進(jìn)板卡運(yùn)行一切正常,表明中斷向量表重定向操作成功了。

      extern uint32_t __VECTOR_TABLE[];
      
      void relocate_vector_table(void)
      {
          __disable_irq();
          // 將 0x30002000 處的初始中斷向量表拷貝到新地址 0x20000000
          memcpy((void *)0x20000000, (void *)__VECTOR_TABLE, 0x400);
          // 將 VTOR 指向 0x20000000
          SCB->VTOR = 0x20000000;
          __enable_irq();
      }
      
      int main(void)
      {
          relocate_vector_table();
      
          // 其余代碼
      }
      

        至此,Cortex-M中斷向量表原理及其重定向方法痞子衡便介紹完畢了,掌聲在哪里~~~

      歡迎訂閱

      文章會(huì)同時(shí)發(fā)布到我的 博客園主頁CSDN主頁知乎主頁微信公眾號(hào) 平臺(tái)上。

      微信搜索"痞子衡嵌入式"或者掃描下面二維碼,就可以在手機(jī)上第一時(shí)間看了哦。

      posted @ 2021-08-04 22:39  痞子衡  閱讀(3096)  評(píng)論(2)    收藏  舉報(bào)
      主站蜘蛛池模板: 人妻蜜臀久久av不卡| 国产精品人妻在线观看| 亚洲AV成人无码久久精品四虎| 国产一区国产精品自拍| 又爽又黄又无遮挡的激情视频| 久久精品无码av| 亚洲一区二区av高清| 亚洲a免费| 成人亚洲精品一区二区三区| 亚洲欧洲日韩国内精品| 久久丫精品久久丫| 亚洲天堂网中文在线资源| 亚洲精品一区二区天堂| 澎湖县| 精品国产亚洲午夜精品av| 男女爽爽无遮挡午夜视频| 国产99视频精品免费视频36| 亚洲一区二区三区蜜桃臀| 国产精品理论片在线观看| 国精品无码一区二区三区在线看| 欧美性猛交xxxx乱大交丰满| 91精品国产一二三产区| 亚洲男女羞羞无遮挡久久丫| 小嫩批日出水无码视频免费| 激情综合网一区二区三区| а∨天堂一区中文字幕| 国产一区二区亚洲一区二区三区| 久久久亚洲欧洲日产国码二区| av一区二区中文字幕| 亚洲老熟女一区二区三区| 野外做受三级视频| 久久精品国产99精品亚洲| 亚洲性av网站| 国产一区二区三区麻豆视频| 亚洲国产精品无码一区二区三区 | 国产精品免费中文字幕| 久在线精品视频线观看| 精品久久精品久久精品久久| 国产精品人成视频免| 国产午夜福利视频第三区| 男女激情一区二区三区|