天天看點

CMSIS-RTOS2 文檔翻譯 之 參考(CMSIS-RTOS2 API 之 OS Tick API)

OS Tick API CMSIS-RTOS2 API

在裝置不可知的 RTOS 實作和特定的周期性定時器功能之間提供低級 API 。更多...

函數

int32_t  OS_Tick_Setup (uint32_t freq, IRQHandler_t handler)
建立 OS Tick 。更多...
void  OS_Tick_Enable (void)
啟用 OS Tick 。更多...
void  OS_Tick_Disable (void)
禁用 OS Tick 。更多...
void  OS_Tick_AcknowledgeIRQ (void)
确認 OS Tick IRQ 。更多...
int32_t  OS_Tick_GetIRQn (void)
擷取 OS Tick IRQ 編号。更多...
uint32_t  OS_Tick_GetClock (void)
擷取 OS Tick 時鐘。更多...
uint32_t  OS_Tick_GetInterval (void)
擷取 OS Tick 間隔。更多...
uint32_t  OS_Tick_GetCount (void)
擷取 OS Tick 計數值。更多...
uint32_t  OS_Tick_GetOverflow (void)
擷取 OS Tick 溢出狀态。更多...

描述

CMSIS OS Tick API 可以被任意 RTOS 實作使用,以便在各種各樣的控制器中輕松使用。

Cortex-M 器件共享一個通用系統節拍定時器,用于 RTOS 定時目的。Cortex-A 器件沒有常見的系統節拍定時器,但是有各種供應商特定的解決方案。為了使 RTOS(如 RTX5)更容易支援多種 Cortex 微控制器,OS Tick API 用于封裝裝置特定的定時器實作。

Cortex-M 系統滴答定時器的預設實作可以在 os_systick.c 中找到。

注意
預設的實作被定義為弱,是以可以很容易地被替代的使用者實作覆寫。

#include "os_tick.h" //lint -emacro((923,9078),SCB,SysTick) "cast from unsigned long to pointer" #include "RTE_Components.h" #include CMSIS_device_header #ifdef SysTick #ifndef SYSTICK_IRQ_PRIORITY #define SYSTICK_IRQ_PRIORITY 0xFFU #endif static uint8_t PendST; // Setup OS Tick. __WEAK int32_t OS_Tick_Setup (uint32_t freq, IRQHandler_t handler) { uint32_t load; (void)handler; if (freq == 0U) { //lint -e{904} "Return statement before end of function" return (-1); } load = (SystemCoreClock / freq) - 1U; if (load > 0x00FFFFFFU) { //lint -e{904} "Return statement before end of function" return (-1); } // Set SysTick Interrupt Priority #if ((defined(__ARM_ARCH_8M_MAIN__) && (__ARM_ARCH_8M_MAIN__ != 0)) || \ (defined(__CORTEX_M) && (__CORTEX_M == 7U))) SCB->SHPR[11] = SYSTICK_IRQ_PRIORITY; #elif (defined(__ARM_ARCH_8M_BASE__) && (__ARM_ARCH_8M_BASE__ != 0)) SCB->SHPR[1] |= ((uint32_t)SYSTICK_IRQ_PRIORITY << 24); #elif ((defined(__ARM_ARCH_7M__) && (__ARM_ARCH_7M__ != 0)) || \ (defined(__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ != 0))) SCB->SHP[11] = SYSTICK_IRQ_PRIORITY; #elif (defined(__ARM_ARCH_6M__) && (__ARM_ARCH_6M__ != 0)) SCB->SHP[1] |= ((uint32_t)SYSTICK_IRQ_PRIORITY << 24); #else #error "Unknown ARM Core!" #endif SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_TICKINT_Msk; SysTick->LOAD = load; SysTick->VAL = 0U; PendST = 0U; return (0); } /// Enable OS Tick. __WEAK void OS_Tick_Enable ( void) { if (PendST != 0U) { PendST = 0U; SCB->ICSR = SCB_ICSR_PENDSTSET_Msk; } SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; } /// Disable OS Tick. __WEAK void OS_Tick_Disable ( void) { SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; if ((SCB->ICSR & SCB_ICSR_PENDSTSET_Msk) != 0U) { SCB->ICSR = SCB_ICSR_PENDSTCLR_Msk; PendST = 1U; } } // Acknowledge OS Tick IRQ. __WEAK void OS_Tick_AcknowledgeIRQ ( void) { (void)SysTick->CTRL; } // Get OS Tick IRQ number. __WEAK int32_t OS_Tick_GetIRQn ( void) { return ((int32_t)SysTick_IRQn); } // Get OS Tick clock. __WEAK uint32_t OS_Tick_GetClock ( void) { return (SystemCoreClock); } // Get OS Tick interval. __WEAK uint32_t OS_Tick_GetInterval ( void) { return (SysTick->LOAD + 1U); } // Get OS Tick count value. __WEAK uint32_t OS_Tick_GetCount ( void) { uint32_t load = SysTick->LOAD; return (load - SysTick->VAL); } // Get OS Tick overflow status. __WEAK uint32_t OS_Tick_GetOverflow ( void) { return ((SysTick->CTRL >> 16) & 1U); } #endif // SysTick

函數文檔

int32_t OS_Tick_Setup ( uint32_t  freq,
IRQHandler_t  handler 
)
參數
[in] freq 滴答頻率,機關為 Hz
[in] handler 滴答 IRQ 處理程式
傳回
成功時為 0 ,錯誤時為 -1 。

設定一個硬體時間,用于為 RTOS 産生周期性的滴答中斷。

定時器應該配置為在給定頻率下産生中斷。給定的回調應該用作中斷處理程式。

定時器隻應該被初始化并相應地配置。在調用 OS_Tick_Enable 之前,它不能啟動也不能建立中斷。

對于使用内置 SystemTick 定時器的簡單 Cortex-M 裝置,預設實作如下例所示:

#ifndef SYSTICK_IRQ_PRIORITY #define SYSTICK_IRQ_PRIORITY 0xFFU #endif static uint8_t PendST; int32_t OS_Tick_Setup (uint32_t freq, IRQHandler_t handler) { (void)handler; uint32_t load; if (freq == 0U) { return (-1); } load = (SystemCoreClock / freq) - 1U; if (load > 0x00FFFFFFU) { return (-1); } NVIC_SetPriority(SysTick_IRQn, SYSTICK_IRQ_PRIORITY); SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_TICKINT_Msk; SysTick->LOAD = load; SysTick->VAL = 0U; PendST = 0U; return (0); }

int32_t OS_Tick_Enable ( void  )

啟動定時器來計數并啟用周期性中斷的生成。

對于使用内置 SystemTick 計時器的簡單 Cortex-M 裝置,預設實作如下例所示:

int32_t OS_Tick_Enable ( void) { if (PendST != 0U) { PendST = 0U; SCB->ICSR = SCB_ICSR_PENDSTSET_Msk; } SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; return (0); }

int32_t OS_Tick_Disable ( void  )

停止定時器計數并禁止生成周期性中斷。

在調用這個函數之後,定時器不能産生任何進一步的中斷。

對于使用内置 SystemTick 計時器的簡單 Cortex-M 裝置,預設實作如下例所示:

int32_t OS_Tick_Disable ( void) { SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; if ((SCB->ICSR & SCB_ICSR_PENDSTSET_Msk) != 0U) { SCB->ICSR = SCB_ICSR_PENDSTCLR_Msk; PendST = 1U; } return (0); }

int32_t OS_Tick_AcknowledgeIRQ ( void  )

确認待處理的滴答中斷,即通過清除挂起标志。

對于使用内置 SystemTick 計時器的簡單 Cortex-M 裝置,預設實作如下例所示:

int32_t OS_Tick_AcknowledgeIRQ ( void) { (void)SysTick->CTRL; return (0); }

int32_t OS_Tick_GetIRQn ( void  )
傳回
OS Tick IRQ 編号。

傳回實際的數值來辨別定時器使用的中斷。

對于使用内置 SystemTick 計時器的簡單 Cortex-M 裝置,預設實作如下例所示:

int32_t OS_Tick_GetIRQn ( void) { return (SysTick_IRQn); }

uint32_t OS_Tick_GetClock ( void  )
傳回
OS Tick 時鐘,機關為 Hz 。

傳回定時器工作的時鐘頻率,即給定内部計數器值的增量。

對于使用内置 SystemTick 計時器的簡單 Cortex-M 裝置,預設實作如下例所示:

uint32_t OS_Tick_GetClock ( void) { return (SystemCoreClock); }

uint32_t OS_Tick_GetInterval ( void  )
傳回
OS Tick 間隔。

将連續滴答中斷之間的内部計數器值的實際計數間隔傳回。

對于使用内置 SystemTick 計時器的簡單 Cortex-M 裝置,預設實作如下例所示:

uint32_t OS_Tick_GetInterval ( void) { return (SysTick->LOAD + 1U); }

uint32_t OS_Tick_GetCount ( void  )
傳回
OS Tick 計數值。

傳回 0 到 OS_Tick_GetInterval() - 1 之間的内部計數器的目前值。

如果需要更高的時間分辨率,則使用此值計算子标記,即 OS_Tick_GetCount()/ OS_Tick_GetInterval()。

注意
如果硬體是一個遞減計數器(例如 Cortex-M 系統節拍定時器),則必須計算相應的遞增計數器值。

對于使用内置 SystemTick 計時器的簡單 Cortex-M 裝置,預設實作如下例所示:

uint32_t OS_Tick_GetCount ( void) { uint32_t load = SysTick->LOAD; return (load - SysTick->VAL); }

OS_Tick_GetOverflow ( void  )
傳回
OS Tick 溢出狀态(1 - 溢出,0 - 無溢出)。

傳回溢出信号的目前狀态,即定時器中斷等待位。

這個資訊可以用來計算一個中間的(但是正确的)滴答值,而滴答中斷正在挂起但被阻塞。

對于使用内置 SystemTick 計時器的簡單 Cortex-M 裝置,預設實作如下例所示:

uint32_t OS_Tick_GetOverflow ( void) { return ((SysTick->CTRL >> 16) & 1U); }