uITRON3のシステムコールをシュミレーションする、uITRON3向けモジュールの単体テスト用ライブラリ。
| Revision | 2c0ddf8d753e97d2fde5def6ebc1e5c092b98b06 (tree) |
|---|---|
| Time | 2013-03-31 09:25:17 |
| Author | nikarana <nikarana@gmai...> |
| Commiter | nikarana |
add c files.
| @@ -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 | +} |
| @@ -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_ */ |
| @@ -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 | +} |
| @@ -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_ */ |
| @@ -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_ */ |
| @@ -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 | +} |
| @@ -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_ */ |
| @@ -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 | +} |
| @@ -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_ */ |
| @@ -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 | +} |
| @@ -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_ */ |
| @@ -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 | +} |
| @@ -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_ */ |
| @@ -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_ */ |
| @@ -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 | +} |
| @@ -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_ */ |
| @@ -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_ */ |
| @@ -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 | + |
| @@ -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_ */ |
| @@ -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 | +} |
| @@ -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_ */ |
| @@ -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 | + |
| @@ -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_ */ |
| @@ -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 | +} |
| @@ -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_ */ |
| @@ -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 | +} |
| @@ -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_ */ |
| @@ -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 | + |
| @@ -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_ */ |
| @@ -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 | +} |
| @@ -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_ */ |
| @@ -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 | +} |
| @@ -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 */ |
| @@ -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) */ |
| @@ -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_ */ |
| @@ -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 | +} |
| @@ -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_ */ |
| @@ -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 | +} |
| @@ -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_ */ |
| @@ -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 |
| @@ -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_ */ |