source: rubycfg_asp/trunk/asp_dcre/test/bit_kernel.c@ 315

Last change on this file since 315 was 315, checked in by coas-nagasima, 7 years ago

SVNプロパティを設定

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-csrc; charset=UTF-8
File size: 11.8 KB
Line 
1/*
2 * TOPPERS/ASP Kernel
3 * Toyohashi Open Platform for Embedded Real-Time Systems/
4 * Advanced Standard Profile Kernel
5 *
6 * Copyright (C) 2005-2011 by Embedded and Real-Time Systems Laboratory
7 * Graduate School of Information Science, Nagoya Univ., JAPAN
8 *
9 * 上記著作権者は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
10 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
11 * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
12 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
13 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
14 * スコード中に含まれていること.
15 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
16 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
17 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
18 * の無保証規定を掲載すること.
19 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
20 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
21 * と.
22 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
23 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
24 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
25 * 報告すること.
26 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
27 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
28 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
29 * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
30 * 免責すること.
31 *
32 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
33 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
34 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
35 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
36 * の責任を負わない.
37 *
38 * @(#) $Id: bit_kernel.c 315 2017-07-23 05:29:40Z coas-nagasima $
39 */
40
41/*
42 * カーネルの整合性検査
43 */
44
45#include "kernel/kernel_impl.h"
46#include "kernel/task.h"
47#include "kernel/wait.h"
48#include "kernel/semaphore.h"
49#include "kernel/eventflag.h"
50#include "kernel/dataqueue.h"
51#include "kernel/pridataq.h"
52#include "kernel/mailbox.h"
53#include "kernel/mempfix.h"
54#include "kernel/time_event.h"
55
56/*
57 * エラーコードの定義
58 */
59#define E_SYS_LINENO ERCD(E_SYS, -(__LINE__))
60
61/*
62 * 管理ブロックのアドレスの正当性のチェック
63 */
64#define VALID_TCB(p_tcb) \
65 ((((char *) p_tcb) - ((char *) tcb_table)) % sizeof(TCB) == 0 \
66 && TMIN_TSKID <= TSKID(p_tcb) && TSKID(p_tcb) <= tmax_tskid)
67
68#define VALID_SEMCB(p_semcb) \
69 ((((char *) p_semcb) - ((char *) semcb_table)) % sizeof(SEMCB) == 0 \
70 && TMIN_SEMID <= SEMID(p_semcb) && SEMID(p_semcb) <= tmax_semid)
71
72#define VALID_FLGCB(p_flgcb) \
73 ((((char *) p_flgcb) - ((char *) flgcb_table)) % sizeof(FLGCB) == 0 \
74 && TMIN_FLGID <= FLGID(p_flgcb) && FLGID(p_flgcb) <= tmax_flgid)
75
76#define VALID_DTQCB(p_dtqcb) \
77 ((((char *) p_dtqcb) - ((char *) dtqcb_table)) % sizeof(DTQCB) == 0 \
78 && TMIN_DTQID <= DTQID(p_dtqcb) && DTQID(p_dtqcb) <= tmax_dtqid)
79
80#define VALID_PDQCB(p_pdqcb) \
81 ((((char *) p_pdqcb) - ((char *) pdqcb_table)) % sizeof(PDQCB) == 0 \
82 && TMIN_PDQID <= PDQID(p_pdqcb) && PDQID(p_pdqcb) <= tmax_pdqid)
83
84#define VALID_MBXCB(p_mbxcb) \
85 ((((char *) p_mbxcb) - ((char *) mbxcb_table)) % sizeof(MBXCB) == 0 \
86 && TMIN_MBXID <= MBXID(p_mbxcb) && MBXID(p_mbxcb) <= tmax_mbxid)
87
88#define VALID_MPFCB(p_mpfcb) \
89 ((((char *) p_mpfcb) - ((char *) mpfcb_table)) % sizeof(MPFCB) == 0 \
90 && TMIN_MPFID <= MPFID(p_mpfcb) && MPFID(p_mpfcb) <= tmax_mpfid)
91
92/*
93 * キューのチェックのための関数
94 *
95 * p_queueにp_entryが含まれているかを調べる.含まれていればtrue,含ま
96 * れていない場合にはfalseを返す.ダブルリンクの不整合の場合にも,
97 * falseを返す.
98 */
99static bool_t
100in_queue(QUEUE *p_queue, QUEUE *p_entry)
101{
102 QUEUE *p_current, *p_next;
103
104 p_current = p_queue->p_next;
105 if (p_current->p_prev != p_queue) {
106 return(false); /* ダブルリンクの不整合 */
107 }
108 while (p_current != p_queue) {
109 if (p_current == p_entry) {
110 return(true); /* p_entryが含まれていた */
111 }
112
113 /*
114 * キューの次の要素に進む
115 */
116 p_next = p_current->p_next;
117 if (p_next->p_prev != p_current) {
118 return(false); /* ダブルリンクの不整合 */
119 }
120 p_current = p_next;
121 }
122 return(false);
123}
124
125/*
126 * スタック上を指しているかの検査
127 */
128static bool_t
129on_stack(void *addr, const TINIB *p_tinib)
130{
131 if (p_tinib->stk <= addr
132 && addr < (void *)((char *)(p_tinib->stk) + p_tinib->stksz)) {
133 return(true);
134 }
135 return(false);
136}
137
138/*
139 * タスク毎の整合性検査
140 */
141static ER
142bit_task(ID tskid)
143{
144 TCB *p_tcb;
145 const TINIB *p_tinib;
146 uint_t tstat, tstat_wait, pri;
147 TMEVTB *p_tmevtb;
148 SEMCB *p_semcb;
149 FLGCB *p_flgcb;
150 DTQCB *p_dtqcb;
151 PDQCB *p_pdqcb;
152 MBXCB *p_mbxcb;
153 MPFCB *p_mpfcb;
154
155 if (!(TMIN_TSKID <= (tskid) && (tskid) <= tmax_tskid)) {
156 return(E_ID);
157 }
158 p_tcb = get_tcb(tskid);
159 p_tinib = p_tcb->p_tinib;
160 tstat = p_tcb->tstat;
161 tstat_wait = (tstat & TS_WAIT_MASK);
162 pri = p_tcb->priority;
163
164 /*
165 * 初期化ブロックへのポインタの検査
166 */
167 if (p_tinib != &(tinib_table[INDEX_TSK(tskid)])) {
168 return(E_SYS_LINENO);
169 }
170
171 /*
172 * tstatの検査
173 */
174 switch (tstat & (TS_RUNNABLE | TS_WAITING | TS_SUSPENDED)) {
175 case TS_DORMANT:
176 if (tstat != TS_DORMANT) {
177 return(E_SYS_LINENO);
178 }
179 break;
180 case TS_RUNNABLE:
181 if (tstat != TS_RUNNABLE) {
182 return(E_SYS_LINENO);
183 }
184 break;
185 case TS_WAITING:
186 case (TS_WAITING | TS_SUSPENDED):
187 if (!(TS_WAIT_DLY <= tstat_wait && tstat_wait <= TS_WAIT_MPF)) {
188 return(E_SYS_LINENO);
189 }
190 if ((tstat & ~(TS_WAIT_MASK | TS_RUNNABLE | TS_WAITING | TS_SUSPENDED))
191 != 0U) {
192 return(E_SYS_LINENO);
193 }
194 break;
195 case TS_SUSPENDED:
196 if (tstat != TS_SUSPENDED) {
197 return(E_SYS_LINENO);
198 }
199 break;
200 default:
201 return(E_SYS_LINENO);
202 }
203
204 /*
205 * actqueの検査
206 */
207 if (TSTAT_DORMANT(tstat) && p_tcb->actque) {
208 return(E_SYS_LINENO);
209 }
210
211 /*
212 * タスク優先度の検査
213 */
214 if (pri >= TNUM_TPRI) {
215 return(E_SYS_LINENO);
216 }
217
218 /*
219 * texptnの検査
220 */
221 if (p_tcb->p_tinib->texrtn == NULL && p_tcb->texptn != 0U) {
222 return(E_SYS_LINENO);
223 }
224
225 /*
226 * 休止状態におけるチェック
227 */
228 if (TSTAT_DORMANT(tstat)) {
229 if (!(pri == p_tinib->ipriority)
230 && (p_tcb->wupque == false)
231 && (p_tcb->enatex == false)
232 && (p_tcb->texptn == 0U)) {
233 return(E_SYS_LINENO);
234 }
235 }
236
237 /*
238 * 実行できる状態におけるチェック
239 */
240 if (TSTAT_RUNNABLE(tstat)) {
241 if (!in_queue(&ready_queue[pri], &(p_tcb->task_queue))) {
242 return(E_SYS_LINENO);
243 }
244 }
245
246 /*
247 * 待ち状態におけるチェック
248 */
249 if (TSTAT_WAITING(tstat)) {
250 if (!on_stack(p_tcb->p_winfo, p_tinib)) {
251 return(E_SYS_LINENO);
252 }
253 p_tmevtb = p_tcb->p_winfo->p_tmevtb;
254 if (p_tmevtb != NULL) {
255 if (!on_stack(p_tmevtb, p_tinib)) {
256 return(E_SYS_LINENO);
257 }
258 /*
259 * (*p_tmevtb)の検査(未完成)
260 */
261 }
262
263 switch (tstat & TS_WAIT_MASK) {
264 case TS_WAIT_SLP:
265 if (p_tcb->wupque == true) {
266 return(E_SYS_LINENO);
267 }
268 break;
269
270 case TS_WAIT_DLY:
271 if (p_tmevtb == NULL) {
272 return(E_SYS_LINENO);
273 }
274 break;
275
276 case TS_WAIT_SEM:
277 p_semcb = ((WINFO_SEM *)(p_tcb->p_winfo))->p_semcb;
278 if (!VALID_SEMCB(p_semcb)) {
279 return(E_SYS_LINENO);
280 }
281 if (!in_queue(&(p_semcb->wait_queue), &(p_tcb->task_queue))) {
282 return(E_SYS_LINENO);
283 }
284 break;
285
286 case TS_WAIT_FLG:
287 p_flgcb = ((WINFO_FLG *)(p_tcb->p_winfo))->p_flgcb;
288 if (!VALID_FLGCB(p_flgcb)) {
289 return(E_SYS_LINENO);
290 }
291 if (!in_queue(&(p_flgcb->wait_queue), &(p_tcb->task_queue))) {
292 return(E_SYS_LINENO);
293 }
294 break;
295
296 case TS_WAIT_SDTQ:
297 p_dtqcb = ((WINFO_DTQ *)(p_tcb->p_winfo))->p_dtqcb;
298 if (!VALID_DTQCB(p_dtqcb)) {
299 return(E_SYS_LINENO);
300 }
301 if (!in_queue(&(p_dtqcb->swait_queue), &(p_tcb->task_queue))) {
302 return(E_SYS_LINENO);
303 }
304 break;
305
306 case TS_WAIT_RDTQ:
307 p_dtqcb = ((WINFO_DTQ *)(p_tcb->p_winfo))->p_dtqcb;
308 if (!VALID_DTQCB(p_dtqcb)) {
309 return(E_SYS_LINENO);
310 }
311 if (!in_queue(&(p_dtqcb->rwait_queue), &(p_tcb->task_queue))) {
312 return(E_SYS_LINENO);
313 }
314 break;
315
316 case TS_WAIT_SPDQ:
317 p_pdqcb = ((WINFO_PDQ *)(p_tcb->p_winfo))->p_pdqcb;
318 if (!VALID_PDQCB(p_pdqcb)) {
319 return(E_SYS_LINENO);
320 }
321 if (!in_queue(&(p_pdqcb->swait_queue), &(p_tcb->task_queue))) {
322 return(E_SYS_LINENO);
323 }
324 break;
325
326 case TS_WAIT_RPDQ:
327 p_pdqcb = ((WINFO_PDQ *)(p_tcb->p_winfo))->p_pdqcb;
328 if (!VALID_PDQCB(p_pdqcb)) {
329 return(E_SYS_LINENO);
330 }
331 if (!in_queue(&(p_pdqcb->rwait_queue), &(p_tcb->task_queue))) {
332 return(E_SYS_LINENO);
333 }
334 break;
335
336 case TS_WAIT_MBX:
337 p_mbxcb = ((WINFO_MBX *)(p_tcb->p_winfo))->p_mbxcb;
338 if (!VALID_MBXCB(p_mbxcb)) {
339 return(E_SYS_LINENO);
340 }
341 if (!in_queue(&(p_mbxcb->wait_queue), &(p_tcb->task_queue))) {
342 return(E_SYS_LINENO);
343 }
344 break;
345
346 case TS_WAIT_MPF:
347 p_mpfcb = ((WINFO_MPF *)(p_tcb->p_winfo))->p_mpfcb;
348 if (!VALID_MPFCB(p_mpfcb)) {
349 return(E_SYS_LINENO);
350 }
351 if (!in_queue(&(p_mpfcb->wait_queue), &(p_tcb->task_queue))) {
352 return(E_SYS_LINENO);
353 }
354 break;
355 }
356 }
357
358 /*
359 * tskctxbの検査
360 */
361 if (!TSTAT_DORMANT(tstat) && p_tcb != p_runtsk) {
362 /*
363 * ターゲット依存の検査
364 */
365#if 0
366 if (bit_tskctxb(&(p_tcb->tskctxb))) {
367 return(E_SYS_LINENO);
368 }
369#endif
370 }
371 return(E_OK);
372}
373
374/*
375 * セマフォ毎の整合性検査
376 */
377#define INDEX_SEM(semid) ((uint_t)((semid) - TMIN_SEMID))
378#define get_semcb(semid) (&(semcb_table[INDEX_SEM(semid)]))
379
380static ER
381bit_semaphore(ID semid)
382{
383 SEMCB *p_semcb;
384 const SEMINIB *p_seminib;
385 uint_t semcnt;
386 QUEUE *p_queue;
387 TCB *p_tcb;
388
389 if (!(TMIN_SEMID <= (semid) && (semid) <= tmax_semid)) {
390 return(E_ID);
391 }
392 p_semcb = get_semcb(semid);
393 p_seminib = p_semcb->p_seminib;
394 semcnt = p_semcb->semcnt;
395
396 /*
397 * 初期化ブロックへのポインタの検査
398 */
399 if (p_seminib != &(seminib_table[INDEX_SEM(semid)])) {
400 return(E_SYS_LINENO);
401 }
402
403 /*
404 * semcntの検査
405 */
406 if (semcnt > p_seminib->maxsem) {
407 return(E_SYS_LINENO);
408 }
409
410 /*
411 * wait_queueの検査
412 */
413 if (semcnt == 0) {
414 p_queue = p_semcb->wait_queue.p_next;
415 while (p_queue != &(p_semcb->wait_queue)) {
416 p_tcb = (TCB *) p_queue;
417 p_queue = p_queue->p_next;
418 if (!VALID_TCB(p_tcb)) {
419 return(E_SYS_LINENO);
420 }
421 if (p_tcb->tstat != (TS_WAITING | TS_WAIT_SEM)) {
422 return(E_SYS_LINENO);
423 }
424 if (p_semcb != ((WINFO_SEM *)(p_tcb->p_winfo))->p_semcb) {
425 return(E_SYS_LINENO);
426 }
427 }
428 }
429 else {
430 if (!queue_empty(&(p_semcb->wait_queue))) {
431 return(E_SYS_LINENO);
432 }
433 }
434 return(E_OK);
435}
436
437/*
438 * 整合性検査ルーチン本体
439 */
440ER
441bit_kernel(void)
442{
443 ID tskid;
444 ID semid;
445 ER ercd;
446
447 /*
448 * タスク毎の検査
449 */
450 for (tskid = TMIN_TSKID; tskid <= tmax_tskid; tskid++) {
451 ercd = bit_task(tskid);
452 if (ercd != E_OK) {
453 return(ercd);
454 }
455 }
456
457 /*
458 * セマフォ毎の検査
459 */
460 for (semid = TMIN_SEMID; semid <= tmax_semid; semid++) {
461 ercd = bit_semaphore(semid);
462 if (ercd != E_OK) {
463 return(ercd);
464 }
465 }
466
467 return(E_OK);
468}
Note: See TracBrowser for help on using the repository browser.