35 #ifndef GSC_KERNEL_IDLE_TASK_STACK_SIZE 36 #define GSC_KERNEL_IDLE_TASK_STACK_SIZE (1024) // $gsc カーネルアイドルタスクのスタックサイズ 42 static int new_task_id;
43 static int enable_schedule;
44 static struct st_tcb *last_task;
46 static struct st_queue ready_queue_head[GSC_KERNEL_MAX_TASK_PRIORITY];
49 static struct st_tcb idle_tcb;
50 static unsigned int idle_stack[GSC_KERNEL_IDLE_TASK_STACK_SIZE/
sizeof(
unsigned int)];
55 static int idle_task(
char *arg)
57 DKFPRINTF(0x01,
"idle_task start\n");
79 run_task = &dummy_task;
81 init_queue(&task_list_head.
queue);
84 init_queue(&ready_queue_head[i]);
92 task_add_ISR(idle_task,
"IDLE", GSC_KERNEL_MAX_TASK_PRIORITY-1, &idle_tcb,
93 idle_stack, GSC_KERNEL_IDLE_TASK_STACK_SIZE, 0);
96 static void task_startup(
void)
108 static struct st_tcb * search_next_task(
void)
113 if(check_queue(&ready_queue_head[i])) {
114 DKPRINTF(2,
"Run task id = %d \"%s\"\n",
115 ((
struct st_tcb *)ready_queue_head[i].next)->
id,
116 ((
struct st_tcb *)ready_queue_head[i].next)->name);
117 return (
struct st_tcb *)(ready_queue_head[i].next);
121 DKFPRINTF(0x01,
"Cannot find exec task\n");
123 return (
struct st_tcb *)0;
126 static void print_queue(
struct st_queue *queue)
130 if(check_queue(queue) != 0) {
131 while(tmp->next != queue->next) {
133 ((
struct st_tcb *)tmp)->name);
140 static void print_tcb_queue(
struct tcb_queue *queue)
144 if(check_queue((
struct st_queue *)queue) != 0) {
145 while(tmp->next != ((
struct st_queue *)queue)->next) {
155 const char status_str[][8] = {
181 if(check_queue((
struct st_queue *)queue) != 0) {
182 while(tmp->next != ((
struct st_queue *)queue)->next) {
202 void print_task(
void)
208 tkprintf(
"PID Name Pri Status Entry PC Stack(size) SP SleepTime\n");
210 if(check_queue((
struct st_queue *)queue) != 0) {
211 while(tmp->next != ((
struct st_queue *)queue)->next) {
212 tkprintf(
"%3d %10s %3d %6s %P %08X %P(%04X) %P %9d\n",
215 ((
struct tcb_queue *)tmp)->tcb->priority,
216 status_str[((
struct tcb_queue *)tmp)->tcb->status],
217 (((
struct tcb_queue *)tmp)->tcb->main_func),
218 #ifndef GSC_TARGET_SYSTEM_EMU
224 (
unsigned int)(((
struct tcb_queue *)tmp)->tcb->stack_size),
226 (((
struct tcb_queue *)tmp)->tcb->wup_time == 0) ?
227 0 : (
unsigned int)(((
struct tcb_queue *)tmp)->tcb->wup_time - systime)
234 void print_queues(
void)
238 tkprintf(
"======== Task Queue ========\n");
241 print_tcb_queue(&task_list_head);
248 print_queue(&ready_queue_head[i]);
254 if(check_queue(&event_queue_list.
list) != 0) {
257 while(tmp->
list.next != event_queue_list.
list.next) {
284 tkprintf(
"===============================\n");
287 static void print_task_stack(
struct st_tcb *tcb)
292 void print_stack(
void)
294 tkprintf(
"Stack dump(PID=%d \"%s\")\n", run_task->
id, run_task->
name);
296 print_task_stack(run_task);
299 static void dispatch_task(
struct st_tcb *task,
int status)
301 struct st_tcb *otcb = run_task;
304 if(task == 0)
return;
306 #ifdef GSC_TARGET_SYSTEM_EMU 307 record_calltrace(SYSCALL_DISPATCH, run_task->
status, task, status, 0, 0);
309 record_calltrace(SYSCALL_DISPATCH, run_task->
status, task, status, 0, task->
sp);
327 last_task = run_task;
331 #ifndef GSC_TARGET_SYSTEM_EMU 333 tkprintf(
"PID %d \"%s\" Stack OVER %p(%ld)\n",
338 disp_regs(run_task->
sp);
342 dispatch(otcb, task);
347 static void wakeup_task(
struct st_tcb *tcb)
349 DKFPRINTF(0x01,
"Wakeup PID = %d \"%s\"\n", tcb->
id, tcb->
name);
353 DKPRINTF(0x02,
"%s SLEEP PID = %d \"%s\"\n", __FUNCTION__,
354 run_task->
id, run_task->
name);
356 disp_regs(run_task->
sp);
358 DKPRINTF(0x02,
"%s WAKEUP PID = %d \"%s\"\n", __FUNCTION__,
366 static void task_add_queue(
struct st_tcb *tcb)
368 DKFPRINTF(0x01,
"Add PID = %d \"%s\"\n", tcb->
id, tcb->
name);
373 #ifdef GSC_TARGET_SYSTEM_EMU 374 extern volatile int flg_interrput_proc;
382 void task_schedule(
void *sp,
unsigned long long systime)
386 DKFPRINTF(3,
"SYSTIME = %lu\n", systime);
388 if(enable_schedule == 0) {
397 if(run_task == &dummy_task) {
404 task = sleepqueue_schedule(systime);
416 SYSERR_PRINT(
"Invalid timeout status(%d)", task->
status);
420 record_calltrace(SYSCALL_TIMEOUT_WAKEUP, task->
status, 0, 0, 0, sp);
421 #ifdef GSC_TARGET_SYSTEM_EMU 422 flg_interrput_proc = 0;
427 #ifdef GSC_TARGET_SYSTEM_EMU 428 flg_interrput_proc = 0;
449 DKFPRINTF(0x01,
"%s", name);
453 SYSERR_PRINT(
"Cannot init tcb %p\n", tcb);
468 task->
sp = (
void *)(stack + stack_size);
476 task->
id = new_task_id;
488 setup_task(stack, stack_size, task_startup, task);
492 DKPRINTF(0x01,
"name(id) \"%s\" (%d)\n", task->
name, task->
id);
493 DKPRINTF(0x01,
"sp = %p\n", task->
sp);
494 DKPRINTF(0x01,
"start = %p\n", task->
main_func);
495 DKPRINTF(0x01,
"id = %d\n", task->
id);
496 DKPRINTF(0x01,
"priority = %d\n", task->
priority);
516 void *stack,
int stack_size,
char *arg)
520 task = task_init(func, name, priority, tcb, stack, stack_size, arg);
542 void *stack,
int stack_size,
char *arg)
546 task = task_init(func, name, priority, tcb, stack, stack_size, arg);
549 task_add_queue(task);
561 void task_exit_ISR(
void *sp)
563 DKFPRINTF(0x01,
"Exit PID = %d \"%s\"\n", run_task->
id,
568 (void)del_next_queue(&ready_queue_head[run_task->
priority]);
578 if(check_queue(queue) == 0) {
579 return (
struct st_tcb *)0;
582 while(tmp->next != queue->next) {
583 if(((
struct st_tcb *)tmp)->
id ==
id) {
584 return (
struct st_tcb *)tmp;
589 return (
struct st_tcb *)0;
592 static struct st_tcb *search_task_id(
int id)
599 tmp = search_id(&ready_queue_head[i],
id);
616 tq = event_queue_list.
list.next;
618 while(tq->next != event_queue_list.
list.next) {
619 tmp = search_id(&((
struct st_event *)tq)->proc_head,
id);
626 return (
struct st_tcb *)0;
637 void task_kill_id_ISR(
void *sp,
int id)
641 task = search_task_id(
id);
645 DKFPRINTF(0x01,
"Kill PID = %d \"%s\"\n", task->id,
649 DKFPRINTF(0x01,
"No task id %d\n",
id);
671 DKFPRINTF(0x01,
"Wakeup PID = %d \"%s\"\n", task->id,
675 DKFPRINTF(0x01,
"No task id %d\n",
id);
687 void task_pause_ISR(
void *sp)
689 DKFPRINTF(0x01,
"Pause PID = %d \"%s\"\n", run_task->
id,
692 record_calltrace(SYSCALL_TASK_PAUSE, run_task->
status,
697 (void)del_next_queue(&ready_queue_head[run_task->
priority]);
699 waitqueue_add(run_task);
713 void task_sleep_ISR(
void *sp,
unsigned int sleep_time)
717 DKFPRINTF(0x01,
"Sleep PID = %d \"%s\" time = %ld\n",
718 run_task->
id, run_task->
name, sleep_time);
722 record_calltrace(SYSCALL_TASK_SLEEP, run_task->
status,
723 0, (
int)sleep_time, 0, sp);
725 (void)del_next_queue(&ready_queue_head[run_task->
priority]);
727 sleepqueue_add(run_task, sleep_time, systime);
742 void event_wait_ISR(
void *sp,
struct st_event *evtque,
void *arg,
unsigned int timeout)
747 DKFPRINTF(0x01,
"evtque = \"%s\" %p\n",
748 evtque->
name, evtque);
749 DKPRINTF(0x01,
"PID = %d \"%s\" arg = %p, timeout = %ld\n",
750 run_task->
id, run_task->
name, arg, timeout);
751 DKPRINTF(0x01,
"evtque->size = %d\n", evtque->
size);
755 if(run_task == &dummy_task) {
756 #ifndef GSC_TARGET_SYSTEM_EMU 757 SYSERR_PRINT(
"No running task\n");
764 record_calltrace(SYSCALL_EVTQUE_WAIT, run_task->
status,
765 (
void *)evtque, (
int)timeout,
fifo_size(&evtque->event), sp);
768 rtn =
read_fifo(&evtque->event, arg, evtque->size);
770 rtn =
drop_fifo(&evtque->event, evtque->size);
780 (void)del_next_queue(&ready_queue_head[run_task->
priority]);
789 sleepqueue_add(run_task, timeout, systime);
792 next_task = search_next_task();
793 DKPRINTF(0x02,
"%s WAIT_EVENT PID = %d \"%s\"\n", __FUNCTION__,
794 run_task->
id, run_task->
name);
796 disp_regs(run_task->
sp);
798 DKPRINTF(0x02,
"%s WAKEUP PID = %d \"%s\"\n", __FUNCTION__,
799 next_task->
id, next_task->
name);
801 disp_regs(next_task->
sp);
818 DKFPRINTF(0x01,
"evtque = \"%s\" %p\n", evtque->
name, evtque);
824 DKFPRINTF(0x01,
"count = %d\n", count);
840 DKFPRINTF(0x01,
"evtque = \"%s\" %p\n", evtque->
name, evtque);
842 record_calltrace(SYSCALL_EVTQUE_CLEAR, run_task->
status, evtque, 0,
fifo_size(&evtque->
event), sp);
859 DKFPRINTF(0x01,
"evtque = \"%s\" %p\n", evtque->
name, evtque);
861 record_calltrace(SYSCALL_EVTQUE_PUSH, run_task->
status, evtque, 0,
fifo_size(&evtque->
event), sp);
865 DKFPRINTF(0x01,
"event fifo full\n");
883 DKFPRINTF(0x01,
"%s evtque = \"%s\" %p\n", evtque->
name, evtque);
892 DKFPRINTF(0x01,
"WAKEUP PID = %d \"%s\"\n", task->
id, task->
name);
906 record_calltrace(SYSCALL_EVTQUE_WAKEUP, task->
status, evtque, 0,
fifo_size(&evtque->
event), sp);
909 record_calltrace(SYSCALL_EVTQUE_WAKEUP, 0, evtque, 0,
fifo_size(&evtque->
event), sp);
927 DKFPRINTF(0x01,
"%s evtque = \"%s\" %p, arg = %p\n", evtque->
name, evtque, arg);
928 DKPRINTF(0x01,
"PID = %d \"%s\"\n", run_task->
id, run_task->
name);
929 DKPRINTF(0x01,
"evtque->size = %d\n", evtque->
size);
931 #ifdef GSC_TARGET_SYSTEM_EMU 932 if(is_in_interrupt()) {
933 SYSERR_PRINT(
"EMU in SIGARM?\n");
944 DKFPRINTF(0x01,
"WAKEUP PID = %d \"%s\"\n", task->
id, task->
name);
949 unsigned char *asp, *adp;
952 for(i=0; i<evtque->
size; i++) {
971 record_calltrace(SYSCALL_EVTQUE_WAKEUP, task->
status, evtque, 0,
fifo_size(&evtque->
event), sp);
976 DKFPRINTF(0x01,
"event fifo full\n");
978 record_calltrace(SYSCALL_EVTQUE_WAKEUP, 0, evtque, 0,
fifo_size(&evtque->
event), sp);
993 void mutex_lock_ISR(
void *sp,
struct st_mutex *mutex,
unsigned int timeout)
997 DKFPRINTF(0x01,
"%s mutex = \"%s\" %p\n", mutex->
name, mutex);
999 if(run_task == &dummy_task) {
1000 #ifndef GSC_TARGET_SYSTEM_EMU 1001 SYSERR_PRINT(
"No running task\n");
1008 record_calltrace(SYSCALL_MUTEX_LOCK, run_task->
status,
1009 (
void *)mutex, (
int)timeout, 0, sp);
1011 rtn = _mutex_lock(mutex, run_task);
1017 (void)del_next_queue(&ready_queue_head[run_task->
priority]);
1019 DKPRINTF(0x01,
"mutex locked wait %s\n", run_task->
name);
1020 _mutex_wait(mutex, run_task);
1029 sleepqueue_add(run_task, timeout, systime);
1034 }
else if(rtn < 0) {
1041 DKPRINTF(0x01,
"mutex lock ok %s\n", run_task->
name);
1055 void mutex_unlock_ISR(
void *sp,
struct st_mutex *mutex)
1058 unsigned int systime;
1060 DKFPRINTF(0x01,
"%s mutex = \"%s\" %p\n", mutex->
name, mutex);
1064 if(run_task == &dummy_task) {
1065 #ifndef GSC_TARGET_SYSTEM_EMU 1066 SYSERR_PRINT(
"No running task\n");
1072 record_calltrace(SYSCALL_MUTEX_UNLOCK, run_task->
status,
1073 (
void *)mutex, 0, 0, sp);
1076 task = _mutex_unlock(mutex, run_task);
1091 DKPRINTF(0x01,
"mutex unlock wakeup %s\n", task->
name);
1103 void task_print_task_queue(
void)
1109 void disp_task_info(
void)
1114 tkprintf(
"LAST PID = %d \"%s\"\n", last_task->
id, last_task->
name);
1115 tkprintf(
"LAST SYSCALL = %s(%d)\n",
1116 syscall_name[last_syscall_type],
unsigned char uchar
GadgetSeedの文字(列)は unsigned char 型となる
struct st_device * con_err_dev
デフォルトエラー出力デバイス
int drop_fifo(struct st_fifo *fp, unsigned int length)
fifoからデータを捨てる
struct st_device * con_in_dev
デフォルト標準入力デバイス
#define PSTAT_MUTEX_WAIT
タスク MUTEXロック解除待ち状態
unsigned int run_time
タスク実行時間(msec)
int read_fifo(struct st_fifo *fp, unsigned char *data, unsigned int length)
fifoからデータを読み出す
struct st_tcb * _eventqueue_wakeup(struct st_event *evtque)
イベント待ちタスクを返す
struct st_fifo event
イベントデータバッファ
int get_tasks_info(struct st_task_info *ti, int count)
タスク情報を取得する
struct tcb_queue timer_list
タイムアウト待ちキュー
#define TASK_NAME_LEN
最大タスク名長
unsigned long long get_system_utime(void)
システム時間を取得する
struct st_queue list
MUTEXのキュー
struct st_tcb * tcb
タスクコンテキストブロックポインタ
struct st_device * stdin_dev
タスク標準入力デバイス
#define init_calltrace(...)
< $gsc カーネルシステムコールトレースを有効にする
#define PSTAT_READY
タスク 実行可能状態
int tkprintf(const char *fmt,...)
非タスクコンテキスト実行用メッセージ出力
struct st_device * stdout_dev
タスク標準出力デバイス
#define PSTAT_REQUEST_WAIT
タスク 起床待ち状態
void _eventqueue_wait(struct st_event *evtque, struct st_tcb *tcb)
タスクをイベント待ちキューに登録する
unsigned int fifo_size(struct st_fifo *fp)
fifoに書き込まれているデータのサイズを返す
unsigned int meas_time
タスク実行時間計測開始システム時間(msec)
int(* task_func)(char *arg)
タスク関数
void task_exit(void)
タスクを終了する
void event_push_ISR(void *sp, struct st_event *evtque, void *arg)
イベントFIFOにイベントを登録する
char name[TASK_NAME_LEN+1]
タスク名
int write_fifo(struct st_fifo *fp, unsigned char *data, unsigned int length)
fifoにデータを書き込む
unsigned long long kernel_time_count
カーネル時間(ms)
struct st_queue proc_head
イベント待ちタスクキュー
void clear_fifo(struct st_fifo *fp)
fifoに書き込まれているデータを全て消去する
void task_add_ISR(task_func func, char *name, int priority, struct st_tcb *tcb, void *stack, int stack_size, char *arg)
タスクを追加する
void kxdump(unsigned char *data, unsigned int len)
非タスクコンテキスト実行用メモリダンプメッセージ出力
void * param
システムコール実行パラメータ
void task_wakeup_id_ISR(void *sp, int id)
idタスクを実行する
unsigned int wup_time
スリープタイムアウト時間
struct tcb_queue task_list
全タスクキュー
#define PSTAT_TIMER_WAIT
タスク タイマ待ち状態
struct st_queue list
イベントキューのキュー
struct st_mutex mutex_queue_list
MUTEXキュー
void event_set_ISR(void *sp, struct st_event *evtque)
イベント待ちタスクを起動する
struct st_tcb * lock_ps
ロックしているタスク
unsigned int stack_size
スタックサイズ
struct st_queue wait_queue_head
待ちタスクキュー
void task_exec_ISR(task_func func, char *name, int priority, struct st_tcb *tcb, void *stack, int stack_size, char *arg)
タスクを実行する
struct st_device * con_out_dev
デフォルト標準出力デバイス
struct st_queue wait_ps
アンロック待ちタスクキュー
const char * name
イベント名文字列
struct st_device * error_dev
タスクエラー出力デバイス
uchar * strncopy(uchar *dest, const uchar *src, unsigned int n)
文字列コピー
#define GSC_KERNEL_MAX_TASK_PRIORITY
$gsc カーネルタスクプライオリティ段階数
unsigned long long get_kernel_time(void)
カーネル時間を取得する
#define PSTAT_EVENT_WAIT
タスク イベント待ち状態
#define PSTAT_DORMANT
タスク 休止状態
struct tcb_queue timeout_wait_queue_head
タイムアウト待ちタスクキュー
void event_wakeup_ISR(void *sp, struct st_event *evtque, void *arg)
イベントキューにイベントを登録し、イベント待ちタスクを起動する
#define PSTAT_RUN
タスク 実行状態
char name[TASK_NAME_LEN+1]
タスク名文字列
void event_clear_ISR(void *sp, struct st_event *evtque)
イベントカウンタをクリアリセットする
struct tcb_queue queue
タスクキュー(st_tcb をst_queueにキャストするために必ず最初に定義する)
unsigned int size
1イベントのサイズ
int event_check_ISR(void *sp, struct st_event *evtque)
イベントカウントを取得する
void * stack_addr
スタック先頭アドレス
unsigned int run_time
タスク実行時間
const char * name
MUTEX名文字列