dsPIC33C系列的中斷向量表(IVT)位于程序存儲器中,起始單元地址是0x000004h(0x000000~0x000002是復位入口地址)。IVT包含6個不可屏蔽陷阱向量和最多246個中斷源。一般來說,每個中斷源都有自己的中斷向量。每個中斷向量都包含一個24位寬的地址。每個中斷向量單元中編程的值是其相關的中斷服務程序(ISR)的起始地址。如下圖所示。
6個不可屏蔽中斷向量表,它們的CPU優先級不可設置,優先級分別為9-15。
中斷向量根據其自然優先級區分優先順序(在沒有分配優先級的情況下,優先級0-7可設置),自然優先級與中斷向量在向量表中的位置有關。一般來說,較低地址的中斷向量具有較高的自然優先級。例如在下列向量表中,與向量編號為8(外部中斷0)相關的中斷比其他向量地址的中斷具有更高的自然優先級。
中斷向量表的重映射
dsPIC33C共有256個中斷源,每一個中斷源對應一個中斷向量地址,且每個中斷向量地址是固定不能改變的。通常,我們在BootLoader中不使用中斷,只在應用程序中使用中斷功能。當禁用CodeGuard時,大多數dsPIC33器件只有一個IVT表。對于具有單個IVT表的MCU ,需要在中斷向量表中設置跳轉偏移量(也就是重映射,在應用程序空間中復制IVT表),讓中斷產生后能跳轉到應用程序中。
在用戶應用程序空間中的固定地址處創建預定義的應用程序中斷重映射表。該表中的每個條目都包含一個GOTO指令,該指令跳至該中斷的實際應用程序中斷服務程序(ISR)。發生中斷時,這些中斷將自動跳到中斷處理函數。
下面是中斷的流程以及它在應用程序中斷服務程序中的結束方式
(1)發生UART1中斷;
(2)PC指針跳轉到硬件中斷向量表中指定的地址(此處地址假設為0x4000),這是應用程序中斷重映射表中的固定位置;
(3)應用程序中斷重映射有一個指向實際應用程序中斷服務程序函數的GOTO指令。
上述中斷跳轉的方法有一定缺點,就程序存儲空間而言,其成本可能更高。每個中斷在dsPIC33器件上需要2條指令(6個字節,GOTO占兩個指令)。在dsPIC33C器件上有256個中斷。如果每個中斷都需要跳轉,則可能需要超過1KB的內存。此外,大多數應用程序代碼僅使用幾個中斷源,在這種情況下,應用程序中斷重映射表中未使用的中斷入口只是浪費空間。
一種“壓縮”或“減小”此表大小的方法是確定將在此設計產品系列中使用或可能使用哪些中斷。然后僅在“應用程序中斷重映射表”中創建入口,并將這些入口放置在“應用程序中斷重映射表”的開頭開始的連續位置。有了此應用程序可以支持的中斷“列表”,Bootloader就可以獲取該列表,并針對識別出的中斷,使用簡化的應用程序中斷重映射表中相應入口的地址在IVT中編程其中斷。此外,對于未使用的中斷,我們可以在應用程序空間中創建一個“默認中斷服務程序”,并在應用程序中斷重映射表中創建一個入口,同時為默認值創建一個ISR。這將通過默認的中斷服務程序將所有其他中斷跳轉到應用程序。這樣,如果應用程序稍后決定需要一個以前不需要的新中斷,則它仍然可以通過重新映射的默認處理程序訪問該中斷。
選擇哪些中斷跳轉到它們自己的ISR,哪些跳轉到默認ISR可能是一項困難的任務,因為Bootloader可能不知道哪些中斷正在使用或可以使用。此外,由于產品的生命周期以年為單位,產品功能可能會隨著時間而改變。 因此,如果閃存空間不是主要考慮因素,那么即使應用程序的外設具有獨立ISR的可能性很小,Bootloaer區也應將其跳轉給獨立的ISR,只有當外設在項目開發中完全確定不會使用,或者不需要使用中斷,或者可以使用默認的ISR中斷時,才將外設跳轉到默認的ISR。
使用上述方法,最終中斷跳轉方案如下所示。 在此示例中,應用程序僅需要兩個專用的ISR(例如UART1和SPI1)。 因此,這兩個外設中的每一個在應用程序中斷重映射表中都有一個專用入口,而應用程序中斷重映射表中的其他入口都采用默認中斷ISR。 所有可以共享一個公共ISR的“未使用的”或外設,其IVT入口都指向應用程序中斷重新映射表中的這個入口,這也是重新映射表中的第一個地址。 通過使用默認的中斷入口,可以大大減小應用程序中斷重映射表的大小。
在上面的示例中,應用程序未使用外設A,B和C,但是將它們的中斷轉發給應用程序默認處理程序,以防萬一以后需要它們時使用。
在boot區需要中斷的情況下,IVT不必將該中斷跳轉至應用程序(注意:在具有備用中斷表的設備-AIVT上,這不是必需的)。 在這種情況下,Bootloader將使用來自IVT的中斷。 在下面的示例中,比如Bootloader需要在中斷模式下使用UART2。 在這種情況下,IVT不會將中斷轉發給應用程序,而是決定將中斷保留在Bootloader。