精選文章
RTOS - Systick
收錄於 : 關於Ameba的一百篇
前篇: vector table - hard fault handler
---
之前 Jserv 的介紹影片如下
2016-06-27 從無到有打造 IoT 作業系統核心
https://www.youtube.com/watch?v=CSKLsCa1gAU
https://www.facebook.com/events/645044348986795
個人筆記 : https://ameba.hackpad.com/RTOS--lQ1X6rtlUeP
---
在介紹中, 有一段很重要的起始觀念.
cortex-M 很多其實是 hardware 動作.
像一開始的啟動 :
(1) 會從 vector table : offset 0 載入到 main stack pointer (MSP)
(2) 從 vector table : offset 4 載入 接下來要跳到的位置 (Reset Handler) 到 Program Counter (PC)
另外像 interrupt handler 進入時, (handler mode)
也會自動把相關 registers push 進 stack. (PSP)
Ref: https://embedded2016.hackpad.com/mini-arm-os-FydFEfAHLPi

在 前篇的 vector table, 我們是用原本 Ameba 的 設定 在 RAM 的 vector table :
0x1000 0000
我們也可以自己準備個 vector table , 並把 VTOR 值 設到 這個 vector table 的 位置.
須注意 [6:0] always 0
也可以參考底下這個 remapping function., 有特別寫 vector table 位置要是 0x100 的倍數. 也就是說 address 位置 要是 256 byte aligned.
__attribute__(aligned(256)) ...
---
tick 可以當作是整個系統的心臟, 在硬體上指 CPU clock, 在 OS 上是指 systick.
之前 vector table, 有留意的話, 可以發現 RTX 會置換 3 個 中斷函式
SVC / PendSVC / Systick
一般相關還沒設定時, 就算 Systick handler 設定了, 會發現並沒有觸發 systick interrupt.
而這個是怎麼觸發的呢 : cortex M3 有設計這幾個 register :
我們可以參考 CMSIS5 底下的 RTOS - RTX 做法
#define NVIC_SYS_PRI3 (*((volatile uint32_t*)0xE000ED20))
https://github.com/ARM-software/CMSIS_5
rt_hal_cm.h
NVIC_ST_CTRL
設成 7 , 代表
bit 0 - 啟動
bit 1 - 數到 0 會發 systick 中斷
bit 2 - 用 cpu 內部 clock
這樣設定好 systick handler 就會被呼叫到了.
設定systick 的 priority 為 255
前篇: vector table - hard fault handler
---
之前 Jserv 的介紹影片如下
2016-06-27 從無到有打造 IoT 作業系統核心
https://www.youtube.com/watch?v=CSKLsCa1gAU
https://www.facebook.com/events/645044348986795
個人筆記 : https://ameba.hackpad.com/RTOS--lQ1X6rtlUeP
在介紹中, 有一段很重要的起始觀念.
cortex-M 很多其實是 hardware 動作.
像一開始的啟動 :
(1) 會從 vector table : offset 0 載入到 main stack pointer (MSP)
(2) 從 vector table : offset 4 載入 接下來要跳到的位置 (Reset Handler) 到 Program Counter (PC)
另外像 interrupt handler 進入時, (handler mode)
也會自動把相關 registers push 進 stack. (PSP)
Ref: https://embedded2016.hackpad.com/mini-arm-os-FydFEfAHLPi
- Reset後程式的運行流程
一旦處理器Reset後,就會進行「取得指令—解碼—執行」的循環,也就是3-stage pipeline。
在離開Reset狀態後,ARM Cortex M3所做的第一件事,就是讀取下列兩個 32位元整數的值:
- 從位址0x00000000處取出MSP (Main Stack Pointer)的初始值
- 從位址0x00000004處取出PC的初始值,處理器隨即自這個值所對應的位址處取值
可用下方示意圖說明:
在 前篇的 vector table, 我們是用原本 Ameba 的 設定 在 RAM 的 vector table :
0x1000 0000
我們也可以自己準備個 vector table , 並把 VTOR 值 設到 這個 vector table 的 位置.
Table 4.16. VTOR bit assignments
Bits | Name | Function |
---|---|---|
[31:7] | TBLOFF |
Vector table base offset field. It contains bits[29:7] of the offset of the table base from the bottom of the memory map.
Note
Bit[29] determines whether the vector table is in the code or SRAM memory region:
In implementations bit[29] is sometimes called the TBLBASE bit.
|
[6:0] | - | Reserved. |
須注意 [6:0] always 0
也可以參考底下這個 remapping function., 有特別寫 vector table 位置要是 0x100 的倍數. 也就是說 address 位置 要是 256 byte aligned.
__attribute__(aligned(256)) ...
/******************************************************************************* * Function Name : NVIC_SetVectorTable * Description : Sets the vector table location and Offset. * Input : - NVIC_VectTab: specifies if the vector table is in RAM or * FLASH memory. * This parameter can be one of the following values: * - NVIC_VectTab_RAM * - NVIC_VectTab_FLASH * - Offset: Vector Table base offset field. * This value must be a multiple of 0x100. * Output : None * Return : None *******************************************************************************/ void NVIC_SetVectorTable(DWORD NVIC_VectTab, DWORD Offset) { NVIC_VECT_TABLE = NVIC_VectTab | (Offset & 0x1FFFFF80); }
---
tick 可以當作是整個系統的心臟, 在硬體上指 CPU clock, 在 OS 上是指 systick.
之前 vector table, 有留意的話, 可以發現 RTX 會置換 3 個 中斷函式
SVC / PendSVC / Systick
一般相關還沒設定時, 就算 Systick handler 設定了, 會發現並沒有觸發 systick interrupt.
而這個是怎麼觸發的呢 : cortex M3 有設計這幾個 register :
The SysTick is configured through the four registers described in Table 5.
Table 5. SysTick Registers
Name | Address | Description |
---|---|---|
SysTick Control and Status | 0xE000E010 | basic control of SysTick e.g. enable, clock source, interrupt or poll |
SysTick Reload Value | 0xE000E014 | value to load Current Value register when 0 is reached |
SysTick Current Value | 0xE000E018 | the current value of the count down. |
SysTick Calibration Value | 0xE000E01C | might contain the number of ticks to generate a 10ms interval and other information, depending on the implementation |
我們可以參考 CMSIS5 底下的 RTOS - RTX 做法
#define NVIC_SYS_PRI3 (*((volatile uint32_t*)0xE000ED20))
https://github.com/ARM-software/CMSIS_5
rt_hal_cm.h
__inline static void rt_systick_init (void) { NVIC_ST_RELOAD = os_trv; NVIC_ST_CURRENT = 0U; NVIC_ST_CTRL = 0x0007U; NVIC_SYS_PRI3 |= 0xFF000000U; }
os_trv 的值 會設定成底下的方式.
OS_CLOCK 指的是 CPU 一秒有幾個 clock,
OS_TICK 指的是 一次發生 OS tick 多長時間, 單位 us.
所以設 10000 就是 10ms 一個 OS tick
( Ameba 是用 1000 - 1ms )
#define OS_TRV ((U32)(((double)OS_CLOCK*(double)OS_TICK)/1E6)-1)
NVIC_ST_RELOAD : 24bit, 當數到 0 時會用此值 load 進去
NVIC_ST_CURRENT : 顯示目前計次
4.4.3. SysTick Current Value Register
The SYST_CVR register contains the current value of the SysTick counter. See the register summary in Table 4.32 for its attributes. The bit assignments are:
NVIC_ST_CTRL
設成 7 , 代表
bit 0 - 啟動
bit 1 - 數到 0 會發 systick 中斷
bit 2 - 用 cpu 內部 clock
這樣設定好 systick handler 就會被呼叫到了.
4.4.1. SysTick Control and Status Register
The SysTick SYST_CSR register enables the SysTick features. The register resets to
0x00000000
, or to 0x00000004
if your device does not implement a reference clock. See the register summary in Table 4.32 for its attributes. The bit assignments are:
Table 4.33. SysTick SYST_CSR register bit assignments
Bits | Name | Function |
---|---|---|
[31:17] | - | Reserved. |
[16] | COUNTFLAG |
Returns 1 if timer counted to 0 since last time this was read.
|
[15:3] | - | Reserved. |
[2] | CLKSOURCE |
Indicates the clock source:
0 = external clock
1 - processor clock.
|
[1] | TICKINT |
Enables SysTick exception request:
0 = counting down to zero does not assert the SysTick exception request
1 = counting down to zero asserts the SysTick exception request.
Software can use COUNTFLAG to determine if SysTick has ever counted to zero.
|
[0] | ENABLE |
Enables the counter:
0 = counter disabled
1 = counter enabled.
|
設定systick 的 priority 為 255
System Handler Priority Register 3
The bit assignments are:
留言
張貼留言