GadgetSeed  0.9.6
systick.c
[詳解]
1 /** @file
2  @brief Cortex-M SysTickドライバ
3 
4  @date 2013.03.10
5  @author Takashi SHUDO
6 */
7 
8 #include "sysconfig.h"
9 #include "asm.h"
10 #include "device.h"
11 #include "device/timer_ioctl.h"
12 #include "interrupt.h"
13 #include "timer.h"
14 #include "tkprintf.h"
15 #include "task/task.h"
16 
17 #include "stm32f7xx_hal.h"
18 
19 static unsigned long long timer_count = 0;
20 
21 static void (* inth_func)(void *sp);
22 
23 /*
24  @brief SysTick割り込みハンドラ
25 */
26 void inthdr_systick(unsigned int intnum, void *sp)
27 {
28  int i;
29 
30  timer_count += GSC_KERNEL_TIMER_INTERVAL_MSEC;
31 
32  for(i=0; i<GSC_KERNEL_TIMER_INTERVAL_MSEC; i++) {
33  HAL_IncTick(); // HALドライバ用
34  }
35 
36  if(inth_func) {
37  inth_func(sp);
38  }
39 }
40 
41 /*
42  @brief SysTick初期化
43  GSC_KERNEL_TIMER_INTERVAL_MSEC(ms)間隔でタイマ割り込み発生
44 */
45 static void start_systick(void)
46 {
47  int clock = HAL_RCC_GetHCLKFreq();
48 
49  HAL_SYSTICK_Config(clock/1000 * GSC_KERNEL_TIMER_INTERVAL_MSEC);
50  tkprintf("System Clock : %ld MHz\n", clock/1000000);
51  /*
52  タイマ割り込みプライオリティが最高になっているので最低に戻し
53  ている。多重割り込みは対応していないので他の割り込みと同じレ
54  ベルにしなければならない
55  */
56  NVIC_SetPriority(SysTick_IRQn, 0);
57 
58  HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
59 }
60 
61 /*
62  @brief SysTick停止
63 */
64 static void stop_systick(void)
65 {
66  SysTick->CTRL &= SysTick_CTRL_ENABLE_Msk;
67 }
68 
69 /*
70  @brief SysTickデバイスドライバ登録
71 */
72 static int systick_register(struct st_device *dev, char *param)
73 {
74  inth_func = 0;
75 
76  register_interrupt(IRQ2VECT(SysTick_IRQn), inthdr_systick);
77 
78  return 0;
79 }
80 
81 /*
82  @brief SysTickデバイスドライバ削除
83 */
84 static int systick_unregister(struct st_device *dev)
85 {
86  unregister_interrupt(IRQ2VECT(SysTick_IRQn));
87 
88  return 0;
89 }
90 
91 /*
92  @brief SysTickを制御する
93  @param[in] com コマンド
94  @param[in] arg コマンド引数
95  @return <0:エラー
96 */
97 static int systick_ioctl(struct st_device *dev, unsigned int com, unsigned int arg, void *param)
98 {
99  switch(com) {
100  case IOCMD_TIMER_GETTIME:
101  // GSC_KERNEL_TIMER_INTERVAL_MSEC の分解能以下のms単位の時間を返す
102  return (SysTick->LOAD - SysTick->VAL)/(HAL_RCC_GetHCLKFreq()/1000);
103  break;
104 
106  {
107  unsigned long long utime = (timer_count * 1000)
108  + (SysTick->LOAD - SysTick->VAL)/(HAL_RCC_GetHCLKFreq()/1000000);
109  *((unsigned long long *)param) = utime;
110  return 0;
111  }
112  break;
113 
114  case IOCMD_TIMER_START:
115  start_systick();
116  return 0;
117  break;
118 
119  case IOCMD_TIMER_STOP:
120  stop_systick();
121  return 0;
122  break;
123 
124  case IOCMD_TIMER_SETFUNC:
125  inth_func = (void (*)(void *))param;
126  return 0;
127  break;
128 
129  default:
130  SYSERR_PRINT("Unknown ioctl(%08lX)\n", com);
131  return -1;
132  }
133 
134  return -1;
135 }
136 
137 /*
138  @brief SysTickを休止状態にする
139  @return <0:エラー
140 */
141 static int systick_suspend(struct st_device *dev)
142 {
143  stop_systick(); // SysTick停止
144 
145  return 0;
146 }
147 
148 /*
149  @brief SysTickを活性化する
150  @return <0:エラー
151 */
152 static int systick_resume(struct st_device *dev)
153 {
154  start_systick(); // SysTickスタート
155 
156  return 0;
157 }
158 
159 const struct st_device cortexm_systick_device = {
161  .explan = "Cortex-M SysTick Driver",
162  .register_dev = systick_register,
163  .unregister_dev = systick_unregister,
164  .ioctl = systick_ioctl,
165  .suspend = systick_suspend,
166  .resume = systick_resume,
167 }; //!< SysTickデバイスドライバ
#define IOCMD_TIMER_GETSYSTIME
タイマの値を取得する(usec)
Definition: timer_ioctl.h:21
#define IOCMD_TIMER_SETFUNC
タイマの割り込みハンドラ処理を登録する
Definition: timer_ioctl.h:18
#define IOCMD_TIMER_STOP
タイマのカウントを停止する
Definition: timer_ioctl.h:20
カーネルタイマ
#define GSC_KERNEL_TIMER_INTERVAL_MSEC
$gsc カーネルタイマ割り込み間隔(ms)
Definition: timer.h:14
int tkprintf(const char *fmt,...)
非タスクコンテキスト実行用メッセージ出力
Definition: tkprintf.c:100
カーネル用機能限定printf
Cortex-M4
割り込みハンドラ
タスク制御
#define IOCMD_TIMER_GETTIME
タイマの値を取得する(msec)
Definition: timer_ioctl.h:17
#define IOCMD_TIMER_START
タイマのカウントを開始する
Definition: timer_ioctl.h:19
デバイスドライバAPI
デバイスドライバ構造体
Definition: device.h:25
char name[MAX_DEVNAMELRN]
デバイス名文字列
Definition: device.h:26
#define DEF_DEV_NAME_TIMER
標準タイマデバイス名
Definition: timer_ioctl.h:15
タイマドライバ ioctl 用マクロ定義