【STM32】FreeRTOS临界区
00. 目錄
文章目錄
- 00. 目錄
- 01. 概述
- 02. 任務(wù)級(jí)臨界區(qū)代碼保護(hù)
- 03.中斷級(jí)臨界區(qū)代碼保護(hù)
- 04. 預(yù)留
- 05. 預(yù)留
- 06. 附錄
- 07. 參考
01. 概述
臨界段代碼也叫做臨界區(qū),是指那些必須完整運(yùn)行,不能被打斷的代碼段,比如有的外設(shè)的初始化需要嚴(yán)格的時(shí)序,初始化過(guò)程中不能被打斷。FreeRTOS在進(jìn)入臨界端代碼的時(shí)候需要關(guān)閉中斷,當(dāng)處理完臨界段代碼以后再打開(kāi)中斷。FreeRTOS系統(tǒng)本身就有很多的臨界段代碼。這些代碼都加了臨界段代碼保護(hù),我們?cè)趯?xiě)自己的用戶程序的時(shí)候有些地方也需要添加臨界段代碼保護(hù)。
FreeRTOS與臨界段代碼保護(hù)有關(guān)的函數(shù)有4個(gè):
/*** task. h** Macro to mark the start of a critical code region. Preemptive context* switches cannot occur when in a critical region.** NOTE: This may alter the stack (depending on the portable implementation)* so must be used with care!** \defgroup taskENTER_CRITICAL taskENTER_CRITICAL* \ingroup SchedulerControl*/ #define taskENTER_CRITICAL() portENTER_CRITICAL() //任務(wù)級(jí) #define taskENTER_CRITICAL_FROM_ISR() portSET_INTERRUPT_MASK_FROM_ISR() //中斷級(jí)/*** task. h** Macro to mark the end of a critical code region. Preemptive context* switches cannot occur when in a critical region.** NOTE: This may alter the stack (depending on the portable implementation)* so must be used with care!** \defgroup taskEXIT_CRITICAL taskEXIT_CRITICAL* \ingroup SchedulerControl*/ #define taskEXIT_CRITICAL() portEXIT_CRITICAL() //任務(wù)級(jí) #define taskEXIT_CRITICAL_FROM_ISR( x ) portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) //中斷級(jí)02. 任務(wù)級(jí)臨界區(qū)代碼保護(hù)
taskENTER_CRITICAL()和taskEXIT_CRITICAL()是任務(wù)級(jí)的臨界區(qū)代碼保護(hù),一個(gè)是進(jìn)入臨界區(qū),一個(gè)是退出臨界區(qū),這兩個(gè)函數(shù)一定要成對(duì)的使用。
/*** task. h** Macro to mark the start of a critical code region. Preemptive context* switches cannot occur when in a critical region.** NOTE: This may alter the stack (depending on the portable implementation)* so must be used with care!** \defgroup taskENTER_CRITICAL taskENTER_CRITICAL* \ingroup SchedulerControl*/ #define taskENTER_CRITICAL() portENTER_CRITICAL() //任務(wù)級(jí)/*** task. h** Macro to mark the end of a critical code region. Preemptive context* switches cannot occur when in a critical region.** NOTE: This may alter the stack (depending on the portable implementation)* so must be used with care!** \defgroup taskEXIT_CRITICAL taskEXIT_CRITICAL* \ingroup SchedulerControl*/ #define taskEXIT_CRITICAL() portEXIT_CRITICAL() //任務(wù)級(jí)portENTER_CRITICAL()和portEXIT_CRITICAL()也是宏定義,在portmacro.h中有定義。
#define portENTER_CRITICAL() vPortEnterCritical()#define portEXIT_CRITICAL() vPortExitCritical()vPortEnterCritical()和vPortExitCritical()函數(shù)實(shí)現(xiàn)如下:
void vPortEnterCritical( void ) {portDISABLE_INTERRUPTS();uxCriticalNesting++;/* This is not the interrupt safe version of the enter critical function so* assert() if it is being called from an interrupt context. Only API* functions that end in "FromISR" can be used in an interrupt. Only assert if* the critical nesting count is 1 to protect against recursive calls if the* assert function also uses a critical section. */if( uxCriticalNesting == 1 ){configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 );} }void vPortExitCritical( void ) {configASSERT( uxCriticalNesting );uxCriticalNesting--;if( uxCriticalNesting == 0 ){portENABLE_INTERRUPTS();} }03.中斷級(jí)臨界區(qū)代碼保護(hù)
taskENTER_CRITICAL_FROM_ISR()和taskEXIT_CRITICAL_FROM_ISR()是中斷級(jí)別臨界區(qū)代碼保護(hù),是用在中斷服務(wù)程序中的,而且這個(gè)中斷的優(yōu)先級(jí)一定要低于預(yù)先設(shè)置的值。
/*** task. h** Macro to mark the start of a critical code region. Preemptive context* switches cannot occur when in a critical region.** NOTE: This may alter the stack (depending on the portable implementation)* so must be used with care!** \defgroup taskENTER_CRITICAL taskENTER_CRITICAL* \ingroup SchedulerControl*/ #define taskENTER_CRITICAL_FROM_ISR() portSET_INTERRUPT_MASK_FROM_ISR() //中斷級(jí)/*** task. h** Macro to mark the end of a critical code region. Preemptive context* switches cannot occur when in a critical region.** NOTE: This may alter the stack (depending on the portable implementation)* so must be used with care!** \defgroup taskEXIT_CRITICAL taskEXIT_CRITICAL* \ingroup SchedulerControl*/ #define taskEXIT_CRITICAL_FROM_ISR( x ) portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) //中斷級(jí)在portmacro.h文件中有如下定義:
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortRaiseBASEPRI()#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vPortSetBASEPRI( x )ulPortRaiseBASEPRI()和vPortSetBASEPRI()相關(guān)實(shí)現(xiàn)
static portFORCE_INLINE void vPortSetBASEPRI( uint32_t ulBASEPRI ){__asm{/* Barrier instructions are not used as this function is only used to* lower the BASEPRI value. */ /* *INDENT-OFF* */msr basepri, ulBASEPRI /* *INDENT-ON* */}}static portFORCE_INLINE uint32_t ulPortRaiseBASEPRI( void ){uint32_t ulReturn, ulNewBASEPRI = configMAX_SYSCALL_INTERRUPT_PRIORITY;__asm{/* Set BASEPRI to the max syscall priority to effect a critical* section. */ /* *INDENT-OFF* */mrs ulReturn, baseprimsr basepri, ulNewBASEPRIdsbisb /* *INDENT-ON* */}return ulReturn;}中斷級(jí)臨界區(qū)代碼應(yīng)用示例
04. 預(yù)留
05. 預(yù)留
06. 附錄
6.1 【STM32】STM32系列教程匯總
網(wǎng)址:【STM32】STM32系列教程匯總
07. 參考
《FreeRTOS Reference Manual》
《Using the FreeRTOS Real Time Kernel -A Practical Guide》
《The Definitive Guide to ARM Cortex-M3 and Cortex-M4 Processors,3rd Edition》
總結(jié)
以上是生活随笔為你收集整理的【STM32】FreeRTOS临界区的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 【STM32】FreeRTOS中断配置
- 下一篇: 【STM32】FreeRTOS中断示例