• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

uITRON3のシステムコールをシュミレーションする、uITRON3向けモジュールの単体テスト用ライブラリ。


Commit MetaInfo

Revision2c0ddf8d753e97d2fde5def6ebc1e5c092b98b06 (tree)
Time2013-03-31 09:25:17
Authornikarana <nikarana@gmai...>
Commiternikarana

Log Message

add c files.

Change Summary

Incremental Difference

--- /dev/null
+++ b/src/alm.c
@@ -0,0 +1,225 @@
1+/**
2+ * @file alm.c
3+ * @brief 時間管理機能(アラーム)
4+ *
5+ * @author nikarana
6+ * @date 2012/11/23
7+ *
8+ */
9+
10+#include "alm.h"
11+#include "it3_common.h"
12+#include "it3_config.h"
13+#include <depend.h>
14+
15+#define ISVALID_ALMNO(almno) ((0 < (almno)) && ((almno) < TNUM_ALM))
16+#define ISVALID_ALMATR(almatr) (TRUE) /* 属性情報はチェックしない */
17+
18+/* アラームハンドラ管理構造体 */
19+typedef struct S_ALMCB
20+{
21+ HNO almno; /**< アラームハンドラ番号 */
22+
23+ VP exinf; /**< 拡張情報 */
24+ ATR almatr; /**< アラームハンドラ属性 */
25+ FP almhdr; /**< アラームハンドラアドレス */
26+ UINT tmmode; /**< 起動時刻指定モード */
27+ ALMTIME almtim; /**< ハンドラ起動時刻 */
28+
29+ ALMTIME lfttim; /**< */
30+
31+ UW time; /**< ハンドラ起動時間 */
32+ FP hdr; /**< アラームハンドラ */
33+
34+} T_ALMCB;
35+
36+static const T_ALMCB almcb_initializer = {0};
37+
38+extern SYSTIME systime;
39+
40+static T_ALMCB almcbs[TNUM_ALM];
41+
42+/**
43+ * @brief 時間管理機能(アラーム)初期化処理
44+ *
45+ * @return エラーコード
46+ * @retval E_OK 正常終了
47+ */
48+ER alm_initialize(void)
49+{
50+ INT cnt;
51+
52+ for(cnt = 0;cnt < TNUM_ALM;cnt++)
53+ {
54+ almcbs[cnt] = almcb_initializer;
55+ }
56+
57+ return E_OK;
58+}
59+
60+/**
61+ * @brief 時間管理機能(アラーム)終了処理
62+ */
63+void alm_terminate(void)
64+{
65+}
66+
67+/**
68+ * @brief 時間管理機能(アラーム)初期化処理
69+ *
70+ * @param steptime 経過時間(ms)
71+ */
72+void alm_timeevent(UW steptime)
73+{
74+ INT cnt;
75+ T_ALMCB *p_almcb;
76+
77+ for(cnt = 0;cnt < TNUM_ALM;cnt++)
78+ {
79+ p_almcb = &(almcbs[cnt]);
80+
81+ depend_EnterCriticalSection();
82+
83+ if(ISVALID_PTR(p_almcb->almhdr))
84+ {
85+ if(steptime < p_almcb->time)
86+ {
87+ p_almcb->time -= steptime;
88+ }
89+ else
90+ {
91+ (p_almcb->almhdr)();
92+
93+ *p_almcb = almcb_initializer;
94+ }
95+ }
96+
97+ depend_LeaveCriticalSection();
98+ }
99+}
100+
101+/**
102+ * @brief アラームハンドラ定義
103+ *
104+ * @param almno アラームハンドラ指定番号
105+ * @param pk_dalm アラームハンドラ定義情報
106+ * @return エラーコード
107+ * @retval E_OK 正常終了
108+ * @retval E_NOMEM メモリ不足(管理ブロック用の領域が確保できない)
109+ * @retval E_RSATR 予約属性(almatrが不正あるいは利用できない)
110+ * @retval E_PAR パラメータエラー(almno, pk_dalm, almhdr, tmmode, almtimが不正あるいは利用できない)
111+ */
112+ER def_alm(HNO almno, T_DALM *pk_dalm)
113+{
114+ ER result;
115+
116+ if(ISVALID_ALMNO(almno))
117+ {
118+ T_ALMCB *p_almcb;
119+
120+ p_almcb = &(almcbs[almno]);
121+
122+ depend_EnterCriticalSection();
123+
124+ if(ISVALID_PTR(pk_dalm))
125+ {
126+ if(ISVALID_ALMATR(pk_dalm->almatr))
127+ {
128+ if((TTM_ABS == pk_dalm->tmmode) || (TTM_REL == pk_dalm->tmmode))
129+ {
130+ if(! ((TTM_REL == pk_dalm->tmmode) && (pk_dalm->almtim.ltime < 0)))
131+ {
132+ *p_almcb = almcb_initializer;
133+
134+ p_almcb->almno = almno;
135+
136+ p_almcb->exinf = pk_dalm->exinf;
137+ p_almcb->almatr = pk_dalm->almatr;
138+ p_almcb->almhdr = pk_dalm->almhdr;
139+ p_almcb->tmmode = pk_dalm->tmmode;
140+ p_almcb->almtim = pk_dalm->almtim;
141+
142+ p_almcb->hdr = pk_dalm->almhdr;
143+ p_almcb->time = pk_dalm->almtim.ltime;
144+ if(TTM_ABS == pk_dalm->tmmode)
145+ {
146+ p_almcb->time += systime.ltime;
147+ }
148+
149+ result = E_OK;;
150+ }
151+ else
152+ {
153+ result = E_PAR;
154+ }
155+ }
156+ else
157+ {
158+ result = E_PAR;
159+ }
160+ }
161+ else
162+ {
163+ result = E_RSATR;
164+ }
165+ }
166+ else
167+ {
168+ *p_almcb = almcb_initializer;
169+
170+ result = E_OK;;
171+ }
172+
173+ depend_LeaveCriticalSection();
174+ }
175+ else
176+ {
177+ result = E_PAR;
178+ }
179+
180+ return result;
181+}
182+
183+/**
184+ * @brief アラームハンドラ状態参照
185+ *
186+ * @param pk_ralm アラームハンドラの状態を返すパケットの先頭アドレス
187+ * @param almno アラームハンドラ指定番号
188+ * @return エラーコード
189+ * @retval E_OK 正常終了
190+ * @retval E_NOEXS オブジェクトが存在していない(almnoのアラームハンドラが定義されていない)
191+ * @retval E_PAR パラメータエラー(almnoが利用できない, リターンパラメータ用のパケットアドレスが使用できない値)
192+ */
193+ER ref_alm(T_RALM *pk_ralm, HNO almno)
194+{
195+ ER result;
196+
197+ if(ISVALID_ALMNO(almno) && ISVALID_PTR(pk_ralm))
198+ {
199+ T_ALMCB *p_almcb;
200+
201+ p_almcb = &(almcbs[almno]);
202+
203+ depend_EnterCriticalSection();
204+
205+ if(0 != p_almcb->almno)
206+ {
207+ pk_ralm->exinf = p_almcb->exinf;
208+ pk_ralm->lfttim = p_almcb->lfttim; // TODO どうしよっかなー
209+
210+ result = E_OK;
211+ }
212+ else
213+ {
214+ result = E_NOEXS;
215+ }
216+
217+ depend_LeaveCriticalSection();
218+ }
219+ else
220+ {
221+ result = E_PAR;
222+ }
223+
224+ return result;
225+}
--- /dev/null
+++ b/src/alm.h
@@ -0,0 +1,18 @@
1+#ifndef _ALM_H_
2+#define _ALM_H_
3+
4+#if defined(__cplusplus)
5+extern "C" {
6+#endif /* defined(__cplusplus) */
7+
8+#include <itron.h>
9+
10+ER alm_initialize(void);
11+void alm_terminate(void);
12+void alm_timeevent(UW steptime);
13+
14+#if defined(__cplusplus)
15+}
16+#endif /* defined(__cplusplus) */
17+
18+#endif /* _ALM_H_ */
--- /dev/null
+++ b/src/cyc.c
@@ -0,0 +1,255 @@
1+/**
2+ * @file cyc.c
3+ * @brief 時間管理機能(周期起動)
4+ *
5+ * @author nikarana
6+ * @date 2012/11/23
7+ *
8+ */
9+
10+#include "cyc.h"
11+#include "it3_common.h"
12+#include "it3_config.h"
13+#include <depend.h>
14+
15+#define ISVALID_CYCNO(cycno) ((0 < (cycno)) && ((cycno) < TNUM_CYC))
16+#define ISVALID_CYCACT(cycact) (0 == ((cycact) & ~(TCY_INI | TCY_ON)))
17+
18+typedef struct S_CYCCB
19+{
20+ HNO cycno; /**< 周期起動ハンドラ番号 */
21+
22+ VP exinf; /**< 拡張情報 */
23+ ATR cycatr; /**< 周期起動ハンドラ属性 */
24+ FP cychdr; /**< 周期起動ハンドラアドレス */
25+ UINT cycact; /**< 周期起動ハンドラ活性状態 */
26+ CYCTIME cyctim; /**< 周期起動時間間隔 */
27+
28+ UINT lftime; /**< 次のハンドラ起動までの残り時間 */
29+ UINT cytime; /**< 周期起動時間間隔 */
30+} T_CYCCB;
31+
32+static const T_CYCCB cyccb_initializer = {0};
33+
34+static T_CYCCB cyccbs[TNUM_CYC];
35+
36+/**
37+ * @brief 時間管理機能(周期起動)初期化処理
38+ *
39+ * @return エラーコード
40+ * @retval E_OK 正常終了
41+ * @retval E_OK以外 異常終了
42+ */
43+ER cyc_initialize(void)
44+{
45+ INT cnt;
46+
47+ for(cnt = 0;cnt < TNUM_CYC;cnt++)
48+ {
49+ cyccbs[cnt] = cyccb_initializer;
50+ }
51+
52+ return E_OK;
53+}
54+
55+/**
56+ * @brief 時間管理機能(周期起動)終了処理
57+ */
58+void cyc_terminate(void)
59+{
60+}
61+
62+/**
63+ * @brief 周期起動タイマイベント
64+ *
65+ * @param steptime 経過時間(ms)
66+ */
67+void cyc_timeevent(UINT steptime)
68+{
69+ INT cnt;
70+ T_CYCCB *p_cyccb;
71+
72+ for(cnt = 0;cnt < TNUM_CYC;cnt++)
73+ {
74+ p_cyccb = &(cyccbs[cnt]);
75+
76+ depend_EnterCriticalSection();
77+
78+ if(0 != p_cyccb->cycno)
79+ {
80+ if(steptime < p_cyccb->lftime)
81+ {
82+ p_cyccb->lftime -= steptime;
83+ }
84+ else
85+ {
86+ p_cyccb->lftime = p_cyccb->cytime; /* 残り時間リセット */
87+
88+ if(TCY_OFF != p_cyccb->cycact)
89+ {
90+ (p_cyccb->cychdr)();
91+ }
92+ }
93+ }
94+
95+ depend_LeaveCriticalSection();
96+ }
97+}
98+
99+/**
100+ * @brief 周期起動ハンドラ定義
101+ *
102+ * @param cycno 周期起動ハンドラ指定番号
103+ * @param pk_dcyc 周期起動ハンドラ定義情報
104+ * @return エラーコード
105+ * @retval E_OK 正常終了
106+ * @retval E_NOMEM メモリ不足(管理ブロック用の領域が確保できない)
107+ * @retval E_RSATR 予約属性(cycatrが不正あるいは利用できない)
108+ * @retval E_PAR パラメータエラー(cycno, pk_dcyc, cychdr, cycact, cyctimが不正あるいは利用できない)
109+ */
110+ER def_cyc(HNO cycno, T_DCYC *pk_dcyc)
111+{
112+ ER result;
113+
114+ if(ISVALID_CYCNO(cycno))
115+ {
116+ T_CYCCB *p_cyccb;
117+
118+ p_cyccb = &(cyccbs[cycno]);
119+
120+ depend_EnterCriticalSection();
121+
122+ if(ISVALID_PTR(pk_dcyc))
123+ {
124+ *p_cyccb = cyccb_initializer;
125+
126+ p_cyccb->cycno = cycno;
127+
128+ p_cyccb->exinf = pk_dcyc->exinf;
129+ p_cyccb->cycatr = pk_dcyc->cycatr;
130+ p_cyccb->cychdr = pk_dcyc->cychdr;
131+ p_cyccb->cycact = pk_dcyc->cycact;
132+ p_cyccb->cyctim = pk_dcyc->cyctim;
133+
134+ p_cyccb->lftime = pk_dcyc->cyctim.ltime;
135+ p_cyccb->cytime = pk_dcyc->cyctim.ltime;
136+
137+ result = E_OK;
138+
139+ }
140+ else
141+ {
142+ *p_cyccb = cyccb_initializer;
143+
144+ result = E_OK;
145+ }
146+
147+ depend_LeaveCriticalSection();
148+ }
149+ else
150+ {
151+ result = E_PAR;
152+ }
153+
154+ return result;
155+}
156+
157+/**
158+ * @brief 周期起動ハンドラ活性制御
159+ *
160+ * @param cycno 周期起動ハンドラ指定番号
161+ * @param cyhact 周期起動ハンドラ活性状態
162+ * @return エラーコード
163+ * @retval E_OK 正常終了
164+ * @retval E_NOEXS オブジェクトが存在していない(cycnoの周期起動ハンドラが定義されていない)
165+ * @retval E_PAR パラメータエラー(cycnoが利用できない, cycactが不正)
166+ */
167+ER act_cyc(HNO cycno, UINT cyhact)
168+{
169+ ER result;
170+
171+ if(ISVALID_CYCNO(cycno))
172+ {
173+ if(ISVALID_CYCACT(cyhact))
174+ {
175+ T_CYCCB *p_cyccb;
176+
177+ p_cyccb = &(cyccbs[cycno]);
178+
179+ depend_EnterCriticalSection();
180+
181+ if(0 != p_cyccb->cycno)
182+ {
183+ p_cyccb->cycact = cyhact;
184+
185+ if(cyhact & TCY_INI) /* 初期化指定あり? */
186+ {
187+ p_cyccb->lftime = p_cyccb->cytime;
188+ }
189+
190+ result = E_OK;
191+ }
192+ else
193+ {
194+ result = E_NOEXS;
195+ }
196+
197+ depend_LeaveCriticalSection();
198+ }
199+ else
200+ {
201+ result = E_PAR;
202+ }
203+ }
204+ else
205+ {
206+ result = E_PAR;
207+ }
208+
209+ return result;
210+}
211+
212+/**
213+ * @brief 周期起動ハンドラ状態参照
214+ *
215+ * @param pk_rcyc 周期起動ハンドラの状態を返すパケットの先頭アドレス
216+ * @param cycno 周期起動ハンドラ指定番号
217+ * @return エラーコード
218+ * @retval E_OK 正常終了
219+ * @retval E_NOEXS オブジェクトが存在していない(cycnoの周期起動ハンドラが定義されていない)
220+ * @retval E_PAR パラメータエラー(cycnoが利用できない, リターンパラメータ用のパケットアドレスが使用できない値)
221+ */
222+ER ref_cyc(T_RCYC *pk_rcyc, HNO cycno)
223+{
224+ ER result;
225+
226+ if(ISVALID_CYCNO(cycno) && ISVALID_PTR(pk_rcyc))
227+ {
228+ T_CYCCB *p_cyccb;
229+
230+ p_cyccb = &(cyccbs[cycno]);
231+
232+ depend_EnterCriticalSection();
233+
234+ if(0 != p_cyccb->cycno)
235+ {
236+ pk_rcyc->exinf = p_cyccb->exinf;
237+ pk_rcyc->lfttim.ltime = p_cyccb->lftime;
238+ pk_rcyc->cycact = p_cyccb->cycact;
239+
240+ result = E_OK;
241+ }
242+ else
243+ {
244+ result = E_NOEXS;
245+ }
246+
247+ depend_LeaveCriticalSection();
248+ }
249+ else
250+ {
251+ result = E_PAR;
252+ }
253+
254+ return result;
255+}
--- /dev/null
+++ b/src/cyc.h
@@ -0,0 +1,18 @@
1+#ifndef _CYC_H_
2+#define _CYC_H_
3+
4+#if defined(__cplusplus)
5+extern "C" {
6+#endif /* defined(__cplusplus) */
7+
8+#include <itron.h>
9+
10+ER cyc_initialize(void);
11+void cyc_terminate(void);
12+void cyc_timeevent(UINT steptime);
13+
14+#if defined(__cplusplus)
15+}
16+#endif /* defined(__cplusplus) */
17+
18+#endif /* _CYC_H_ */
--- /dev/null
+++ b/src/depend/depend.h
@@ -0,0 +1,8 @@
1+#ifndef _DEPEND_H_
2+#define _DEPEND_H_
3+
4+#ifdef WIN32
5+#include "depend/win32/depend_win32.h"
6+#endif /* WIN32 */
7+
8+#endif /* _DEPEND_H_ */
--- /dev/null
+++ b/src/depend/win32/depend_win32.c
@@ -0,0 +1,523 @@
1+#define _WIN32_WINNT 0x0500
2+
3+#include <windows.h>
4+#include <limits.h>
5+#include <stdio.h>
6+#include <stdarg.h>
7+
8+#include <mmsystem.h>
9+#pragma comment(lib, "winmm.lib")
10+
11+#include "depend.h"
12+#include <it3_debug.h>
13+
14+#define ISVALID_TSKID(tskid) ((0 < (tskid)) && ((tskid) < DEPEND_TNUM_TSK))
15+#define ISVALID_TIMID(timid) ((0 < (timid)) && ((timid) < DEPEND_TNUM_TIM))
16+
17+/*
18+===============================================================================
19+ 環境依存処理のための独自の型定義
20+===============================================================================
21+*/
22+/* 環境依存処理 独自タスクのTCB */
23+typedef struct S_DEPEND_TCB
24+{
25+ int tskid;
26+
27+ LPVOID p_fiber; /* ファイバーアドレス */
28+
29+ void (*p_func)(void *); /* 仮想タスクの開始アドレス */
30+ void *p_param; /* 仮想タスクに関連付けられたデータ
31+ 下記で取得できる
32+ ・仮想タスクの引数
33+ ・depend_get_param()
34+ */
35+} T_DEPEND_TCB;
36+
37+typedef struct S_DEPEND_TIMCB
38+{
39+ int timid;
40+
41+ void (*p_func)(void *);
42+ void *p_param;
43+} T_DEPEND_TIMCB;
44+
45+static const T_DEPEND_TCB dep_tcb_initializer = {0};
46+
47+static const T_DEPEND_TIMCB dep_tim_initializer = {0};
48+
49+
50+/*
51+===============================================================================
52+ 環境依存処理のためのグローバル変数
53+===============================================================================
54+*/
55+static DWORD tickcount = 0;
56+
57+/* 仮想タスクのための情報 */
58+static T_DEPEND_TCB dep_tcbs[DEPEND_TNUM_TSK];
59+
60+static CRITICAL_SECTION cs;
61+
62+static HANDLE dep_timer_handle;
63+static T_DEPEND_TIMCB dep_timcbs[DEPEND_TNUM_TIM];
64+
65+
66+/*
67+ 環境依存部分
68+ 仮想タスク … ファイバー
69+ 仮想タスクID … スレッドID
70+
71+ */
72+
73+static void ShowErrorMessage(void)
74+{
75+ LPVOID lpMsgBuf;
76+
77+ FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER |
78+ FORMAT_MESSAGE_FROM_SYSTEM |
79+ FORMAT_MESSAGE_IGNORE_INSERTS,
80+ NULL,
81+ GetLastError(),
82+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // 既定の言語
83+ (LPTSTR) &lpMsgBuf,
84+ 0,
85+ NULL
86+ );
87+
88+ // 文字列を表示する。
89+ IT3_LOG1("%s", lpMsgBuf);
90+
91+ // バッファを解放する。
92+ LocalFree(lpMsgBuf);
93+
94+}
95+
96+/* 環境依存部分 タスク機能初期化 */
97+static int depend_tsk_initialize(void)
98+{
99+ int result;
100+ int cnt;
101+ T_DEPEND_TCB *p_dep_tcb;
102+ LPVOID p_fiber;
103+
104+ /* 仮想タスクのTCBを初期化 */
105+ for(cnt = 0;cnt < DEPEND_TNUM_TSK;cnt++)
106+ {
107+ dep_tcbs[cnt] = dep_tcb_initializer;
108+ }
109+
110+ /* ============================
111+ * スレッドをファイバーに変換
112+ * ============================ */
113+ /* カーネルの環境依存TCBを取得 */
114+ p_dep_tcb = &(dep_tcbs[0]);
115+
116+ /* この処理を動かしたスレッドをuITRONのカーネル用ファイバとする */
117+ p_fiber = ConvertThreadToFiber(p_dep_tcb);
118+ if(p_fiber)
119+ {
120+ p_dep_tcb->p_fiber = p_fiber;
121+
122+ result = 0;
123+ }
124+ else
125+ {
126+ result = (-1);
127+ }
128+
129+ return result;
130+}
131+
132+static void depend_tsk_terminate(void)
133+{
134+ int cnt;
135+ T_DEPEND_TCB *p_dep_tcb;
136+ BOOL ret;
137+
138+ for(cnt = 1;cnt < DEPEND_TNUM_TSK;cnt++)
139+ {
140+ p_dep_tcb = &(dep_tcbs[cnt]);
141+
142+ if(0 != p_dep_tcb)
143+ {
144+ DeleteFiber(p_dep_tcb->p_fiber);
145+ *p_dep_tcb = dep_tcb_initializer;
146+ }
147+ }
148+
149+ /* カーネル用ファイバをスレッドに戻す */
150+ ret = ConvertFiberToThread();
151+ if(! ret)
152+ {
153+ ShowErrorMessage();
154+ }
155+ dep_tcbs[0] = dep_tcb_initializer;
156+}
157+
158+static int depend_tim_initialize(void)
159+{
160+ int result;
161+ HANDLE timer_handle;
162+
163+ timer_handle = CreateTimerQueue();
164+ if(NULL != timer_handle)
165+ {
166+ dep_timer_handle = timer_handle;
167+ result = 0;
168+ }
169+ else
170+ {
171+ ShowErrorMessage();
172+ result = (-1);
173+ }
174+
175+ return result;
176+}
177+
178+static void depend_tim_terminate(void)
179+{
180+ if(NULL != dep_timer_handle)
181+ {
182+ DeleteTimerQueueEx(dep_timer_handle, NULL);
183+ dep_timer_handle = NULL;
184+ }
185+}
186+
187+/* 環境依存部分の初期化 */
188+int depend_initialize(void)
189+{
190+ int result;
191+ int ret;
192+
193+ ret = depend_CreateCriticalSection();
194+ if(0 == ret)
195+ {
196+ /* 仮想タスク機能の初期化 */
197+ ret = depend_tsk_initialize();
198+ if(0 == ret)
199+ {
200+ ret = depend_tim_initialize();
201+ if(0 == ret)
202+ {
203+ /* 起動時刻を取得 */
204+ tickcount = GetTickCount();
205+
206+ result = 0;
207+ }
208+ else
209+ {
210+ depend_tsk_terminate();
211+ depend_DestoryCriticalSection();
212+ result = (-3);
213+ }
214+ }
215+ else
216+ {
217+ depend_DestoryCriticalSection();
218+ result = (-2);
219+ }
220+ }
221+ else
222+ {
223+ result = (-1);
224+ }
225+
226+ return result;
227+}
228+
229+/* 環境依存部分の終了 */
230+void depend_terminate(void)
231+{
232+ depend_tim_terminate();
233+ depend_tsk_terminate();
234+ depend_DestoryCriticalSection();
235+}
236+
237+/* 呼出している制御に関連付けられたデータを返す */
238+void * depend_GetParam(void)
239+{
240+ void *p_param = NULL;
241+
242+ __try
243+ {
244+ T_DEPEND_TCB *p_dep_tcb;
245+
246+ /*
247+ * この関数を動かしているファイバーに関連付けられたデータを取得する
248+ * この値は、depend_cre_tskのT_DEP_CRE_TSKp_dataCreateFiber,ConvertThreadToFiberで
249+ * 与えられた値である
250+ */
251+ p_dep_tcb = (T_DEPEND_TCB *)GetFiberData();
252+ if(p_dep_tcb)
253+ {
254+ p_param = p_dep_tcb->p_param;
255+ }
256+ }
257+ __finally
258+ {
259+ /* この関数を動かしているのは、ファイバーじゃない */
260+ }
261+
262+ return p_param;
263+}
264+
265+VOID CALLBACK FiberProc(PVOID lpParameter) // ファイバデータ
266+{
267+ T_DEPEND_TCB *p_dep_tcb = lpParameter;
268+
269+ (p_dep_tcb->p_func)(p_dep_tcb->p_param);
270+}
271+
272+/* 仮想タスクを生成する */
273+int depend_CreateTask(int tskid, const T_DEPEND_CTSK *p_dep_ctsk)
274+{
275+ int result;
276+ T_DEPEND_TCB *p_dep_tcb;
277+
278+ if(ISVALID_TSKID(tskid))
279+ {
280+ p_dep_tcb = &(dep_tcbs[tskid]);
281+
282+ if(0 != p_dep_tcb->tskid)
283+ {
284+ p_dep_tcb->tskid = tskid;
285+ p_dep_tcb->p_func = p_dep_ctsk->p_func;
286+ p_dep_tcb->p_param = p_dep_ctsk->p_param;
287+
288+ p_dep_tcb->p_fiber = CreateFiber(p_dep_ctsk->stksz, FiberProc, p_dep_tcb);
289+ if(NULL != p_dep_tcb->p_fiber)
290+ {
291+ result = 0;
292+ }
293+ else
294+ {
295+ *p_dep_tcb = dep_tcb_initializer;
296+ result = (-3);
297+ }
298+ }
299+ else
300+ {
301+ result = (-2);
302+ }
303+ }
304+ else
305+ {
306+ result = (-1);
307+ }
308+
309+ return result;
310+}
311+
312+int depend_DestoryTask(int tskid)
313+{
314+ int result;
315+
316+ if(ISVALID_TSKID(tskid))
317+ {
318+ T_DEPEND_TCB *p_dep_tcb;
319+
320+ p_dep_tcb = &(dep_tcbs[tskid]);
321+
322+ if(0 != p_dep_tcb->tskid)
323+ {
324+ DeleteFiber(p_dep_tcb->p_fiber);
325+
326+ *p_dep_tcb = dep_tcb_initializer;
327+
328+ /* カーネルに制御を移す */
329+ // depend_wakeup_tsk(0);
330+
331+ result = 0;
332+ }
333+ else
334+ {
335+ result = (-2);
336+ }
337+ }
338+ else
339+ {
340+ result = (-1);
341+ }
342+
343+ return result;
344+}
345+
346+int depend_SetTimer(int timid, T_DEPEND_CTIM *p_ctim)
347+{
348+ int result;
349+
350+ if(ISVALID_TIMID(timid))
351+ {
352+ T_DEPEND_TIMCB *p_timcb;
353+
354+ p_timcb = &(dep_timcbs[timid]);
355+ if(0 != p_timcb->timid)
356+ {
357+ HANDLE tim_handle;
358+ BOOL ret;
359+
360+ p_timcb->timid = timid;
361+#if 0 // TODO
362+ ret = CreateTimerQueueTimer(&tim_handle, dep_timer_handle, )
363+ if()
364+#endif
365+
366+ result = 0;
367+ }
368+ else
369+ {
370+ result = (-2);
371+ }
372+ }
373+ else
374+ {
375+ result = (-1);
376+ }
377+
378+ return result;
379+}
380+
381+int depend_KillTimer(int timid)
382+{
383+ int result;
384+
385+ // TODO
386+ result = 0;
387+
388+ return result;
389+}
390+
391+/* イベントの生成 */
392+void* depend_cre_evt(const char *p_name)
393+{
394+ void * hEventToKernel;
395+ hEventToKernel = CreateEvent(NULL, FALSE, FALSE, p_name);
396+
397+ return hEventToKernel;
398+}
399+
400+/* イベントの破棄 */
401+int depend_des_evt(void *p_handle_evt)
402+{
403+ CloseHandle((HANDLE)p_handle_evt);
404+
405+ return 0;
406+}
407+
408+/* イベントを待つ */
409+int depend_wai_evt(void *p_handle_evt, int time)
410+{
411+ DWORD d;
412+
413+ if(-1 == time) /* 無期限指定? */
414+ {
415+ time = INFINITE;
416+ }
417+
418+ d = WaitForSingleObject((HANDLE)p_handle_evt, time);
419+
420+ return 0;
421+}
422+
423+/* イベントを設定 */
424+int depend_set_evt(void *p_handle_evt)
425+{
426+ SetEvent((HANDLE)p_handle_evt);
427+
428+ return 0;
429+}
430+
431+/* 指定時間だけ処理を止める(ミリ秒) */
432+void depend_sleep(int time)
433+{
434+ Sleep(time);
435+}
436+
437+/* 現在時刻取得 */
438+int depend_get_time(void)
439+{
440+ int time;
441+ DWORD new_tickcount;
442+
443+ new_tickcount = GetTickCount();
444+
445+ if(tickcount <= new_tickcount)
446+ {
447+ time = new_tickcount - tickcount;
448+ }
449+ else
450+ {
451+ time = (ULONG_MAX - tickcount) + new_tickcount;
452+ }
453+
454+ return time;
455+}
456+
457+/* 指定された仮想タスクに制御を切り替える */
458+int depend_SwitchTask(int tskid)
459+{
460+ IT3_ASSERT(ISVALID_TSKID(tskid));
461+
462+ SwitchToFiber(dep_tcbs[tskid].p_fiber);
463+
464+ return 0;
465+}
466+
467+/* メッセージ表示 */
468+void depend_message_show(const char *p_fmt, ...)
469+{
470+ char buff[256];
471+ va_list arg;
472+
473+ va_start(arg, p_fmt); /* Initialize variable arguments. */
474+
475+ vsprintf(buff, p_fmt, arg);
476+
477+ va_end(arg); /* Reset variable arguments. */
478+
479+ MessageBox(NULL, buff, "ASSERT", MB_OK | MB_ICONINFORMATION);
480+}
481+
482+void * depend_malloc(int size)
483+{
484+ return malloc(size);
485+}
486+
487+void depend_free(void *p_mem)
488+{
489+ free(p_mem);
490+}
491+
492+int depend_CreateCriticalSection(void)
493+{
494+ int result;
495+
496+ __try
497+ {
498+ InitializeCriticalSection(&cs);
499+ result = 0;
500+ }
501+ __except(STATUS_NO_MEMORY)
502+ {
503+ IT3_LOG("CriticalSection not enough memory.");
504+ result = (-1);
505+ }
506+
507+ return result;
508+}
509+
510+void depend_DestoryCriticalSection(void)
511+{
512+ DeleteCriticalSection(&cs);
513+}
514+
515+void depend_EnterCriticalSection(void)
516+{
517+ EnterCriticalSection(&cs);
518+}
519+
520+void depend_LeaveCriticalSection(void)
521+{
522+ LeaveCriticalSection(&cs);
523+}
--- /dev/null
+++ b/src/depend/win32/depend_win32.h
@@ -0,0 +1,83 @@
1+#ifndef _DEPEND_WIN32_H_
2+#define _DEPEND_WIN32_H_
3+
4+/* 環境依存部分でサポートできるタスク数 */
5+#define DEPEND_TNUM_TSK (256)
6+
7+/* 環境依存部分でサポートできるタイマ数 */
8+#define DEPEND_TNUM_TIM (256)
9+
10+typedef struct S_DEPEND_CTSK
11+{
12+ unsigned long stksz; /* スタックサイズ(byte) */
13+ void (*p_func)(void *); /* 仮想タスクの開始アドレス */
14+ void *p_param; /* 仮想タスクに関連付けるデータ
15+ 以下のタイミングで取得できるようになる
16+ ・仮想タスクの引数
17+ ・depend_get_paramの戻り値
18+ */
19+} T_DEPEND_CTSK;
20+
21+typedef struct S_DEPEND_CTIM
22+{
23+ void (*p_func)(void *); /* タイマのコールバック関数アドレス */
24+ void *p_param; /* コールバック関数に渡す引数 */
25+} T_DEPEND_CTIM;
26+
27+/* 環境依存部分の初期化 */
28+int depend_initialize(void);
29+
30+/* 環境依存部分の終了 */
31+void depend_terminate(void);
32+
33+/* 仮想タスクの作成 */
34+int depend_CreateTask(int tskid, const T_DEPEND_CTSK *p_dep_ctsk);
35+
36+/* 仮想タスクの破棄 */
37+int depend_DestoryTask(int tsk);
38+
39+/* 仮想タスク起床 */
40+int depend_SwitchTask(int tskid);
41+
42+/* 仮想タスクに関連付けられたデータを取得 */
43+void * depend_GetParam(void);
44+
45+void * depend_malloc(int size);
46+void depend_free(void *p_mem);
47+
48+int depend_CreateCriticalSection(void);
49+void depend_DestoryCriticalSection(void);
50+void depend_EnterCriticalSection(void);
51+void depend_LeaveCriticalSection(void);
52+
53+
54+
55+
56+/* イベントの生成 */
57+void * depend_cre_evt(const char *p_name);
58+
59+/* イベントの破棄 */
60+int depend_des_evt(void *p_handle_evt);
61+
62+/* イベントを待つ */
63+int depend_wai_evt(void *p_handle_evt, int time);
64+
65+/* イベントを設定 */
66+int depend_set_evt(void *p_handle_evt);
67+
68+/* 実行停止 */
69+void depend_sleep(int time);
70+
71+/* 現在時刻取得 */
72+int depend_get_time(void);
73+
74+
75+
76+
77+
78+
79+/* メッセージ表示 */
80+void depend_message_show(const char *p_fmt, ...);
81+
82+
83+#endif /* _DEPEND_WIN32_H_ */
--- /dev/null
+++ b/src/flg.c
@@ -0,0 +1,888 @@
1+#include "flg.h"
2+#include "it3_debug.h"
3+#include "it3_common.h"
4+#include "it3_config.h"
5+
6+#include "que_ctl.h"
7+#include "tsk.h"
8+#include "kernel.h"
9+
10+#define ISVALID_FLGID(flgid) ((0 < flgid) && (flgid < TNUM_FLG))
11+#define ISVALID_FLGATR(flgatr) (TRUE) /* 属性値はチェックしない */
12+#define ISVALID_WFMODE(wfmode) (0 == ((wfmode) & ~(TWF_ORW | TWF_CLR)))
13+#define ISVALID_TMOUT(tmout) ((0 < (tmout)) || (TMO_FEVR == (tmout)) || (TMO_POL == (tmout)))
14+
15+typedef struct S_FLGCB
16+{
17+ ID flgid; /**< イベントフラグID */
18+ VP exinf; /**< 拡張情報 */
19+ ATR flgatr; /**< 属性情報 */
20+ UINT flgptn; /**< フラグパターン */
21+
22+ T_LST wtsklst; /**< 待ちタスクリスト */
23+
24+// T_TCB *head; /**< 先頭TCBへのポインタ */
25+// VH wtskmode; /**< 待ち順序 */
26+// ID wtskcnt; /**< 待ちタスク数 */
27+// VB dmy[4]; /**< ダミー */
28+
29+} T_FLGCB;
30+
31+static const T_FLGCB flgcb_initializer = {0};
32+
33+static T_FLGCB flgcb[TNUM_FLG];
34+
35+/* イベントフラグ待ちキューにタスクを追加 */
36+static void add_flgq(T_FLGCB *p_flgcb, T_TCB *p_tcb)
37+{
38+ IT3_ASSERT(p_flgcb);
39+ IT3_ASSERT(p_tcb);
40+
41+ if(TA_TPRI & p_flgcb->flgatr)
42+ {
43+ T_LST *p_insert_pos;
44+
45+ p_insert_pos = p_flgcb->wtsklst.p_next;
46+
47+ while(&(p_flgcb->wtsklst) != p_insert_pos)
48+ {
49+ if(p_tcb->tskpri < ((T_TCB *)p_insert_pos)->tskpri)
50+ {
51+ break;
52+ }
53+
54+ p_insert_pos = p_insert_pos->p_next;
55+ }
56+
57+ lst_insert(p_insert_pos, (T_LST *)p_tcb);
58+ }
59+ else
60+ {
61+ lst_insert(&(p_flgcb->wtsklst), (T_LST *)p_tcb);
62+ }
63+
64+#if 0 // T_LSTへ移行するので使うのやめる
65+ T_FLGCB *p_flgq;
66+ T_TCB *toptcb, *endtcb, *nextcb, *pretcb;
67+
68+ p_flgq = &flgcb[addtcb->wid];
69+
70+ toptcb = p_flgq->head;
71+ if(NULL != toptcb)
72+ {
73+ /*-------------------- 他のタスクがある --------------------*/
74+ if( p_flgq->wtskmode == TA_TFIFO ) /* 待ち順序は FIFO */
75+ {
76+ /* 一番後ろにつなげる */
77+ endtcb = toptcb->prev;
78+ addtcb->prev = endtcb;
79+ addtcb->next = toptcb;
80+ toptcb->prev = addtcb;
81+ endtcb->next = addtcb;
82+ }
83+ else /* 待ち順序は 優先順 */
84+ {
85+ /* 挿入場所を探してつなげる */
86+ endtcb = toptcb->prev;
87+ nextcb = toptcb;
88+
89+ do
90+ {
91+ if( addtcb->pri < nextcb->pri )
92+ {
93+ pretcb = nextcb->prev;
94+
95+ addtcb->prev = pretcb;
96+ addtcb->next = nextcb;
97+ nextcb->prev = addtcb;
98+ pretcb->next = addtcb;
99+
100+ if( nextcb == toptcb )
101+ {
102+ p_flgq->head = addtcb;
103+ }
104+
105+ break;
106+ }
107+
108+ nextcb = nextcb->next;
109+ } while((nextcb != toptcb) && (p_flgq->head != NULL));
110+
111+ if( nextcb == toptcb )
112+ {
113+ addtcb->prev = endtcb;
114+ addtcb->next = toptcb;
115+ toptcb->prev = addtcb;
116+ endtcb->next = addtcb;
117+ }
118+ }
119+
120+ (p_flgq->wtskcnt)++; /* 待ちタスク数を加算 */
121+ }
122+ else
123+ {
124+ /*-------------------- 他のタスクがない --------------------*/
125+ p_flgq->head = addtcb;
126+ addtcb->next = addtcb;
127+ addtcb->prev = addtcb;
128+
129+ p_flgq->wtskcnt = 1; /* 待ちタスク数は1 */
130+ }
131+
132+ return;
133+#endif
134+}
135+
136+/* イベントフラグ待ちキューからタスクを削除 */
137+void del_flgq(T_FLGCB *p_flgcb, T_TCB *p_tcb)
138+{
139+ lst_delete((T_LST *)p_tcb);
140+
141+#if 0 // T_LSTへ移行するので使うのやめる
142+ T_FLGCB *p_flgq;
143+ T_TCB *pretcb, *nextcb;
144+
145+ p_flgq = &flgcb[deltcb->wid];
146+
147+ if( (pretcb = deltcb->prev) != deltcb )
148+ {
149+ /*-------------------- 他のタスクがある --------------------*/
150+ nextcb = deltcb->next;
151+ pretcb->next = nextcb;
152+ nextcb->prev = pretcb;
153+ if( p_flgq->head == deltcb )
154+ {
155+ p_flgq->head = nextcb;
156+ }
157+
158+ ( p_flgq->wtskcnt )--; /* 待ちタスク数を減算 */
159+ }
160+ else
161+ {
162+ /*-------------------- 他のタスクがない --------------------*/
163+ p_flgq->head = NULL;
164+
165+ p_flgq->wtskcnt = 0; /* 待ちタスク数は0 */
166+ }
167+
168+ /*deltcb->prev = NULL;*/
169+ /*deltcb->next = NULL;*/
170+
171+ return;
172+#endif
173+}
174+
175+/**
176+ * @brief 同期・通信機能(イベントフラグ)初期化処理
177+ */
178+ER flg_initialize(void)
179+{
180+ INT cnt;
181+
182+ for(cnt = 0;cnt < TNUM_FLG;cnt++)
183+ {
184+ flgcb[cnt] = flgcb_initializer;
185+ }
186+
187+ return E_OK;
188+}
189+
190+/**
191+ * @brief 同期・通信機能(イベントフラグ)終了処理
192+ */
193+void flg_terminate(void)
194+{
195+}
196+
197+/*----------------- 同期、通信機能(イベントフラグ)---------------------*/
198+/* イベントフラグ生成 */
199+ER cre_flg(ID flgid, T_CFLG *pk_cflg)
200+{
201+ ER result;
202+
203+ if(ISVALID_FLGID(flgid))
204+ {
205+ if(ISVALID_PTR(pk_cflg))
206+ {
207+ T_FLGCB *p_flgcb;
208+
209+ p_flgcb = &(flgcb[flgid]);
210+
211+ depend_EnterCriticalSection();
212+
213+ if(0 == p_flgcb->flgid)
214+ {
215+ *p_flgcb = flgcb_initializer;
216+
217+ p_flgcb->flgid = flgid;
218+
219+ p_flgcb->exinf = pk_cflg->exinf;
220+ p_flgcb->flgatr = pk_cflg->flgatr;
221+ p_flgcb->flgptn = pk_cflg->iflgptn; /* イベントフラグ初期値 */
222+
223+ lst_init(&(p_flgcb->wtsklst));
224+
225+ result = E_OK;
226+ }
227+ else
228+ {
229+ result = E_OBJ;
230+ }
231+
232+ depend_LeaveCriticalSection();
233+ }
234+ else
235+ {
236+ result = E_PAR;
237+ }
238+ }
239+ else
240+ {
241+ result = E_ID;
242+ }
243+
244+ return result;
245+}
246+
247+/* イベントフラグ削除 */
248+ER del_flg(ID flgid)
249+{
250+ ER result;
251+
252+ if(ISVALID_FLGID(flgid))
253+ {
254+ T_FLGCB *p_flgcb;
255+
256+ p_flgcb = &(flgcb[flgid]);
257+
258+ depend_EnterCriticalSection();
259+
260+ if(0 != p_flgcb->flgid)
261+ {
262+ T_TCB *p_tcb;
263+
264+ /*----- 条件成立を待っているタスクの待ち解除 -----*/
265+ while(! lst_empty(&(p_flgcb->wtsklst)))
266+ {
267+ p_tcb = (T_TCB *)(p_flgcb->wtsklst.p_next);
268+
269+ del_flgq(p_flgcb, p_tcb); /* FLGQ から TCB を外す */
270+
271+ if(WTIM & p_tcb->tskwait) /* タイムアウトあり */
272+ {
273+ T_TCBTMO *p_tcbtmo = &(tcbtmoq[p_tcb->tskid]);
274+ del_timq(p_tcbtmo); /* TIMQ から TCB を外す */
275+ p_tcbtmo->sts = 0;
276+ }
277+
278+ /* エラーコードを待ちオブジェクトの削除に */
279+ *(p_tcb->p_wercd) = E_DLT;
280+
281+ p_tcb->tskstat &= ~(TTS_WAI);
282+ p_tcb->tskwait &= ~(WTIM | TTW_FLG);
283+ p_tcb->wid = 0;
284+ if(0 == (TTS_SUS & tcb->tskstat))
285+ {
286+ p_tcb->tskstat = TTS_RDY; /* タスク状態を READY に */
287+ p_tcb->tskwait = 0;
288+ p_tcb->wid = 0;
289+ add_rdq(p_tcb); /* RDQ に TCB をつなげる */
290+ }
291+ }
292+
293+ *p_flgcb = flgcb_initializer;
294+
295+ /* ディスパッチされるまで待つ */
296+ tsk_wait_dispatch();
297+
298+ result = E_OK;
299+ }
300+ else
301+ {
302+ result = E_NOEXS;
303+ }
304+
305+ depend_LeaveCriticalSection();
306+ }
307+ else
308+ {
309+ result = E_ID;
310+ }
311+
312+ return result;
313+}
314+
315+/* イベントフラグのセット */
316+ER set_flg(ID flgid, UINT setptn)
317+{
318+ ER result;
319+
320+ result = iset_flg(flgid, setptn);
321+ if(E_OK == result)
322+ {
323+ /* ディスパッチされるまで待つ */
324+ tsk_wait_dispatch();
325+ }
326+
327+ return result;
328+}
329+
330+/* イベントフラグのセット(タスク独立部専用) */
331+ER iset_flg(ID flgid, UINT setptn)
332+{
333+ ER result;
334+
335+ if(ISVALID_FLGID(flgid))
336+ {
337+ T_FLGCB *p_flgcb;
338+ T_TCB *p_tcb, *p_next_tcb;
339+ UINT ptn;
340+
341+ p_flgcb = &(flgcb[flgid]);
342+
343+ depend_EnterCriticalSection();
344+
345+ p_flgcb->flgptn |= setptn;
346+
347+ p_tcb = (T_TCB *)(p_flgcb->wtsklst.p_next);
348+
349+ while(&(p_flgcb->wtsklst) != (T_LST *)p_tcb)
350+ {
351+ p_next_tcb = (T_TCB *)(((T_LST *)p_tcb)->p_next);
352+
353+ ptn = p_flgcb->flgptn & p_tcb->wait.wflg.waiptn;
354+
355+ if( ((0 != (p_tcb->wait.wflg.wfmode & TWF_ANDW)) && (p_tcb->wait.wflg.waiptn == ptn)) ||
356+ ((0 != (p_tcb->wait.wflg.wfmode & TWF_ORW)) && (0 != ptn)) )
357+ {
358+ /* 条件成立 */
359+
360+ *(UW *)p_tcb->arg = p_flgcb->flgptn; /* 待ち解除時フラグパターン */
361+
362+ if(0 != (p_tcb->wait.wflg.wfmode & TWF_CLR)) /* クリア指定あり */
363+ {
364+ p_flgcb->flgptn &= ~(p_tcb->wait.wflg.waiptn);
365+ }
366+
367+ del_flgq(p_flgcb, p_tcb); /* FLGQ から TCB を外す */
368+ p_tcb->wait.wflg.wfmode = 0; /* TCB の待ちパターンをクリア */
369+
370+ if(WTIM & p_tcb->tskstat) /* タイムアウトあり */
371+ {
372+ T_TCBTMO *p_tcbtmo = &(tcbtmoq[p_tcb->tskid]);
373+ del_timq(p_tcbtmo); /* TIMQ から TCB を外す */
374+ p_tcbtmo->sts = 0;
375+ }
376+
377+ if(TTS_SUS == p_tcb->tskstat)
378+ {
379+ /* 二重待ち状態 */
380+ p_tcb->tskstat = TTS_SUS; /* タスク状態を SUSPEND に */
381+ }
382+ else
383+ {
384+ /* メッセージ待ち状態 */
385+ add_rdq(p_tcb); /* RDQ に TCB をつなげる */
386+ p_tcb->tskstat = TTS_RDY; /* タスク状態を READY に */
387+ }
388+ }
389+
390+ p_tcb = p_next_tcb;
391+ }
392+
393+ depend_LeaveCriticalSection();
394+
395+ result = E_OK;
396+ }
397+ else
398+ {
399+ result = E_ID;
400+ }
401+
402+ return result;
403+#if 0
404+ T_FLGCB *p_flgq;
405+ T_TCB *p_tcb, *p_next_tcb;
406+ UH wtskcnt;
407+ INT i;
408+ UW ptn;
409+
410+ /* パラメータチェック */
411+ if(! ISVALID_FLGID(flgid))
412+ {
413+ return E_ID;
414+ }
415+
416+ p_flgq = &(flgcb[flgid]);
417+
418+ /* イベントフラグの値を設定 */
419+ p_flgq->flgptn |= setptn;
420+
421+ p_tcb = p_flgq->head;
422+ wtskcnt = p_flgq->wtskcnt; /* イベントフラグ待ちタスクの数 */
423+
424+ for(i = 0;i < wtskcnt;i++)
425+ {
426+ p_next_tcb = p_tcb->next;
427+
428+ ptn = p_flgq->flgptn & p_tcb->waiptn;
429+
430+ if( ((0 != (p_tcb->wfmode & TWF_ANDW)) && (p_tcb->waiptn == ptn)) ||
431+ ((0 != (p_tcb->wfmode & TWF_ORW)) && (0 != ptn)) )
432+ {
433+ /* 条件成立 */
434+
435+ *(UW *)p_tcb->arg = p_flgq->flgptn; /* 待ち解除時フラグパターン */
436+
437+ if(0 != (p_tcb->wfmode & TWF_CLR)) /* クリア指定あり */
438+ {
439+ p_flgq->flgptn &= ~(p_tcb->waiptn);
440+ }
441+
442+ del_flgq(p_flgq, p_tcb); /* FLGQ から TCB を外す */
443+ p_tcb->wfmode = 0; /* TCB の待ちパターンをクリア */
444+
445+ if(WTIM & p_tcb->tskstat) /* タイムアウトあり */
446+ {
447+ T_TCBTMO *p_tcbtmo = &(tcbtmoq[p_tcb->tskid]);
448+ del_timq(p_tcbtmo); /* TIMQ から TCB を外す */
449+ p_tcbtmo->sts = 0;
450+ }
451+
452+ if(TTS_SUS == p_tcb->tskstat)
453+ {
454+ /* 二重待ち状態 */
455+ p_tcb->tskstat = TTS_SUS; /* タスク状態を SUSPEND に */
456+ }
457+ else
458+ {
459+ /* メッセージ待ち状態 */
460+ add_rdq(p_tcb); /* RDQ に TCB をつなげる */
461+ p_tcb->tskstat = TTS_RDY; /* タスク状態を READY に */
462+ }
463+ }
464+
465+ p_tcb = p_next_tcb;
466+ }
467+
468+ return E_OK;
469+#endif
470+}
471+
472+/* イベントフラグのクリア */
473+ER clr_flg(ID flgid, UINT clrptn)
474+{
475+ ER result;
476+
477+ if(ISVALID_FLGID(flgid))
478+ {
479+ T_FLGCB *p_flgcb;
480+
481+ p_flgcb = &(flgcb[flgid]);
482+
483+ depend_EnterCriticalSection();
484+
485+ if(0 != p_flgcb->flgid)
486+ {
487+ p_flgcb->flgptn &= clrptn;
488+ result = E_OK;
489+ }
490+ else
491+ {
492+ result = E_NOEXS;
493+ }
494+
495+ depend_LeaveCriticalSection();
496+ }
497+ else
498+ {
499+ result = E_ID;
500+ }
501+
502+ return result;
503+}
504+
505+/* イベントフラグ待ち */
506+ER wai_flg(UINT *p_flgptn, ID flgid, UINT waiptn, UINT wfmode)
507+{
508+ return twai_flg(p_flgptn, flgid, waiptn, wfmode, TMO_FEVR);
509+
510+#if 0 // TODO もうやめる
511+ T_FLGCB *p_flgq;
512+ T_TCB *p_tcb;
513+ ER ercd;
514+ UINT ptn;
515+
516+ /* パラメータチェック */
517+ if(! ISVALID_FLGID(flgid))
518+ {
519+ return E_ID;
520+ }
521+
522+ if(0 == waiptn)
523+ {
524+ /* waiptn が不正 */
525+ return E_PAR;
526+ }
527+
528+ if(0 != (wfmode & ~(TWF_ANDW | TWF_ORW | TWF_CLR)))
529+ {
530+ /* wfmode が不正 */
531+ return E_PAR;
532+ }
533+
534+ p_flgq = &(flgcb[flgid]);
535+ ercd = tsk_get_tcb(TSK_SELF, &p_tcb);
536+ if(E_OK != ercd)
537+ {
538+ return ercd;
539+ }
540+
541+ /* タスクの待ち条件と一致するか? */
542+ ptn = p_flgq->flgptn & waiptn; /* フラグパターン判定 */
543+
544+ if( ((0 != (wfmode & TWF_ANDW)) && (ptn == waiptn)) ||
545+ ((0 != (wfmode & TWF_ORW)) && (ptn != 0)) )
546+ {
547+ *p_flgptn = p_flgq->flgptn; /* 待ち解除時フラグパターン */
548+
549+ if(0 != (TWF_CLR & wfmode)) /* クリア指定あり? */
550+ {
551+ /* ビットパターンをクリア */
552+ p_flgq->flgptn &= ~(waiptn);
553+ }
554+ }
555+ else
556+ {
557+ /* TCBをRDQから外す */
558+ del_rdq(p_tcb);
559+
560+ /* タスク状態をWAITにする */
561+ p_tcb->tskstat = TTS_WAI;
562+ p_tcb->tskwait = TTW_FLG;
563+ p_tcb->wid = flgid;
564+
565+ /* waiptn,wfmodeをTCBに設定 */
566+ p_tcb->waiptn = waiptn;
567+ p_tcb->wfmode = wfmode;
568+
569+ /* 引数を保存 */
570+ p_tcb->arg = (VP)p_flgptn;
571+
572+ if(TA_TFIFO == p_flgq->wtskmode) /* 待ち行列はFIFO? */
573+ {
574+ /* TCBをFLGQにつなぐ */
575+ add_flgq(p_flgq, p_tcb);
576+ }
577+ else
578+ {
579+ /* 優先順位の高い方から挿入位置を検索 */
580+ /* FLGQの検索した位置にTCBをつなぐ */
581+ add_flgq(p_flgq, p_tcb);
582+ }
583+ }
584+
585+ /* ディスパッチされるまで待つ */
586+ tsk_wait_dispatch();
587+
588+ return E_OK;
589+#endif
590+}
591+
592+/* イベントフラグ待ち(ポーリング) */
593+ER pol_flg(UINT *p_flgptn, ID flgid, UINT waiptn, UINT wfmode)
594+{
595+ return twai_flg(p_flgptn, flgid, waiptn, wfmode, TMO_POL);
596+
597+#if 0 // TODO もうやめ
598+ ER ercd;
599+ T_FLGCB *p_flgq;
600+ T_TCB *p_tcb;
601+ UINT ptn;
602+
603+ /* パラメータチェック */
604+ if(! ISVALID_FLGID(flgid))
605+ {
606+ return E_ID;
607+ }
608+
609+ if(0 != (wfmode & ~(TWF_ANDW | TWF_ORW | TWF_CLR)))
610+ {
611+ /* wfmode が不正 */
612+ return E_PAR;
613+ }
614+
615+ if(0 == waiptn)
616+ {
617+ /* waiptn が不正 */
618+ return E_PAR;
619+ }
620+
621+ p_flgq = &(flgcb[flgid]);
622+ ercd = tsk_get_tcb(TSK_SELF, &p_tcb);
623+ if(E_OK != ercd)
624+ {
625+ return ercd;
626+ }
627+
628+ /*-------------------- イベントフラグを得る ---------------------*/
629+ ptn = p_flgq->flgptn & waiptn;
630+
631+ if( ((0 != (wfmode & TWF_ANDW)) && (ptn == waiptn)) ||
632+ ((0 != (wfmode & TWF_ORW)) && (ptn != 0)) )
633+ {
634+ /* 条件成立 */
635+
636+ *p_flgptn = p_flgq->flgptn; /* 待ち解除時フラグパターン */
637+
638+ if(0 != (wfmode & TWF_CLR)) /* クリア指定あり? */
639+ {
640+ p_flgq->flgptn &= ~(waiptn);
641+ }
642+ }
643+ else
644+ {
645+ return E_TMOUT;
646+ }
647+
648+ return E_OK;
649+#endif
650+}
651+
652+/* イベントフラグ待ち(タイムアウト有)) */
653+ER twai_flg(UINT *p_flgptn, ID flgid, UINT waiptn, UINT wfmode, TMO tmout)
654+{
655+ ER result;
656+
657+ if(ISVALID_FLGID(flgid))
658+ {
659+ if((0 != waiptn) && ISVALID_WFMODE(wfmode) && ISVALID_TMOUT(tmout))
660+ {
661+ T_FLGCB *p_flgcb;
662+ ER ret;
663+ T_TCB *p_tcb;
664+
665+ p_flgcb = &(flgcb[flgid]);
666+
667+ ret = tsk_get_tcb(TSK_SELF, &p_tcb);
668+ if(E_OK == ret)
669+ {
670+ depend_EnterCriticalSection();
671+
672+ if( ((TWF_ORW & wfmode) && ((waiptn & p_flgcb->flgptn) != 0)) ||
673+ ((waiptn & p_flgcb->flgptn) == waiptn))
674+ {
675+ if(p_flgptn)
676+ {
677+ *p_flgptn = p_flgcb->flgptn;
678+ }
679+
680+ if(0 != (TWF_CLR & wfmode)) /* クリア指定あり? */
681+ {
682+ p_flgcb->flgptn = 0;
683+ }
684+
685+ result = E_OK;
686+ }
687+ else
688+ {
689+ if(TMO_POL == tmout)
690+ {
691+ result = E_TMOUT;
692+ }
693+ else if(TMO_FEVR == tmout)
694+ {
695+ del_rdq(p_tcb); /* RDQ から TCB を外す */
696+
697+ p_tcb->tskstat = TTS_WAI;
698+ p_tcb->tskwait = TTW_FLG;
699+ p_tcb->wid = flgid;
700+
701+ p_tcb->arg = (VB *)p_flgptn; /* 戻り値用のアドレスを保存 */
702+ p_tcb->wait.wflg.waiptn = waiptn; /* 待ちパターンを設定 */
703+ p_tcb->wait.wflg.wfmode = wfmode; /* 待ちモードを設定 */
704+
705+ add_flgq(p_flgcb, p_tcb); /* FLGQ に TCB をつなげる */
706+
707+ /* ディスパッチされるまで待つ */
708+ tsk_wait_dispatch();
709+
710+ result = E_OK;
711+ }
712+ else
713+ {
714+ T_TCBTMO *p_tcbtmo = &(tcbtmoq[p_tcb->tskid]);
715+
716+ del_rdq(p_tcb); /* RDQ から TCB を外す */
717+ p_tcb->tskstat = TTS_WAI;
718+ p_tcb->tskwait = WTIM | TTW_FLG;
719+ p_tcb->wid = flgid; /* フラグ ID を設定 */
720+
721+ p_tcb->arg = (VB *)p_flgptn; /* 戻り値用のアドレスを保存 */
722+ p_tcb->wait.wflg.waiptn = waiptn; /* 待ちパターンを設定 */
723+ p_tcb->wait.wflg.wfmode = wfmode; /* 待ちモードを設定 */
724+
725+ p_tcbtmo->sts = p_tcb->tskstat;
726+ p_tcbtmo->tmout = timq.time + tmout; /* タイムアウト時刻を設定 */
727+
728+ add_flgq(p_flgcb, p_tcb); /* FLGQ に TCB をつなげる */
729+ add_timq(p_tcb); /* 時間待ち行列につなぐ */
730+
731+ /* ディスパッチされるまで待つ */
732+ tsk_wait_dispatch();
733+
734+ result = E_OK;
735+ }
736+ }
737+
738+ depend_LeaveCriticalSection();
739+ }
740+ else
741+ {
742+ result = ret;
743+ }
744+ }
745+ else
746+ {
747+ result = E_PAR;
748+ }
749+ }
750+ else
751+ {
752+ result = E_ID;
753+ }
754+
755+ return result;
756+
757+#if 0 // TODO 変える
758+ ER ercd;
759+// UINT wfmode = pararr[0];
760+// TMO tmout = pararr[1];
761+
762+ T_FLGCB *p_flgq;
763+ T_TCB *p_tcb;
764+
765+// if (DSPENA == OFF) return E_CTX; /* コンテキストエラー */
766+
767+ /*----- パラメータエラー判定 -----*/
768+ if(! ISVALID_FLGID(flgid))
769+ {
770+ return E_ID; /* 不正 ID 番号 */
771+ }
772+
773+ if(0 == waiptn)
774+ {
775+ return E_PAR; /* パラメータエラー */
776+ }
777+
778+ p_flgq = &(flgcb[flgid]);
779+ ercd = tsk_get_tcb(TSK_SELF, &p_tcb);
780+ if(E_OK != ercd)
781+ {
782+ return ercd;
783+ }
784+
785+ /*----- イベントフラグ待ち -----*/
786+ if( ((TWF_ORW & wfmode) && ((waiptn & p_flgq->flgptn) != 0)) ||
787+ ((waiptn & p_flgq->flgptn) == waiptn))
788+ {
789+ /* 条件成立 */
790+ *p_flgptn = p_flgq->flgptn; /* 待ち解除時フラグパターン */
791+
792+ if(0 != (TWF_CLR & wfmode)) /* クリア指定あり? */
793+ {
794+ p_flgq->flgptn = 0;
795+ }
796+
797+ return E_OK;
798+ }
799+
800+ if(TMO_POL == tmout)
801+ {
802+ return E_TMOUT;
803+ }
804+ else if(TMO_FEVR == tmout)
805+ {
806+ del_rdq(p_tcb); /* RDQ から TCB を外す */
807+ p_tcb->tskstat = TTS_WAI;
808+ p_tcb->tskwait = TTW_FLG;
809+ p_tcb->wid = flgid; /* フラグ ID を設定 */
810+
811+ p_tcb->arg = (VB *)p_flgptn; /* 戻り値用のアドレスを保存 */
812+ p_tcb->waiptn = waiptn; /* 待ちパターンを設定 */
813+ p_tcb->wfmode = wfmode; /* 待ちモードを設定 */
814+
815+ add_flgq(p_flgq, p_tcb); /* FLGQ に TCB をつなげる */
816+
817+ /* ディスパッチされるまで待つ */
818+ tsk_wait_dispatch();
819+ return E_OK;
820+ }
821+ else
822+ {
823+ T_TCBTMO *p_tcbtmo = &(tcbtmoq[p_tcb->tskid]);
824+
825+ del_rdq(p_tcb); /* RDQ から TCB を外す */
826+ p_tcb->tskstat = TTS_WAI;
827+ p_tcb->tskwait = WTIM | TTW_FLG;
828+ p_tcb->wid = flgid; /* フラグ ID を設定 */
829+
830+ p_tcb->arg = (VB *)p_flgptn; /* 戻り値用のアドレスを保存 */
831+ p_tcb->waiptn = waiptn; /* 待ちパターンを設定 */
832+ p_tcb->wfmode = wfmode; /* 待ちモードを設定 */
833+
834+ p_tcbtmo->sts = p_tcb->sts;
835+ p_tcbtmo->tmout = timq.time + tmout; /* タイムアウト時刻を設定 */
836+
837+ add_flgq(p_flgq, p_tcb); /* FLGQ に TCB をつなげる */
838+ add_timq(p_tcb); /* 時間待ち行列につなぐ */
839+
840+ /* ディスパッチされるまで待つ */
841+ tsk_wait_dispatch();
842+ return E_OK;
843+ }
844+#endif
845+}
846+
847+/* イベントフラグ状態参照 */
848+ER ref_flg(T_RFLG *pk_rflg, ID flgid)
849+{
850+ ER result;
851+
852+ if(ISVALID_FLGID(flgid))
853+ {
854+ if(ISVALID_PTR(pk_rflg))
855+ {
856+ T_FLGCB *p_flgcb;
857+
858+ p_flgcb = &(flgcb[flgid]);
859+
860+ depend_EnterCriticalSection();
861+
862+ if(0 != p_flgcb->flgid)
863+ {
864+ pk_rflg->exinf = p_flgcb->exinf;
865+ pk_rflg->wtsk = (lst_empty(&(p_flgcb->wtsklst))) ? FALSE : ((T_TCB *)(p_flgcb->wtsklst.p_next))->tskid;
866+ pk_rflg->flgptn = p_flgcb->flgptn;
867+
868+ result = E_OK;
869+ }
870+ else
871+ {
872+ result = E_NOEXS;
873+ }
874+
875+ depend_LeaveCriticalSection();
876+ }
877+ else
878+ {
879+ result = E_PAR;
880+ }
881+ }
882+ else
883+ {
884+ result = E_ID;
885+ }
886+
887+ return result;
888+}
--- /dev/null
+++ b/src/flg.h
@@ -0,0 +1,9 @@
1+#ifndef _FLG_H_
2+#define _FLG_H_
3+
4+#include <itron.h>
5+
6+ER flg_initialize(void);
7+void flg_terminate(void);
8+
9+#endif /* _FLG_H_ */
--- /dev/null
+++ b/src/int.c
@@ -0,0 +1,186 @@
1+#include "int.h"
2+#include "it3_common.h"
3+#include "it3_config.h"
4+#include <depend.h>
5+
6+#define ISVALID_INTNO(intno) ((0 < (intno)) && ((intno) < TNUM_INT))
7+#define ISVALID_INTATR(intatr) (TRUE) /* 属性をチェックしない */
8+
9+/* 割込みハンドラ定義情報 */
10+typedef struct S_INTCB
11+{
12+ UINT intno;
13+
14+ ATR intatr; /* 割込みハンドラ属性 */
15+ FP inthdr; /* 割込みハンドラアドレス */
16+
17+ /* インプリメント依存の情報 */
18+ B intmsk; /* 割込みマスク */
19+ B intpri; /* 割込みレベル */
20+
21+} T_INTCB;
22+
23+static const T_INTCB intcb_initializer = {0};
24+
25+static T_INTCB intcbs[TNUM_INT];
26+
27+ER int_initialize(void)
28+{
29+ INT cnt;
30+
31+ for(cnt = 0;cnt < TNUM_INT;cnt++)
32+ {
33+ intcbs[cnt] = intcb_initializer;
34+ }
35+
36+ return E_OK;
37+}
38+
39+void int_terminate(void)
40+{
41+}
42+
43+ER int_event(void)
44+{
45+ INT cnt;
46+ T_INTCB *p_intcb;
47+
48+ for(cnt = 0;cnt < TNUM_INT;cnt++)
49+ {
50+ p_intcb = &(intcbs[cnt]);
51+
52+ depend_EnterCriticalSection();
53+
54+ if(0 != p_intcb->intno)
55+ {
56+ (p_intcb->inthdr)();
57+ p_intcb->intatr = 0;
58+ }
59+
60+ depend_LeaveCriticalSection();
61+ }
62+
63+ return E_OK;
64+}
65+
66+ER set_int(UINT intno)
67+{
68+ ER result;
69+
70+ if(ISVALID_INTNO(intno))
71+ {
72+ T_INTCB *p_intcb;
73+
74+ p_intcb = &(intcbs[intno]);
75+
76+ depend_EnterCriticalSection();
77+
78+ if(0 != p_intcb->intno)
79+ {
80+ p_intcb->intatr = 1;
81+
82+ result = E_OK;
83+ }
84+ else
85+ {
86+ result = E_NOEXS;
87+ }
88+
89+ depend_LeaveCriticalSection();
90+ }
91+ else
92+ {
93+ result = E_PAR;
94+ }
95+
96+ return result;
97+}
98+
99+
100+/* 割込みハンドラ定義 */
101+ER def_int(UINT dintno, T_DINT *pk_dint)
102+{
103+ ER result;
104+
105+ if(ISVALID_INTNO(dintno))
106+ {
107+ T_INTCB *p_intcb;
108+
109+ p_intcb = &(intcbs[dintno]);
110+
111+ depend_EnterCriticalSection();
112+
113+ if(ISVALID_PTR(pk_dint))
114+ {
115+ if(ISVALID_INTATR(intatr))
116+ {
117+ if(0 == p_intcb->intno)
118+ {
119+ *p_intcb = intcb_initializer;
120+
121+ p_intcb->intno = dintno;
122+
123+ p_intcb->intatr = pk_dint->intatr;
124+ p_intcb->inthdr = pk_dint->inthdr;
125+
126+ result = E_OK;
127+ }
128+ else
129+ {
130+ result = E_OBJ;
131+ }
132+ }
133+ else
134+ {
135+ result = E_RSATR;
136+ }
137+ }
138+ else
139+ {
140+ *p_intcb = intcb_initializer;
141+
142+ result = E_OK;
143+ }
144+
145+ depend_LeaveCriticalSection();
146+ }
147+ else
148+ {
149+ result = E_PAR;
150+ }
151+
152+ return result;
153+}
154+
155+void ret_int(void)
156+{
157+}
158+
159+void ret_wup(ID tskid)
160+{
161+
162+}
163+
164+/* 割込みとディスパッチの禁止 */
165+ER loc_cpu(void)
166+{
167+ return E_NOSPT;
168+}
169+
170+/* 割込みとディスパッチの許可 */
171+ER unl_cpu(void)
172+{
173+ return E_NOSPT;
174+}
175+
176+/* 割込み禁止 */
177+ER dis_int(UINT eintno)
178+{
179+ return E_NOSPT;
180+}
181+
182+/* 割込み許可 */
183+ER ena_int(UINT eintno)
184+{
185+ return E_NOSPT;
186+}
--- /dev/null
+++ b/src/int.h
@@ -0,0 +1,13 @@
1+#ifndef _INT_H_
2+#define _INT_H_
3+
4+#include <itron.h>
5+
6+ER int_initialize(void);
7+void int_terminate(void);
8+
9+ER int_event(void);
10+
11+ER set_int(UINT intno);
12+
13+#endif /* INT_H_ */
--- /dev/null
+++ b/src/it3.c
@@ -0,0 +1,213 @@
1+#include "it3.h"
2+#include "it3_common.h"
3+#include "it3_debug.h"
4+
5+#define EXTDEF
6+#include "kernel.h"
7+#undef EXTDEF
8+
9+#include "tsk.h"
10+#include "sem.h"
11+#include "flg.h"
12+#include "mbx.h"
13+#include "mbf.h"
14+#include "por.h"
15+#include "int.h"
16+#include "mpl.h"
17+#include "mpf.h"
18+#include "tim.h"
19+#include "alm.h"
20+#include "cyc.h"
21+#include "sys.h"
22+#include "net.h"
23+
24+static ER (*init_funcs[])(void) = {
25+ tsk_initialize,
26+ sem_initialize,
27+ flg_initialize,
28+ mbx_initialize,
29+ mbf_initialize,
30+ por_initialize,
31+ int_initialize,
32+ mpl_initialize,
33+ mpf_initialize,
34+ tim_initialize,
35+ alm_initialize,
36+ cyc_initialize,
37+ sys_initialize,
38+ net_initialize,
39+};
40+
41+static void (*term_funcs[])(void) = {
42+ net_terminate,
43+ sys_terminate,
44+ cyc_terminate,
45+ alm_terminate,
46+ tim_terminate,
47+ mpf_terminate,
48+ mpl_terminate,
49+ int_terminate,
50+ por_terminate,
51+ mbf_terminate,
52+ mbx_terminate,
53+ flg_terminate,
54+ sem_terminate,
55+ tsk_terminate,
56+};
57+
58+/* カーネルの初期化 */
59+static ER it3_initialize(void)
60+{
61+ ER result;
62+ INT cnt, cnt_max;
63+ int int_ret;
64+ ER er_ret;
65+
66+ /* 環境依存部分の初期化 */
67+ int_ret = depend_initialize();
68+ if(0 == int_ret)
69+ {
70+ result = E_OK;
71+
72+ cnt_max = ARRAY_CNT(init_funcs);
73+ for(cnt = 0;cnt < cnt_max;cnt++)
74+ {
75+ er_ret = (init_funcs[cnt])();
76+ if(E_OK != er_ret)
77+ {
78+ IT3_LOG2("it3 init failure.[cnt:%d, ret:%d]", cnt, er_ret);
79+ result = er_ret;
80+ break;
81+ }
82+ }
83+ }
84+ else
85+ {
86+ IT3_LOG1("it3 depend init abort.[ret:%d]", int_ret);
87+ result = E_SYS;
88+ }
89+
90+ return result;
91+}
92+
93+/* カーネル実行 */
94+static int it3_run(void)
95+{
96+ /* システム時刻を初期化 */
97+
98+ /* 割り込みを許可 */
99+
100+ /* タスクの実行開始 */
101+ /* 全てのタスクがDOMANT状態になったら、終了する */
102+ while(TRUE)
103+ {
104+ /* 割込みハンドラ */
105+ int_event();
106+
107+ /* タイムイベントハンドラ */
108+ tim_event();
109+
110+ /* CPU例外ハンドラ */
111+ /* 拡張サービスコールルーチン */
112+ /* タスク */
113+
114+// if() /* 全てのタスクがDOMANT? */
115+// {
116+// break;
117+// }
118+
119+ /* タスクをディスパッチ */
120+ tsk_dispatch();
121+ }
122+
123+ depend_message_show("uITRONを終わるYO!");
124+
125+ /* 環境依存部分の終了 */
126+ depend_terminate();
127+
128+ return E_OK;
129+}
130+
131+/* カーネルの終了処理 */
132+static void it3_terminate(void)
133+{
134+ INT cnt, cnt_max;
135+
136+ cnt_max = ARRAY_CNT(term_funcs);
137+ for(cnt = 0;cnt < cnt_max;cnt++)
138+ {
139+ (term_funcs[cnt])();
140+ }
141+
142+ depend_terminate();
143+}
144+
145+/* カーネルのエントリーポイント */
146+ER IT3_main(const T_IT3_ARG *p_arg)
147+{
148+ int result;
149+ ER ret;
150+
151+ it3_debug_initialize();
152+
153+ IT3_LOG("-->it3_main");
154+
155+ /* ハードウェア依存の初期化処理 */
156+ ret = (ISVALID_PTR(p_arg->pf_hw_init)) ? (p_arg->pf_hw_init)() : E_OK;
157+ if(E_OK == ret)
158+ {
159+ /* カーネル自身の初期化処理 */
160+ ret = it3_initialize();
161+ if(E_OK == ret)
162+ {
163+ /* 静的APIの処理 */
164+ /* 今のところ静的APIは未実装なので、することが無い */
165+
166+ /* ユーザースタートアップ */
167+ ret = (p_arg->pf_startup)();
168+ if(E_OK == ret)
169+ {
170+ /* カーネルの動作開始 */
171+ it3_run();
172+
173+ result = E_OK;
174+ }
175+ else
176+ {
177+ IT3_LOG1("user startup failure[ret:%d].", ret);
178+ result = ret;
179+ }
180+
181+ /* カーネルの終了 */
182+ it3_terminate();
183+ }
184+ else
185+ {
186+ IT3_LOG1("it3 init failure.[ercd:%d]", ret);
187+ result = ret;
188+ }
189+
190+ /* ハードウェアの終了処理 */
191+ if(ISVALID_PTR(p_arg->pf_hw_term))
192+ {
193+ (p_arg->pf_hw_term)();
194+ }
195+ }
196+ else
197+ {
198+ IT3_LOG1("hardware init failure.[ret:%d]", ret);
199+ result = ret;
200+ }
201+
202+ IT3_LOG("<--it3_main");
203+
204+ it3_debug_terminate();
205+
206+ return result;
207+}
208+
209+/* 割込み信号設定 */
210+ER IT3_interrupt_signel(UINT intno)
211+{
212+ return set_int(intno);
213+}
--- /dev/null
+++ b/src/it3_common.h
@@ -0,0 +1,16 @@
1+#ifndef _IT3_COMMON_H_
2+#define _IT3_COMMON_H_
3+
4+#include <itron.h>
5+
6+#ifdef NULL
7+#undef NULL
8+#endif /* NULL */
9+#define NULL ((void *)0)
10+
11+#define ISVALID_PTR(ptr) ((NULL != (ptr)) && (((void *)NADR) != (ptr)))
12+#define ISVALID_TMOUT(tmout) ((0 < (tmout)) || (TMO_FEVR == (tmout)) || (TMO_POL == (tmout)))
13+
14+#define ARRAY_CNT(ar) (sizeof(ar) / sizeof(ar[0]))
15+
16+#endif /* _IT3_COMMON_H_ */
--- /dev/null
+++ b/src/it3_config.h
@@ -0,0 +1,180 @@
1+#ifndef _IT3_CONFIG_H_
2+#define _IT3_CONFIG_H_
3+
4+/* task */
5+
6+/* Number of tasks */
7+#define TNUM_TSK (256)
8+
9+/* semaphore */
10+/* Number of semaphore */
11+#define TNUM_SEM (256)
12+
13+/* event flag */
14+/* Number of event flags */
15+#define TNUM_FLG (256)
16+
17+
18+/* data queue */
19+/* Number of data queue */
20+#define TNUM_DTQ (256)
21+
22+
23+/* mail box */
24+/* Number of mail box */
25+#define TNUM_MBX (256)
26+
27+
28+/* mutex */
29+/* Number of mutex */
30+#define TNUM_MTX (256)
31+
32+
33+/* message buffer */
34+/* Number of message buffer */
35+#define TNUM_MBF (256)
36+
37+
38+/* rendezvous port */
39+/* Number of rendezvous port */
40+#define TNUM_POR (256)
41+
42+
43+/* fixed-sized memory pool */
44+/* Number of fixed-sized memory pool */
45+#define TNUM_MPF (256)
46+
47+
48+/* memory pool */
49+/* Number of memory pool */
50+#define TNUM_MPL (256)
51+
52+
53+/* cyclic handler */
54+/* Number of cyclic handler */
55+#define TNUM_CYC (256)
56+
57+
58+/* alarm handler */
59+/* Number of alarm handler */
60+#define TNUM_ALM (256)
61+
62+
63+/* overrun handler */
64+/* Number of overrun handler */
65+#define TNUM_OVR (256)
66+
67+
68+/* interrupt service routine */
69+/* Number of interrupt handler */
70+#define TNUM_INH (256)
71+/* Number of interrupt service routine */
72+#define TNUM_ISR (256)
73+/* Number of interrupt number */
74+#define TNUM_INT (256)
75+
76+
77+/* super viser call */
78+/* Number of super viser call */
79+#define TNUM_SVC (256)
80+
81+
82+/* CPU exception handler */
83+/* Number of cpu exception handler */
84+#define TNUM_EXC (256)
85+
86+/* Minimum value of task priority */
87+#define TMIN_TPRI (1)
88+/* Maximum value of task priority */
89+#define TMAX_TPRI (16)
90+
91+/* Minimum value of message priority */
92+#define TMIN_MPRI (1)
93+/* Maximum value of message priority */
94+#define TMAX_MPRI (16)
95+
96+/* Maker code of kernel */
97+#define TKERNEL_MAKER (0x0000)
98+/* Production ID of kernel */
99+#define TKERNEL_PRID (0x0000)
100+/*
101+ * ITRON spec version.
102+ *
103+ * 0xABBB
104+ *
105+ * A - TRON spec kind.
106+ * 0x0 TRON共通の仕様(TADなど)
107+ * 0x1 ITRON仕様(ITRON1,ITRON2)
108+ * 0x2 BTRON仕様
109+ * 0x3 CTRON仕様
110+ * 0x5 μITRON仕様(μITRON2.0,μITRON3.0,μITRON4.0)
111+ * 0x6 μBTRON仕様
112+ *
113+ * BBB - spec version.(BCD)
114+ *
115+ * ex) uITRON 03.02.02 => 0x5322
116+ */
117+#define TKERNEL_SPVER (0x5322)
118+/* Produnction version of kernel */
119+#define TKERNEL_PRVER (0x0000)
120+/* Production number of kernel */
121+#define TKERNEL_PRNO0 (0x0000)
122+#define TKERNEL_PRNO1 (0x0000)
123+#define TKERNEL_PRNO2 (0x0000)
124+#define TKERNEL_PRNO3 (0x0000)
125+/* CPU information */
126+#define TKERNEL_CPU (0x0000)
127+/* Variation of kernel */
128+#define TKERNEL_VAR (0x0000)
129+
130+/* Maximum value of task wake-up-request count */
131+#define TMAX_WUPCNT (16)
132+/* Maximum value of task force-wait-request nest count */
133+#define TMAX_SUSCNT (16)
134+
135+/* Number of bits of task exception factor */
136+#define TBIT_TEXPTN (16)
137+/* Number of bits of event flag */
138+#define TBIT_FLGPTN (16)
139+/* Number of bits of rendezvous condition */
140+#define TBIT_RDVPTN (16)
141+
142+/* numerator of period of time tick */
143+#define TIC_NUME (1)
144+/* denominator of period of time tick */
145+#define TIC_DENO (1)
146+
147+/* Size of data-queue-area required to store pieces of dtqcnt (bytes) */
148+#define TSZ_DTQ(dtqcnt) ((SIZE)((UINT)(dtqcnt) * 1))
149+/* 送信されるメッセージの優先度の最大値が maxmpri のメールボックスに
150+必要な優先度別メッセージキューヘッダ領域のサイズ(バイト数)
151+SIZE mprihdsz = TSZ_MPRIHD ( PRI maxmpri ) */
152+#define TSZ_MPRIHD(maxmpri) ((SIZE)((PRI)(maxmpri) * 4 ))
153+/* サイズが msgsz バイトのメッセージを msgcnt 個バッファリングするのに
154+必要なメッセージバッファ領域のサイズ(目安のバイト数)
155+SIZE mbfsz = TSZ_MBF ( UINT msgcnt, UINT msgsz ) */
156+#define TSZ_MBF(msgcnt, msgsz) ((SIZE)((UINT)(msgcnt) * (UINT)(msgsz)))
157+/* サイズがblkszバイトのメモリブロックをblkcnt個獲得できるのに必要な
158+固定長メモリプール領域のサイズ(バイト数)
159+SIZE mpfsz = TSZ_MPF ( UINT blkcnt, UINT blksz ) */
160+#define TSZ_MPF(blkcnt, blksz) ((SIZE)((UINT)(blkcnt) * (UINT)(blksz)))
161+/* サイズがblkszバイトのメモリブロックをblkcnt個獲得できるのに必要な
162+可変長メモリプール領域のサイズ(目安のバイト数)
163+SIZE mplsz = TSZ_MPL ( UINT blkcnt, UINT blksz ) */
164+#define TSZ_MPL(blkcnt, blksz) ((SIZE)((UINT)(blkcnt) * (UINT)(blksz)))
165+
166+/* Maximum of maximum resource number of semaphore */
167+#define TMAX_MAXSEM (256)
168+
169+
170+
171+
172+/*--------------------------------------------------------------------------*/
173+/* uITRONシミュレーションカーネルのログ出力 */
174+/* 0 : カーネルログを出力しない */
175+/* 1 : カーネルログを出力する */
176+/*--------------------------------------------------------------------------*/
177+#define UITRON_KERNEL_LOG 1
178+
179+
180+#endif /* _IT3_CONFIG_H_ */
--- /dev/null
+++ b/src/it3_debug.c
@@ -0,0 +1,28 @@
1+#include <stdio.h>
2+#include <stdarg.h>
3+#include "it3_debug.h"
4+
5+/* デバッグシステムの初期化 */
6+int it3_debug_initialize(void)
7+{
8+ return 0;
9+}
10+
11+/* デバッグシステムの終了 */
12+void it3_debug_terminate(void)
13+{
14+}
15+
16+void it3_debug_printf(const char *fmt, ...)
17+{
18+ va_list ap;
19+
20+ va_start(ap, fmt);
21+ vprintf(fmt, ap);
22+ va_end(ap);
23+}
24+
25+void it3_debug_assert(void)
26+{
27+
28+}
--- /dev/null
+++ b/src/it3_debug.h
@@ -0,0 +1,34 @@
1+#ifndef _IT3_DEBUG_H_
2+#define _IT3_DEBUG_H_
3+
4+/* デバッグシステムの初期化 */
5+int it3_debug_initialize(void);
6+
7+/* デバッグシステムの終了 */
8+void it3_debug_terminate(void);
9+
10+#ifdef _DEBUG
11+
12+extern void it3_debug_printf(const char *fmt, ...);
13+
14+#define IT3_ASSERT(s) {if(! (s)){ it3_debug_printf("Assert!:(" #s "), %s:%d\n", __FILE__, __LINE__); }}
15+
16+#define IT3_LOG(s) it3_debug_printf("[IT3] " s "\n")
17+#define IT3_LOG1(fmt, p1) it3_debug_printf("[IT3] " fmt "\n", (p1))
18+#define IT3_LOG2(fmt, p1, p2) it3_debug_printf("[IT3] " fmt "\n", (p1), (p2))
19+#define IT3_LOG3(fmt, p1, p2, p3) it3_debug_printf("[IT3] " fmt "\n", (p1), (p2), (p3))
20+#define IT3_LOG4(fmt, p1, p2, p3, p4) it3_debug_printf("[IT3] " fmt "\n", (p1), (p2), (p3), (p4))
21+
22+#else /* _DEBUG */
23+
24+#define IT3_ASSERT(s)
25+
26+#define IT3_LOG(s)
27+#define IT3_LOG1(fmt, p1)
28+#define IT3_LOG2(fmt, p1, p2)
29+#define IT3_LOG3(fmt, p1, p2, p3)
30+#define IT3_LOG4(fmt, p1, p2, p3, p4)
31+
32+#endif /* _DEBUG */
33+
34+#endif /* _IT3_DEBUG_H_ */
--- /dev/null
+++ b/src/kernel.h
@@ -0,0 +1,47 @@
1+#ifndef _KERNEL_H_
2+#define _KERNEL_H_
3+
4+#include "it3_config.h"
5+
6+#include <itron.h>
7+
8+/* カーネルデバッグ */
9+//#include "kernel_debug.h"
10+
11+/* タスクモジュール */
12+#include "tsk.h"
13+
14+#include "tim.h"
15+
16+#include "depend.h"
17+
18+
19+#if (DEPEND_TSK_NUM != TSKNUM)
20+/* 環境依存部分とシミュレーション部分のタスク数が異なっているYO!*/
21+#error DEPEND_TSK_NUM not equal TSKNUM
22+#endif /* (DEPEND_TSK_NUM != TSKNUM) */
23+
24+
25+
26+/* カーネル内主関数 */
27+/* カーネルの初期化 */
28+int kernel_initialize(void);
29+
30+/* カーネル実行 */
31+int kernel_run(void);
32+
33+/* カーネルの終了処理 */
34+int kernel_terminate(void);
35+
36+#ifdef EXTDEF
37+#define EXTERN
38+#else /* EXTDEF */
39+#define EXTERN extern
40+#endif /* EXTDEF */
41+
42+EXTERN T_TCB tcb[TNUM_TSK];
43+EXTERN T_TCBTMO tcbtmoq[TNUM_TSK];
44+EXTERN T_LST rdq[TNUM_TSK];
45+EXTERN T_TIMQ timq;
46+
47+#endif /* _KERNEL_H_ */
--- /dev/null
+++ b/src/kernel_etc.c
@@ -0,0 +1,73 @@
1+#include <stdio.h>
2+
3+#include "kernel.h"
4+
5+#include "sem.h"
6+
7+#include "que_ctl.h"
8+
9+
10+#if 0 // TODO
11+
12+/*--------------------------------------------------------------------------*/
13+/* 強制中断要求をマスクする */
14+/*--------------------------------------------------------------------------*/
15+ER sus_mask(void)
16+{
17+ ER ercd;
18+ T_TCB *p_tcb;
19+
20+ ercd = kernel_tsk_get_tcb(TSK_SELF, &p_tcb);
21+ if(E_OK != ercd)
22+ {
23+ return ercd;
24+ }
25+
26+ p_tcb->susmask = MASK; /* マスク状態設定 */
27+
28+ return E_OK;
29+}
30+
31+/*--------------------------------------------------------------------------*/
32+/* 強制中断要求マスクを解除する */
33+/*--------------------------------------------------------------------------*/
34+ER sus_free(void)
35+{
36+ ER ercd;
37+ T_TCB *p_tcb;
38+
39+ ercd = kernel_tsk_get_tcb(TSK_SELF, &p_tcb);
40+
41+ if(p_tcb->susmask == FREE ) /* マスク状態でない */
42+ {
43+ return E_NGMASK;
44+ }
45+
46+ p_tcb->susmask = FREE; /* マスク状態解除 */
47+
48+ if(0 == p_tcb->suscnt) /* 強制中断要求が1度も無かった場合 */
49+ {
50+ return E_NGSUS;
51+ }
52+
53+ /* 強制中断要求がキューイングされている場合 */
54+
55+ (p_tcb->suscnt)--;
56+
57+ del_rdq(p_tcb); /* RDQ から TCB を外す */
58+ p_tcb->tskstat = TTS_SUS; /* タスク状態をSUSPENDに */
59+
60+ /* ディスパッチされるまで待つ */
61+ kernel_tsk_wait_dispatch();
62+
63+ return E_OK;
64+}
65+
66+#endif
67+
68+
69+
70+
71+
72+
73+
--- /dev/null
+++ b/src/lst.h
@@ -0,0 +1,101 @@
1+#ifndef _LST_H_
2+#define _LST_H_
3+
4+#include <itron.h>
5+
6+#define INLINE __inline
7+
8+typedef struct S_LST {
9+ struct S_LST *p_next;
10+ struct S_LST *p_prev;
11+} T_LST;
12+
13+/**
14+ * initialize list.
15+ */
16+INLINE void lst_init(T_LST *p_lst)
17+{
18+ p_lst->p_prev = p_lst->p_next = p_lst;
19+}
20+
21+/**
22+ * list insert item.
23+ * p_lst の直前に entry を挿入する.
24+ * p_lst がキューヘッダを指す場合には,キューの最後尾に entry を挿入することになる.
25+ */
26+INLINE void lst_insert(T_LST *p_lst, T_LST *p_item)
27+{
28+ p_item->p_prev = p_lst->p_prev;
29+ p_item->p_next = p_lst;
30+ p_lst->p_prev->p_next = p_item;
31+ p_lst->p_prev = p_item;
32+}
33+
34+/*
35+ * キューからエントリを削除
36+ *
37+ * entry をキューから削除する.
38+ */
39+INLINE void lst_delete(T_LST *p_item)
40+{
41+ if (p_item->p_next != p_item)
42+ {
43+ p_item->p_prev->p_next = p_item->p_next;
44+ p_item->p_next->p_prev = p_item->p_prev;
45+ }
46+}
47+
48+/*
49+ * キューの先頭のエントリの取り出し
50+ *
51+ * p_lst の直後のエントリをキューから削除し,削除したエントリを返す.
52+ * p_lst がキューヘッダを指す場合には,キューの先頭のエントリを取り出
53+ * すことになる.
54+ */
55+INLINE T_LST * lst_delete_next(T_LST *p_lst)
56+{
57+ T_LST *p_item;
58+
59+ if (p_lst->p_next != p_lst)
60+ {
61+ p_item = p_lst->p_next;
62+ p_lst->p_next = p_item->p_next;
63+ p_item->p_next->p_prev = p_lst;
64+ }
65+ else
66+ {
67+ p_item = (void *)NADR;
68+ }
69+
70+ return (p_item);
71+}
72+
73+/*
74+ * キュー中のエントリのサーチ
75+ *
76+ * p_lst で示すキューから,offset で示すフィールドが val より大きいの
77+ * エントリをサーチし,そのエントリを返す.該当するエントリがない場合
78+ * は,p_lst を返す.
79+ */
80+INLINE T_LST * lst_search_gt(T_LST *p_lst, INT val, INT offset)
81+{
82+ T_LST *entry;
83+
84+ for (entry = p_lst->p_next; entry != p_lst; entry = entry->p_next) {
85+ if (*((INT *)(((VB *) entry) + offset)) > val) {
86+ break;
87+ }
88+ }
89+
90+ return(entry);
91+}
92+
93+/*
94+ * キューが空かどうかのチェック
95+ */
96+INLINE BOOL lst_empty(T_LST *p_lst)
97+{
98+ return ((p_lst->p_next == p_lst) ? TRUE : FALSE);
99+}
100+
101+#endif /* _LST_H_ */
--- /dev/null
+++ b/src/mbf.c
@@ -0,0 +1,247 @@
1+#include "mbf.h"
2+#include "it3_common.h"
3+#include "it3_config.h"
4+
5+#define ISVALID_MBFID(mbfid) ((0 < (mbfid)) && ((mbfid) < TNUM_MBF))
6+#define ISVALID_MBFATR(mbfatr) (TRUE) /* 属性情報はチェックしない */
7+
8+typedef struct S_MBFCB
9+{
10+ ID mbfid;
11+
12+ VP exinf; /* 拡張情報 */
13+ ATR mbfatr; /* メッセージバッファ属性 */
14+ INT bufsz; /* メッセージバッファのサイズ */
15+ INT maxmsz; /* メッセージの最大長 */
16+
17+} T_MBFCB;
18+
19+static const T_MBFCB mbfcb_initializer = {0};
20+
21+static T_MBFCB mbfcbs[TNUM_MBF];
22+
23+ER mbf_initialize(void)
24+{
25+ INT cnt;
26+
27+ for(cnt = 0;cnt < TNUM_MBF;cnt++)
28+ {
29+ mbfcbs[cnt] = mbfcb_initializer;
30+ }
31+
32+ return E_OK;
33+}
34+
35+void mbf_terminate(void)
36+{
37+}
38+
39+/* メッセージバッファ生成 */
40+ER cre_mbf(ID mbfid, T_CMBF *pk_cmbf)
41+{
42+ ER result;
43+
44+ if(ISVALID_MBFID(mbfid))
45+ {
46+ if(ISVALID_PTR(pk_cmbf) && ISVALID_MBFATR(pk_cmbf->mbfatr))
47+ {
48+ T_MBFCB *p_mbfcb;
49+
50+ p_mbfcb = &(mbfcbs[mbfid]);
51+
52+ if(0 == p_mbfcb->mbfid)
53+ {
54+ *p_mbfcb = mbfcb_initializer;
55+
56+ p_mbfcb->mbfid = mbfid;
57+ p_mbfcb->exinf = pk_cmbf->exinf;
58+ p_mbfcb->mbfatr = pk_cmbf->mbfatr;
59+ p_mbfcb->bufsz = pk_cmbf->bufsz;
60+ p_mbfcb->maxmsz = pk_cmbf->maxmsz;
61+
62+ result = E_OK;
63+ }
64+ else
65+ {
66+ result = E_OBJ;
67+ }
68+ }
69+ else
70+ {
71+ result = E_PAR;
72+ }
73+ }
74+ else
75+ {
76+ result = E_ID;
77+ }
78+
79+ return result;
80+}
81+
82+/* メッセージバッファ削除 */
83+ER del_mbf(ID mbfid)
84+{
85+ ER result;
86+
87+ if(ISVALID_MBFID(mbfid))
88+ {
89+ T_MBFCB *p_mbfcb;
90+
91+ p_mbfcb = &(mbfcbs[mbfid]);
92+
93+ if(0 != p_mbfcb->mbfid)
94+ {
95+ *p_mbfcb = mbfcb_initializer;
96+
97+ result = E_OK;
98+ }
99+ else
100+ {
101+ result = E_NOEXS;
102+ }
103+ }
104+ else
105+ {
106+ result = E_ID;
107+ }
108+
109+ return result;
110+}
111+
112+/* メッセージバッファへ送信 */
113+ER snd_mbf(ID mbfid, VP msg, INT msgsz)
114+{
115+ return tsnd_mbf(mbfid, msg, msgsz, TMO_FEVR);
116+}
117+
118+/* メッセージバッファへ送信(ポーリング) */
119+ER psnd_mbf(ID mbfid, VP msg, INT msgsz)
120+{
121+ return tsnd_mbf(mbfid, msg, msgsz, TMO_POL);
122+}
123+
124+/* メッセージバッファへ送信(タイムアウト有) */
125+ER tsnd_mbf(ID mbfid, VP msg, INT msgsz, TMO tmout)
126+{
127+ ER result;
128+
129+ if(ISVALID_MBFID(mbfid))
130+ {
131+ if(ISVALID_PTR(msg) && (0 < msgsz) && ISVALID_TMOUT(tmout))
132+ {
133+ T_MBFCB *p_mbfcb;
134+
135+ p_mbfcb = &(mbfcbs[mbfid]);
136+
137+ if(0 != p_mbfcb->mbfid)
138+ {
139+ // TODO どうしよっかなー
140+ result = E_NOSPT;
141+ }
142+ else
143+ {
144+ result = E_NOEXS;
145+ }
146+ }
147+ else
148+ {
149+ result = E_PAR;
150+ }
151+ }
152+ else
153+ {
154+ result = E_ID;
155+ }
156+
157+ return result;
158+}
159+
160+/* メッセージバッファから受信 */
161+ER rcv_mbf(VP msg, INT *p_msgsz, ID mbfid)
162+{
163+ return trcv_mbf(msg, p_msgsz, mbfid, TMO_FEVR);
164+}
165+
166+/* メッセージバッファから受信(ポーリング) */
167+ER prcv_mbf(VP msg, INT *p_msgsz, ID mbfid)
168+{
169+ return trcv_mbf(msg, p_msgsz, mbfid, TMO_POL);
170+}
171+
172+/* メッセージバッファから受信(タイムアウト有) */
173+ER trcv_mbf(VP msg, INT *p_msgsz, ID mbfid, TMO tmout)
174+{
175+ ER result;
176+
177+ if(ISVALID_MBFID(mbfid))
178+ {
179+ if(ISVALID_PTR(msg) && ISVALID_PTR(p_msgsz) && ISVALID_TMOUT(tmout))
180+ {
181+ T_MBFCB *p_mbfcb;
182+
183+ p_mbfcb = &(mbfcbs[mbfid]);
184+
185+ if(0 != p_mbfcb->mbfid)
186+ {
187+ // TODO どうしよっかなー
188+ result = E_NOSPT;
189+ }
190+ else
191+ {
192+ result = E_NOEXS;
193+ }
194+ }
195+ else
196+ {
197+ result = E_PAR;
198+ }
199+ }
200+ else
201+ {
202+ result = E_ID;
203+ }
204+
205+ return result;
206+}
207+
208+/* メッセージバッファ状態参照 */
209+ER ref_mbf(T_RMBF *pk_rmbf, ID mbfid)
210+{
211+ ER result;
212+
213+ if(ISVALID_MBFID(mbfid))
214+ {
215+ if(ISVALID_PTR(pk_rmbf))
216+ {
217+ T_MBFCB *p_mbfcb;
218+
219+ p_mbfcb = &(mbfcbs[mbfid]);
220+
221+ if(0 != p_mbfcb->mbfid)
222+ {
223+ pk_rmbf->exinf = p_mbfcb->exinf;
224+ pk_rmbf->wtsk = FALSE; // TODO どうしよっかなー
225+ pk_rmbf->stsk = FALSE; // TODO どうしよっかなー
226+ pk_rmbf->msgsz = 0; // TODO どうしよっかなー
227+ pk_rmbf->frbufsz = 0; // TODO どうしよっかなー
228+
229+ result = E_OK;
230+ }
231+ else
232+ {
233+ result = E_NOEXS;
234+ }
235+ }
236+ else
237+ {
238+ result = E_PAR;
239+ }
240+ }
241+ else
242+ {
243+ result = E_ID;
244+ }
245+
246+ return result;
247+}
--- /dev/null
+++ b/src/mbf.h
@@ -0,0 +1,9 @@
1+#ifndef _MBF_H_
2+#define _MBF_H_
3+
4+#include <itron.h>
5+
6+ER mbf_initialize(void);
7+void mbf_terminate(void);
8+
9+#endif /* _MBF_H_ */
--- /dev/null
+++ b/src/mbx.c
@@ -0,0 +1,753 @@
1+#include "mbx.h"
2+#include "it3_common.h"
3+#include "it3_debug.h"
4+#include "lst.h"
5+
6+#include "kernel.h"
7+#include "que_ctl.h"
8+
9+
10+#define ISVALID_MBXID(mbxid) ((0 < (mbxid)) && ((mbxid) < TNUM_MBX))
11+#define ISVALID_MBXATR(mbxatr) (TRUE) /* 属性値はチェックしない */
12+
13+/* メイルボックスキュー管理ブロック(MBXQ) */
14+typedef struct S_MBXCB
15+{
16+ ID mbxid;
17+
18+ VP exinf;
19+ ATR mbxatr;
20+ INT bufcnt;
21+
22+ T_LST wtsklst;
23+
24+ T_MSG *p_mhead;
25+
26+
27+ T_TCB *head; /* 先頭TCBへのポインタ */
28+ T_MSG *msg; /* 先頭メッセージへのポインタ */
29+ VH wtskmode; /* 待ち順序 */
30+ VH wmsgmode; /* 待ち順序 */
31+ VB dmy[4]; /* ダミー */
32+} T_MBXCB;
33+
34+
35+static const T_MBXCB mbxcb_initializer = {0};
36+
37+static T_MBXCB mbxcbs[TNUM_MBX];
38+
39+/*--------------------------------------------------------------------------*/
40+/* メッセージ待ちキューにタスクを追加 */
41+/*--------------------------------------------------------------------------*/
42+static void add_mbxq(T_MBXCB *p_mbxcb, T_TCB *p_tcb)
43+{
44+ IT3_ASSERT(p_mbxcb);
45+ IT3_ASSERT(p_tcb);
46+
47+ if(TA_TPRI & p_mbxcb->mbxatr)
48+ {
49+ T_LST *p_insert_pos;
50+
51+ p_insert_pos = p_mbxcb->wtsklst.p_next;
52+
53+ while(&(p_mbxcb->wtsklst) != p_insert_pos)
54+ {
55+ if(p_tcb->tskpri < ((T_TCB *)p_insert_pos)->tskpri)
56+ {
57+ break;
58+ }
59+
60+ p_insert_pos = p_insert_pos->p_next;
61+ }
62+
63+ lst_insert(p_insert_pos, (T_LST *)p_tcb);
64+ }
65+ else
66+ {
67+ lst_insert(&(p_mbxcb->wtsklst), (T_LST *)p_tcb);
68+ }
69+
70+#if 0 // lstに変える
71+ T_MBXCB *p_mbxq;
72+ T_TCB *toptcb, *endtcb, *nextcb, *pretcb;
73+
74+ p_mbxq = &(mbxcbs[p_tcb->wid]);
75+
76+ toptcb = p_mbxq->head;
77+ if(NULL != toptcb)
78+ {
79+ /*-------------------- 他のタスクがある --------------------*/
80+ if(p_mbxq->wtskmode == TA_TFIFO) /* 待ち順序は FIFO */
81+ {
82+ /* 一番後ろにつなげる */
83+ endtcb = toptcb->prev;
84+ p_tcb->prev = endtcb;
85+ p_tcb->next = toptcb;
86+ toptcb->prev = p_tcb;
87+ endtcb->next = p_tcb;
88+ }
89+ else /* 待ち順序は 優先順 */
90+ {
91+ /* 挿入場所を探してつなげる */
92+ endtcb = toptcb->prev;
93+ nextcb = toptcb;
94+
95+ do
96+ {
97+ if( p_tcb->pri < nextcb->pri )
98+ {
99+ pretcb = nextcb->prev;
100+
101+ p_tcb->prev = pretcb;
102+ p_tcb->next = nextcb;
103+ nextcb->prev = p_tcb;
104+ pretcb->next = p_tcb;
105+
106+ if( nextcb == toptcb )
107+ {
108+ p_mbxq->head = p_tcb;
109+ }
110+ break;
111+ }
112+
113+ nextcb = nextcb->next;
114+
115+ } while( (nextcb != toptcb)&&(mbxcbs->head != NULL) );
116+
117+ if( nextcb == toptcb )
118+ {
119+ p_tcb->prev = endtcb;
120+ p_tcb->next = toptcb;
121+ toptcb->prev = p_tcb;
122+ endtcb->next = p_tcb;
123+ }
124+ }
125+ }
126+ else
127+ {
128+ /*-------------------- 他のタスクがない --------------------*/
129+ mbxcbs->head = p_tcb;
130+ p_tcb->next = p_tcb;
131+ p_tcb->prev = p_tcb;
132+ }
133+
134+ return;
135+#endif
136+}
137+
138+/*--------------------------------------------------------------------------*/
139+/* メッセージ待ちキューからタスクを削除 */
140+/*--------------------------------------------------------------------------*/
141+static void del_mbxq(T_MBXCB *p_mbxcb, T_TCB *p_tcb)
142+{
143+ IT3_ASSERT(p_tcb);
144+
145+ lst_delete((T_LST *)p_tcb);
146+
147+#if 0 // lstに変える
148+ T_MBXCB *p_mbxq;
149+ T_TCB *pretcb, *nextcb;
150+
151+ p_mbxq = &(mbxcbs[deltcb->wid]);
152+
153+ pretcb = deltcb->prev;
154+ if(pretcb != deltcb)
155+ {
156+ /*-------------------- 他のタスクがある --------------------*/
157+ nextcb = deltcb->next;
158+ pretcb->next = nextcb;
159+ nextcb->prev = pretcb;
160+ if(p_mbxq->head == deltcb)
161+ {
162+ mbxcbs->head = nextcb;
163+ }
164+ }
165+ else
166+ {
167+ /*-------------------- 他のタスクがない --------------------*/
168+ mbxcbs->head = NULL;
169+ }
170+
171+ /*deltcb->prev = NULL;*/
172+ /*deltcb->next = NULL;*/
173+
174+ return;
175+#endif
176+}
177+
178+/*--------------------------------------------------------------------------*/
179+/* メッセージキューにメッセージを追加 */
180+/*--------------------------------------------------------------------------*/
181+void add_msg(ID mbxid, T_MSG *addmsg)
182+{
183+ T_MBXCB *p_mbxq;
184+ T_MSG *topmsg, *endmsg, *nexmsg, *premsg;
185+
186+ p_mbxq = &(mbxcbs[mbxid]);
187+
188+ topmsg = mbxcbs->msg;
189+ if(topmsg != NULL)
190+ {
191+ /*-------------------- 他のメッセージがある --------------------*/
192+ if( mbxcbs->wmsgmode == TA_TFIFO ) /* 待ち順序は FIFO */
193+ {
194+ /* 一番後ろにつなげる */
195+ endmsg = topmsg->pk_prev;
196+ addmsg->pk_prev = endmsg;
197+ addmsg->pk_next = topmsg;
198+ topmsg->pk_prev = addmsg;
199+ endmsg->pk_next = addmsg;
200+ }
201+ else /* 待ち順序は 優先順 */
202+ {
203+ /* 挿入場所を探してつなげる */
204+ endmsg = topmsg->pk_prev;
205+ nexmsg = topmsg;
206+
207+ do
208+ {
209+ if( tcb[addmsg->tskid].tskpri < tcb[nexmsg->tskid].tskpri )
210+ {
211+ premsg = nexmsg->pk_prev;
212+
213+ addmsg->pk_prev = premsg;
214+ addmsg->pk_next = nexmsg;
215+ nexmsg->pk_prev = addmsg;
216+ premsg->pk_next = addmsg;
217+
218+ if( nexmsg == topmsg )
219+ {
220+ mbxcbs->msg = addmsg;
221+ }
222+
223+ break;
224+ }
225+
226+ nexmsg = nexmsg->pk_next;
227+
228+ } while( (nexmsg != topmsg)&&(mbxcbs->msg != NULL) );
229+
230+ if( nexmsg == topmsg )
231+ {
232+ addmsg->pk_prev = endmsg;
233+ addmsg->pk_next = topmsg;
234+ topmsg->pk_prev = addmsg;
235+ endmsg->pk_next = addmsg;
236+ }
237+ }
238+ }
239+ else
240+ {
241+ /*-------------------- 他のメッセージがない --------------------*/
242+ mbxcbs->msg = addmsg;
243+ addmsg->pk_next = addmsg;
244+ addmsg->pk_prev = addmsg;
245+ }
246+
247+ return;
248+}
249+
250+/*--------------------------------------------------------------------------*/
251+/* メッセージキューからメッセージを削除 */
252+/*--------------------------------------------------------------------------*/
253+void del_msg(ID mbxid, T_MSG *delmsg)
254+{
255+ T_MBXCB *p_mbxq;
256+ T_MSG *premsg, *nexmsg;
257+
258+ p_mbxq = &(mbxcbs[mbxid]);
259+
260+ premsg = delmsg->pk_prev;
261+ if(premsg != delmsg )
262+ {
263+ /*-------------------- 他のメッセージがある --------------------*/
264+ nexmsg = delmsg->pk_next;
265+ premsg->pk_next = nexmsg;
266+ nexmsg->pk_prev = premsg;
267+
268+ if(p_mbxq->msg == delmsg)
269+ {
270+ mbxcbs->msg = nexmsg;
271+ }
272+ }
273+ else
274+ {
275+ /*-------------------- 他のメッセージがない --------------------*/
276+ p_mbxq->msg = NULL;
277+ }
278+
279+ delmsg->pk_next = NULL;
280+ delmsg->pk_prev = NULL;
281+
282+ return;
283+}
284+
285+
286+ER mbx_initialize(void)
287+{
288+ INT cnt;
289+
290+ for(cnt = 0;cnt < TNUM_MBX;cnt++)
291+ {
292+ mbxcbs[cnt] = mbxcb_initializer;
293+ lst_init(&(mbxcbs[cnt].wtsklst));
294+ }
295+
296+ return E_OK;
297+}
298+
299+void mbx_terminate(void)
300+{
301+}
302+
303+/* メイルボックス生成 */
304+ER cre_mbx(ID mbxid, T_CMBX* pk_cmbx)
305+{
306+ ER result;
307+
308+ if(ISVALID_MBXID(mbxid))
309+ {
310+ if(ISVALID_PTR(pk_cmbx) && ISVALID_MBXATR(pk_cmbx->mbxatr))
311+ {
312+ T_MBXCB *p_mbxcb;
313+
314+ p_mbxcb = &(mbxcbs[mbxid]);
315+
316+ if(0 == p_mbxcb->mbxid)
317+ {
318+ *p_mbxcb = mbxcb_initializer;
319+
320+ p_mbxcb->mbxid = mbxid;
321+
322+ p_mbxcb->exinf = pk_cmbx->exinf;
323+ p_mbxcb->mbxatr = pk_cmbx->mbxatr;
324+ p_mbxcb->bufcnt = pk_cmbx->bufcnt;
325+
326+ lst_init(&(p_mbxcb->wtsklst));
327+
328+ result = E_OK;
329+ }
330+ else
331+ {
332+ result = E_OBJ;
333+ }
334+ }
335+ else
336+ {
337+ result = E_PAR;
338+ }
339+ }
340+ else
341+ {
342+ result = E_ID;
343+ }
344+
345+ return result;
346+}
347+
348+/* メイルボックス削除 */
349+ER del_mbx(ID mbxid)
350+{
351+ ER result;
352+
353+ if(ISVALID_MBXID(mbxid))
354+ {
355+ T_MBXCB *p_mbxcb;
356+
357+ p_mbxcb = &(mbxcbs[mbxid]);
358+
359+ if(0 != p_mbxcb->mbxid)
360+ {
361+ // TODO どうしよっかなー
362+
363+ *p_mbxcb = mbxcb_initializer;
364+
365+ result = E_OK;
366+ }
367+ else
368+ {
369+ result = E_NOEXS;
370+ }
371+ }
372+ else
373+ {
374+ result = E_ID;
375+ }
376+
377+ return result;
378+}
379+
380+/* メイルボックスへ送信 */
381+ER snd_msg(ID mbxid, T_MSG *pk_msg)
382+{
383+ ER result;
384+
385+ if(ISVALID_MBXID(mbxid))
386+ {
387+ if(ISVALID_PTR(pk_msg))
388+ {
389+ T_MBXCB *p_mbxcb;
390+
391+ p_mbxcb = &(mbxcbs[mbxid]);
392+
393+ // TODO どうしよっかなー
394+
395+ result = E_OK;
396+ }
397+ else
398+ {
399+ result = E_PAR;
400+ }
401+ }
402+ else
403+ {
404+ result = E_ID;
405+ }
406+
407+ return result;
408+
409+
410+#if 0
411+ T_MBXCB *p_mbxq;
412+ T_TCB *p_tcb;
413+
414+ /*-------------------- パラメータエラー判定 ---------------------*/
415+ if(! ISVALID_MBXID(mbxid))
416+ {
417+ return E_ID;
418+ }
419+
420+ p_mbxq = &(mbxcbs[mbxid]);
421+
422+ if((0 != pk_msg->pk_next) || (0 != pk_msg->pk_prev))
423+ {
424+ /* OS管理領域が初期化されていない */
425+ return E_PAR;
426+ }
427+
428+ /* 送信タスクIDを記録 */
429+ kernel_tsk_get_self_tskid(&(pk_msg->tskid));
430+
431+ if(NULL == mbxcbs->head)
432+ {
433+ /*---------------- メッセージ待ちのタスクがない -----------------*/
434+ /* メッセージを待ち行列につなげる */
435+ add_msg(mbxid, pk_msg);
436+ }
437+ else
438+ {
439+ /*---------------- メッセージ待ちのタスクがある -----------------*/
440+ p_tcb = mbxcbs->head;
441+
442+ *((T_MSG **)(p_tcb->arg)) = pk_msg; /* メッセージを渡す */
443+
444+ del_mbxq(p_mbxq, p_tcb); /* MBXQ から TCB を外す */
445+
446+ if(p_tcb->tskstat & TTS_SUS)
447+ {
448+ /* 二重待ち状態 */
449+ p_tcb->tskstat = TTS_SUS; /* タスク状態を SUSPEND に */
450+ }
451+ else
452+ {
453+ /* メッセージ待ち状態 */
454+ p_tcb->tskstat = TTS_RDY; /* タスク状態を READY に */
455+ p_tcb->tskwait = 0;
456+ p_tcb->wid = 0;
457+ add_rdq(p_tcb); /* RDQ に TCB をつなげる */
458+ }
459+
460+ /* ディスパッチされるまで待つ */
461+ tsk_wait_dispatch();
462+ }
463+
464+ return E_OK;
465+#endif
466+}
467+
468+/* メイルボックスへ送信(割り込みハンドラ専用) */
469+ER isnd_msg(ID mbxid, T_MSG *pk_msg)
470+{
471+ return snd_msg(mbxid, pk_msg);
472+}
473+
474+/* メイルボックスから受信 */
475+ER rcv_msg(T_MSG **ppk_msg, ID mbxid)
476+{
477+ return trcv_msg(ppk_msg, mbxid, TMO_FEVR);
478+
479+#if 0
480+ T_MBXCB *p_mbxq;
481+ T_TCB *p_tcb;
482+ T_MSG *p_msg;
483+
484+// if( DSPENA == OFF ) { /* ディスパッチ禁止状態 */
485+// return( E_CTX );
486+// }
487+
488+ /*-------------------- パラメータエラー判定 ---------------------*/
489+ if(! ISVALID_MBXID(mbxid))
490+ {
491+ /* ID範囲外 */
492+ return E_ID;
493+ }
494+
495+ p_mbxq = &(mbxcbs[mbxid]);
496+
497+ if(NULL != p_mbxq->msg)
498+ {
499+ /*----------------------- メッセージがある ----------------------*/
500+ p_msg = p_mbxq->msg;
501+ *pk_msg = (T_MSG *)p_msg; /* メッセージを受け取る */
502+
503+ del_msg(mbxid, p_msg); /* MBXQ から メッセージを外す */
504+ }
505+ else
506+ {
507+ ER ercd;
508+
509+ /*----------------------- メッセージがない ----------------------*/
510+ ercd = kernel_tsk_get_tcb(TSK_SELF, &p_tcb);
511+ if(E_OK != ercd)
512+ {
513+ return ercd;
514+ }
515+
516+ del_rdq(p_tcb); /* RDQ から TCB を外す */
517+
518+ p_tcb->tskstat = TTS_WAI;
519+ p_tcb->tskwait = TTW_MBX;
520+ p_tcb->wid = mbxid;
521+
522+ p_tcb->arg = (VB *)pk_msg; /* 戻り値用のアドレスを保存 */
523+ add_mbxq(p_tcb); /* MBXQ に TCB をつなげる */
524+
525+ /* ディスパッチされるまで待つ */
526+ tsk_wait_dispatch();
527+ }
528+
529+ return E_OK;
530+#endif
531+}
532+
533+/* メイルボックスから受信(ポーリング) */
534+ER prcv_msg(T_MSG **ppk_msg, ID mbxid)
535+{
536+ return trcv_msg(ppk_msg, mbxid, TMO_POL);
537+
538+#if 0
539+ T_MBXCB *p_mbxq;
540+ T_MSG *p_msg;
541+
542+ /*-------------------- パラメータエラー判定 ---------------------*/
543+ if(! ISVALID_MBXID(mbxid))
544+ {
545+ /* ID範囲外 */
546+ return E_ID;
547+ }
548+
549+ p_mbxq = &(mbxcbs[mbxid]);
550+
551+ if(NULL == p_mbxq->msg) /* メッセージがない? */
552+ {
553+ return E_TMOUT;
554+ }
555+
556+ /*----------------------- メッセージがある ----------------------*/
557+ p_msg = mbxcbs->msg;
558+ *pk_msg = (T_MSG *)p_msg; /* メッセージを受け取る */
559+
560+ del_msg(mbxid, p_msg); /* MBXQ から メッセージを外す */
561+
562+ return E_OK;
563+#endif
564+}
565+
566+/* メイルボックスから受信(タイムアウト有) */
567+ER trcv_msg(T_MSG **ppk_msg, ID mbxid, TMO tmout)
568+{
569+ ER result;
570+
571+ if(ISVALID_MBXID(mbxid))
572+ {
573+ if(ISVALID_PTR(ppk_msg) && ISVALID_TMOUT(tmout))
574+ {
575+ T_MBXCB *p_mbxcb;
576+
577+ p_mbxcb = &(mbxcbs[mbxid]);
578+
579+ if(0 != p_mbxcb->mbxid)
580+ {
581+ if(p_mbxcb->p_mhead)
582+ {
583+ *ppk_msg = p_mbxcb->p_mhead;
584+ p_mbxcb->p_mhead = p_mbxcb->p_mhead->pk_next;
585+
586+ result = E_OK;
587+ }
588+ else
589+ {
590+ result = E_TMOUT;
591+ if(tmout != TMO_POL) {
592+// ctxtsk->wspec = (mbxcb->mbxatr & TA_TPRI) ?
593+// &wspec_mbx_tpri : &wspec_mbx_tfifo;
594+// ctxtsk->wercd = &ercd;
595+// ctxtsk->winfo.mbx.ppk_msg = ppk_msg;
596+// gcb_make_wait((GCB *) mbxcb, tmout);
597+ }
598+ }
599+ }
600+ else
601+ {
602+ result = E_NOEXS;
603+ }
604+ }
605+ else
606+ {
607+ result = E_PAR;
608+ }
609+ }
610+ else
611+ {
612+ result = E_ID;
613+ }
614+
615+ return result;
616+}
617+
618+/* メイルボックス状態参照 */
619+ER ref_mbx(T_RMBX *pk_rmbx, ID mbxid)
620+{
621+ ER result;
622+
623+ if(ISVALID_MBXID(mbxid))
624+ {
625+ if(pk_rmbx)
626+ {
627+ T_MBXCB *p_mbxcb;
628+
629+ p_mbxcb = &(mbxcbs[mbxid]);
630+
631+ if(0 != p_mbxcb->mbxid)
632+ {
633+ pk_rmbx->exinf = p_mbxcb->exinf;
634+ pk_rmbx->wtsk = TSK_GET_WTSKID(&(p_mbxcb->wtsklst));
635+ pk_rmbx->pk_msg = NULL; // TODO どうしよっかなー
636+
637+ result = E_OK;
638+ }
639+ else
640+ {
641+ result = E_NOEXS;
642+ }
643+ }
644+ else
645+ {
646+ result = E_PAR;
647+ }
648+ }
649+ else
650+ {
651+ result = E_ID;
652+ }
653+
654+ return result;
655+
656+}
657+
658+/*--------------------------------------------------------------------------*/
659+/* メイルボックス状態を参照する */
660+/*--------------------------------------------------------------------------*/
661+ER mbx_sts(ID *p_wtskid, T_MSG **ppk_msg, ID mbxid)
662+{
663+ T_MBXCB *p_mbxq;
664+
665+ /*-------------------- パラメータエラー判定 ---------------------*/
666+ if(! ISVALID_MBXID(mbxid))
667+ {
668+ /* ID範囲外 */
669+ return E_ID;
670+ }
671+
672+ p_mbxq = &(mbxcbs[mbxid]);
673+
674+ *ppk_msg = (T_MSG *)NADR;
675+ *p_wtskid = FALSE;
676+
677+ if(NULL != p_mbxq->head)
678+ {
679+ /* 待ちタスクがある */
680+ *p_wtskid = p_mbxq->head->tskid; /* 先頭の待ちタスクIDを設定 */
681+ }
682+ else if(NULL != p_mbxq->msg)
683+ {
684+ /* メッセージがある */
685+ *ppk_msg = p_mbxq->msg; /* 先頭のメッセージアドレスを設定 */
686+ }
687+
688+ return E_OK;
689+}
690+
691+/*--------------------------------------------------------------------------*/
692+/* 自タスクが送信したメッセージを待ちキューから外す(終了処理専用) */
693+/*--------------------------------------------------------------------------*/
694+ER edel_msg(ID mbxid)
695+{
696+ T_MBXCB *p_mbxq;
697+ T_MSG *topmsg, *nextmsg, *msg;
698+ UH msgnum, d_msgnum;
699+ UH i;
700+
701+ /*-------------------- パラメータエラー判定 ---------------------*/
702+ if((mbxid < 0) || (TNUM_MBX <= mbxid))
703+ {
704+ /* ID範囲外 */
705+ return E_ID;
706+ }
707+
708+ d_msgnum = 0;
709+
710+ p_mbxq = &(mbxcbs[mbxid]);
711+
712+ if(NULL != p_mbxq->msg)
713+ {
714+ /*- メッセージがある -*/
715+ ID tskid;
716+ tskid = kernel_tsk_get_self_tskid(TSK_SELF);
717+
718+ topmsg = msg = p_mbxq->msg;
719+
720+ /* メッセージの数を数える */
721+ msgnum = 0;
722+ do
723+ {
724+ msgnum++;
725+ msg = msg->pk_next;
726+ } while(topmsg != msg);
727+
728+ msg = topmsg;
729+
730+ for(i = 0;i < msgnum;i++)
731+ {
732+ if(msg->tskid == tskid)
733+ {
734+ nextmsg = msg->pk_next;
735+ del_msg(mbxid, msg); /* MBXQ から メッセージを外す */
736+ msg = nextmsg;
737+ d_msgnum++;
738+ }
739+ else
740+ {
741+ msg = msg->pk_next;
742+ }
743+ }
744+ }
745+
746+ if(0 == d_msgnum)
747+ {
748+ return E_OBJ;
749+ }
750+
751+ return E_OK;
752+}
753+
--- /dev/null
+++ b/src/mbx.h
@@ -0,0 +1,9 @@
1+#ifndef _MBX_H_
2+#define _MBX_H_
3+
4+#include <itron.h>
5+
6+ER mbx_initialize(void);
7+void mbx_terminate(void);
8+
9+#endif /* _MBX_H_ */
--- /dev/null
+++ b/src/mpf.c
@@ -0,0 +1,371 @@
1+#include "mpf.h"
2+#include "it3_common.h"
3+#include "it3_config.h"
4+#include <depend.h>
5+#include "tsk.h"
6+
7+#define ISVALID_MPFID(mpfid) ((0 < (mpfid)) && ((mpfid) < TNUM_MPF))
8+#define ISVALID_MPFATR(mpfatr) (0 == ((mpfatr) & ~(TA_TPRI)))
9+#define ISVALID_BLF(blf, p_mpf, mpfcnt, blfsz) (0 == ((mpfatr) & ~(TA_TPRI)))
10+
11+typedef struct S_MPFCB
12+{
13+ ID mpfid;
14+
15+ VP exinf; /* 拡張情報 */
16+ ATR mpfatr; /* メモリプール属性 */
17+ INT mpfcnt; /* メモリプール全体のブロック数 */
18+ INT blfsz; /* 固定長メモリブロックサイズ */
19+
20+ T_LST wtsklst; /* 待ちタスクリスト */
21+ INT frbcnt; /* 空きブロックの数 */
22+ T_LST frblst; /* 空きブロックのリスト */
23+ B *p_mpf; /* メモリプールのアドレス */
24+} T_MPFCB;
25+
26+static const T_MPFCB mpfcb_initializer = {0};
27+
28+static T_MPFCB mpfcbs[TNUM_MPF];
29+
30+static void build_frblst(T_LST *p_frblst, B *p_mpf, INT mpfcnt, INT blfsz)
31+{
32+ INT cnt;
33+
34+ lst_init(p_frblst);
35+
36+ for(cnt = 0;cnt < mpfcnt;cnt++)
37+ {
38+ lst_insert(p_frblst, (T_LST *)(p_mpf + (blfsz * cnt)));
39+ }
40+}
41+
42+static BOOL is_valid_blf(VP blf, B *p_mpf, INT mpfcnt, INT blfsz)
43+{
44+ BOOL result = FALSE;
45+
46+ if((p_mpf <= (B *)blf) && ((B *)blf < (p_mpf + (mpfcnt * blfsz))))
47+ {
48+ if(0 == (((B *)blf - p_mpf) % blfsz))
49+ {
50+ result = TRUE;
51+ }
52+ }
53+
54+ return result;
55+}
56+
57+ER mpf_initialize(void)
58+{
59+ INT cnt;
60+
61+ for(cnt = 0;cnt < TNUM_MPF;cnt++)
62+ {
63+ mpfcbs[cnt] = mpfcb_initializer;
64+ }
65+
66+ return E_OK;
67+}
68+
69+void mpf_terminate(void)
70+{
71+}
72+
73+ER cre_mpf(ID mpfid, T_CMPF *pk_cmpf)
74+{
75+ ER result;
76+
77+ if(ISVALID_MPFID(mpfid))
78+ {
79+ if(ISVALID_PTR(pk_cmpf) && ISVALID_MPFATR(pk_cmpf->mpfatr))
80+ {
81+ T_MPFCB *p_mpfcb;
82+
83+ p_mpfcb = &(mpfcbs[mpfid]);
84+
85+ depend_EnterCriticalSection();
86+
87+ if(0 == p_mpfcb->mpfid)
88+ {
89+ B *p_mpf;
90+
91+ p_mpf = (B *)depend_malloc(pk_cmpf->blfsz * pk_cmpf->mpfcnt);
92+ if(ISVALID_PTR(p_mpf))
93+ {
94+ *p_mpfcb = mpfcb_initializer;
95+
96+ p_mpfcb->mpfid = mpfid;
97+
98+ p_mpfcb->exinf = pk_cmpf->exinf;
99+ p_mpfcb->mpfatr = pk_cmpf->mpfatr;
100+ p_mpfcb->mpfcnt = pk_cmpf->mpfcnt;
101+ p_mpfcb->blfsz = pk_cmpf->blfsz;
102+
103+ lst_init(&(p_mpfcb->wtsklst));
104+ p_mpfcb->frbcnt = pk_cmpf->mpfcnt;
105+ build_frblst(&(p_mpfcb->frblst), p_mpf, p_mpfcb->mpfcnt, p_mpfcb->blfsz);
106+ p_mpfcb->p_mpf = p_mpf;
107+
108+ result = E_OK;
109+ }
110+ else
111+ {
112+ result = E_NOMEM;
113+ }
114+ }
115+ else
116+ {
117+ result = E_OBJ;
118+ }
119+
120+ depend_LeaveCriticalSection();
121+ }
122+ else
123+ {
124+ result = E_PAR;
125+ }
126+ }
127+ else
128+ {
129+ result = E_ID;
130+ }
131+
132+ return result;
133+}
134+
135+ER del_mpf(ID mpfid)
136+{
137+ ER result;
138+
139+ if(ISVALID_MPFID(mpfid))
140+ {
141+ T_MPFCB *p_mpfcb;
142+
143+ p_mpfcb = &(mpfcbs[mpfid]);
144+
145+ depend_EnterCriticalSection();
146+
147+ if(0 != p_mpfcb->mpfid)
148+ {
149+ depend_free(p_mpfcb->p_mpf);
150+
151+ *p_mpfcb = mpfcb_initializer;
152+
153+ result = E_OK;
154+ }
155+ else
156+ {
157+ result = E_NOEXS;
158+ }
159+
160+ depend_LeaveCriticalSection();
161+ }
162+ else
163+ {
164+ result = E_ID;
165+ }
166+
167+ return result;
168+}
169+
170+ER get_blf(VP *p_blf, ID mpfid)
171+{
172+ return tget_blf(p_blf, mpfid, TMO_FEVR);
173+}
174+
175+ER pget_blf(VP *p_blf, ID mpfid)
176+{
177+ return tget_blf(p_blf, mpfid, TMO_POL);
178+}
179+
180+ER ipget_blf(VP *p_blf, ID mpfid)
181+{
182+ return E_NOSPT;
183+}
184+
185+ER tget_blf(VP *p_blf, ID mpfid, TMO tmout)
186+{
187+ ER result;
188+
189+ if(ISVALID_MPFID(mpfid))
190+ {
191+ if(ISVALID_PTR(p_blf) && ISVALID_TMOUT(tmout))
192+ {
193+ T_MPFCB *p_mpfcb;
194+
195+ p_mpfcb = &(mpfcbs[mpfid]);
196+
197+ depend_EnterCriticalSection();
198+
199+ if(0 != p_mpfcb->mpfid)
200+ {
201+ if(lst_empty(&(p_mpfcb->wtsklst)))
202+ {
203+ if(TMO_POL != tmout)
204+ {
205+#if 0
206+ T_TCB *p_tcb;
207+ ER ret;
208+
209+ ret = tsk_get_tcb(TSK_SELF, &p_tcb);
210+ if(E_OK == ret)
211+ {
212+ del_rdq(NULL, p_tcb);
213+ p_tcb->tskstat = TTS_WAI;
214+ p_tcb->tskwait = TTW_MPF;
215+ p_tcb->wid = mpfid;
216+ lst_insert(&(p_mpfcb->wtsklst), (T_LST *)p_tcb);
217+ result = tsk_wait(p_tcb);
218+ if(E_OK == result)
219+ {
220+ *p_blf = p_tcb->wait.wmpf.blf;
221+ }
222+ }
223+ else
224+ {
225+ result = ret;
226+ }
227+#endif
228+ // TODO 空きが無いので待つ
229+ result = E_NOSPT;
230+ }
231+ else
232+ {
233+ result = E_TMOUT;
234+ }
235+ }
236+ else
237+ {
238+ T_LST *p_frb;
239+
240+ p_frb = p_mpfcb->wtsklst.p_next;
241+ lst_delete(p_frb);
242+ (p_mpfcb->frbcnt)--;
243+
244+ *p_blf = (VP)p_frb;
245+
246+ result = E_OK;
247+ }
248+ }
249+ else
250+ {
251+ result = E_NOEXS;
252+ }
253+
254+ depend_LeaveCriticalSection();
255+ }
256+ else
257+ {
258+ result = E_PAR;
259+ }
260+ }
261+ else
262+ {
263+ result = E_ID;
264+ }
265+
266+ return result;
267+}
268+
269+ER rel_blf(ID mpfid, VP blf)
270+{
271+ ER result;
272+
273+ if(ISVALID_MPFID(mpfid))
274+ {
275+ if(ISVALID_PTR(blf))
276+ {
277+ T_MPFCB *p_mpfcb;
278+
279+ p_mpfcb = &(mpfcbs[mpfid]);
280+
281+ depend_EnterCriticalSection();
282+
283+ if(0 != p_mpfcb->mpfid)
284+ {
285+ if(is_valid_blf(blf, p_mpfcb->p_mpf, p_mpfcb->mpfcnt, p_mpfcb->blfsz))
286+ {
287+ if(lst_empty(&(p_mpfcb->wtsklst)))
288+ {
289+ lst_insert(&(p_mpfcb->frblst), (T_LST *)blf);
290+ (p_mpfcb->frbcnt)++;
291+ }
292+ else
293+ {
294+#if 0
295+ T_TCB *p_tcb;
296+
297+ p_tcb = (T_TCB *)(p_mpfcb->wtsklst.p_next);
298+ p_tcb->winfo.mpf.blf = blf;
299+ tsk_wait_release(p_tcb, E_OK);
300+#endif
301+ // TODO どうしよっかなー
302+ result = E_NOSPT;
303+ }
304+ result = E_OK;
305+ }
306+ else
307+ {
308+ result = E_PAR;
309+ }
310+ }
311+ else
312+ {
313+ result = E_NOEXS;
314+ }
315+
316+ depend_LeaveCriticalSection();
317+ }
318+ else
319+ {
320+ result = E_PAR;
321+ }
322+ }
323+ else
324+ {
325+ result = E_ID;
326+ }
327+
328+ return result;
329+}
330+
331+ER ref_mpf(T_RMPF *pk_rmpf, ID mpfid)
332+{
333+ ER result;
334+
335+ if(ISVALID_MPFID(mpfid))
336+ {
337+ if(ISVALID_PTR(pk_rmpf))
338+ {
339+ T_MPFCB *p_mpfcb;
340+
341+ p_mpfcb = &(mpfcbs[mpfid]);
342+
343+ depend_EnterCriticalSection();
344+
345+ if(0 != p_mpfcb->mpfid)
346+ {
347+ pk_rmpf->exinf = p_mpfcb->exinf;
348+ pk_rmpf->wtsk = TSK_GET_WTSKID(&(p_mpfcb->wtsklst));
349+ pk_rmpf->frbcnt = p_mpfcb->frbcnt;
350+
351+ result = E_OK;
352+ }
353+ else
354+ {
355+ result = E_NOEXS;
356+ }
357+
358+ depend_LeaveCriticalSection();
359+ }
360+ else
361+ {
362+ result = E_PAR;
363+ }
364+ }
365+ else
366+ {
367+ result = E_ID;
368+ }
369+
370+ return result;
371+}
--- /dev/null
+++ b/src/mpf.h
@@ -0,0 +1,9 @@
1+#ifndef _MPF_H_
2+#define _MPF_H_
3+
4+#include <itron.h>
5+
6+ER mpf_initialize(void);
7+void mpf_terminate(void);
8+
9+#endif /* _MPF_H_ */
--- /dev/null
+++ b/src/mpl.c
@@ -0,0 +1,232 @@
1+#include "mpl.h"
2+#include "it3_common.h"
3+#include "it3_config.h"
4+
5+#define ISVALID_MPLID(mplid) ((0 < (mplid)) && ((mplid) < TNUM_MPL))
6+#define ISVALID_MPLATR(mplatr) (TRUE) /* 属性情報はチェックしない */
7+
8+typedef struct S_MPLCB
9+{
10+ ID mplid;
11+
12+ VP exinf; /* 拡張情報 */
13+ ATR mplatr; /* メモリプール属性 */
14+ INT mplsz; /* メモリプール全体のサイズ */
15+
16+} T_MPLCB;
17+
18+static const T_MPLCB mplcb_initializer = {0};
19+
20+static T_MPLCB mplcbs[TNUM_MPL];
21+
22+ER mpl_initialize(void)
23+{
24+ INT cnt;
25+
26+ for(cnt = 0;cnt < TNUM_MPL;cnt++)
27+ {
28+ mplcbs[cnt] = mplcb_initializer;
29+ }
30+
31+ return E_OK;
32+}
33+
34+void mpl_terminate(void)
35+{
36+
37+}
38+
39+ER cre_mpl(ID mplid, T_CMPL *pk_cmpl)
40+{
41+ ER result;
42+
43+ if(ISVALID_MPLID(mplid))
44+ {
45+ if(ISVALID_PTR(pk_cmpl) && ISVALID_MPLATR(pk_cmpl->mplatr))
46+ {
47+ T_MPLCB *p_mplcb;
48+
49+ p_mplcb = &(mplcbs[mplid]);
50+
51+ if(0 == p_mplcb->mplid)
52+ {
53+ *p_mplcb = mplcb_initializer;
54+
55+ p_mplcb->mplid = mplid;
56+
57+ p_mplcb->exinf = pk_cmpl->exinf;
58+ p_mplcb->mplatr = pk_cmpl->mplatr;
59+ p_mplcb->mplsz = pk_cmpl->mplsz;
60+
61+ result = E_OK;
62+ }
63+ else
64+ {
65+ result = E_OBJ;
66+ }
67+ }
68+ else
69+ {
70+ result = E_PAR;
71+ }
72+ }
73+ else
74+ {
75+ result = E_ID;
76+ }
77+
78+ return result;
79+}
80+
81+ER del_mpl(ID mplid)
82+{
83+ ER result;
84+
85+ if(ISVALID_MPLID(mplid))
86+ {
87+ T_MPLCB *p_mplcb;
88+
89+ p_mplcb = &(mplcbs[mplid]);
90+
91+ if(0 != p_mplcb->mplid)
92+ {
93+ *p_mplcb = mplcb_initializer;
94+
95+ result = E_OK;
96+ }
97+ else
98+ {
99+ result = E_NOEXS;
100+ }
101+ }
102+ else
103+ {
104+ result = E_ID;
105+ }
106+
107+ return result;
108+}
109+
110+ER get_blk(VP *p_blk, ID mplid, INT blksz)
111+{
112+ return tget_blk(p_blk, mplid, blksz, TMO_FEVR);
113+}
114+
115+ER pget_blk(VP *p_blk, ID mplid, INT blksz)
116+{
117+ return tget_blk(p_blk, mplid, blksz, TMO_POL);
118+}
119+
120+ER ipget_blk(VP *p_blk, ID mplid, INT blksz)
121+{
122+ return E_NOSPT;
123+}
124+
125+ER tget_blk(VP *p_blk, ID mplid, INT blksz, TMO tmout)
126+{
127+ ER result;
128+
129+ if(ISVALID_MPLID(mplid))
130+ {
131+ if(ISVALID_PTR(p_blk) && (0 < blksz) && ISVALID_TMOUT(tmout))
132+ {
133+ T_MPLCB *p_mplcb;
134+
135+ p_mplcb = &(mplcbs[mplid]);
136+
137+ if(0 != p_mplcb->mplid)
138+ {
139+ // TODO どうしよっかなー
140+ result = E_NOSPT;
141+ }
142+ else
143+ {
144+ result = E_NOEXS;
145+ }
146+ }
147+ else
148+ {
149+ result = E_PAR;
150+ }
151+ }
152+ else
153+ {
154+ result = E_ID;
155+ }
156+
157+ return result;
158+}
159+
160+ER rel_blk(ID mplid, VP blk)
161+{
162+ ER result;
163+
164+ if(ISVALID_MPLID(mplid))
165+ {
166+ if(ISVALID_PTR(blk))
167+ {
168+ T_MPLCB *p_mplcb;
169+
170+ p_mplcb = &(mplcbs[mplid]);
171+
172+ if(0 != p_mplcb->mplid)
173+ {
174+ // TODO どうしよっかなー
175+ result = E_NOSPT;
176+ }
177+ else
178+ {
179+ result = E_NOEXS;
180+ }
181+ }
182+ else
183+ {
184+ result = E_PAR;
185+ }
186+ }
187+ else
188+ {
189+ result = E_ID;
190+ }
191+
192+ return result;
193+}
194+
195+ER ref_mpl(T_RMPL *pk_rmpl, ID mplid)
196+{
197+ ER result;
198+
199+ if(ISVALID_MPLID(mplid))
200+ {
201+ if(ISVALID_PTR(pk_rmpl))
202+ {
203+ T_MPLCB *p_mplcb;
204+
205+ p_mplcb = &(mplcbs[mplid]);
206+
207+ if(0 != p_mplcb->mplid)
208+ {
209+ pk_rmpl->exinf = p_mplcb->exinf;
210+ pk_rmpl->wtsk = FALSE; // TODO どうしよっかなー
211+ pk_rmpl->frsz = 0; // TODO どうしよっかなー
212+ pk_rmpl->maxsz = 0; // TODO どうしよっかなー
213+
214+ result = E_OK;
215+ }
216+ else
217+ {
218+ result = E_NOEXS;
219+ }
220+ }
221+ else
222+ {
223+ result = E_PAR;
224+ }
225+ }
226+ else
227+ {
228+ result = E_ID;
229+ }
230+
231+ return result;
232+}
--- /dev/null
+++ b/src/mpl.h
@@ -0,0 +1,9 @@
1+#ifndef _MPL_H_
2+#define _MPL_H_
3+
4+#include <itron.h>
5+
6+ER mpl_initialize(void);
7+void mpl_terminate(void);
8+
9+#endif /* _MPL_H_ */
--- /dev/null
+++ b/src/net.c
@@ -0,0 +1,31 @@
1+#include "net.h"
2+
3+ER net_initialize(void)
4+{
5+ return E_OK;
6+}
7+
8+void net_terminate(void)
9+{
10+}
11+
12+ER nrea_dat(INT *p_reasz, VP dstadr, NODE srcnode, VP srcadr, INT datsz)
13+{
14+ return E_NOSPT;
15+}
16+
17+ER nwri_dat(INT *p_wrisz, NODE dstnode, VP dstadr, VP srcadr, INT datsz)
18+{
19+ return E_NOSPT;
20+}
21+
22+ER nget_nod(NODE *p_node)
23+{
24+ return E_NOSPT;
25+}
26+
27+ER nget_ver(T_VER *pk_ver, NODE node)
28+{
29+ return E_NOSPT;
30+}
31+
--- /dev/null
+++ b/src/net.h
@@ -0,0 +1,9 @@
1+#ifndef _NET_H_
2+#define _NET_H_
3+
4+#include <itron.h>
5+
6+ER net_initialize(void);
7+void net_terminate(void);
8+
9+#endif /* _NET_H_ */
--- /dev/null
+++ b/src/por.c
@@ -0,0 +1,307 @@
1+#include "por.h"
2+#include "it3_common.h"
3+#include "it3_config.h"
4+
5+#include "lst.h"
6+
7+#define ISVALID_PORID(porid) ((0 < (porid)) && ((porid) < TNUM_POR))
8+#define ISVALID_PORATR(poratr) (TRUE) /* 属性情報はチェックしない */
9+#define ISVALID_RDVNO(rdvno) (TRUE) /* TODO RNOの判定はどうやるんだ? */
10+
11+typedef struct S_PORCB
12+{
13+ T_LST call_queue; /* ポート呼出待ちキュー */
14+ ID porid; /* ポートID */
15+ VP exinf; /* 拡張情報 */
16+ ATR poratr; /* ポート属性 */
17+ T_LST accept_queue; /* ポート受付待ちキュー */
18+ INT maxcmsz; /* 呼出メッセージの最大長 */
19+ INT maxrmsz; /* 返答メッセージの最大長 */
20+} T_PORCB;
21+
22+static T_PORCB porcbs[TNUM_POR];
23+
24+static const T_PORCB porcb_initializer = {0};
25+
26+ER por_initialize(void)
27+{
28+ INT cnt;
29+
30+ for(cnt = 0;cnt < TNUM_POR;cnt++)
31+ {
32+ porcbs[cnt] = porcb_initializer;
33+ }
34+
35+ return E_OK;
36+}
37+
38+void por_terminate(void)
39+{
40+
41+}
42+
43+/* ランデブ用のポート生成 */
44+ER cre_por(ID porid, T_CPOR *pk_cpor)
45+{
46+ ER result;
47+
48+ if(ISVALID_PORID(porid))
49+ {
50+ if(ISVALID_PTR(pk_cpor))
51+ {
52+ T_PORCB *p_porcb;
53+
54+ p_porcb = &(porcbs[porid]);
55+
56+ if(0 == p_porcb->porid)
57+ {
58+ *p_porcb = porcb_initializer;
59+
60+ p_porcb->porid = porid;
61+
62+ p_porcb->exinf = pk_cpor->exinf;
63+ p_porcb->poratr = pk_cpor->poratr;
64+ p_porcb->maxcmsz = pk_cpor->maxcmsz;
65+ p_porcb->maxrmsz = pk_cpor->maxrmsz;
66+
67+ lst_init(&(p_porcb->accept_queue));
68+ lst_init(&(p_porcb->call_queue));
69+
70+ result = E_OK;
71+ }
72+ else
73+ {
74+ result = E_OBJ;
75+ }
76+ }
77+ else
78+ {
79+ result = E_PAR;
80+ }
81+ }
82+ else
83+ {
84+ result = E_ID;
85+ }
86+
87+ return result;
88+}
89+
90+/* ランデブ用のポート削除 */
91+ER del_por(ID porid)
92+{
93+ ER result;
94+
95+ if(ISVALID_PORID(porid))
96+ {
97+ T_PORCB *p_porcb;
98+
99+ p_porcb = &(porcbs[porid]);
100+
101+ if(0 != p_porcb->porid)
102+ {
103+ *p_porcb = porcb_initializer;
104+
105+ result = E_OK;
106+ }
107+ else
108+ {
109+ result = E_NOEXS;
110+ }
111+ }
112+ else
113+ {
114+ result = E_ID;
115+ }
116+
117+ return result;
118+}
119+
120+/* ポートに対するランデブの呼出 */
121+ER cal_por(VP msg, INT *p_rmsgsz, ID porid, UINT calptn, INT cmsgsz)
122+{
123+ return tcal_por(msg, p_rmsgsz, porid, calptn, cmsgsz, TMO_FEVR);
124+}
125+
126+/* ポートに対するランデブの呼出(ポーリング) */
127+ER pcal_por(VP msg, INT *p_rmsgsz, ID porid, UINT calptn, INT cmsgsz)
128+{
129+ return tcal_por(msg, p_rmsgsz, porid, calptn, cmsgsz, TMO_POL);
130+}
131+
132+/* ポートに対するランデブの呼出(タイムアウト有) */
133+ER tcal_por(VP msg, INT *p_rmsgsz, ID porid, UINT calptn, INT cmsgsz, TMO tmout)
134+{
135+ ER result;
136+
137+ if(ISVALID_PORID(porid))
138+ {
139+ if(ISVALID_PTR(msg) && ISVALID_PTR(p_rmsgsz) && (0 != calptn) && (0 < cmsgsz) && ISVALID_TMOUT(tmout))
140+ {
141+ T_PORCB *p_porcb;
142+
143+ p_porcb = &(porcbs[porid]);
144+
145+ if(0 != p_porcb->porid)
146+ {
147+ // TODO どうしよっかなー
148+ result = E_NOSPT;
149+ }
150+ else
151+ {
152+ result = E_NOEXS;
153+ }
154+ }
155+ else
156+ {
157+ result = E_PAR;
158+ }
159+ }
160+ else
161+ {
162+ result = E_ID;
163+ }
164+
165+ return result;
166+}
167+
168+/* ポートに対するランデブ受付 */
169+ER acp_por(RNO *p_rdvno, VP msg, INT *p_cmsgsz, ID porid, UINT acpptn)
170+{
171+ return tacp_por(p_rdvno, msg, p_cmsgsz, porid, acpptn, TMO_FEVR);
172+}
173+
174+/* ポートに対するランデブ受付(ポーリング) */
175+ER pacp_por(RNO *p_rdvno, VP msg, INT *p_cmsgsz, ID porid, UINT acpptn)
176+{
177+ return tacp_por(p_rdvno, msg, p_cmsgsz, porid, acpptn, TMO_POL);
178+}
179+
180+/* ポートに対するランデブ受付(タイムアウト有) */
181+ER tacp_por(RNO *p_rdvno, VP msg, INT *p_cmsgsz, ID porid, UINT acpptn, TMO tmout)
182+{
183+ ER result;
184+
185+ if(ISVALID_PORID(porid))
186+ {
187+ if(ISVALID_PTR(p_rdvno) && ISVALID_PTR(msg) && ISVALID_PTR(p_cmsgsz) && (0 != acpptn) && ISVALID_TMOUT(tmout))
188+ {
189+ T_PORCB *p_porcb;
190+
191+ p_porcb = &(porcbs[porid]);
192+
193+ if(0 != p_porcb->porid)
194+ {
195+ // TODO どうしよっかなー
196+ result = E_NOSPT;
197+ }
198+ else
199+ {
200+ result = E_NOEXS;
201+ }
202+ }
203+ else
204+ {
205+ result = E_PAR;
206+ }
207+ }
208+ else
209+ {
210+ result = E_ID;
211+ }
212+
213+ return result;
214+}
215+
216+/* ポートに対するランデブ回送 */
217+ER fwd_por(ID porid, UINT calptn, RNO rdvno, VP msg, INT cmsgsz)
218+{
219+ ER result;
220+
221+ if(ISVALID_PORID(porid))
222+ {
223+ if((0 != calptn) && ISVALID_RDVNO(rdvno) && ISVALID_PTR(msg) && (0 < cmsgsz))
224+ {
225+ T_PORCB *p_porcb;
226+
227+ p_porcb = &(porcbs[porid]);
228+
229+ if(0 != p_porcb->porid)
230+ {
231+ // TODO どうしよっかなー
232+ result = E_NOSPT;
233+ }
234+ else
235+ {
236+ result = E_NOEXS;
237+ }
238+ }
239+ else
240+ {
241+ result = E_PAR;
242+ }
243+ }
244+ else
245+ {
246+ result = E_ID;
247+ }
248+
249+ return result;
250+}
251+
252+/* ランデブ返答 */
253+ER rpl_rdv(RNO rdvno, VP msg, INT rmsgsz)
254+{
255+ ER result;
256+
257+ if(ISVALID_RDVNO(rdvno) && ISVALID_PTR(msg) && (0 < rmsgsz))
258+ {
259+ // TODO どうしよっかなー
260+ result = E_NOSPT;
261+ }
262+ else
263+ {
264+ result = E_PAR;
265+ }
266+
267+ return result;
268+}
269+
270+/* ポート状態参照 */
271+ER ref_por(T_RPOR *pk_rpor, ID porid)
272+{
273+ ER result;
274+
275+ if(ISVALID_PORID(porid))
276+ {
277+ if(ISVALID_PTR(pk_rpor))
278+ {
279+ T_PORCB *p_porcb;
280+
281+ p_porcb = &(porcbs[porid]);
282+
283+ if(0 != p_porcb->porid)
284+ {
285+ pk_rpor->exinf = p_porcb->exinf;
286+ pk_rpor->wtsk = FALSE; // TODO どうしよっかなー
287+ pk_rpor->atsk = FALSE; // TODO どうしよっかなー
288+
289+ result = E_OK;
290+ }
291+ else
292+ {
293+ result = E_NOEXS;
294+ }
295+ }
296+ else
297+ {
298+ result = E_PAR;
299+ }
300+ }
301+ else
302+ {
303+ result = E_ID;
304+ }
305+
306+ return result;
307+}
--- /dev/null
+++ b/src/por.h
@@ -0,0 +1,9 @@
1+#ifndef _POR_H_
2+#define _POR_H_
3+
4+#include <itron.h>
5+
6+ER por_initialize(void);
7+void por_terminate(void);
8+
9+#endif /* _POR_H_ */
--- /dev/null
+++ b/src/que_ctl.c
@@ -0,0 +1,680 @@
1+#include <stdio.h>
2+#include <string.h>
3+
4+#include "kernel.h"
5+
6+#include "tsk.h"
7+
8+extern T_LST rdq[];
9+
10+/* レディキューにタスクを追加 */
11+ER add_rdq(T_TCB *p_tcb)
12+{
13+ lst_insert(&(rdq[p_tcb->tskpri]), (T_LST *)p_tcb);
14+
15+ return E_OK;
16+}
17+
18+/* レディキューからタスクを削除 */
19+void del_rdq(T_TCB *p_tcb)
20+{
21+ lst_delete((T_LST *)p_tcb);
22+}
23+
24+#if 0 // move to flg.c
25+/*--------------------------------------------------------------------------*/
26+/* イベントフラグ待ちキューにタスクを追加 */
27+/*--------------------------------------------------------------------------*/
28+void add_flgq(T_FLGCB *p_flgcb, T_TCB *p_tcb)
29+{
30+
31+ if(TA_TPRI & p_flgcb->flgatr)
32+ {
33+ T_LST *p_insert_pos;
34+
35+ p_insert_pos = p_flgcb->wtsklst.p_next;
36+
37+ while(&(p_flgcb->wtsklst) != p_insert_pos)
38+ {
39+ if(p_tcb->tskpri < ((T_TCB *)p_insert_pos)->tskpri)
40+ {
41+ break;
42+ }
43+
44+ p_insert_pos = p_insert_pos->p_next;
45+ }
46+
47+ lst_insert(p_insert_pos, (T_LST *)p_tcb);
48+ }
49+ else
50+ {
51+ lst_insert(&(p_flgcb->wtsklst), (T_LST *)p_tcb);
52+ }
53+
54+#if 0 // T_LSTへ移行するので使うのやめる
55+ T_FLGCB *p_flgq;
56+ T_TCB *toptcb, *endtcb, *nextcb, *pretcb;
57+
58+ p_flgq = &flgq[addtcb->wid];
59+
60+ toptcb = p_flgq->head;
61+ if(NULL != toptcb)
62+ {
63+ /*-------------------- 他のタスクがある --------------------*/
64+ if( p_flgq->wtskmode == TA_TFIFO ) /* 待ち順序は FIFO */
65+ {
66+ /* 一番後ろにつなげる */
67+ endtcb = toptcb->prev;
68+ addtcb->prev = endtcb;
69+ addtcb->next = toptcb;
70+ toptcb->prev = addtcb;
71+ endtcb->next = addtcb;
72+ }
73+ else /* 待ち順序は 優先順 */
74+ {
75+ /* 挿入場所を探してつなげる */
76+ endtcb = toptcb->prev;
77+ nextcb = toptcb;
78+
79+ do
80+ {
81+ if( addtcb->pri < nextcb->pri )
82+ {
83+ pretcb = nextcb->prev;
84+
85+ addtcb->prev = pretcb;
86+ addtcb->next = nextcb;
87+ nextcb->prev = addtcb;
88+ pretcb->next = addtcb;
89+
90+ if( nextcb == toptcb )
91+ {
92+ p_flgq->head = addtcb;
93+ }
94+
95+ break;
96+ }
97+
98+ nextcb = nextcb->next;
99+ } while((nextcb != toptcb) && (p_flgq->head != NULL));
100+
101+ if( nextcb == toptcb )
102+ {
103+ addtcb->prev = endtcb;
104+ addtcb->next = toptcb;
105+ toptcb->prev = addtcb;
106+ endtcb->next = addtcb;
107+ }
108+ }
109+
110+ (p_flgq->wtskcnt)++; /* 待ちタスク数を加算 */
111+ }
112+ else
113+ {
114+ /*-------------------- 他のタスクがない --------------------*/
115+ p_flgq->head = addtcb;
116+ addtcb->next = addtcb;
117+ addtcb->prev = addtcb;
118+
119+ p_flgq->wtskcnt = 1; /* 待ちタスク数は1 */
120+ }
121+
122+ return;
123+#endif
124+}
125+
126+/*--------------------------------------------------------------------------*/
127+/* イベントフラグ待ちキューからタスクを削除 */
128+/*--------------------------------------------------------------------------*/
129+void del_flgq(T_FLGCB *p_flgcb, T_TCB *p_tcb)
130+{
131+ lst_delete((T_LST *)p_tcb);
132+
133+#if 0 // T_LSTへ移行するので使うのやめる
134+ T_FLGCB *p_flgq;
135+ T_TCB *pretcb, *nextcb;
136+
137+ p_flgq = &flgq[deltcb->wid];
138+
139+ if( (pretcb = deltcb->prev) != deltcb )
140+ {
141+ /*-------------------- 他のタスクがある --------------------*/
142+ nextcb = deltcb->next;
143+ pretcb->next = nextcb;
144+ nextcb->prev = pretcb;
145+ if( p_flgq->head == deltcb )
146+ {
147+ p_flgq->head = nextcb;
148+ }
149+
150+ ( p_flgq->wtskcnt )--; /* 待ちタスク数を減算 */
151+ }
152+ else
153+ {
154+ /*-------------------- 他のタスクがない --------------------*/
155+ p_flgq->head = NULL;
156+
157+ p_flgq->wtskcnt = 0; /* 待ちタスク数は0 */
158+ }
159+
160+ /*deltcb->prev = NULL;*/
161+ /*deltcb->next = NULL;*/
162+
163+ return;
164+#endif
165+}
166+#endif
167+
168+#if 0 // move to sem.c
169+/*--------------------------------------------------------------------------*/
170+/* セマフォ待ちキューにタスクを追加 */
171+/*--------------------------------------------------------------------------*/
172+void add_semq( T_TCB *addtcb )
173+{
174+ T_SEMCB *p_semq;
175+ T_TCB *toptcb, *endtcb, *nextcb, *pretcb;
176+
177+ p_semq = &(semq[addtcb->wid]);
178+
179+ toptcb = semq->head;
180+ if(NULL != toptcb)
181+ {
182+ /*-------------------- 他のタスクがある --------------------*/
183+
184+ if( semq->wtskmode == TA_TFIFO ) /* 待ち順序は FIFO */
185+ {
186+ /* 一番後ろにつなげる */
187+ endtcb = toptcb->prev;
188+ addtcb->prev = endtcb;
189+ addtcb->next = toptcb;
190+ toptcb->prev = addtcb;
191+ endtcb->next = addtcb;
192+ }
193+ else /* 待ち順序は 優先順 */
194+ {
195+ /* 挿入場所を探してつなげる */
196+ endtcb = toptcb->prev;
197+ nextcb = toptcb;
198+
199+ do
200+ {
201+ if( addtcb->pri < nextcb->pri )
202+ {
203+
204+ pretcb = nextcb->prev;
205+
206+ addtcb->prev = pretcb;
207+ addtcb->next = nextcb;
208+ nextcb->prev = addtcb;
209+ pretcb->next = addtcb;
210+
211+ if( nextcb == toptcb )
212+ {
213+ p_semq->head = addtcb;
214+ }
215+ break;
216+ }
217+
218+ nextcb = nextcb->next;
219+
220+ } while((nextcb != toptcb) && (p_semq->head != NULL));
221+
222+ if(nextcb == toptcb)
223+ {
224+ addtcb->prev = endtcb;
225+ addtcb->next = toptcb;
226+ toptcb->prev = addtcb;
227+ endtcb->next = addtcb;
228+ }
229+ }
230+ }
231+ else
232+ {
233+ /*-------------------- 他のタスクがない --------------------*/
234+ p_semq->head = addtcb;
235+ addtcb->next = addtcb;
236+ addtcb->prev = addtcb;
237+ }
238+
239+ return;
240+}
241+
242+/*--------------------------------------------------------------------------*/
243+/* セマフォ待ちキューからタスクを削除 */
244+/*--------------------------------------------------------------------------*/
245+void del_semq( T_TCB *deltcb )
246+{
247+ T_SEMCB *p_semq;
248+ T_TCB *pretcb, *nextcb;
249+
250+ p_semq = &(semq[deltcb->wid]);
251+
252+ pretcb = deltcb->prev;
253+ if(pretcb != deltcb)
254+ {
255+ /*-------------------- 他のタスクがある --------------------*/
256+ nextcb = deltcb->next;
257+ pretcb->next = nextcb;
258+ nextcb->prev = pretcb;
259+
260+ if( p_semq->head == deltcb )
261+ {
262+ p_semq->head = nextcb;
263+ }
264+ }
265+ else
266+ {
267+ /*-------------------- 他のタスクがない --------------------*/
268+ semq->head = NULL;
269+ }
270+
271+ /*deltcb->prev = NULL;*/
272+ /*deltcb->next = NULL;*/
273+
274+ return;
275+}
276+#endif
277+#if 0 // move to msg.c
278+/*--------------------------------------------------------------------------*/
279+/* メッセージ待ちキューにタスクを追加 */
280+/*--------------------------------------------------------------------------*/
281+void add_mbxq(T_TCB *addtcb)
282+{
283+ T_MBXCB *p_mbxq;
284+ T_TCB *toptcb, *endtcb, *nextcb, *pretcb;
285+
286+ p_mbxq = &(mbxq[addtcb->wid]);
287+
288+ toptcb = p_mbxq->head;
289+ if(NULL != toptcb)
290+ {
291+ /*-------------------- 他のタスクがある --------------------*/
292+ if(p_mbxq->wtskmode == TA_TFIFO) /* 待ち順序は FIFO */
293+ {
294+ /* 一番後ろにつなげる */
295+ endtcb = toptcb->prev;
296+ addtcb->prev = endtcb;
297+ addtcb->next = toptcb;
298+ toptcb->prev = addtcb;
299+ endtcb->next = addtcb;
300+ }
301+ else /* 待ち順序は 優先順 */
302+ {
303+ /* 挿入場所を探してつなげる */
304+ endtcb = toptcb->prev;
305+ nextcb = toptcb;
306+
307+ do
308+ {
309+ if( addtcb->pri < nextcb->pri )
310+ {
311+ pretcb = nextcb->prev;
312+
313+ addtcb->prev = pretcb;
314+ addtcb->next = nextcb;
315+ nextcb->prev = addtcb;
316+ pretcb->next = addtcb;
317+
318+ if( nextcb == toptcb )
319+ {
320+ p_mbxq->head = addtcb;
321+ }
322+ break;
323+ }
324+
325+ nextcb = nextcb->next;
326+
327+ } while( (nextcb != toptcb)&&(mbxq->head != NULL) );
328+
329+ if( nextcb == toptcb )
330+ {
331+ addtcb->prev = endtcb;
332+ addtcb->next = toptcb;
333+ toptcb->prev = addtcb;
334+ endtcb->next = addtcb;
335+ }
336+ }
337+ }
338+ else
339+ {
340+ /*-------------------- 他のタスクがない --------------------*/
341+ mbxq->head = addtcb;
342+ addtcb->next = addtcb;
343+ addtcb->prev = addtcb;
344+ }
345+
346+ return;
347+}
348+
349+/*--------------------------------------------------------------------------*/
350+/* メッセージ待ちキューからタスクを削除 */
351+/*--------------------------------------------------------------------------*/
352+void del_mbxq(T_TCB *deltcb)
353+{
354+ T_MBXCB *p_mbxq;
355+ T_TCB *pretcb, *nextcb;
356+
357+ p_mbxq = &(mbxq[deltcb->wid]);
358+
359+ pretcb = deltcb->prev;
360+ if(pretcb != deltcb)
361+ {
362+ /*-------------------- 他のタスクがある --------------------*/
363+ nextcb = deltcb->next;
364+ pretcb->next = nextcb;
365+ nextcb->prev = pretcb;
366+ if(p_mbxq->head == deltcb)
367+ {
368+ mbxq->head = nextcb;
369+ }
370+ }
371+ else
372+ {
373+ /*-------------------- 他のタスクがない --------------------*/
374+ mbxq->head = NULL;
375+ }
376+
377+ /*deltcb->prev = NULL;*/
378+ /*deltcb->next = NULL;*/
379+
380+ return;
381+}
382+#endif
383+#if 0 // move to msg.c
384+/*--------------------------------------------------------------------------*/
385+/* メッセージキューにメッセージを追加 */
386+/*--------------------------------------------------------------------------*/
387+void add_msg(ID mbxid, T_MSG *addmsg)
388+{
389+ T_MBXCB *p_mbxq;
390+ T_MSG *topmsg, *endmsg, *nexmsg, *premsg;
391+
392+ p_mbxq = &(mbxq[mbxid]);
393+
394+ topmsg = mbxq->msg;
395+ if(topmsg != NULL)
396+ {
397+ /*-------------------- 他のメッセージがある --------------------*/
398+ if( mbxq->wmsgmode == TA_TFIFO ) /* 待ち順序は FIFO */
399+ {
400+ /* 一番後ろにつなげる */
401+ endmsg = topmsg->pk_prev;
402+ addmsg->pk_prev = endmsg;
403+ addmsg->pk_next = topmsg;
404+ topmsg->pk_prev = addmsg;
405+ endmsg->pk_next = addmsg;
406+ }
407+ else /* 待ち順序は 優先順 */
408+ {
409+ /* 挿入場所を探してつなげる */
410+ endmsg = topmsg->pk_prev;
411+ nexmsg = topmsg;
412+
413+ do
414+ {
415+ if( tcb[addmsg->tskid].pri < tcb[nexmsg->tskid].pri )
416+ {
417+ premsg = nexmsg->pk_prev;
418+
419+ addmsg->pk_prev = premsg;
420+ addmsg->pk_next = nexmsg;
421+ nexmsg->pk_prev = addmsg;
422+ premsg->pk_next = addmsg;
423+
424+ if( nexmsg == topmsg )
425+ {
426+ mbxq->msg = addmsg;
427+ }
428+
429+ break;
430+ }
431+
432+ nexmsg = nexmsg->pk_next;
433+
434+ } while( (nexmsg != topmsg)&&(mbxq->msg != NULL) );
435+
436+ if( nexmsg == topmsg )
437+ {
438+ addmsg->pk_prev = endmsg;
439+ addmsg->pk_next = topmsg;
440+ topmsg->pk_prev = addmsg;
441+ endmsg->pk_next = addmsg;
442+ }
443+ }
444+ }
445+ else
446+ {
447+ /*-------------------- 他のメッセージがない --------------------*/
448+ mbxq->msg = addmsg;
449+ addmsg->pk_next = addmsg;
450+ addmsg->pk_prev = addmsg;
451+ }
452+
453+ return;
454+}
455+
456+/*--------------------------------------------------------------------------*/
457+/* メッセージキューからメッセージを削除 */
458+/*--------------------------------------------------------------------------*/
459+void del_msg(ID mbxid, T_MSG *delmsg)
460+{
461+ T_MBXCB *p_mbxq;
462+ T_MSG *premsg, *nexmsg;
463+
464+ p_mbxq = &(mbxq[mbxid]);
465+
466+ premsg = delmsg->pk_prev;
467+ if(premsg != delmsg )
468+ {
469+ /*-------------------- 他のメッセージがある --------------------*/
470+ nexmsg = delmsg->pk_next;
471+ premsg->pk_next = nexmsg;
472+ nexmsg->pk_prev = premsg;
473+
474+ if(p_mbxq->msg == delmsg)
475+ {
476+ mbxq->msg = nexmsg;
477+ }
478+ }
479+ else
480+ {
481+ /*-------------------- 他のメッセージがない --------------------*/
482+ p_mbxq->msg = NULL;
483+ }
484+
485+ delmsg->pk_next = NULL;
486+ delmsg->pk_prev = NULL;
487+
488+ return;
489+}
490+#endif
491+
492+/*--------------------------------------------------------------------------*/
493+/* タイマ待ちキューにタスクを追加 */
494+/*--------------------------------------------------------------------------*/
495+void add_timq(T_TCB *addtcb)
496+{
497+ T_TIMQ *p_timq;
498+ T_TCB *toptcb, *endtcb, *pretcb, *nextcb;
499+
500+ p_timq = &(timq);
501+
502+ toptcb = p_timq->head;
503+ /*-------------------- 他のタスクがある --------------------*/
504+ if(toptcb != NULL )
505+ {
506+ endtcb = toptcb->prev;
507+ nextcb = toptcb;
508+
509+ do
510+ {
511+ if(addtcb->tmout < nextcb->tmout)
512+ {
513+ pretcb = nextcb->prev;
514+
515+ addtcb->prev = pretcb;
516+ addtcb->next = nextcb;
517+ nextcb->prev = addtcb;
518+ pretcb->next = addtcb;
519+
520+ if(nextcb == toptcb)
521+ {
522+ p_timq->head = addtcb;
523+ }
524+
525+ break;
526+ }
527+
528+ nextcb = nextcb->next;
529+
530+ } while( (nextcb != toptcb)&&(p_timq->head != NULL) );
531+
532+ if( nextcb == toptcb )
533+ {
534+ addtcb->prev = endtcb;
535+ addtcb->next = toptcb;
536+ toptcb->prev = addtcb;
537+ endtcb->next = addtcb;
538+ }
539+ }
540+ else
541+ {
542+ /*-------------------- 他のタスクがない --------------------*/
543+ p_timq->head = addtcb;
544+ addtcb->next = addtcb;
545+ addtcb->prev = addtcb;
546+ }
547+
548+ return;
549+}
550+
551+
552+/*--------------------------------------------------------------------------*/
553+/* メッセージ待ちキューからタスクを削除 */
554+/*--------------------------------------------------------------------------*/
555+void del_timq(T_TCB *deltcb)
556+{
557+ T_TIMQ *p_timq;
558+ T_TCB *pretcb, *nextcb;
559+
560+ p_timq = &timq;
561+
562+ pretcb = deltcb->prev;
563+ if(pretcb != deltcb )
564+ {
565+ /*-------------------- 他のタスクがある --------------------*/
566+ nextcb = deltcb->next;
567+ pretcb->next = nextcb;
568+ nextcb->prev = pretcb;
569+
570+ if( p_timq->head == deltcb )
571+ {
572+ p_timq->head = nextcb;
573+ }
574+ }
575+ else
576+ {
577+ /*-------------------- 他のタスクがない --------------------*/
578+ p_timq->head = NULL;
579+ }
580+
581+ /*deltcb->prev = NULL;*/
582+ /*deltcb->next = NULL;*/
583+
584+ return;
585+}
586+
587+#if 0
588+/*--------------------------------------------------------------------------*/
589+/* ディスパッチ要求記憶 */
590+/*--------------------------------------------------------------------------*/
591+ER dispatch( errcode )
592+REG ER errcode;
593+{
594+ DISPATCH = ON;
595+ return( errcode );
596+}
597+/*--------------------------------------------------------------------------*/
598+/* 次に実行するタスクを検索 */
599+/*--------------------------------------------------------------------------*/
600+//#include "irqdef.h"
601+UH next_tsk()
602+{
603+ T_RDQ *rdq;
604+
605+ if( DISPATCH == OFF ) return( OFF ); /* ディスパッチ要求なし */
606+ if( DSPENA == OFF ) return( OFF ); /* ディスパッチ禁止状態 */
607+
608+ rdq = &RDQ[ 0 ];
609+
610+ while(1){
611+ if( rdq->head != NULL ) break;
612+ rdq++;
613+ }
614+ DISPATCH = OFF;
615+
616+ if( rdq->head == NOW_TCB ) return( OFF ); /* スイッチング必要なし */
617+
618+ NEXT_TCB = rdq->head; /* 次実行タスクの TCB アドレス */
619+ return( ON );
620+}
621+#endif
622+
623+/*--------------------------------------------------------------------------*/
624+/* 論理タイマ処理(10msに1回起動) */
625+/*--------------------------------------------------------------------------*/
626+void os_timer(void)
627+{
628+ T_TCB *p_tcb;
629+ T_TIMQ *p_timq;
630+
631+// os_cyc(1);
632+// os_alm(1);
633+
634+ p_timq = &timq;
635+
636+ (p_timq->time)++; /* タイマをカウントアップ(10ms単位) */
637+
638+ p_tcb = p_timq->head;
639+
640+ while(NULL != p_tcb) /* タイマ待ちのタスクがある */
641+ {
642+ if(p_tcb->tmout <= p_timq->time) /* タイムアウト時間 */
643+ {
644+ del_timq(p_tcb); /* TIMQ から TCB を外す */
645+
646+ if(TTW_FLG & p_tcb->tskwait) /* イベントフラグ待ち */
647+ {
648+ T_TCBTMO *tcbtmo = (T_TCBTMO *)p_tcb; /* tricky! */
649+ p_tcb = tcbtmo->tcb; /* TCB の本体 */
650+
651+ tcbtmo->sts = 0;
652+
653+// TODO del_flgq(p_tcb); /* FLGQ から TCB を外す */
654+
655+// ((T_TSKCTX *)p_tcb->sp)->r0 = E_TMOUT;
656+ /* エラーコードをポーリング失敗またはタイムアウトに */
657+ }
658+
659+ if(p_tcb->tskstat & TTS_SUS )
660+ {
661+ /* 二重待ち状態 */
662+ p_tcb->tskstat = TTS_SUS; /* タスク状態を SUSPEND に */
663+ }
664+ else
665+ {
666+ /* 時間待ち状態 */
667+// TODO add_rdq(p_tcb); /* RDQ に TCB をつなげる */
668+ p_tcb->tskstat = TTS_RDY; /* タスク状態を READY に */
669+ }
670+
671+// DISPATCH = ON;
672+ }
673+ else
674+ {
675+ break;
676+ }
677+ }
678+
679+ return;
680+}
--- /dev/null
+++ b/src/que_ctl.h
@@ -0,0 +1,111 @@
1+#ifndef que_ctl_h_Included
2+#define que_ctl_h_Included
3+
4+#include <itron.h>
5+#include "tsk.h"
6+
7+/*--------------------------------------------------------------------------*/
8+/* レディキューにタスクを追加 */
9+/*--------------------------------------------------------------------------*/
10+ER add_rdq( T_TCB *addtcb );
11+
12+/*--------------------------------------------------------------------------*/
13+/* レディキューからタスクを削除 */
14+/*--------------------------------------------------------------------------*/
15+void del_rdq( T_TCB *deltcb );
16+
17+#if 0 // move to flg.c
18+/*--------------------------------------------------------------------------*/
19+/* イベントフラグ待ちキューにタスクを追加 */
20+/*--------------------------------------------------------------------------*/
21+void add_flgq(T_FLGCB *p_flgcb, T_TCB *p_tcb);
22+
23+/*--------------------------------------------------------------------------*/
24+/* イベントフラグ待ちキューからタスクを削除 */
25+/*--------------------------------------------------------------------------*/
26+void del_flgq(T_FLGCB *p_flgcb, T_TCB *p_tcb);
27+#endif
28+#if 0 // move to sem.c
29+/*--------------------------------------------------------------------------*/
30+/* セマフォ待ちキューにタスクを追加 */
31+/*--------------------------------------------------------------------------*/
32+void add_semq( T_TCB *addtcb );
33+
34+/*--------------------------------------------------------------------------*/
35+/* セマフォ待ちキューからタスクを削除 */
36+/*--------------------------------------------------------------------------*/
37+void del_semq( T_TCB *deltcb );
38+#endif
39+#if 0 // move to msg.c
40+/*--------------------------------------------------------------------------*/
41+/* メッセージ待ちキューにタスクを追加 */
42+/*--------------------------------------------------------------------------*/
43+void add_mbxq( T_TCB *addtcb );
44+
45+/*--------------------------------------------------------------------------*/
46+/* メッセージ待ちキューからタスクを削除 */
47+/*--------------------------------------------------------------------------*/
48+void del_mbxq( T_TCB *deltcb );
49+
50+/*--------------------------------------------------------------------------*/
51+/* メッセージキューにメッセージを追加 */
52+/*--------------------------------------------------------------------------*/
53+void add_msg( ID mbxid, T_MSG *addmsg );
54+
55+/*--------------------------------------------------------------------------*/
56+/* メッセージキューからメッセージを削除 */
57+/*--------------------------------------------------------------------------*/
58+void del_msg( ID mbxid, T_MSG *delmsg );
59+#endif
60+/*--------------------------------------------------------------------------*/
61+/* タイマ待ちキューにタスクを追加 */
62+/*--------------------------------------------------------------------------*/
63+void add_timq( T_TCB *addtcb );
64+
65+/*--------------------------------------------------------------------------*/
66+/* メッセージ待ちキューからタスクを削除 */
67+/*--------------------------------------------------------------------------*/
68+void del_timq( T_TCB *deltcb );
69+
70+#if 0
71+/*--------------------------------------------------------------------------*/
72+/* ディスパッチ要求記憶 */
73+/*--------------------------------------------------------------------------*/
74+ER dispatch( errcode )
75+REG ER errcode;
76+{
77+ DISPATCH = ON;
78+ return( errcode );
79+}
80+/*--------------------------------------------------------------------------*/
81+/* 次に実行するタスクを検索 */
82+/*--------------------------------------------------------------------------*/
83+//#include "irqdef.h"
84+UH next_tsk()
85+{
86+ T_RDQ *rdq;
87+
88+ if( DISPATCH == OFF ) return( OFF ); /* ディスパッチ要求なし */
89+ if( DSPENA == OFF ) return( OFF ); /* ディスパッチ禁止状態 */
90+
91+ rdq = &RDQ[ 0 ];
92+
93+ while(1){
94+ if( rdq->head != NULL ) break;
95+ rdq++;
96+ }
97+ DISPATCH = OFF;
98+
99+ if( rdq->head == NOW_TCB ) return( OFF ); /* スイッチング必要なし */
100+
101+ NEXT_TCB = rdq->head; /* 次実行タスクの TCB アドレス */
102+ return( ON );
103+}
104+#endif
105+
106+/*--------------------------------------------------------------------------*/
107+/* 論理タイマ処理(10msに1回起動) */
108+/*--------------------------------------------------------------------------*/
109+void os_timer(void);
110+
111+#endif /* que_ctl_h_Included */
--- /dev/null
+++ b/src/sem.c
@@ -0,0 +1,912 @@
1+/**
2+ * @brief 同期・通信機能(セマフォ)
3+ *
4+ * @author nikarana
5+ * @date 2012/11/23
6+ */
7+
8+#include "sem.h"
9+#include "it3_debug.h"
10+#include "it3_common.h"
11+#include "lst.h"
12+
13+#include "kernel.h"
14+
15+#include "que_ctl.h"
16+
17+#define ISVALID_SEMID(semid) ((0 < (semid)) && ((semid) < TNUM_SEM))
18+#define ISVALID_SEMCNT(semcnt, maxsem) ((0 < (semcnt)) && ((semcnt) < (maxsem)))
19+#define ISVALID_SEMATR(sematr) (TRUE) /* 属性情報はチェックしない */
20+
21+/* セマフォ管理ブロック(SEMCB) */
22+typedef struct S_SEMCB
23+{
24+ ID semid; /**< セマフォID */
25+
26+ VP exinf; /**< 拡張情報 */
27+ ATR sematr; /**< セマフォ属性 */
28+ INT maxsem; /**< セマフォの最大値 */
29+
30+ INT semcnt; /**< セマフォカウンタ */
31+ T_LST wtsklst; /**< 待ちタスクリスト */
32+
33+
34+ T_TCB *head; /**< 先頭TCBへのポインタ */
35+ VH wtskmode; /**< 待ち順序 */
36+ ID tskid; /**< セマを持っているタスク */
37+ VB dmy[6]; /**< ダミー */
38+} T_SEMCB;
39+
40+static const T_SEMCB semcb_initializer = {0};
41+
42+static T_SEMCB semcbs[TNUM_SEM];
43+
44+#if defined(__cplusplus)
45+extern "C" {
46+#endif /* defined(__cplusplus) */
47+
48+static void CreateCriticalSection(void)
49+{
50+
51+}
52+
53+static void EnterCriticalSection(void)
54+{
55+
56+}
57+
58+static void LeaveCriticalSection(void)
59+{
60+
61+}
62+
63+/* セマフォ待ちキューにタスクを追加 */
64+static void add_semq(T_SEMCB *p_semcb, T_TCB *p_tcb)
65+{
66+ IT3_ASSERT(p_semcb);
67+ IT3_ASSERT(p_tcb);
68+
69+ if(TA_TPRI & p_semcb->sematr)
70+ {
71+ T_LST *p_insert_pos;
72+
73+ p_insert_pos = p_semcb->wtsklst.p_next;
74+
75+ while(&(p_semcb->wtsklst) != p_insert_pos)
76+ {
77+ if(p_tcb->tskpri < ((T_TCB *)p_insert_pos)->tskpri)
78+ {
79+ break;
80+ }
81+
82+ p_insert_pos = p_insert_pos->p_next;
83+ }
84+
85+ lst_insert(p_insert_pos, (T_LST *)p_tcb);
86+ }
87+ else
88+ {
89+ lst_insert(&(p_semcb->wtsklst), (T_LST *)p_tcb);
90+ }
91+
92+
93+#if 0
94+ T_SEMCB *p_semq;
95+ T_TCB *toptcb, *endtcb, *nextcb, *pretcb;
96+
97+ p_semq = &(semcbs[p_tcb->wid]);
98+
99+ toptcb = semcbs->head;
100+ if(NULL != toptcb)
101+ {
102+ /*-------------------- 他のタスクがある --------------------*/
103+
104+ if( semcbs->wtskmode == TA_TFIFO ) /* 待ち順序は FIFO */
105+ {
106+ /* 一番後ろにつなげる */
107+ endtcb = toptcb->prev;
108+ p_tcb->prev = endtcb;
109+ p_tcb->next = toptcb;
110+ toptcb->prev = p_tcb;
111+ endtcb->next = p_tcb;
112+ }
113+ else /* 待ち順序は 優先順 */
114+ {
115+ /* 挿入場所を探してつなげる */
116+ endtcb = toptcb->prev;
117+ nextcb = toptcb;
118+
119+ do
120+ {
121+ if( p_tcb->pri < nextcb->pri )
122+ {
123+
124+ pretcb = nextcb->prev;
125+
126+ p_tcb->prev = pretcb;
127+ p_tcb->next = nextcb;
128+ nextcb->prev = p_tcb;
129+ pretcb->next = p_tcb;
130+
131+ if( nextcb == toptcb )
132+ {
133+ p_semq->head = p_tcb;
134+ }
135+ break;
136+ }
137+
138+ nextcb = nextcb->next;
139+
140+ } while((nextcb != toptcb) && (p_semq->head != NULL));
141+
142+ if(nextcb == toptcb)
143+ {
144+ p_tcb->prev = endtcb;
145+ p_tcb->next = toptcb;
146+ toptcb->prev = p_tcb;
147+ endtcb->next = p_tcb;
148+ }
149+ }
150+ }
151+ else
152+ {
153+ /*-------------------- 他のタスクがない --------------------*/
154+ p_semq->head = p_tcb;
155+ p_tcb->next = p_tcb;
156+ p_tcb->prev = p_tcb;
157+ }
158+
159+ return;
160+#endif
161+}
162+
163+/* セマフォ待ちキューからタスクを削除 */
164+static void del_semq(T_SEMCB *p_semcb, T_TCB *p_tcb)
165+{
166+ IT3_ASSERT(p_tcb);
167+
168+ lst_delete((T_LST *)p_tcb);
169+
170+#if 0
171+ T_SEMCB *p_semq;
172+ T_TCB *pretcb, *nextcb;
173+
174+ p_semq = &(semcbs[p_tcb->wid]);
175+
176+ pretcb = p_tcb->prev;
177+ if(pretcb != p_tcb)
178+ {
179+ /*-------------------- 他のタスクがある --------------------*/
180+ nextcb = p_tcb->next;
181+ pretcb->next = nextcb;
182+ nextcb->prev = pretcb;
183+
184+ if( p_semq->head == p_tcb )
185+ {
186+ p_semq->head = nextcb;
187+ }
188+ }
189+ else
190+ {
191+ /*-------------------- 他のタスクがない --------------------*/
192+ semcbs->head = NULL;
193+ }
194+
195+ /*deltcb->prev = NULL;*/
196+ /*deltcb->next = NULL;*/
197+
198+ return;
199+#endif
200+}
201+
202+ER sem_initialize(void)
203+{
204+ INT cnt;
205+
206+ for(cnt = 0;cnt < TNUM_SEM;cnt++)
207+ {
208+ semcbs[cnt] = semcb_initializer;
209+ }
210+
211+ return E_OK;
212+}
213+
214+void sem_terminate(void)
215+{
216+}
217+
218+/**
219+ * @brief セマフォ生成
220+ *
221+ * @param semid セマフォID
222+ * @param pk_csem セマフォ生成情報
223+ * @return エラーコード
224+ * @retval E_OK 正常終了
225+ * @retval E_NOMEM メモリ不足(管理ブロック用の領域が確保できない)
226+ * @retval E_ID 不正ID番号(semidが不正あるいは利用できない)
227+ * @retval E_RSATR 予約属性(sematrが不正あるいは利用できない)
228+ * @retval E_OBJ オブジェクトの状態が不正(同一ID番号のセマフォが既に存在)
229+ * @retval E_OACV オブジェクトアクセス権違反(ユーザタスクからの発行でsemid<(-4), インプリメント依存)
230+ * @retval E_PAR パラメータエラー(pk_csemが不正, isemcnt, maxsemが負または不正)
231+ * @retval EN_OBJNO 対象ノード側でアクセスできないオブジェクト番号を指定
232+ * @retval EN_CTXID タスク独立部あるいはディスパッチ禁止状態のタスクから発行されたシステムコールで他ノード上のオブジェクトを指定
233+ */
234+ER cre_sem(ID semid, T_CSEM *pk_csem)
235+{
236+ ER result;
237+
238+ if(ISVALID_SEMID(semid))
239+ {
240+ if(ISVALID_PTR(pk_csem) && ISVALID_SEMCNT(pk_csem->isemcnt, pk_csem->maxsem))
241+ {
242+ if(ISVALID_SEMATR(pk_csem->sematr))
243+ {
244+ T_SEMCB *p_semcb;
245+
246+ p_semcb = &(semcbs[semid]);
247+
248+ if(0 == p_semcb->semid)
249+ {
250+ *p_semcb = semcb_initializer;
251+
252+ p_semcb->semid = semid;
253+
254+ p_semcb->exinf = pk_csem->exinf;
255+ p_semcb->sematr = pk_csem->sematr;
256+ p_semcb->maxsem = pk_csem->maxsem;
257+
258+ p_semcb->semcnt = pk_csem->isemcnt;
259+ lst_init(&(p_semcb->wtsklst));
260+
261+ p_semcb->head = NULL; /* 先頭TCBへのポインタ */
262+ p_semcb->wtskmode = pk_csem->sematr; /* 待ち順序 */
263+ p_semcb->tskid = 0; /* セマを持っているタスク */
264+
265+ result = E_OK;
266+ }
267+ else
268+ {
269+ result = E_OBJ;
270+ }
271+ }
272+ else
273+ {
274+ result = E_RSATR;
275+ }
276+ }
277+ else
278+ {
279+ result = E_PAR;
280+ }
281+ }
282+ else
283+ {
284+ result = E_ID;
285+ }
286+
287+ return result;
288+}
289+
290+/**
291+ * @brief セマフォ削除
292+ *
293+ * @param semid セマフォID
294+ * @return エラーコード
295+ * @retval E_OK 正常終了
296+ * @retval E_ID 不正ID番号(semidが不正あるいは利用できない)
297+ * @retval E_NOEXS オブジェクトが存在していない(semidのセマフォが存在しない)
298+ * @retval E_OACV オブジェクトアクセス権違反(ユーザタスクからの発行でsemid<(-4), インプリメント依存)
299+ * @retval EN_OBJNO 対象ノード側でアクセスできないオブジェクト番号を指定
300+ * @retval EN_CTXID タスク独立部あるいはディスパッチ禁止状態のタスクから発行されたシステムコールで他ノード上のオブジェクトを指定
301+ */
302+ER del_sem(ID semid)
303+{
304+ ER result;
305+
306+ if(ISVALID_SEMID(semid))
307+ {
308+ T_SEMCB *p_semcb;
309+
310+ p_semcb = &(semcbs[semid]);
311+
312+ if(0 != p_semcb->semid)
313+ {
314+ T_TCB *p_tcb;
315+
316+ /*----- 条件成立を待っているタスクの待ち解除 -----*/
317+ while(! lst_empty(&(p_semcb->wtsklst)))
318+ {
319+ p_tcb = (T_TCB *)(p_semcb->wtsklst.p_next);
320+
321+ del_semq(p_semcb, p_tcb); /* SEMQ から TCB を外す */
322+
323+ /* エラーコードを待ちオブジェクトの削除に */
324+ *(p_tcb->p_wercd) = E_DLT;
325+
326+ p_tcb->tskstat &= ~(TTS_WAI);
327+ p_tcb->tskwait &= ~(TTW_SEM);
328+ if(! (TTS_SUS & p_tcb->tskstat))
329+ {
330+ p_tcb->tskstat = TTS_RDY; /* タスク状態を READY に */
331+ p_tcb->tskwait = 0;
332+ p_tcb->wid = 0;
333+ add_rdq(p_tcb); /* RDQ に TCB をつなげる */
334+ }
335+ }
336+
337+ /*----- 初期化 -----*/
338+ p_semcb->semcnt = 1;
339+ p_semcb->wtskmode = TA_TFIFO;
340+ p_semcb->tskid = 0;
341+
342+ *p_semcb = semcb_initializer;
343+
344+ /* ディスパッチされるまで待つ */
345+ tsk_wait_dispatch();
346+
347+ result = E_OK;
348+ }
349+ else
350+ {
351+ result = E_NOEXS;
352+ }
353+ }
354+ else
355+ {
356+ result = E_ID;
357+ }
358+
359+ return result;
360+}
361+
362+/**
363+ * @brief セマフォ資源返却
364+ *
365+ * @param semid セマフォID
366+ * @return エラーコード
367+ * @retval E_OK 正常終了
368+ * @retval E_ID 不正ID番号(semidが不正あるいは利用できない)
369+ * @retval E_NOEXS オブジェクトが存在していない(semidのセマフォが存在しない)
370+ * @retval E_OACV オブジェクトアクセス権違反(ユーザタスクからの発行でsemid<(-4), インプリメント依存)
371+ * @retval E_QOVR キューイングまたはネストのオーバーフロー(キューイング数semcntのオーバーフロー)
372+ * @retval EN_OBJNO 対象ノード側でアクセスできないオブジェクト番号を指定
373+ * @retval EN_CTXID タスク独立部あるいはディスパッチ禁止状態のタスクから発行されたシステムコールで他ノード上のオブジェクトを指定
374+ */
375+ER sig_sem(ID semid)
376+{
377+ ER result;
378+
379+ result = isig_sem(semid);
380+ if(E_OK == result)
381+ {
382+ /* ディスパッチされるまで待つ */
383+ tsk_wait_dispatch();
384+ }
385+
386+ return result;
387+}
388+
389+/**
390+ * @brief セマフォ資源返却(タスク独立部)
391+ *
392+ * @param semid セマフォID
393+ * @return エラーコード
394+ * @retval E_OK 正常終了
395+ * @retval E_ID 不正ID番号(semidが不正あるいは利用できない)
396+ * @retval E_NOEXS オブジェクトが存在していない(semidのセマフォが存在しない)
397+ * @retval E_OACV オブジェクトアクセス権違反(ユーザタスクからの発行でsemid<(-4), インプリメント依存)
398+ * @retval E_QOVR キューイングまたはネストのオーバーフロー(キューイング数semcntのオーバーフロー)
399+ * @retval EN_OBJNO 対象ノード側でアクセスできないオブジェクト番号を指定
400+ * @retval EN_CTXID タスク独立部あるいはディスパッチ禁止状態のタスクから発行されたシステムコールで他ノード上のオブジェクトを指定
401+ */
402+ER isig_sem(ID semid)
403+{
404+ ER result;
405+
406+ if(ISVALID_SEMID(semid))
407+ {
408+ T_SEMCB *p_semcb;
409+
410+ p_semcb = &(semcbs[semid]);
411+
412+ depend_EnterCriticalSection();
413+
414+ if(0 != p_semcb->semid)
415+ {
416+ if(lst_empty(&(p_semcb->wtsklst)))
417+ {
418+ if(p_semcb->semcnt < p_semcb->maxsem)
419+ {
420+ (p_semcb->semcnt)++;
421+
422+ result = E_OK;
423+ }
424+ else
425+ {
426+ result = E_QOVR;
427+ }
428+ }
429+ else
430+ {
431+ tsk_wait_release((T_TCB *)(p_semcb->wtsklst.p_next), E_OK);
432+
433+ result = E_OK;
434+ }
435+ }
436+ else
437+ {
438+ result = E_NOEXS;
439+ }
440+
441+ depend_LeaveCriticalSection();
442+ }
443+ else
444+ {
445+ result = E_ID;
446+ }
447+
448+ return result;
449+
450+#if 0
451+ ER ercd;
452+ T_SEMCB *p_semq;
453+ T_TCB *p_tcb;
454+
455+ /*-------------------- パラメータエラー判定 ---------------------*/
456+ if(! ISVALID_SEMID(semid))
457+ {
458+ /* ID範囲外 */
459+ return E_ID;
460+ }
461+
462+ p_semq = &(semcbs[semid]);
463+ ercd = tsk_get_tcb(TSK_SELF, &p_tcb);
464+ if(E_OK != ercd)
465+ {
466+ return ercd;
467+ }
468+
469+ /* 現在のタスクが既にセマフォを獲得しているなら、 */
470+ /* 何もしないで正常終了する */
471+ if(p_semq->tskid != p_tcb->tskid) /* 既にセマフォ獲得済み? */
472+ {
473+ return E_OK;
474+ }
475+
476+ if(NULL == p_semq->head)
477+ {
478+ /*----------------- セマフォ待ちのタスクがない ------------------*/
479+
480+ /*if( p_semq->semcnt == 1 ){*/
481+ /*printf( "[os] sig_sem(%d)(tskid %d) error semcnt > 1\n",*/
482+ /*semid, TSK_SELF );*/
483+ /*return( E_OK );*/
484+ /*}*/
485+
486+ (p_semq->semcnt)++; /* キューイング */
487+
488+ p_semq->tskid = 0; /* セマを持っているタスクはない */
489+
490+ if(p_semq->maxsem < p_semq->semcnt) /* キューイングのオーバフロー? */
491+ {
492+ (p_semq->semcnt)--;
493+ return E_QOVR;
494+ }
495+ }
496+ else
497+ {
498+ /*------------------ 待ちタスクに資源を与える -------------------*/
499+ p_tcb = p_semq->head; /* 先頭のセマ待ちタスク */
500+
501+ del_semq(p_semq, p_tcb); /* SEMQ から TCB を外す */
502+
503+ if(p_tcb->tskstat & TTS_SUS)
504+ {
505+ /* 二重待ち状態 */
506+ p_tcb->tskstat = TTS_SUS; /* タスク状態を SUSPEND に */
507+ }
508+ else
509+ {
510+ p_tcb->tskstat = TTS_RDY; /* タスク状態を READY に */
511+ p_tcb->tskwait = 0;
512+ p_tcb->wid = 0;
513+
514+ /* メッセージ待ち状態 */
515+ add_rdq(p_tcb); /* RDQ に TCB をつなげる */
516+ }
517+
518+ p_semq->tskid = p_tcb->tskid; /* セマを持っているタスクを記録しておく */
519+
520+ /* ディスパッチされるまで待つ */
521+ tsk_wait_dispatch();
522+ }
523+
524+ return E_OK;
525+#endif
526+}
527+
528+/**
529+ * @brief セマフォ資源獲得
530+ *
531+ * @param semid セマフォID
532+ * @return エラーコード
533+ * @retval
534+ */
535+ER wai_sem(ID semid)
536+{
537+ return twai_sem(semid, TMO_FEVR);
538+}
539+
540+/**
541+ * @brief セマフォ資源獲得(ポーリング)
542+ */
543+ER preq_sem(ID semid)
544+{
545+ return twai_sem(semid, TMO_POL);
546+}
547+
548+/**
549+ * @brief セマフォ資源獲得(タイムアウト有)
550+ */
551+ER twai_sem(ID semid, TMO tmout)
552+{
553+ ER result;
554+
555+ if(ISVALID_SEMID(semid))
556+ {
557+ if(ISVALID_TMOUT(tmout))
558+ {
559+ T_SEMCB *p_semcb;
560+
561+ p_semcb = &(semcbs[semid]);
562+
563+ depend_EnterCriticalSection();
564+
565+ if(0 < p_semcb->semcnt) /* 資源がある? */
566+ {
567+ (p_semcb->semcnt)--;
568+
569+ result = E_OK;
570+ }
571+ else
572+ {
573+ if(TMO_POL != tmout)
574+ {
575+ ER ret;
576+ T_TCB *p_tcb;
577+
578+ ret = tsk_get_tcb(TSK_SELF, &p_tcb);
579+ if(E_OK == ret)
580+ {
581+ lst_delete((T_LST *)p_tcb); /* rdqから外す */
582+
583+ p_tcb->p_wercd = &result;
584+ p_tcb->tskstat = TTS_WAI;
585+ p_tcb->tskwait = TTW_SEM;
586+ p_tcb->wid = semid; /* セマIDを設定 */
587+
588+// TODO tsk_go_wait(p_tcb);
589+ }
590+ else
591+ {
592+ result = ret;
593+ }
594+ }
595+ else
596+ {
597+ result = E_TMOUT;
598+ }
599+
600+#if 0 // 置き換える
601+ ER ret;
602+ T_TCB *p_tcb;
603+
604+ ret = tsk_get_tcb(TSK_SELF, &p_tcb);
605+ if(E_OK == ret)
606+ {
607+ del_rdq(p_tcb); /* RDQ から TCB を外す */
608+
609+ p_tcb->tskstat = TTS_WAI;
610+ p_tcb->tskwait = TTW_SEM;
611+ p_tcb->wid = semid; /* セマIDを設定 */
612+
613+ add_semq(p_semcb, p_tcb); /* SEMQ に TCB をつなぐ */
614+
615+ /* ディスパッチされるまで待つ */
616+ tsk_wait_dispatch();
617+
618+ result = E_OK;
619+ }
620+ else
621+ {
622+ result = ret;
623+ }
624+#endif
625+ }
626+
627+ depend_LeaveCriticalSection();
628+ }
629+ else
630+ {
631+ result = E_PAR;
632+ }
633+ }
634+ else
635+ {
636+ result = E_ID;
637+ }
638+
639+ return result;
640+
641+#if 0 // 元wai_sem
642+ ER ercd; /* 呼び出した関数の戻り値 */
643+ T_SEMCB *p_semq;
644+ T_TCB *p_tcb;
645+
646+
647+// if( DSPENA == OFF ) { /* ディスパッチ禁止状態 */
648+// return( E_CTX );
649+// }
650+
651+ /*-------------------- パラメータエラー判定 ---------------------*/
652+ if((semid < 0) || (TNUM_SEM <= semid))
653+ {
654+ /* ID範囲外 */
655+ return E_ID;
656+ }
657+
658+ p_semq = &semcbs[semid];
659+ ercd = tsk_get_tcb(TSK_SELF, &p_tcb);
660+ if(E_OK != ercd)
661+ {
662+ return ercd;
663+ }
664+
665+ if(0 < p_semq->semcnt) /* 資源がある? */
666+ {
667+ (p_semq->semcnt)--;
668+ p_semq->tskid = p_tcb->tskid; /* セマを持っているタスクを記録 */
669+
670+ return E_OK;
671+ }
672+ else
673+ {
674+ /* 資源がないから待ちにする */
675+
676+ if(p_semq->tskid == p_tcb->tskid ) /* 同じタスクで待とうとしてる? */
677+ {
678+ /* 既にセマフォを確保しているタスクから */
679+ /* 再度セマフォ獲得しようとしているなら、*/
680+ /* 待ちとさせない */
681+ return E_OK;
682+ }
683+
684+ del_rdq(p_tcb); /* RDQ から TCB を外す */
685+
686+ p_tcb->sts = ((TTW_SEM << 8) | TTS_WAI); /* タスク状態を WAIT(セマ待ち)に */
687+ p_tcb->tskstat = TTS_WAI;
688+ p_tcb->tskwait = TTW_SEM;
689+ p_tcb->wid = semid; /* セマIDを設定 */
690+
691+ add_semq(p_tcb); /* SEMQ に TCB をつなぐ */
692+
693+ /* ディスパッチされるまで待つ */
694+ tsk_wait_dispatch();
695+ }
696+
697+ return E_OK;
698+#endif
699+
700+#if 0 /* 元preq_sem */
701+
702+ ER ercd;
703+ T_SEMCB *p_semq;
704+ T_TCB *p_tcb;
705+
706+ /*-------------------- パラメータエラー判定 ---------------------*/
707+ if(! ISVALID_SEMID(semid))
708+ {
709+ /* ID範囲外 */
710+ return E_ID;
711+ }
712+
713+ p_semq = &(semcbs[semid]);
714+
715+ ercd = tsk_get_tcb(TSK_SELF, &p_tcb);
716+ if(E_OK != ercd)
717+ {
718+ return ercd;
719+ }
720+
721+ if(0 < p_semq->semcnt) /* 資源がある? */
722+ {
723+ (p_semq->semcnt)--;
724+ p_semq->tskid = p_tcb->tskid;
725+ }
726+ else
727+ {
728+ /* 資源がない */
729+ return E_TMOUT;
730+ }
731+
732+ return E_OK;
733+#endif
734+}
735+
736+/**
737+ * @brief セマフォ状態参照
738+ *
739+ * @param pk_rsem セマフォ状態を返すパケットアドレス
740+ * @param semid セマフォID
741+ * @return エラーコード
742+ * @retval E_OK 正常終了
743+ * @retval E_ID 不正ID番号(semidが不正あるいは利用できない)
744+ * @retval E_NOEXS オブジェクトが存在していない(semidのセマフォが存在しない)
745+ * @retval E_OACV オブジェクトアクセス権違反(ユーザタスクからの発行でsemid<(-4), インプリメント依存)
746+ * @retval E_PAR パラメータエラー(リターンパラメータ用のパケットアドレスが使用できない値)
747+ * @retval EN_OBJNO 対象ノード側でアクセスできないオブジェクト番号を指定
748+ * @retval EN_CTXID タスク独立部あるいはディスパッチ禁止状態のタスクから発行されたシステムコールで他ノード上のオブジェクトを指定
749+ * @retval EN_RPAR 要求ノードや通信パケットでサポートされていない範囲の値がリターンパラメータとして返された(exinf, wtsk, semcntが要求ノードで表現できる値の範囲外)
750+ */
751+ER ref_sem(T_RSEM *pk_rsem, ID semid)
752+{
753+ ER result;
754+
755+ if(ISVALID_SEMID(semid))
756+ {
757+ if(ISVALID_PTR(pk_rsem))
758+ {
759+ T_SEMCB *p_semcb;
760+
761+ EnterCriticalSection();
762+
763+ p_semcb = &(semcbs[semid]);
764+
765+ if(0 != p_semcb->semid)
766+ {
767+ pk_rsem->exinf = p_semcb->exinf;
768+ pk_rsem->wtsk = (lst_empty(&(p_semcb->wtsklst))) ? FALSE : ((T_TCB *)(p_semcb->wtsklst.p_next))->tskid;
769+ pk_rsem->semcnt = p_semcb->semcnt;
770+
771+ result = E_OK;
772+ }
773+ else
774+ {
775+ result = E_NOEXS;
776+ }
777+
778+ LeaveCriticalSection();
779+ }
780+ else
781+ {
782+ result = E_PAR;
783+ }
784+ }
785+ else
786+ {
787+ result = E_ID;
788+ }
789+
790+ return result;
791+}
792+
793+#if 0
794+/*--------------------------------------------------------------------------*/
795+/* 自タスクの持っているセマを解放する(終了処理専用) */
796+/*--------------------------------------------------------------------------*/
797+ER edel_sem(ID semid)
798+{
799+ ER ercd;
800+ T_SEMCB *p_semq;
801+ T_TCB *p_tcb;
802+
803+ /*-------------------- パラメータエラー判定 ---------------------*/
804+ if((semid < 0) || (TNUM_SEM <= semid))
805+ {
806+ /* ID範囲外 */
807+ return E_ID;
808+ }
809+
810+ p_semq = &(semcbs[semid]);
811+
812+ ercd = tsk_get_tcb(TSK_SELF, &p_tcb);
813+ if(E_OK != ercd)
814+ {
815+ return ercd;
816+ }
817+
818+ if(p_semq->tskid != p_tcb->tskid)
819+ {
820+ /* 自タスクがセマを獲得していない場合 */
821+ return E_OBJ;
822+ }
823+
824+ if(p_semq->head == NULL)
825+ {
826+ /*- セマフォ待ちのタスクがない -*/
827+ p_semq->semcnt = 1;
828+ p_semq->tskid = 0;
829+ }
830+ else
831+ {
832+ /*- 待ちタスクに資源を与える -*/
833+
834+ p_tcb = p_semq->head; /* 先頭のセマ待ちタスク */
835+ del_semq(p_semq, p_tcb); /* SEMQ から TCB を外す */
836+ add_rdq(p_tcb); /* RDQ に TCB をつなげる */
837+ p_tcb->tskstat = TTS_RDY; /* タスク状態を READY に */
838+ p_tcb->tskwait = 0;
839+ p_tcb->wid = 0;
840+ p_semq->tskid = p_tcb->tskid; /* タスクを記録 */
841+ }
842+
843+ /* ディスパッチされるまで待つ */
844+ tsk_wait_dispatch();
845+
846+ return E_OK;
847+}
848+
849+/*--------------------------------------------------------------------------*/
850+/* セマフォに対する信号操作( 別タスクで獲得したセマフォに対しても有効 ) */
851+/*--------------------------------------------------------------------------*/
852+ER fsig_sem(ID semid)
853+{
854+ T_SEMCB *p_semq;
855+ T_TCB *p_tcb;
856+
857+ /*-------------------- パラメータエラー判定 ---------------------*/
858+ if((semid < 0) || (TNUM_SEM <= semid))
859+ {
860+ /* ID範囲外 */
861+ return E_ID;
862+ }
863+
864+ p_semq = &(semcbs[semid]);
865+
866+ if(NULL == p_semq->head)
867+ {
868+ /*----------------- セマフォ待ちのタスクがない ------------------*/
869+ (p_semq->semcnt)++; /* キューイング */
870+
871+ p_semq->tskid = 0; /* セマを持っているタスクはない */
872+
873+ if(0 == p_semq->semcnt) /* キューイングのオーバフロー */
874+ {
875+ (semcbs->semcnt)--;
876+ return E_QOVR;
877+ }
878+ }
879+ else
880+ {
881+ /*------------------ 待ちタスクに資源を与える -------------------*/
882+ p_tcb = semcbs->head; /* 先頭のセマ待ちタスク */
883+
884+ del_semq(p_semq, p_tcb); /* SEMQ から TCB を外す */
885+
886+ if(p_tcb->tskstat & TTS_SUS)
887+ {
888+ /* 二重待ち状態 */
889+ p_tcb->tskstat = TTS_SUS; /* タスク状態を SUSPEND に */
890+ }
891+ else
892+ {
893+ /* メッセージ待ち状態 */
894+ p_tcb->tskstat = TTS_RDY; /* タスク状態を READY に */
895+ p_tcb->tskwait = 0;
896+ p_tcb->wid = 0;
897+ add_rdq(p_tcb); /* RDQ に TCB をつなげる */
898+ }
899+
900+ p_semq->tskid = p_tcb->tskid; /* セマを持っているタスクを記録しておく */
901+
902+ /* ディスパッチされるまで待つ */
903+ tsk_wait_dispatch();
904+ }
905+
906+ return E_OK;
907+}
908+#endif
909+
910+#if defined(__cplusplus)
911+}
912+#endif /* defined(__cplusplus) */
--- /dev/null
+++ b/src/sem.h
@@ -0,0 +1,17 @@
1+#ifndef _SEM_H_
2+#define _SEM_H_
3+
4+#if defined(__cplusplus)
5+extern "C" {
6+#endif /* defined(__cplusplus) */
7+
8+#include <itron.h>
9+
10+ER sem_initialize(void);
11+void sem_terminate(void);
12+
13+#if defined(__cplusplus)
14+}
15+#endif /* defined(__cplusplus) */
16+
17+#endif /* _SEM_H_ */
--- /dev/null
+++ b/src/sys.c
@@ -0,0 +1,198 @@
1+/**
2+ * @file sys.c
3+ * @brief
4+ */
5+#include "sys.h"
6+#include "it3_common.h"
7+#include "it3_config.h"
8+
9+#define ISVALID_FNCD(fncd) ((0 < (fncd)) && ((fncd) < TNUM_SVC))
10+#define ISVALID_SVCATR(svcatr) (TRUE) /* 属性値はチェックしない */
11+
12+#define ISVALID_EXCKIND(exckind) ((0 < (exckind)) && ((exckind) < TNUM_EXC))
13+#define ISVALID_EXCATR(excatr) (TRUE) /* 属性値はチェックしない */
14+
15+typedef struct S_SVCCB
16+{
17+ FN s_fncd;
18+
19+ ATR svcatr; /* 拡張SVCハンドラ属性 */
20+ FP svchdr; /* 拡張SVCハンドラアドレス */
21+} T_SVCCB;
22+
23+typedef struct S_EXCCB
24+{
25+ UINT exckind;
26+
27+ ATR excatr; /* 例外ハンドラ属性 */
28+ FP exchdr; /* 例外ハンドラアドレス */
29+} T_EXCCB;
30+
31+
32+static const T_SVCCB svccb_initializer = {0};
33+
34+static const T_EXCCB exccb_initializer = {0};
35+
36+static T_SVCCB svccbs[TNUM_SVC];
37+
38+static T_EXCCB exccbs[TNUM_EXC];
39+
40+ER sys_initialize(void)
41+{
42+ INT cnt;
43+
44+ for(cnt = 0;cnt < TNUM_SVC;cnt++)
45+ {
46+ svccbs[cnt] = svccb_initializer;
47+ }
48+
49+ return E_OK;
50+}
51+
52+void sys_terminate(void)
53+{
54+}
55+
56+ER get_ver(T_VER *pk_ver)
57+{
58+ ER result;
59+
60+ if(ISVALID_PTR(pk_ver))
61+ {
62+ pk_ver->maker = TKERNEL_MAKER;
63+ pk_ver->id = TKERNEL_PRID;
64+ pk_ver->spver = TKERNEL_SPVER;
65+ pk_ver->prver = TKERNEL_PRVER;
66+ pk_ver->prno[0] = TKERNEL_PRNO0;
67+ pk_ver->prno[1] = TKERNEL_PRNO1;
68+ pk_ver->prno[2] = TKERNEL_PRNO2;
69+ pk_ver->prno[3] = TKERNEL_PRNO3;
70+ pk_ver->cpu = TKERNEL_CPU;
71+ pk_ver->var = TKERNEL_VAR;
72+
73+ result = E_OK;
74+ }
75+ else
76+ {
77+ result = E_PAR;
78+ }
79+
80+ return result;
81+}
82+
83+ER ref_sys(T_RSYS *pk_rsys)
84+{
85+ ER result;
86+
87+ if(ISVALID_PTR(pk_rsys))
88+ {
89+ pk_rsys->sysstat = 0; // TODO どうしよっかなー
90+
91+ result = E_OK;
92+ }
93+ else
94+ {
95+ result = E_PAR;
96+ }
97+
98+ return result;
99+}
100+
101+ER ref_cfg(T_RCFG *pk_rcfg)
102+{
103+ ER result;
104+
105+ if(ISVALID_PTR(pk_rcfg))
106+ {
107+
108+ result = E_OK;
109+ }
110+ else
111+ {
112+ result = E_PAR;
113+ }
114+
115+ return result;
116+}
117+
118+ER def_svc(FN s_fncd, T_DSVC *pk_dsvc)
119+{
120+ ER result;
121+
122+ if(ISVALID_FNCD(s_fncd))
123+ {
124+ T_SVCCB *p_svccb;
125+
126+ p_svccb = &(svccbs[s_fncd]);
127+
128+ if(ISVALID_PTR(pk_dsvc))
129+ {
130+ if(ISVALID_SVCATR(pk_dsvc->svcatr))
131+ {
132+ *p_svccb = svccb_initializer;
133+
134+ p_svccb->s_fncd = s_fncd;
135+ p_svccb->svcatr = pk_dsvc->svcatr;
136+ p_svccb->svchdr = pk_dsvc->svchdr;
137+
138+ result = E_OK;
139+ }
140+ else
141+ {
142+ result = E_RSATR;
143+ }
144+ }
145+ else
146+ {
147+ *p_svccb = svccb_initializer;
148+ result = E_OK;
149+ }
150+ }
151+ else
152+ {
153+ result = E_PAR;
154+ }
155+
156+ return result;
157+}
158+
159+ER def_exc(UINT exckind, T_DEXC *pk_dexc)
160+{
161+ ER result;
162+
163+ if(ISVALID_EXCKIND(exckind))
164+ {
165+ T_EXCCB *p_exccb;
166+
167+ p_exccb = &(exccbs[exckind]);
168+
169+ if(ISVALID_PTR(pk_dexc))
170+ {
171+ if(ISVALID_SVCATR(pk_dexc->excatr))
172+ {
173+ *p_exccb = exccb_initializer;
174+
175+ p_exccb->exckind = exckind;
176+ p_exccb->excatr = pk_dexc->excatr;
177+ p_exccb->exchdr = pk_dexc->exchdr;
178+
179+ result = E_OK;
180+ }
181+ else
182+ {
183+ result = E_RSATR;
184+ }
185+ }
186+ else
187+ {
188+ *p_exccb = exccb_initializer;
189+ result = E_OK;
190+ }
191+ }
192+ else
193+ {
194+ result = E_PAR;
195+ }
196+
197+ return result;
198+}
--- /dev/null
+++ b/src/sys.h
@@ -0,0 +1,9 @@
1+#ifndef _SYS_H_
2+#define _SYS_H_
3+
4+#include <itron.h>
5+
6+ER sys_initialize(void);
7+void sys_terminate(void);
8+
9+#endif /* _SYS_H_ */
--- /dev/null
+++ b/src/tim.c
@@ -0,0 +1,119 @@
1+#include "tim.h"
2+#include "it3_common.h"
3+#include <depend.h>
4+#include "kernel.h"
5+#include "que_ctl.h"
6+
7+#include "alm.h"
8+#include "cyc.h"
9+
10+static UINT last_time = 0;
11+SYSTIME systime = {0, 0};
12+
13+ER tim_initialize(void)
14+{
15+ return E_OK;
16+}
17+
18+void tim_terminate(void)
19+{
20+}
21+
22+/* タイムイベントハンドラ */
23+ER tim_event(void)
24+{
25+ int steptime, now_time;
26+
27+ /* 現在時刻を取得 */
28+ now_time = depend_get_time();
29+
30+ /* 経過時間を算出 */
31+ steptime = now_time - last_time;
32+
33+ systime.ltime += steptime;
34+
35+ /* アラームタイマ */
36+ alm_timeevent(steptime);
37+
38+ /* 周期タイマ */
39+ cyc_timeevent(steptime);
40+
41+ /* 現在時刻を保存 */
42+ last_time = now_time;
43+
44+ return E_OK;
45+}
46+
47+/* タイムティックの供給 */
48+ER isig_tim(void)
49+{
50+ systime.ltime += 1; /* invoked every 1msec */
51+ if(systime.ltime < 1)
52+ {
53+ systime.utime++;
54+ }
55+
56+ os_timer();
57+
58+ return E_OK;
59+}
60+
61+ER set_tim(SYSTIME *pk_tim)
62+{
63+ depend_EnterCriticalSection();
64+
65+ systime = *pk_tim;
66+
67+ depend_LeaveCriticalSection();
68+
69+ return E_OK;
70+}
71+
72+/* システム時刻の参照 */
73+ER get_tim(SYSTIME *p_systim)
74+{
75+ ER result;
76+
77+ if(ISVALID_PTR(p_systim))
78+ {
79+ *p_systim = systime;
80+
81+ result = E_OK;
82+ }
83+ else
84+ {
85+ result = E_PAR;
86+ }
87+
88+ return result;
89+}
90+
91+/* 自タスクの遅延 */
92+ER dly_tsk(DLYTIME dlytim)
93+{
94+ ER ercd;
95+ T_TCB *p_tcb;
96+
97+// if(DSPENA == OFF)
98+// {
99+// return E_CTX; /* コンテキストエラー */
100+// }
101+
102+ ercd = tsk_get_tcb(TSK_SELF, &p_tcb);
103+
104+ del_rdq(p_tcb); /* TCB を RDQ から外す */
105+ p_tcb->tskstat = TTS_WAI; /* タスク状態は時間経過待ちに */
106+ p_tcb->tskwait = TTW_DLY; /* タスク状態は時間経過待ちに */
107+ p_tcb->wid = 0;
108+ p_tcb->tmout = timq.time + dlytim; /* タイムアウト時刻を設定 */
109+ add_timq(p_tcb); /* 時間待ち行列につなぐ */
110+
111+ /* ディスパッチされるまで待つ */
112+ tsk_wait_dispatch();
113+
114+ return E_OK;
115+}
116+
117+void ret_tmr(void)
118+{
119+}
--- /dev/null
+++ b/src/tim.h
@@ -0,0 +1,28 @@
1+#ifndef _TIM_H_
2+#define _TIM_H_
3+
4+#if defined(__cplusplus)
5+extern "C" {
6+#endif /* defined(__cplusplus) */
7+
8+#include <itron.h>
9+#include "tsk.h"
10+
11+/* タイマキュー管理ブロック(TIMQ) */
12+typedef struct S_TIMQ
13+{
14+ T_TCB *head; /* 先頭TCBへのポインタ */
15+ TMO time; /* 論理タイマ値 */
16+} T_TIMQ;
17+
18+ER tim_initialize(void);
19+void tim_terminate(void);
20+
21+/* タイムイベントハンドラ */
22+ER tim_event(void);
23+
24+#if defined(__cplusplus)
25+}
26+#endif /* defined(__cplusplus) */
27+
28+#endif /* _TIM_H_ */
--- /dev/null
+++ b/src/tsk.c
@@ -0,0 +1,1563 @@
1+#include "tsk.h"
2+#include "it3_debug.h"
3+#include "it3_common.h"
4+#include <depend.h>
5+
6+#include "kernel.h"
7+#include "que_ctl.h"
8+
9+
10+#define ISVALID_TSKID(tskid) ((0 < (tskid)) && ((tskid) < TNUM_TSK))
11+#define ISVALID_TSKPRI(tskpri) ((0 < (tskpri)) || ((tskpri) < TNUM_TSK))
12+
13+#define NCT (0)
14+
15+static const T_TCB tcb_initializer = {0};
16+
17+
18+/**
19+ * @brief タスク起動用スレッド関数
20+ * @param p_arg スレッドの引数
21+ * @desc tskidで指定されるID番号を持つタスクを、pk_ctskで指定されるタスク生成情報に基づいて生成する。
22+ */
23+static void task_crt_function(void *p_arg)
24+{
25+ T_TCB *p_tcb = (T_TCB *)p_arg;
26+ ID tskid;
27+ FP task;
28+ VP arg;
29+
30+ IT3_ASSERT(p_tcb);
31+
32+ depend_EnterCriticalSection();
33+
34+ tskid = p_tcb->tskid;
35+ task = p_tcb->task;
36+ arg = p_tcb->arg;
37+
38+ depend_LeaveCriticalSection();
39+
40+ IT3_ASSERT(ISVALID_TSKID(tskid));
41+ IT3_ASSERT(task);
42+ IT3_ASSERT(arg);
43+
44+
45+ IT3_LOG1("task start.[tskid:%d]", tskid);
46+ (task)(arg);
47+ IT3_LOG1("task end.[tskid:%d]", tskid);
48+
49+ /* タスク終了 */
50+ depend_DestoryTask(tskid);
51+}
52+
53+#if 0
54+/*--------------------------------------------------------------------------*/
55+/* TCB を終了処理実行状態にする */
56+/*--------------------------------------------------------------------------*/
57+ER end_func_set(ID tskid)
58+{
59+ T_TCB *p_tcb;
60+// UH i;
61+// UW *sp;
62+// FP TaskStart;
63+
64+ /*-------------------- パラメータエラー判定 ---------------------*/
65+ if((tskid < 0) || (TNUM_TSK <= tskid ))
66+ {
67+ /* ID範囲外 */
68+ return E_ID;
69+ }
70+
71+ if(TSK_SELF == tskid)
72+ {
73+ /* 自タスクの指定 */
74+ return E_ID;
75+ }
76+
77+ p_tcb = &(tcb[tskid]);
78+
79+ if(NCT == p_tcb->tskstat)
80+ {
81+ /* タスクが未登録 */
82+ return E_NOEXS;
83+ }
84+
85+ p_tcb->pri = p_tcb->endpri;
86+ p_tcb->tskstat = TTS_DMT;
87+ p_tcb->tskwait = 0;
88+ p_tcb->wid = 0;
89+ p_tcb->next = NULL;
90+ p_tcb->prev = NULL;
91+ p_tcb->wfmode = 0;
92+ p_tcb->waiptn = 0;
93+ p_tcb->wupcnt = 0;
94+ p_tcb->suscnt = 0;
95+ p_tcb->tmout = 0;
96+ p_tcb->arg = NULL;
97+ /*p_tcb->sp = p_tcb->stack;*//* '94.01.30 c/o */
98+// p_tcb->susmask = FREE;
99+
100+ /*------------------ レジスタスタックの設定 -------------------*/
101+ sp = (UW *)tcb->sp;
102+
103+ sp--; *sp = (UW)TaskStart; /* PR *//* <- v82 */
104+ sp--; *sp = 0x40000000; /* SR */
105+ sp--; *sp = (UW)tcb->end_func; /* PC */
106+
107+ sp--; *sp = 0x00000000; /* R0 */
108+ sp--; *sp = 0x00000000; /* R1 */
109+ sp--; *sp = 0x00000000; /* R2 */
110+ sp--; *sp = 0x00000000; /* R3 */
111+ sp--; *sp = 0x00000000; /* R4 */
112+ sp--; *sp = 0x00000000; /* R5 */
113+ sp--; *sp = 0x00000000; /* R6 */
114+ sp--; *sp = 0x00000000; /* R7 */
115+
116+ sp--; *sp = FPSCR_DEF; /* FPSCR *//* add FPSCR */
117+
118+ sp--; *sp = 0x00000000; /* R8 */
119+ sp--; *sp = 0x00000000; /* R9 */
120+ sp--; *sp = 0x00000000; /* R10 */
121+ sp--; *sp = 0x00000000; /* R11 */
122+ sp--; *sp = 0x00000000; /* MACL */
123+ sp--; *sp = 0x00000000; /* R12 */
124+ sp--; *sp = 0x00000000; /* MACH */
125+ sp--; *sp = 0x00000000; /* R13 */
126+ sp--; *sp = 0x00000000; /* GBR */
127+ sp--; *sp = 0x00000000; /* R14 */
128+
129+ /*------------------ FPUレジスタスタックの設定 ----------------*/
130+ sp--; *sp = 0x00000000; /* FPUL */
131+ sp--; *sp = FPSCR_DEF; /* FPSCR */
132+ sp--; *sp = 0x00000000; /* FR15 */
133+ sp--; *sp = 0x00000000; /* FR14 */
134+ sp--; *sp = 0x00000000; /* FR13 */
135+ sp--; *sp = 0x00000000; /* FR12 */
136+ sp--; *sp = 0x00000000; /* FR11 */
137+ sp--; *sp = 0x00000000; /* FR10 */
138+ sp--; *sp = 0x00000000; /* FR9 */
139+ sp--; *sp = 0x00000000; /* FR8 */
140+ sp--; *sp = 0x00000000; /* FR7 */
141+ sp--; *sp = 0x00000000; /* FR6 */
142+ sp--; *sp = 0x00000000; /* FR5 */
143+ sp--; *sp = 0x00000000; /* FR4 */
144+ sp--; *sp = 0x00000000; /* FR3 */
145+ sp--; *sp = 0x00000000; /* FR2 */
146+ sp--; *sp = 0x00000000; /* FR1 */
147+ sp--; *sp = 0x00000000; /* FR0 */
148+ sp--; *sp = 0x00000000; /* XF15 */
149+ sp--; *sp = 0x00000000; /* XF14 */
150+ sp--; *sp = 0x00000000; /* XF13 */
151+ sp--; *sp = 0x00000000; /* XF12 */
152+ sp--; *sp = 0x00000000; /* XF11 */
153+ sp--; *sp = 0x00000000; /* XF10 */
154+ sp--; *sp = 0x00000000; /* XF9 */
155+ sp--; *sp = 0x00000000; /* XF8 */
156+ sp--; *sp = 0x00000000; /* XF7 */
157+ sp--; *sp = 0x00000000; /* XF6 */
158+ sp--; *sp = 0x00000000; /* XF5 */
159+ sp--; *sp = 0x00000000; /* XF4 */
160+ sp--; *sp = 0x00000000; /* XF3 */
161+ sp--; *sp = 0x00000000; /* XF2 */
162+ sp--; *sp = 0x00000000; /* XF1 */
163+ sp--; *sp = 0x00000000; /* XF0 */
164+
165+ tcb->sp = (VB *)sp;
166+
167+ return E_OK;
168+}
169+#endif
170+
171+#if 0 // TODO
172+void add_rdq(T_TCB *p_tcb)
173+{
174+ IT3_ASSERT(p_tcb);
175+
176+ lst_insert(&(rdq[p_tcb->tskpri]), (T_LST *)p_tcb);
177+}
178+
179+void del_rdq(T_TCB *p_tcb)
180+{
181+ IT3_ASSERT(p_tcb);
182+
183+ lst_delete((T_LST *)p_tcb);
184+}
185+#endif
186+
187+/**
188+ * @brief タスクシステムの初期化
189+ */
190+ER tsk_initialize(void)
191+{
192+ INT cnt;
193+
194+ /* TCBの初期化 */
195+ for(cnt = 0;cnt < TNUM_TSK;cnt++)
196+ {
197+ tcb[cnt] = tcb_initializer;
198+ }
199+
200+ /* RDQの初期化 */
201+ for(cnt = 0;cnt < TNUM_TSK;cnt++)
202+ {
203+ lst_init(&(rdq[cnt]));
204+ }
205+
206+ return E_OK;
207+}
208+
209+/**
210+ * @brief タスクシステムの終了
211+ */
212+void tsk_terminate(void)
213+{
214+}
215+
216+ER kernel_cre_tsk(T_TCB *p_tcb)
217+{
218+ ER result;
219+ T_DEPEND_CTSK ctsk;
220+ int ret;
221+
222+ IT3_ASSERT(p_tcb);
223+
224+ ctsk.stksz = p_tcb->stksz;
225+ ctsk.p_func = task_crt_function;
226+ ctsk.p_param = p_tcb;
227+
228+ ret = depend_CreateTask(p_tcb->tskid, &ctsk);
229+ if(0 == ret)
230+ {
231+ result = E_OK;
232+ }
233+ else
234+ {
235+ result = E_SYS;
236+ }
237+
238+ return result;
239+}
240+
241+/*
242+ * @brief 自タスクのIDを得る
243+ * @param p_tskid 自タスクIDを格納するバッファのアドレス
244+ * @return 戻り値
245+ * @retval E_OK 取得成功
246+ * @retval E_OK以外 取得失敗
247+ */
248+ER kernel_tsk_get_self_tskid(ID *p_tskid)
249+{
250+ ER result;
251+ T_TCB *p_tcb;
252+
253+ IT3_ASSERT(ISVALID_PTR(p_tskid));
254+
255+ p_tcb = (T_TCB *)depend_GetParam();
256+ if(p_tcb)
257+ {
258+ *p_tskid = p_tcb->tskid;
259+
260+ result = E_OK;
261+ }
262+ else
263+ {
264+ result = E_CTX;
265+ }
266+
267+ return result;
268+}
269+
270+/**
271+ * @brief TCBを得る
272+ */
273+ER tsk_get_tcb(ID tskid, T_TCB** pp_tcb)
274+{
275+ ER result;
276+ T_TCB *p_tcb;
277+
278+ IT3_ASSERT(ISVALID_TSKID(tskid) || (TSK_SELF == tskid));
279+ IT3_ASSERT(ISVALID_PTR(pp_tcb));
280+
281+ if(TSK_SELF == tskid)
282+ {
283+ p_tcb = (T_TCB *)depend_GetParam();
284+ }
285+ else
286+ {
287+ p_tcb = &(tcb[tskid]);
288+ }
289+
290+ if(ISVALID_PTR(p_tcb))
291+ {
292+ *pp_tcb = p_tcb;
293+ result = E_OK;
294+ }
295+ else
296+ {
297+ result = E_CTX;
298+ }
299+
300+ return result;
301+}
302+
303+/**
304+ * @brief ディスパッチされるまで待つ
305+ */
306+void tsk_wait_dispatch(void)
307+{
308+ T_TCB *p_tcb;
309+
310+ p_tcb = (T_TCB *)depend_GetParam();
311+ if(p_tcb)
312+ {
313+ IT3_LOG1("Sleep task[tskid:%d].Wake up kernel.", p_tcb->tskid);
314+
315+ depend_SwitchTask(0);
316+ }
317+ else
318+ {
319+ /* この制御はタスクじゃない(つまりカーネル)、
320+ 制御を切り替える必要が無い */
321+ }
322+
323+}
324+
325+/**
326+ * @brief タスクをディスパッチする
327+ */
328+void tsk_dispatch(void)
329+{
330+ INT cnt;
331+ T_LST *p_rdq;
332+ T_TCB *p_tcb = NULL;
333+
334+//カーネルデバッグ用
335+#if 0
336+ for(cnt = 0;cnt < (sizeof(rdq) / sizeof(rdq[0]));cnt++)
337+ {
338+ p_rdq = &(rdq[cnt]);
339+
340+ IT3_LOG1("rdq[%d]", cnt);
341+
342+ p_tcb = p_rdq->head;
343+ while(p_tcb)
344+ {
345+ IT3_LOG2(" ID:%d, NAME:%s", p_tcb->tskid, p_tcb->name);
346+ p_tcb = p_tcb->next;
347+
348+ if(p_tcb == p_rdq->head)
349+ {
350+ break;
351+ }
352+ }
353+
354+ IT3_LOG(" NULL");
355+ }
356+#endif /* 0 */
357+//カーネルデバッグ用
358+
359+ /* レディーキューから、次に起動するタスクを取得する */
360+ for(cnt = 0;cnt < (sizeof(rdq) / sizeof(rdq[0]));cnt++)
361+ {
362+ p_rdq = &(rdq[cnt]);
363+
364+ if(! lst_empty(p_rdq))
365+ {
366+ p_tcb = (T_TCB *)(p_rdq->p_next);
367+ break;
368+ }
369+ }
370+
371+ if(p_tcb) /* 実行可能タスクがある? */
372+ {
373+ IT3_LOG1("Wake up task.[tskid:%d]", p_tcb->tskid);
374+ depend_SwitchTask(p_tcb->tskid);
375+ }
376+
377+ depend_sleep(1);
378+}
379+
380+void tsk_wait_delete(T_LST *p_wtsklst)
381+{
382+ IT3_ASSERT(p_wtsklst);
383+}
384+
385+void tsk_wait_release(T_TCB *p_tcb, ER ercd)
386+{
387+ IT3_ASSERT(p_tcb);
388+ IT3_ASSERT(0 != p_tcb->tskid);
389+
390+ lst_delete((T_LST *)p_tcb);
391+
392+ IT3_ASSERT(p_tcb->p_wercd);
393+
394+ *(p_tcb->p_wercd) = ercd;
395+
396+ if(p_tcb->tskstat & TTS_SUS)
397+ {
398+ /* 二重待ち状態 */
399+ p_tcb->tskstat = TTS_SUS; /* タスク状態を SUSPEND に */
400+ }
401+ else
402+ {
403+ p_tcb->tskstat = TTS_RDY; /* タスク状態を READY に */
404+ p_tcb->tskwait = 0;
405+ p_tcb->wid = 0;
406+
407+ /* メッセージ待ち状態 */
408+ add_rdq(p_tcb); /* RDQ に TCB をつなげる */
409+ }
410+}
411+
412+/*
413+ * ==========================================================================
414+ * rst_tsk
415+ *【機能】
416+ * TCBを初期状態に戻す
417+ *【引数】
418+ * ID tskid タスクID
419+ *【戻り値】
420+ * E_OK 正常終了
421+ * E_IDOVR ID範囲外
422+ * E_NOEXS オブジェクトが存在していない(tskidのタスクが存在しない)
423+ * E_NODMT タスクがDORMANTでない(tskidのタスクがDORMANTでない)
424+ * E_OBJ オブジェクト状態エラー
425+ *【解説】
426+ * tskidで示されたタスクのTCBを初期状態に戻す。
427+ * ==========================================================================
428+ */
429+ER rst_tsk(ID tskid )
430+{
431+ ER result;
432+
433+ if(ISVALID_TSKID(tskid))
434+ {
435+ T_TCB *p_tcb;
436+
437+ p_tcb = &(tcb[tskid]);
438+
439+ if(NCT != p_tcb->tskstat)
440+ {
441+ p_tcb->tskpri = p_tcb->itskpri;
442+ p_tcb->tskstat = TTS_DMT;
443+ p_tcb->tskwait = 0;
444+ p_tcb->wid = 0;
445+ p_tcb->next = NULL;
446+ p_tcb->prev = NULL;
447+// p_tcb->wfmode = 0;
448+// p_tcb->waiptn = 0;
449+ p_tcb->wupcnt = 0;
450+ p_tcb->suscnt = 0;
451+ p_tcb->tmout = 0;
452+ p_tcb->arg = NULL;
453+// p_tcb->susmask = FREE;
454+
455+ result = E_OK;
456+ }
457+ else
458+ {
459+ result = E_NOEXS;
460+ }
461+ }
462+ else
463+ {
464+ result = E_ID;
465+ }
466+
467+ return result;
468+}
469+
470+/**
471+ * cre_tsk
472+ * @brief タスクを生成する
473+ * @param tskid タスクID
474+ * @param pk_ctsk タスク生成情報のポインタ
475+ * @return エラーコード
476+ * @retval E_OK 正常終了
477+ * @retval E_IDOVR 不正ID番号
478+ * @retval E_NOMEM メモリ不足
479+ * @retval E_RSATR 予約属性
480+ * @retval E_PAR パラメータエラー
481+ * @retval E_OBJ オブジェクト状態エラー
482+ *
483+ * tskidで指定されるID番号を持つタスクを、pk_ctskで指定されるタスク生成
484+ * 情報に基づいて生成する。
485+ */
486+ER cre_tsk(ID tskid, T_CTSK *pk_ctsk)
487+{
488+ ER result;
489+
490+ if(ISVALID_TSKID(tskid)) /* タスクIDが範囲内? */
491+ {
492+ if(ISVALID_PTR(pk_ctsk))
493+ {
494+ T_TCB *p_tcb;
495+ T_TCBTMO *p_tcbtmo;
496+
497+ p_tcb = &(tcb[tskid]);
498+
499+ depend_EnterCriticalSection();
500+
501+ if(0 == p_tcb->tskid)
502+ {
503+ *p_tcb = tcb_initializer;
504+
505+ lst_init(&(p_tcb->lst));
506+
507+ p_tcb->tskid = tskid;
508+
509+ p_tcb->exinf = pk_ctsk->exinf;
510+ p_tcb->tskatr = pk_ctsk->tskatr;
511+ p_tcb->task = pk_ctsk->task;
512+ p_tcb->itskpri = pk_ctsk->itskpri;
513+ p_tcb->stksz = pk_ctsk->stksz;
514+
515+ p_tcb->tskpri = pk_ctsk->itskpri;
516+ p_tcb->tskstat = TTS_DMT;
517+ p_tcb->tskwait = 0;
518+ p_tcb->wid = 0;
519+ p_tcb->wupcnt = 0;
520+ p_tcb->suscnt = 0;
521+
522+ p_tcb->p_wercd = NULL;
523+// p_tcb->wfmode = 0;
524+// p_tcb->waiptn = 0;
525+
526+
527+// p_tcb->pri = pk_ctsk->itskpri;
528+// p_tcb->sts = TTS_DMT;
529+// p_tcb->wid = 0;
530+ p_tcb->next = NULL;
531+ p_tcb->prev = NULL;
532+
533+ p_tcb->tmout = 0;
534+ p_tcb->arg = NULL;
535+
536+// p_tcb->sta_func = pk_ctsk->task;
537+// p_tcb->end_func = NULL;
538+// p_tcb->stack = stack + pk_ctsk->stksz;
539+
540+// p_tcb->endpri = 0x1;
541+// p_tcb->susmask = FREE;
542+// p_tcb->ipri = pk_ctsk->itskpri;
543+
544+// p_tcb->size = pk_ctsk->stksz / 1024;
545+// p_tcb->r_size = p_tcb->size;
546+// p_tcb->scp = (UW*)(stack + pk_ctsk->stksz);
547+
548+// strncpy(p_tcb->name, pk_ctsk->name, sizeof(p_tcb->name) - 1);
549+
550+ p_tcbtmo = &(tcbtmoq[tskid]);
551+
552+ p_tcbtmo->tskid = tskid;
553+ p_tcbtmo->sts = 0;
554+ p_tcbtmo->next = p_tcbtmo->prev = 0;
555+ p_tcbtmo->tmout = 0;
556+ p_tcbtmo->tcb = p_tcb;
557+
558+ /* タスク生成 */
559+ kernel_cre_tsk(p_tcb);
560+
561+ result = E_OK;
562+ }
563+ else
564+ {
565+ result = E_OBJ;
566+ }
567+
568+ depend_LeaveCriticalSection();
569+ }
570+ else
571+ {
572+ result = E_PAR;
573+ }
574+ }
575+ else
576+ {
577+ result = E_ID;
578+ }
579+
580+ return result;
581+}
582+
583+/**
584+ * @brief タスクの削除
585+ */
586+ER del_tsk(ID tskid)
587+{
588+ ER result;
589+
590+ if(ISVALID_TSKID(tskid))
591+ {
592+ T_TCB *p_tcb;
593+
594+ p_tcb = &(tcb[tskid]);
595+
596+ depend_EnterCriticalSection();
597+
598+ if(0 != p_tcb->tskid)
599+ {
600+ if(TTS_DMT == p_tcb->tskstat)
601+ {
602+ *p_tcb = tcb_initializer;
603+
604+ result = E_OK;
605+ }
606+ else
607+ {
608+ result = E_OBJ;
609+ }
610+ }
611+ else
612+ {
613+ result = E_NOEXS;
614+ }
615+
616+ depend_LeaveCriticalSection();
617+ }
618+ else
619+ {
620+ result = E_ID;
621+ }
622+
623+ return result;
624+}
625+
626+/**
627+ * sta_tsk
628+ *
629+ * @brief タスクを起動する
630+ *
631+ * @param tskid タスクID
632+ * @return エラーコード
633+ * @retval E_OK 正常終了
634+ * @retval E_IDOVR ID範囲外(インプリメント依存)
635+ * @retval E_NOEXS オブジェクトが存在していない(tskidのタスクが存在しない)
636+ * @retval E_NODMT タスクがDORMANTでない(tskidのタスクがDORMANTでない)
637+ * @retval E_OBJ オブジェクト状態エラー
638+ *
639+ * tskidで示されたタスクを起動する。
640+ */
641+ER sta_tsk(ID tskid, INT stacd)
642+{
643+ ER result;
644+
645+ if(ISVALID_TSKID(tskid))
646+ {
647+ T_TCB *p_tcb;
648+
649+ p_tcb = &(tcb[tskid]);
650+
651+ depend_EnterCriticalSection();
652+
653+ if(0 != p_tcb->tskid)
654+ {
655+ if(TTS_DMT == p_tcb->tskstat)
656+ {
657+ rst_tsk(tskid); /* TCB を初期状態に戻す */
658+
659+ p_tcb->tskstat = TTS_RDY; /* タスク状態を READY にする */
660+ p_tcb->tskwait = 0;
661+ p_tcb->wid = 0;
662+ add_rdq(p_tcb); /* TCB を RDQ につなぐ */
663+
664+ /* ディスパッチされるまで待つ */
665+ tsk_wait_dispatch();
666+
667+ result = E_OK;
668+ }
669+ else
670+ {
671+ result = E_OBJ;
672+ }
673+ }
674+ else
675+ {
676+ result = E_NOEXS;
677+ }
678+
679+ depend_LeaveCriticalSection();
680+ }
681+ else
682+ {
683+ result = E_ID;
684+ }
685+
686+ return result;
687+}
688+
689+/**
690+ * @brief 自タスクを正常終了する
691+ */
692+void ext_tsk(void)
693+{
694+ ER ercd; /* 呼び出した関数の戻り値 */
695+ T_TCB *p_tcb;
696+
697+ ercd = tsk_get_tcb(TSK_SELF, &p_tcb);
698+ if(E_OK == ercd)
699+ {
700+ depend_EnterCriticalSection();
701+
702+ del_rdq(p_tcb); /* RDQ から TCB を外す */
703+
704+ p_tcb->tskstat = TTS_DMT;
705+ p_tcb->tskwait = 0;
706+ p_tcb->wid = 0;
707+
708+ // DSPENA = ON; /* ディスパッチ許可状態 */
709+
710+ depend_LeaveCriticalSection();
711+
712+ /* ディスパッチされるまで待つ */
713+ tsk_wait_dispatch();
714+ }
715+}
716+
717+/**
718+ * @brief 自タスクの終了と削除
719+ */
720+void exd_tsk(void)
721+{
722+ ER ret;
723+ T_TCB *p_tcb;
724+
725+ ret = tsk_get_tcb(TSK_SELF, &p_tcb);
726+ if(E_OK == ret)
727+ {
728+ depend_EnterCriticalSection();
729+ del_rdq(p_tcb); /* RDQ から TCB を外す */
730+
731+ p_tcb->tskstat = NCT;
732+
733+// DSPENA = ON; /* ディスパッチ許可状態 */
734+
735+ depend_LeaveCriticalSection();
736+
737+ /* ディスパッチされるまで待つ */
738+ tsk_wait_dispatch();
739+ }
740+}
741+
742+
743+/**
744+ * @brief 他タスクを強制的に異常終了させる
745+ */
746+ER ter_tsk(ID tskid)
747+{
748+ ER ercd; /* 呼び出した関数の戻り値 */
749+ UINT tsksts;
750+ UINT waists;
751+ T_TCB *p_tcb;
752+
753+ /*==============*/
754+ /* 引数チェック */
755+ /*==============*/
756+ if(! ISVALID_TSKID(tskid)) /* タスクIDが範囲外? */
757+ {
758+ return E_ID;
759+ }
760+
761+ if(TSK_SELF == tskid)
762+ {
763+ /* 自タスクの指定 */
764+ return E_ID;
765+ }
766+
767+ /*************/
768+ /* TCBを取得 */
769+ /*************/
770+ ercd = tsk_get_tcb(tskid, &p_tcb);
771+ if(E_OK != ercd)
772+ {
773+ return ercd;
774+ }
775+
776+ tsksts = p_tcb->tskstat; /* タスクの状態 */
777+ waists = p_tcb->tskwait; /* 待ちの種類 */
778+
779+ if(NCT == tsksts)
780+ {
781+ /* タスクが未登録 */
782+ return E_NOEXS;
783+ }
784+
785+ if(TTS_DMT == tsksts)
786+ {
787+ /* タスクが DORMANT である */
788+ return E_OBJ;
789+ }
790+
791+ /*------------------ TCB を管理ブロックから外す -----------------*/
792+ if(TTS_RDY == tsksts)
793+ {
794+ /* タスクが READY の場合 */
795+ del_rdq( p_tcb ); /* RDQ から TCB を外す */
796+ }
797+ else if(( tsksts == TTS_WAI )||( tsksts == TTS_WAS ))
798+ {
799+ /* タスクが WAIT or WAIT-SUSPEND の場合 */
800+
801+ switch(waists)
802+ {
803+ case WTIM: /* 時間待ち */
804+ case TTW_DLY: /* 時間経過待ち */
805+ del_timq( p_tcb ); /* TIMQ から TCB を外す */
806+ break;
807+
808+ case TTW_FLG: /* イベントフラグ待ち */
809+// del_flgq(NULL, p_tcb); /* FLGQ から TCB を外す */
810+ lst_delete((T_LST *)p_tcb);
811+ break;
812+
813+ case TTW_SEM: /* セマフォ待ち */
814+// del_semq(NULL, p_tcb); /* SEMQ から TCB を外す */
815+ lst_delete((T_LST *)p_tcb);
816+ break;
817+
818+ case TTW_MBX: /* メッセージ待ち */
819+// del_mbxq(NULL, p_tcb); /* MBXQ から TCB を外す */
820+ lst_delete((T_LST *)p_tcb);
821+ break;
822+
823+ case (WTIM | TTW_FLG): /* イベントフラグ待ち */
824+// del_flgq(NULL, p_tcb); /* FLGQ から TCB を外す */
825+ lst_delete((T_LST *)p_tcb);
826+ {
827+ T_TCBTMO *tcbtmo = &tcbtmoq[tcb->tskid];
828+// del_timq(tcbtmo); /* TIMQ から TCB を外す */
829+ tcbtmo->sts = 0;
830+ }
831+ break;
832+
833+ default: /* 単純待ち */
834+ break;
835+ }
836+ }
837+ else
838+ {
839+ /* タスクが SUSPEND の場合 */
840+ }
841+#if 0
842+ /*---------------------- 終了処理の有無判定 ---------------------*/
843+ if(p_tcb->end_func != NULL )
844+ {
845+ /* 終了処理ルーチンが登録されている */
846+
847+ end_func_set(p_tcb->tskid); /* TCB を終了処理実行状態にする */
848+
849+ add_rdq( p_tcb ); /* TCB を RDQ つなげる */
850+ tcb->sts = TTS_RDY; /* タスク状態を READY にする */
851+
852+ /* ディスパッチされるまで待つ */
853+ tsk_wait_dispatch();
854+ }
855+ else
856+ {
857+ /* 終了処理ルーチンが登録されていない */
858+ tcb->sts = TTS_DMT;
859+ }
860+#endif
861+ return E_OK;
862+}
863+
864+/* ディスパッチを禁止する */
865+ER dis_dsp(void)
866+{
867+// DSPENA = OFF; /* ディスパッチ禁止状態 */
868+ return E_OK;
869+}
870+
871+/* ディスパッチを許可する */
872+ER ena_dsp(void)
873+{
874+// DSPENA = ON; /* ディスパッチ許可状態 */
875+ return E_OK;
876+}
877+
878+/* タスク優先度を変更する */
879+ER chg_pri(ID tskid, PRI tskpri)
880+{
881+ ER result;
882+
883+ result = ichg_pri(tskid, tskpri);
884+ if(E_OK == result)
885+ {
886+ /* ディスパッチされるまで待つ */
887+ tsk_wait_dispatch();
888+ }
889+
890+ return result;
891+}
892+
893+/* タスク優先度を変更する (タスク独立部専用) */
894+ER ichg_pri(ID tskid, PRI tskpri)
895+{
896+ ER result;
897+
898+ if(ISVALID_TSKID(tskid) || (TSK_SELF == tskid))
899+ {
900+ if(ISVALID_TSKPRI(tskpri) || (TPRI_INI == tskpri))
901+ {
902+ ER ret;
903+ T_TCB *p_tcb;
904+
905+ ret = tsk_get_tcb(tskid, &p_tcb);
906+ if(E_OK == ret)
907+ {
908+ depend_EnterCriticalSection();
909+
910+ if(0 != p_tcb->tskid)
911+ {
912+ if(TPRI_INI == tskpri)
913+ {
914+ tskpri = p_tcb->itskpri;
915+ }
916+
917+ if(TTS_RDY == p_tcb->tskstat)
918+ {
919+ del_rdq(p_tcb);
920+ p_tcb->tskpri = tskpri;
921+ add_rdq(p_tcb);
922+ }
923+ else
924+ {
925+ p_tcb->tskpri = tskpri;
926+ }
927+
928+ result = E_OK;
929+ }
930+ else
931+ {
932+ result = E_OBJ;
933+ }
934+
935+ depend_LeaveCriticalSection();
936+ }
937+ else
938+ {
939+ result = (E_CTX == ret) ? E_ID : ret;
940+ }
941+ }
942+ else
943+ {
944+ result = E_PAR;
945+ }
946+
947+ }
948+ else
949+ {
950+ result = E_ID;
951+ }
952+
953+ return result;
954+}
955+
956+/* タスクのレディキューを回転する */
957+ER rot_rdq(PRI tskpri)
958+{
959+ ER result;
960+
961+ if(ISVALID_TSKPRI(tskpri) || (TPRI_RUN == tskpri))
962+ {
963+ ER ret = E_OK;
964+
965+ if(TPRI_RUN == tskpri)
966+ {
967+ T_TCB *p_tcb;
968+
969+ ret = tsk_get_tcb(TSK_SELF, &p_tcb);
970+ if(E_OK == ret)
971+ {
972+ tskpri = p_tcb->tskpri;
973+ }
974+ }
975+
976+ if(E_OK == ret)
977+ {
978+ T_LST *p_rdq;
979+
980+ p_rdq = &(rdq[tskpri]);
981+
982+ if(p_rdq->p_next)
983+ {
984+ T_TCB *p_tcb;
985+
986+ p_rdq->p_prev = p_rdq->p_next;
987+ p_rdq->p_next = (p_rdq->p_next)->p_next;
988+
989+ ret = tsk_get_tcb(TSK_SELF, &p_tcb);
990+ if(E_OK == ret)
991+ {
992+ /* ディスパッチされるまで待つ */
993+ tsk_wait_dispatch();
994+
995+ result = E_OK;
996+ }
997+ else
998+ {
999+ result = ret;
1000+ }
1001+ }
1002+ else
1003+ {
1004+ result = E_PAR;
1005+ }
1006+ }
1007+ else
1008+ {
1009+ result = ret;
1010+ }
1011+ }
1012+ else
1013+ {
1014+ result = E_PAR;
1015+ }
1016+
1017+ return result;
1018+}
1019+
1020+/* タスクのレディキューを回転する(タスク独立部専用) */
1021+ER irot_rdq(PRI tskpri)
1022+{
1023+ return E_NOSPT;
1024+}
1025+
1026+/* 他タスクの待ち状態解除 */
1027+ER rel_wai(ID tskid)
1028+{
1029+ return E_NOSPT;
1030+
1031+}
1032+
1033+/* 他タスクの待ち状態解除(タスク独立部専用) */
1034+ER irel_wai(ID tskid)
1035+{
1036+ return E_NOSPT;
1037+}
1038+
1039+/* 自タスクのIDを得る */
1040+ER get_tid(ID *p_tskid)
1041+{
1042+ return kernel_tsk_get_self_tskid(p_tskid);
1043+}
1044+
1045+ER ref_tsk(T_RTSK *pk_rtsk, ID tskid)
1046+{
1047+ ER result;
1048+
1049+ if(ISVALID_TSKID(tskid) || (TSK_SELF == tskid))
1050+ {
1051+ if(ISVALID_PTR(pk_rtsk))
1052+ {
1053+ ER ret;
1054+ T_TCB *p_tcb;
1055+
1056+ ret = tsk_get_tcb(tskid, &p_tcb);
1057+ if(E_OK == ret)
1058+ {
1059+ depend_EnterCriticalSection();
1060+
1061+ pk_rtsk->exinf = p_tcb->exinf;
1062+ pk_rtsk->tskpri = p_tcb->tskpri;
1063+ pk_rtsk->tskstat = p_tcb->tskstat;
1064+
1065+ pk_rtsk->tskwait = p_tcb->tskwait;
1066+ pk_rtsk->wid = p_tcb->wid;
1067+ pk_rtsk->wupcnt = p_tcb->wupcnt;
1068+ pk_rtsk->suscnt = p_tcb->suscnt;
1069+
1070+ depend_LeaveCriticalSection();
1071+
1072+ result = E_OK;
1073+ }
1074+ else
1075+ {
1076+ result = ret;
1077+ }
1078+ }
1079+ else
1080+ {
1081+ result = E_PAR;
1082+ }
1083+ }
1084+ else
1085+ {
1086+ result = E_ID;
1087+ }
1088+
1089+ return result;
1090+}
1091+
1092+/* 他タスクを強制待ち状態へ移行 */
1093+ER sus_tsk(ID tskid)
1094+{
1095+ ER result;
1096+
1097+ if(ISVALID_TSKID(tskid))
1098+ {
1099+ ER ret;
1100+ T_TCB *p_tcb;
1101+
1102+ ret = tsk_get_tcb(tskid, &p_tcb);
1103+ if(E_OK == ret)
1104+ {
1105+ depend_EnterCriticalSection();
1106+
1107+ if(0 != p_tcb->tskid)
1108+ {
1109+ if(TTS_DMT != p_tcb->tskstat)
1110+ {
1111+ result = E_OK;
1112+
1113+ if(TTS_RDY == p_tcb->tskstat)
1114+ {
1115+ del_rdq(p_tcb);
1116+ p_tcb->tskstat = TTS_SUS;
1117+ p_tcb->tskwait = 0;
1118+ p_tcb->wid = 0;
1119+ }
1120+ else if(TTS_WAI == p_tcb->tskstat)
1121+ {
1122+ p_tcb->tskstat = TTS_SUS;
1123+ p_tcb->tskwait = 0;
1124+ p_tcb->wid = 0;
1125+ }
1126+ else if((TTS_SUS == p_tcb->tskstat) || (TTS_WAS == p_tcb->tskstat))
1127+ {
1128+ if(p_tcb->suscnt < TMAX_SUSCNT)
1129+ {
1130+ (p_tcb->suscnt)++;
1131+ }
1132+ else
1133+ {
1134+ result = E_QOVR;
1135+ }
1136+ }
1137+ else
1138+ {
1139+ // not action.
1140+ }
1141+
1142+ if(E_OK == result)
1143+ {
1144+ tsk_wait_dispatch();
1145+ }
1146+ }
1147+ else
1148+ {
1149+ result = E_OBJ;
1150+ }
1151+ }
1152+ else
1153+ {
1154+ result = E_NOEXS;
1155+ }
1156+
1157+ depend_LeaveCriticalSection();
1158+ }
1159+ else
1160+ {
1161+ result = ret;
1162+ }
1163+ }
1164+ else
1165+ {
1166+ result = E_ID;
1167+ }
1168+
1169+ return result;
1170+}
1171+
1172+ER isus_tsk(ID tskid)
1173+{
1174+ return E_NOSPT;
1175+}
1176+
1177+/* 強制待ち状態のタスクを再開 */
1178+ER rsm_tsk(ID tskid)
1179+{
1180+ ER result;
1181+
1182+ if(ISVALID_TSKID(tskid))
1183+ {
1184+ T_TCB *p_tcb;
1185+
1186+ p_tcb = &(tcb[tskid]);
1187+
1188+ depend_EnterCriticalSection();
1189+
1190+ if(0 != p_tcb->tskid)
1191+ {
1192+ if((TTS_DMT != p_tcb->tskstat) && (TTS_SUS & p_tcb->tskstat))
1193+ {
1194+ if(0 < p_tcb->suscnt)
1195+ {
1196+ (p_tcb->suscnt)--;
1197+ }
1198+ else
1199+ {
1200+ p_tcb->tskstat &= ~(TTS_SUS); /* SUSPEND を解除 */
1201+
1202+ if(TTS_WAI != (p_tcb->tskstat & TTS_WAI))
1203+ {
1204+ p_tcb->tskstat = TTS_RDY; /* タスク状態を READY にする */
1205+ p_tcb->tskwait = 0;
1206+ p_tcb->wid = 0;
1207+ add_rdq(p_tcb); /* RDQ に TCB をつなげる */
1208+
1209+ /* ディスパッチされるまで待つ */
1210+ tsk_wait_dispatch();
1211+ }
1212+ }
1213+
1214+ result = E_OK;
1215+ }
1216+ else
1217+ {
1218+ result = E_OBJ;
1219+ }
1220+ }
1221+ else
1222+ {
1223+ result = E_NOEXS;
1224+ }
1225+
1226+ depend_LeaveCriticalSection();
1227+ }
1228+ else
1229+ {
1230+ result = (TSK_SELF != tskid) ? E_ID : E_OBJ;
1231+ }
1232+
1233+ return result;
1234+}
1235+
1236+ER irsm_tsk(ID tskid)
1237+{
1238+ return E_NOSPT;
1239+}
1240+
1241+ER frsm_tsk(ID tskid)
1242+{
1243+ return E_NOSPT;
1244+}
1245+
1246+ER ifrsm_tsk(ID tskid)
1247+{
1248+ return E_NOSPT;
1249+}
1250+
1251+/* 自タスクを起床待ち状態へ移行 */
1252+ER slp_tsk(void)
1253+{
1254+ return tslp_tsk(TMO_FEVR);
1255+}
1256+
1257+ER tslp_tsk(TMO tmout)
1258+{
1259+ ER result;
1260+ ER ret;
1261+ T_TCB *p_tcb;
1262+
1263+ if(ISVALID_TMOUT(tmout))
1264+ {
1265+ ret = tsk_get_tcb(TSK_SELF, &p_tcb);
1266+ if(E_OK == ret)
1267+ {
1268+ depend_EnterCriticalSection();
1269+
1270+ IT3_ASSERT(0 != p_tcb->tskid);
1271+ IT3_ASSERT(TTS_RUN == p_tcb->tskstat);
1272+
1273+ if(0 < p_tcb->wupcnt)
1274+ {
1275+ (p_tcb->wupcnt)--;
1276+ }
1277+ else
1278+ {
1279+ del_rdq(p_tcb);
1280+
1281+ p_tcb->tskstat = TTS_WAI;
1282+
1283+ if(TMO_FEVR == tmout)
1284+ {
1285+ p_tcb->tskwait = 0;
1286+ p_tcb->wid = 0;
1287+ }
1288+ else
1289+ {
1290+ p_tcb->tskwait = WTIM;
1291+ p_tcb->wid = 0;
1292+
1293+ p_tcb->tmout = timq.time + tmout;
1294+ add_timq(p_tcb);
1295+ }
1296+
1297+ /* ディスパッチされるまで待つ */
1298+ tsk_wait_dispatch();
1299+ }
1300+
1301+ depend_LeaveCriticalSection();
1302+
1303+ result = E_OK;
1304+ }
1305+ else
1306+ {
1307+ result = ret;
1308+ }
1309+ }
1310+ else
1311+ {
1312+ result = E_PAR;
1313+ }
1314+
1315+ return result;
1316+}
1317+
1318+/* 他タスクの起床 */
1319+ER wup_tsk(ID tskid)
1320+{
1321+ ER result;
1322+
1323+ if(ISVALID_TSKID(tskid))
1324+ {
1325+ T_TCB *p_tcb;
1326+
1327+ p_tcb = &(tcb[tskid]);
1328+
1329+ depend_EnterCriticalSection();
1330+
1331+ if(0 != p_tcb->tskid)
1332+ {
1333+ if(TTS_DMT == p_tcb->tskstat)
1334+ {
1335+ result = E_OK;
1336+
1337+ if(TTS_WAI == p_tcb->tskstat)
1338+ {
1339+ if(WTIM == p_tcb->tskwait) /* 時間待ち状態? */
1340+ {
1341+ del_timq(p_tcb); /* TIMQからTCBを外す */
1342+ }
1343+ else
1344+ {
1345+ p_tcb->tskstat = TTS_RDY; /* タスク状態をREADY */
1346+ add_rdq(p_tcb); /* TCBをRDQにつなぐ */
1347+ }
1348+ }
1349+ else if(TTS_WAS == p_tcb->tskstat) /* 二重待ち */
1350+ {
1351+ if(WTIM == p_tcb->tskwait) /* 時間待ち状態? */
1352+ {
1353+ del_timq(p_tcb); /* TIMQからTCBを外す */
1354+ }
1355+ else
1356+ {
1357+ p_tcb->tskstat = TTS_SUS; /* タスク状態をSUSPEND */
1358+ }
1359+ }
1360+ else
1361+ {
1362+ if(p_tcb->wupcnt < TMAX_WUPCNT)
1363+ {
1364+ (p_tcb->wupcnt)++;
1365+ }
1366+ else
1367+ {
1368+ result = E_QOVR;
1369+ }
1370+ }
1371+
1372+ if(E_OK == result)
1373+ {
1374+ /* ディスパッチされるまで待つ */
1375+ tsk_wait_dispatch();
1376+ }
1377+ }
1378+ else
1379+ {
1380+ result = E_OBJ;
1381+ }
1382+ }
1383+ else
1384+ {
1385+ result = E_NOEXS;
1386+ }
1387+
1388+ depend_LeaveCriticalSection();
1389+ }
1390+ else
1391+ {
1392+ result = (TSK_SELF != tskid) ? E_ID : E_OBJ;
1393+ }
1394+
1395+ return result;
1396+}
1397+
1398+ER iwup_tsk(ID tskid)
1399+{
1400+ return E_NOSPT;
1401+}
1402+
1403+/* タスクの起床要求を無効化 */
1404+ER can_wup(INT *p_wupcnt, ID tskid)
1405+{
1406+ ER result;
1407+
1408+ if(ISVALID_TSKID(tskid) || (TSK_SELF == tskid))
1409+ {
1410+ if(ISVALID_PTR(p_wupcnt))
1411+ {
1412+ ER ret;
1413+ T_TCB *p_tcb;
1414+
1415+ ret = tsk_get_tcb(tskid, &p_tcb);
1416+ if(E_OK == ret)
1417+ {
1418+ depend_EnterCriticalSection();
1419+
1420+ if(0 != p_tcb->tskid)
1421+ {
1422+ if(TTS_DMT != p_tcb->tskstat)
1423+ {
1424+ *p_wupcnt = p_tcb->wupcnt;
1425+ p_tcb->wupcnt = 0;
1426+
1427+ result = E_OK;
1428+ }
1429+ else
1430+ {
1431+ result = E_OBJ;
1432+ }
1433+ }
1434+ else
1435+ {
1436+ result = E_NOEXS;
1437+ }
1438+
1439+ depend_LeaveCriticalSection();
1440+ }
1441+ else
1442+ {
1443+ result = (E_CTX == ret) ? E_ID : ret;
1444+ }
1445+ }
1446+ else
1447+ {
1448+ result = E_PAR;
1449+ }
1450+ }
1451+ else
1452+ {
1453+ result = E_ID;
1454+ }
1455+
1456+ return result;
1457+}
1458+
1459+/*
1460+ * =============================================================================
1461+ * ここから非標準関数の実装
1462+ * =============================================================================
1463+ */
1464+#if 0
1465+/*
1466+ * --------------------------------------------------------------------------
1467+ * タスクを一定時間待ち状態へ移行する
1468+ * --------------------------------------------------------------------------
1469+ */
1470+ER wai_tsk(TMO tmout)
1471+{
1472+ ER ercd; /* 呼び出した関数の戻り値 */
1473+ T_TCB *p_tcb;
1474+
1475+// if( DSPENA == OFF ) /* ディスパッチ禁止状態 */
1476+// {
1477+// return( E_CTX );
1478+// }
1479+
1480+ ercd = tsk_get_tcb(TSK_SELF, &p_tcb);
1481+ if(E_OK != ercd)
1482+ {
1483+ return ercd;
1484+ }
1485+
1486+ if(0 != p_tcb->wupcnt) /* 起床要求がある? */
1487+ {
1488+ /* 起床要求がキューイングされている */
1489+ (p_tcb->wupcnt)--;
1490+ }
1491+ else
1492+ {
1493+ /* 起床要求がキューイングされていない */
1494+ del_rdq(p_tcb); /* TCBをRDQ から外す */
1495+ p_tcb->tskstat = TTS_WAI; /* タスク状態は時間待ちに */
1496+ p_tcb->tskwait = WTIM; /* タスク状態は時間待ちに */
1497+ p_tcb->wid = 0;
1498+ p_tcb->tmout = timq.time + tmout; /* タイムアウト時刻を設定 */
1499+ add_timq(p_tcb); /* 時間待ち行列につなぐ */
1500+
1501+ /* ディスパッチされるまで待つ */
1502+ tsk_wait_dispatch();
1503+ }
1504+
1505+ return E_OK;
1506+}
1507+
1508+/* タスクの状態を見る */
1509+ER tsk_sts(UINT *p_tskstat, PRI *p_tskpri, ID tskid)
1510+{
1511+ ER result;
1512+
1513+ /*==============*/
1514+ /* 引数チェック */
1515+ /*==============*/
1516+ if(ISVALID_TSKID(tskid))
1517+ {
1518+ ER ret;
1519+ T_TCB *p_tcb;
1520+
1521+ ret = tsk_get_tcb(tskid, &p_tcb);
1522+ if(E_OK == ret)
1523+ {
1524+ if(NCT != p_tcb->sts)
1525+ {
1526+ if(p_tskstat)
1527+ {
1528+ /*----------------- タスクの状態、優先度を得る ------------------*/
1529+ if((TTS_RDY == p_tcb->sts) && (TSK_SELF == tskid))
1530+ {
1531+ *p_tskstat = TTS_RUN;
1532+ }
1533+ else
1534+ {
1535+ *p_tskstat = (p_tcb->sts & 0x00ff);
1536+ }
1537+ }
1538+
1539+ if(p_tskpri)
1540+ {
1541+ *p_tskpri = p_tcb->pri;
1542+ }
1543+
1544+ result = E_OK;
1545+ }
1546+ else
1547+ {
1548+ result = E_NOEXS;
1549+ }
1550+ }
1551+ else
1552+ {
1553+ result = ret;
1554+ }
1555+ }
1556+ else
1557+ {
1558+ result = E_ID;
1559+ }
1560+
1561+ return result;
1562+}
1563+#endif
--- /dev/null
+++ b/src/tsk.h
@@ -0,0 +1,159 @@
1+/**
2+ * @file tsk.h
3+ *
4+ */
5+
6+#ifndef _TSK_H_
7+#define _TSK_H_
8+
9+#include <itron.h>
10+#include "lst.h"
11+
12+// TODO 非標準の移植のための暫定措置
13+#define WTIM (0x4000)
14+
15+/* 内部用TCB構造体 */
16+typedef struct S_TCB
17+{
18+ T_LST lst; /**< list controller */
19+
20+ ID tskid; /**< タスクID番号 */
21+
22+ VP exinf; /**< 拡張情報 */
23+ ATR tskatr; /**< タスク属性 */
24+ FP task; /**< タスク起動アドレス */
25+ PRI itskpri; /**< タスク起動時優先度 */
26+ INT stksz; /**< スタックサイズ */
27+
28+ PRI tskpri; /**< 現在の優先度 */
29+ UINT tskstat; /**< タスク状態 */
30+ UINT tskwait; /**< 待ち要因 */
31+ ID wid; /**< 待ち行列のID */
32+ INT wupcnt; /**< 起床要求キューイング数 */
33+ INT suscnt; /**< SUSPEND要求ネスト数 */
34+
35+ ER *p_wercd; /**< 待ち結果のアドレス */
36+
37+ union U_WAIT
38+ {
39+ struct S_WFLG
40+ {
41+ UINT wfmode; /**< フラグ待ちモード */
42+ UINT waiptn; /**< 待ちフラグパターン */
43+ UINT flgptn; /**< 待ち解除時のフラグパターン */
44+ } wflg;
45+
46+ struct S_WMBX
47+ {
48+ T_MSG **ppk_msg; /**< メッセージパケットの先頭を入れるアドレス */
49+ } wmbx;
50+
51+ struct S_WMBF
52+ {
53+ VP msg; /**< 受信メッセージを入れるアドレス */
54+ INT msgsz; /**< 受信メッセージのサイズ */
55+ } wmbf;
56+
57+ struct S_WMPL {
58+ INT blksz; /**< メモリブロックサイズ */
59+ VP blk; /**< メモリブロックのアドレス */
60+ } wmpl;
61+
62+ struct S_WMPF
63+ {
64+ VP blf; /**< メモリブロックのアドレス */
65+ } wmpf;
66+
67+ } wait;
68+
69+
70+
71+
72+ struct S_TCB *next; /**< 次のTCBへのポインタ */
73+ struct S_TCB *prev; /**< 前のTCBへのポインタ */
74+
75+// PRI pri; /**< タスク優先度 */
76+// VH sts; /**< タスク状態フラグ */
77+
78+ VB dmy[2]; /**< ダミー */
79+ TMO tmout; /**< タイムアウト時刻 */
80+ VB *arg; /**< 引数のアドレス */
81+
82+// FP sta_func; /**< スタートアドレス */
83+// VB *end_func; /**< 終了処理関数のアドレス */
84+// VB *stack; /**< スタック初期値 */
85+// VB *sp; /**< スタックポインタ */
86+
87+// PRI endpri; /**< 終了処理実行時の優先度 */
88+ UH susmask; /**< SUSPEND マスク状態 */
89+// UH ipri; /**< 初期タスク優先度 */
90+// UB size; /**< スタックサイズ(KB) */
91+// UB r_size; /**< 残りスタックサイズ(%) */
92+// UW *scp; /**< スタックチェックポイント */
93+
94+
95+ /* ここから、このシミュレータ独自の実装 */
96+ B name[16]; /**< タスク名 */
97+
98+} T_TCB;
99+
100+typedef struct S_TCBTMO
101+{
102+ ID tskid; /* タスクID番号 */
103+ PRI _pri; /* ダミー */
104+ VH sts; /* タスク状態フラグ */
105+ ID _wid; /* ダミー */
106+ T_TCB *next; /* 次のTCBへのポインタ */
107+ T_TCB *prev; /* 前のTCBへのポインタ */
108+
109+ VH _wfmode; /* ダミー */
110+ VH _waiptn; /* ダミー */
111+ UH _wupcnt; /* ダミー */
112+ UH _suscnt; /* ダミー */
113+ TMO tmout; /* タイムアウト時刻 */
114+ T_TCB *tcb; /* TCB の本体 */
115+} T_TCBTMO;
116+
117+/*--------------------------------------------------------------------------*/
118+/* レディキュー管理ブロック ( RDQ ) */
119+/*--------------------------------------------------------------------------*/
120+typedef struct S_RDQ
121+{
122+ T_LST lst;
123+
124+ T_TCB *head;
125+} T_RDQ;
126+
127+/* タスクシステムの初期化 */
128+int tsk_initialize(void);
129+
130+/* タスクシステムの終了 */
131+void tsk_terminate(void);
132+
133+ER kernel_cre_tsk(T_TCB *p_tcb);
134+
135+/* タスクIDを取得する */
136+ER kernel_tsk_get_self_tskid(ID *p_tskid);
137+
138+/* TCBを得る */
139+ER tsk_get_tcb(ID tskid, T_TCB** pp_tcb);
140+
141+/* ディスパッチされるまで待つ */
142+/* 引数p_kernel_tcbにNULLを指定すると、ブロックしない */
143+void tsk_wait_dispatch(void);
144+
145+/* タスクスケジューラにディスパッチされるまで待つ */
146+void tsk_dispatch(void);
147+
148+/* 待ちタスクリストに繋がれたタスクの待ち状態を解除する */
149+void tsk_wait_delete(T_LST *p_wtsklst);
150+
151+void tsk_wait_release(T_TCB *p_tcb, ER ercd);
152+
153+#define TSK_GET_WTSKID(p_wtsklst) ((BOOL_ID)(lst_empty(p_wtsklst) ? FALSE : ((T_TCB *)(p_wtsklst))->tskid))
154+
155+ER end_func_set(ID tskid);
156+
157+
158+
159+#endif /* _TSK_H_ */