GadgetSeed  0.9.6
syscall.c
[詳解]
1 /** @file
2  @brief システムコール
3 
4  GadgetSeed のタスク関連システムコールはソフトウェア割り込みを使用します。
5 
6  @date 2011.02.26
7  @author Takashi SHUDO
8 */
9 
10 #include "asm.h"
11 #include "syscall.h"
12 #include "tkprintf.h"
13 #include "calltrace.h"
14 #include "syscall_param.h"
15 #include "task_opration.h"
16 #include "console.h"
17 
18 //#define DEBUGKBITS 2
19 #include "dkprintf.h"
20 
21 
22 const char syscall_name[][16] = {
23  "dispatch->", // 0
24  "TASK_ADD", // 1
25  "TASK_EXEC", // 2
26  "TASK_EXIT", // 3
27  "TASK_PAUSE", // 4
28  "TASK_SLEEP", // 5
29  "TASK_KILL", // 6
30  "TASK_WAKEUP", // 7
31  "EVT_REG", // 8
32  "EVT_WAIT", // 9
33  "EVT_PUSH", // 10
34  "EVT_CHECK", // 11
35  "EVT_CLEAR", // 12
36  "EVT_WAKEUP", // 13
37  "EVT_UNREG", // 14
38  "MTX_REG", // 15
39  "MTX_LOCK", // 16
40  "MTX_UNLOCK", // 17
41  "MTX_UNREG", // 18
42  "SET_CON_IN", // 19
43  "SET_CON_OUT", // 20
44  "SET_ERR_OUT", // 21
45 
46  "TIM_WAKEUP", // 22
47 
48  "PRINT_TASK",
49  "PRINT_QUEUE",
50  "PRINT_CALLTRACE",
51  "GET_TASKS_INFO"
52 };
53 
54 int syscall_cnt = 0;
55 
56 /* NOT API
57  @brief システムコール割り込み処理
58 */
59 void syscall_inthdr(unsigned int intnum, void *sp)
60 {
61  if(syscall_cnt == 0) {
62  SYSERR_PRINT("!!! Invalid syscall ?\n");
63  }
64  syscall_cnt --;
65 
66  run_task->sp = sp;
67 
68  DKPRINTF(0x01, "-- SYSCALL --\n");
69  DKPRINTF(0x01, "task \"%s\"\n", run_task->name);
70  DKPRINTF(0x01, "SP = %p\n", sp);
71  DKPRINTF(0x01, "type = %s(%d)\n", syscall_name[run_task->syscall.type],
72  run_task->syscall.type);
73  DKPRINTF(0x01, "param = %p\n", run_task->syscall.param);
74 #ifdef DEBUG
75 #include "timer.h"
76  {
77  unsigned int systime = get_kernel_time();
78  DKPRINTF(0x01, "systime = %ld\n", systime);
79  }
80 #endif
81 
82  switch(run_task->syscall.type) {
83  case SYSCALL_TASK_ADD:
84  {
85  struct exec_task_param *param =
86  (struct exec_task_param *)run_task->syscall.param;
87 
88  DKPRINTF(0x01, "SC param = %p\n", param);
89  DKPRINTF(0x01, "SC func = %p\n", param->func);
90  DKPRINTF(0x01, "SC name = \"%s\"\n", param->name);
91  DKPRINTF(0x01, "SC priority= %d\n", param->priority);
92  DKPRINTF(0x01, "SC stack= %p\n", param->stack);
93  DKPRINTF(0x01, "SC stack_size = %d\n", param->stack_size);
94  DKPRINTF(0x01, "SC arg = %d\n", param->arg);
95 
96  if(param == 0) {
97  SYSERR_PRINT("type=%d param=%p\n",
98  run_task->syscall.type,
99  run_task->syscall.param);
100  print_queues();
101  return;
102  }
103  task_add_ISR(param->func,
104  param->name,
105  param->priority,
106  param->tcb,
107  param->stack,
108  param->stack_size,
109  param->arg);
110  }
111  break;
112 
113  case SYSCALL_TASK_EXEC:
114  {
115  struct exec_task_param *param =
116  (struct exec_task_param *)run_task->syscall.param;
117 
118  DKPRINTF(0x01, "SC param = %p\n", param);
119  DKPRINTF(0x01, "SC func = %p\n", param->func);
120  DKPRINTF(0x01, "SC name = \"%s\"\n", param->name);
121  DKPRINTF(0x01, "SC priority= %d\n", param->priority);
122  DKPRINTF(0x01, "SC stack= %p\n", param->stack);
123  DKPRINTF(0x01, "SC stack_size = %d\n", param->stack_size);
124  DKPRINTF(0x01, "SC arg = %d\n", param->arg);
125 
126  if(param == 0) {
127  SYSERR_PRINT("type=%d param=%p\n",
128  run_task->syscall.type,
129  run_task->syscall.param);
130  print_queues();
131  return;
132  }
133  task_exec_ISR(param->func,
134  param->name,
135  param->priority,
136  param->tcb,
137  param->stack,
138  param->stack_size,
139  param->arg);
140  }
141  break;
142 
143  case SYSCALL_TASK_EXIT:
144  task_exit_ISR(sp);
145  break;
146 
147  case SYSCALL_TASK_PAUSE:
148  task_pause_ISR(sp);
149  break;
150 
151  case SYSCALL_TASK_SLEEP:
152  task_sleep_ISR(sp, (unsigned int)(long)run_task->syscall.param);
153  break;
154 
155  case SYSCALL_TASK_KILL:
156  task_kill_id_ISR(sp, (int)(long)run_task->syscall.param);
157  break;
158 
159  case SYSCALL_TASK_WAKEUP:
160  task_wakeup_id_ISR(sp, (int)(long)run_task->syscall.param);
161  break;
162 
163  case SYSCALL_EVTQUE_INIT:
164  {
165  struct evtque_param *param =
166  (struct evtque_param *)run_task->syscall.param;
167  eventqueue_register_ISR(param->evtque, param->name, param->arg, param->size, param->count);
168  }
169  break;
170 
171  case SYSCALL_EVTQUE_WAIT:
172  {
173  struct evtque_param *param =
174  (struct evtque_param *)run_task->syscall.param;
175  event_wait_ISR(sp, param->evtque, param->arg, param->timeout);
176  }
177  break;
178 
179  case SYSCALL_EVTQUE_CLEAR:
180  event_clear_ISR(sp, (struct st_event *)run_task->syscall.param);
181  break;
182 
183  case SYSCALL_EVTQUE_CHECK:
184  {
185  struct evtque_param *param =
186  (struct evtque_param *)run_task->syscall.param;
187  param->ret = event_check_ISR(sp, (struct st_event *)param->evtque);
188  }
189  break;
190 
191  case SYSCALL_EVTQUE_WAKEUP:
192  {
193  struct evtque_param *param =
194  (struct evtque_param *)run_task->syscall.param;
195  event_wakeup_ISR(sp, param->evtque, param->arg);
196  }
197  break;
198 
199  case SYSCALL_EVTQUE_DISPOSE:
201  (struct st_event *)run_task->syscall.param);
202  break;
203 
204  case SYSCALL_MUTEX_INIT:
205  {
206  struct mutex_param *param =
207  (struct mutex_param *)run_task->syscall.param;
208  mutex_register_ISR(param->mutex, param->name);
209  }
210  break;
211 
212  case SYSCALL_MUTEX_LOCK:
213  {
214  struct mutex_param *param =
215  (struct mutex_param *)run_task->syscall.param;
216  mutex_lock_ISR(sp, param->mutex, param->timeout);
217  }
218  break;
219 
220  case SYSCALL_MUTEX_UNLOCK:
221  {
222  struct mutex_param *param =
223  (struct mutex_param *)run_task->syscall.param;
224  mutex_unlock_ISR(sp, param->mutex);
225  }
226  break;
227 
228  case SYSCALL_MUTEX_DISPOSE:
229  mutex_unregister_ISR((struct st_mutex *)run_task->syscall.param);
230  break;
231 
232  case SYSCALL_SET_CONSOLE_IN:
233  set_console_in_device_ISR((struct st_device *)run_task->syscall.param);
234  break;
235 
236  case SYSCALL_SET_CONSOLE_OUT:
237  set_console_out_device_ISR((struct st_device *)run_task->syscall.param);
238  break;
239 
240  case SYSCALL_SET_ERROR_OUT:
241  set_error_out_device_ISR((struct st_device *)run_task->syscall.param);
242  break;
243 
244  case SYSCALL_PRINT_TASK_LIST:
245  print_task();
246  break;
247 
248  case SYSCALL_PRINT_TASK_QUEUE:
249  task_print_task_queue();
250  break;
251 
252  case SYSCALL_PRINT_CALLTRACE:
253  print_calltrace();
254  break;
255 
256  case SYSCALL_GET_TASKS_INFO:
257  {
258  struct st_task_info_param *param =
259  (struct st_task_info_param *)run_task->syscall.param;
260  param->ret = get_tasks_info(param->ti, param->count);
261  }
262  break;
263 
264  default:
265  SYSERR_PRINT("Undifined SYSCALL %d\n", run_task->syscall.type);
266  break;
267  }
268 
269  dispatch(run_task, run_task);
270 }
271 
272 int last_syscall_type = 0;
273 
274 void sys_call(int type, void *param)
275 {
276  DKFPRINTF(0x01, "type = %d param = %p\n", type, param);
277 
278 #if 0
279  if(syscall_cnt != 0) {
280  SYSERR_PRINT("!!! Have not executed syscall %d ?\n",
281  syscall_cnt);
282  }
283 #endif
284  syscall_cnt ++;
285 
286  if(run_task == &dummy_task) {
287  DKPRINTF(0x01, "Cannot exec syscall type=%d\n", type);
288  }
289 
290  run_task->syscall.type = type;
291  run_task->syscall.param = param;
292 
293  last_syscall_type = type;
294 
295 #ifndef LINT
296  syscall_trap();
297 #endif
298 }
void event_clear_ISR(void *sp, struct st_event *evtque)
イベントカウンタをクリアリセットする
Definition: task.c:838
int type
システムコールタイプ
Definition: tcb.h:60
void task_exec_ISR(task_func func, char *name, int priority, struct st_tcb *tcb, void *stack, int stack_size, char *arg)
タスクを実行する
Definition: task.c:515
void set_console_out_device_ISR(struct st_device *dev)
標準出力デバイスを設定する
Definition: console.c:307
void eventqueue_unregister_ISR(struct st_event *evtque)
イベントキューを登録解除する
Definition: event.c:58
タスク追加、起動用システムコールパラメータ
Definition: syscall_param.h:44
void set_error_out_device_ISR(struct st_device *dev)
エラー出力デバイスを設定する
Definition: console.c:322
int get_tasks_info(struct st_task_info *ti, int count)
タスク情報を取得する
Definition: task.c:175
カーネルタイマ
void eventqueue_register_ISR(struct st_event *evtque, const char *name, void *args, unsigned int arg_size, int arg_count)
イベントキューを登録する
Definition: event.c:36
void event_wakeup_ISR(void *sp, struct st_event *evtque, void *arg)
イベントキューにイベントを登録し、イベント待ちタスクを起動する
Definition: task.c:923
カーネル用機能限定printf
char name[TASK_NAME_LEN+1]
タスク名
Definition: tcb.h:39
システムコールパラメータ定義
Cortex-M4
MUTEX
Definition: mutex.h:13
void * sp
スタックポインタ
Definition: tcb.h:40
void * param
システムコール実行パラメータ
Definition: tcb.h:61
int event_check_ISR(void *sp, struct st_event *evtque)
イベントカウントを取得する
Definition: task.c:814
イベント
Definition: event.h:15
システムコール
デバッグ用システムコールトレース
void task_add_ISR(task_func func, char *name, int priority, struct st_tcb *tcb, void *stack, int stack_size, char *arg)
タスクを追加する
Definition: task.c:541
void task_wakeup_id_ISR(void *sp, int id)
idタスクを実行する
Definition: task.c:662
void set_console_in_device_ISR(struct st_device *dev)
標準入力デバイスを設定する
Definition: console.c:292
コンソールI/O
unsigned long long get_kernel_time(void)
カーネル時間を取得する
Definition: timer.c:192
タスク操作
デバイスドライバ構造体
Definition: device.h:25
カーネル、ドライバ(非タスク)デバッグ用マクロ
イベント用システムコールパラメータ
Definition: syscall_param.h:55
MUTEX用システムコールパラメータ
Definition: syscall_param.h:65
タスク情報取得用システムコールパラメータ
Definition: syscall_param.h:72
void mutex_register_ISR(struct st_mutex *mutex, const char *name)
MUTEXを登録する
Definition: mutex.c:37
int mutex_unregister_ISR(struct st_mutex *mutex)
MUTEXを登録解除する
Definition: mutex.c:56