https://github.com/xhawk18/TinyThreadgit
TinyThread 是基於Cortex-M0的小型的OS.github
知識儲備:函數
IPSR(中斷程序狀態寄存器),IPSR包含了當前正在執行的中斷服務程序編號,用於識別當前中斷。ui
Cortex-M0處理器內置中斷控制器,而且支持最多32箇中斷請求(IRQ)和一個不可屏蔽中斷(NMI).spa
PRIMASK置位(寫1),開啓屏蔽,屏蔽除了NMI和硬件錯誤(hardfault)外的全部中斷。清除此位,關閉屏蔽。code
TinyThread中斷控制涉及到的文件主要有:tt_sys.h、tt_sys.cblog
TinyThread中斷控制函數API主要有如下兩個,它們分別是打開IPSR和關閉IPSR寄存器(中斷屏蔽特殊寄存器).ip
tt_sys.c開發
1 #include "../Inc/tt_thread.h" 2 3 volatile int g_iIRQ_disable_count = 0; 4 volatile bool g_bIRQ_real_disable = 0;
tt_sys.hget
#ifndef INC_TT_SYS_H__ #define INC_TT_SYS_H__ #ifdef __cplusplus extern "C" { #endif extern volatile int g_iIRQ_disable_count; extern volatile bool g_bIRQ_real_disable; //#define TT_SYS_NO_PRINTF /* Implement in tt_syscall.s */ #if defined __CC_ARM # if __CM0_CMSIS_VERSION < 0x00020000 TT_INLINE bool tt_is_in_irq (void) //__get_IPSR()獲得當前 中斷程序狀態寄存器 的值,此函數用來判斷當前是否處在中斷狀態。 { register uint32_t __regIPSR __asm("ipsr"); return(__regIPSR); } # else TT_INLINE bool tt_is_in_irq (void) { return __get_IPSR (); } #endif #elif defined __GNUC__ __attribute__((always_inline )) TT_INLINE bool tt_is_in_irq (void) { uint32_t result; __asm__ volatile ("MRS %0, ipsr" : "=r" (result) ); return(result); } #elif defined __ICCARM__ # pragma diag_suppress=Pe940 TT_INLINE bool tt_is_in_irq (void) { __asm(" MRS R0, IPSR "); } #endif TT_INLINE bool tt_is_irq_disabled (void) //查看 中斷屏蔽特殊寄存器的值 中斷被屏蔽返回true,中斷可用返回false { int primask = __get_PRIMASK (); if ((primask & 1) == 0) //中斷程序狀態寄存器第0位置1,表示中斷被屏蔽 return false; else return true; } TT_INLINE void tt_enable_irq (void) { if (!tt_is_irq_disabled ()) //若是中斷可使用 { __set_PRIMASK(1); //PRIMASK寫1,屏蔽中斷 #if !defined TT_SYS_NO_PRINTF printf ("Not call tt_disable_irq before tt_enable_irq\n"); #endif while (1); //錯誤處理,用死循環提示,我我的認爲做者這麼處理的緣由是程序死掉,開發人員會追到這裏,就知道緣由了(沒有先執行tt_disable_irq函數). } g_iIRQ_disable_count--; if (g_iIRQ_disable_count == 0) { if (g_bIRQ_real_disable) { __set_PRIMASK(0); } } } TT_INLINE void tt_disable_irq (void) { if (tt_is_irq_disabled ()) //已經disbale過了 { if (g_iIRQ_disable_count == 0) g_bIRQ_real_disable = false; } else { __set_PRIMASK(1); if (g_iIRQ_disable_count == 0) g_bIRQ_real_disable = true; } g_iIRQ_disable_count++; }
在 void tt_enable_irq (void) 函數中,咱們能夠知道,在沒有先disable irq的狀況下,不容許執行此函數. 若是連續執行此函數,報錯。
在 void tt_disable_irq (void) 函數中,咱們能夠知道,雖然能夠連續執行tt_disable_irq函數,可是當連續執行此函數後, g_bIRQ_real_disable 的值爲 false, 那麼當enable irq時是沒有其做用的。
因此使用這對函數,必定要成對出現,並且要先disable,而後enable.