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

  • 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
BitsNameFunction
[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:
  • 0 = code
  • 1 = SRAM.
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
NameAddressDescription
SysTick Control and Status0xE000E010basic control of SysTick e.g. enable, clock source, interrupt or poll
SysTick Reload Value0xE000E014value to load Current Value register when 0 is reached
SysTick Current Value0xE000E018the current value of the count down.
SysTick Calibration Value0xE000E01Cmight 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:

Table 4.35. SYST_CVR register bit assignments
BitsNameFunction
[31:24]-Reserved.
[23:0]CURRENT
Reads return the current value of the SysTick counter.
A write of any value clears the field to 0, and also clears the SYST_CSR COUNTFLAG bit to 0.




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
BitsNameFunction
[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:

Table 4.23. SHPR3 register bit assignments
BitsNameFunction
[31:24]PRI_15Priority of system handler 15, SysTick exception
[23:16]PRI_14Priority of system handler 14, PendSV
[15:0]-Reserved

留言

熱門文章