source: asp3_wo_tecs/trunk/test/bit_kernel.c@ 305

Last change on this file since 305 was 305, checked in by ertl-honda, 7 years ago

3.0.0のリリース版に追従

File size: 14.3 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-2016 by Embedded and Real-Time Systems Laboratory
7 * Graduate School of Information Science, Nagoya Univ., JAPAN
8 *
9 * 上記著作権者
10は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
11 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
12 * 変・再é…
13å¸ƒï¼ˆä»¥ä¸‹ï¼Œåˆ©ç”¨ã¨å‘¼ã¶ï¼‰ã™ã‚‹ã“とを無償で許諾する.
14 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
15 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
16 * スコード中に含まれていること.
17 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
18 * 用できる形で再é…
19å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œå†é…
20å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨
21 * 者
22マニュアルなど)に,上記の著作権表示,この利用条件および下記
23 * の無保証規定を掲載すること.
24 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
25 * 用できない形で再é…
26å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œæ¬¡ã®ã„ずれかの条件を満たすこ
27 * と.
28 * (a) 再é…
29å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨è€…
30マニュアルなど)に,上記の著
31 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
32 * (b) 再é…
33å¸ƒã®å½¢æ…
34‹ã‚’,別に定める方法によって,TOPPERSプロジェクトに
35 * 報告すること.
36 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
37 * 害からも,上記著作権者
38およびTOPPERSプロジェクトをå…
39è²¬ã™ã‚‹ã“と.
40 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
41 * 由に基づく請求からも,上記著作権者
42およびTOPPERSプロジェクトを
43 * å…
44è²¬ã™ã‚‹ã“と.
45 *
46 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者
47お
48 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
49 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
50 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
51 * の責任を負わない.
52 *
53 * $Id: bit_kernel.c 554 2016-01-17 13:21:59Z ertl-hiro $
54 */
55
56/*
57 * カーネルの整合性検査
58 */
59
60#include "kernel/kernel_impl.h"
61#include "kernel/task.h"
62#include "kernel/wait.h"
63#include "kernel/semaphore.h"
64#include "kernel/eventflag.h"
65#include "kernel/dataqueue.h"
66#include "kernel/pridataq.h"
67#include "kernel/mutex.h"
68#include "kernel/mempfix.h"
69#include "kernel/time_event.h"
70#include "kernel/check.h"
71
72/*
73 * エラーコードの定義
74 */
75#define E_SYS_LINENO ERCD(E_SYS, -(__LINE__))
76
77/*
78 * 管理ブロックのアドレスの正当性のチェック
79 */
80#define VALID_TCB(p_tcb) \
81 ((((char *) p_tcb) - ((char *) tcb_table)) % sizeof(TCB) == 0 \
82 && TMIN_TSKID <= TSKID(p_tcb) && TSKID(p_tcb) <= tmax_tskid)
83
84#define VALID_SEMCB(p_semcb) \
85 ((((char *) p_semcb) - ((char *) semcb_table)) % sizeof(SEMCB) == 0 \
86 && TMIN_SEMID <= SEMID(p_semcb) && SEMID(p_semcb) <= tmax_semid)
87
88#define VALID_FLGCB(p_flgcb) \
89 ((((char *) p_flgcb) - ((char *) flgcb_table)) % sizeof(FLGCB) == 0 \
90 && TMIN_FLGID <= FLGID(p_flgcb) && FLGID(p_flgcb) <= tmax_flgid)
91
92#define VALID_DTQCB(p_dtqcb) \
93 ((((char *) p_dtqcb) - ((char *) dtqcb_table)) % sizeof(DTQCB) == 0 \
94 && TMIN_DTQID <= DTQID(p_dtqcb) && DTQID(p_dtqcb) <= tmax_dtqid)
95
96#define VALID_PDQCB(p_pdqcb) \
97 ((((char *) p_pdqcb) - ((char *) pdqcb_table)) % sizeof(PDQCB) == 0 \
98 && TMIN_PDQID <= PDQID(p_pdqcb) && PDQID(p_pdqcb) <= tmax_pdqid)
99
100#define VALID_MTXCB(p_mtxcb) \
101 ((((char *) p_mtxcb) - ((char *) mtxcb_table)) % sizeof(MTXCB) == 0 \
102 && TMIN_MTXID <= MTXID(p_mtxcb) && MTXID(p_mtxcb) <= tmax_mtxid)
103
104#define VALID_MPFCB(p_mpfcb) \
105 ((((char *) p_mpfcb) - ((char *) mpfcb_table)) % sizeof(MPFCB) == 0 \
106 && TMIN_MPFID <= MPFID(p_mpfcb) && MPFID(p_mpfcb) <= tmax_mpfid)
107
108/*
109 * キューのチェックのための関数
110 *
111 * p_queueにp_entryが含まれているかを調べる.含まれていればtrue,含ま
112 * れていない場合にはfalseを返す.ダブルリンクの不整合の場合にも,
113 * falseを返す.
114 */
115static bool_t
116in_queue(QUEUE *p_queue, QUEUE *p_entry)
117{
118 QUEUE *p_current, *p_next;
119
120 p_current = p_queue->p_next;
121 if (p_current->p_prev != p_queue) {
122 return(false); /* ダブルリンクの不整合 */
123 }
124 while (p_current != p_queue) {
125 if (p_current == p_entry) {
126 return(true); /* p_entryが含まれていた */
127 }
128
129 /*
130 * キューの次の要素に進む
131 */
132 p_next = p_current->p_next;
133 if (p_next->p_prev != p_current) {
134 return(false); /* ダブルリンクの不整合 */
135 }
136 p_current = p_next;
137 }
138 return(false);
139}
140
141/*
142 * スタック上を指しているかの検査
143 */
144static bool_t
145on_stack(void *addr, const TINIB *p_tinib)
146{
147#ifdef USE_TSKINICTXB
148 /*
149 * この関数の実装
150はターゲット依存になる.
151 */
152 return(true);
153#else /* USE_TSKINICTXB */
154 if (p_tinib->stk <= addr
155 && addr < (void *)((char *)(p_tinib->stk) + p_tinib->stksz)) {
156 return(true);
157 }
158 return(false);
159#endif /* USE_TSKINICTXB */
160}
161
162/*
163 * スケジューリングのためのデータ構造の検査
164 */
165#ifndef PRIMAP_BIT
166#define PRIMAP_BIT(pri) (1U << (pri))
167#endif /* PRIMAP_BIT */
168
169Inline bool_t
170primap_empty(void)
171{
172#ifndef PRIMAP_LEVEL_2
173 return(ready_primap == 0U);
174#else /* PRIMAP_LEVEL_2 */
175 return(ready_primap1 == 0U);
176#endif /* PRIMAP_LEVEL_2 */
177}
178
179Inline uint16_t
180primap_extract_bit(uint_t pri)
181{
182#ifndef PRIMAP_LEVEL_2
183 return(ready_primap & PRIMAP_BIT(pri));
184#else /* PRIMAP_LEVEL_2 */
185 return(ready_primap2[pri / TBIT_PRIMAP] & PRIMAP_BIT(pri % TBIT_PRIMAP));
186#endif /* PRIMAP_LEVEL_2 */
187}
188
189static ER
190bit_schedcb(void)
191{
192 uint_t pri;
193 QUEUE *p_queue;
194 TCB *p_tcb;
195
196 /*
197 * enadspとp_schedtskの整合性の検査
198 */
199 if (enadsp) {
200 if (primap_empty()) {
201 if (p_schedtsk != NULL) {
202 return(E_SYS_LINENO);
203 }
204 }
205 else {
206 if (p_schedtsk != search_schedtsk()) {
207 return(E_SYS_LINENO);
208 }
209 }
210 }
211
212#ifdef PRIMAP_LEVEL_2
213 /*
214 * ready_primap1とready_primap2の整合性の検査
215 */
216 for (pri = 0; pri < TNUM_TPRI; pri += TBIT_PRIMAP) {
217 if (ready_primap2[pri / TBIT_PRIMAP] == 0U) {
218 if ((ready_primap1 & PRIMAP_BIT(pri / TBIT_PRIMAP)) != 0U) {
219 return(E_SYS_LINENO);
220 }
221 }
222 else {
223 if ((ready_primap1 & PRIMAP_BIT(pri / TBIT_PRIMAP)) == 0U) {
224 return(E_SYS_LINENO);
225 }
226 }
227 }
228#endif /* PRIMAP_LEVEL_2 */
229
230 /*
231 * ready_queueとready_primapの整合性の検査
232 */
233 for (pri = 0; pri < TNUM_TPRI; pri++) {
234 p_queue = ready_queue[pri].p_next;
235 if (p_queue == &ready_queue[pri]) {
236 if (primap_extract_bit(pri) != 0U) {
237 return(E_SYS_LINENO);
238 }
239 }
240 else {
241 if (primap_extract_bit(pri) == 0U) {
242 return(E_SYS_LINENO);
243 }
244 }
245 while (p_queue != &ready_queue[pri]) {
246 p_tcb = (TCB *) p_queue;
247 if (!VALID_TCB(p_tcb)) {
248 return(E_SYS_LINENO);
249 }
250 if (!TSTAT_RUNNABLE(p_tcb->tstat)) {
251 return(E_SYS_LINENO);
252 }
253 if (p_tcb->priority != pri) {
254 return(E_SYS_LINENO);
255 }
256 p_queue = p_queue->p_next;
257 }
258 }
259 return(E_OK);
260}
261
262/*
263 * タスク毎の整合性検査
264 */
265static ER
266bit_task(ID tskid)
267{
268 TCB *p_tcb;
269 const TINIB *p_tinib;
270 uint_t tstat, bpri, pri;
271 TMEVTB *p_tmevtb;
272 SEMCB *p_semcb;
273 FLGCB *p_flgcb;
274 DTQCB *p_dtqcb;
275 PDQCB *p_pdqcb;
276 MTXCB *p_mtxcb;
277 MPFCB *p_mpfcb;
278
279 if (!VALID_TSKID(tskid)) {
280 return(E_ID);
281 }
282 p_tcb = get_tcb(tskid);
283 p_tinib = p_tcb->p_tinib;
284 tstat = p_tcb->tstat;
285 bpri = p_tcb->bpriority;
286 pri = p_tcb->priority;
287
288 /*
289 * タスク初期化ブロックへのポインタの検査
290 */
291 if (p_tinib != &(tinib_table[INDEX_TSK(tskid)])) {
292 return(E_SYS_LINENO);
293 }
294
295 /*
296 * tstatの検査
297 */
298 if (TSTAT_DORMANT(tstat)) {
299 if (tstat != TS_DORMANT) {
300 return(E_SYS_LINENO);
301 }
302 }
303 else if (TSTAT_WAITING(tstat)) {
304 if ((tstat & ~(TS_WAITING_MASK | TS_SUSPENDED)) != 0U) {
305 return(E_SYS_LINENO);
306 }
307 }
308 else if (TSTAT_SUSPENDED(tstat)) {
309 if (tstat != TS_SUSPENDED) {
310 return(E_SYS_LINENO);
311 }
312 }
313 else {
314 if (tstat != TS_RUNNABLE) {
315 return(E_SYS_LINENO);
316 }
317 }
318
319 /*
320 * ベース優å…
321ˆåº¦ã®æ¤œæŸ»
322 */
323 if (bpri >= TNUM_TPRI) {
324 return(E_SYS_LINENO);
325 }
326
327 /*
328 * 現在の優å…
329ˆåº¦ã®æ¤œæŸ»
330 */
331 if (pri > bpri) {
332 return(E_SYS_LINENO);
333 }
334
335 /*
336 * rasterと他の状æ…
337‹ã®æ•´åˆæ€§ã®æ¤œæŸ»
338 */
339 if (p_tcb->raster && (p_tcb->enater || TSTAT_WAITING(tstat))) {
340 return(E_SYS_LINENO);
341 }
342
343 /*
344 * 休止状æ…
345‹ã«ãŠã‘るチェック
346 */
347 if (TSTAT_DORMANT(tstat)) {
348 if (!(bpri == p_tinib->ipriority
349 && pri == p_tinib->ipriority
350 && p_tcb->actque == false
351 && p_tcb->wupque == false
352 && p_tcb->raster == false
353 && p_tcb->enater == true
354 && p_tcb->p_lastmtx == NULL)) {
355 return(E_SYS_LINENO);
356 }
357 }
358
359 /*
360 * 実行できる状æ…
361‹ã«ãŠã‘るチェック
362 */
363 if (TSTAT_RUNNABLE(tstat)) {
364 if (!in_queue(&ready_queue[pri], &(p_tcb->task_queue))) {
365 return(E_SYS_LINENO);
366 }
367 }
368
369 /*
370 * 待
371ち状æ…
372‹ã«ãŠã‘るチェック
373 */
374 if (TSTAT_WAITING(tstat)) {
375 if (!on_stack(p_tcb->p_winfo, p_tinib)) {
376 return(E_SYS_LINENO);
377 }
378 p_tmevtb = p_tcb->p_winfo->p_tmevtb;
379 if (p_tmevtb != NULL) {
380 if (!on_stack(p_tmevtb, p_tinib)) {
381 return(E_SYS_LINENO);
382 }
383 /*
384 * (*p_tmevtb)の検査(未完成)
385 */
386 }
387
388 switch (tstat & TS_WAITING_MASK) {
389 case TS_WAITING_SLP:
390 if (p_tcb->wupque == true) {
391 return(E_SYS_LINENO);
392 }
393 break;
394
395 case TS_WAITING_DLY:
396 if (p_tmevtb == NULL) {
397 return(E_SYS_LINENO);
398 }
399 break;
400
401 case TS_WAITING_SEM:
402 p_semcb = ((WINFO_SEM *)(p_tcb->p_winfo))->p_semcb;
403 if (!VALID_SEMCB(p_semcb)) {
404 return(E_SYS_LINENO);
405 }
406 if (!in_queue(&(p_semcb->wait_queue), &(p_tcb->task_queue))) {
407 return(E_SYS_LINENO);
408 }
409 break;
410
411 case TS_WAITING_FLG:
412 p_flgcb = ((WINFO_FLG *)(p_tcb->p_winfo))->p_flgcb;
413 if (!VALID_FLGCB(p_flgcb)) {
414 return(E_SYS_LINENO);
415 }
416 if (!in_queue(&(p_flgcb->wait_queue), &(p_tcb->task_queue))) {
417 return(E_SYS_LINENO);
418 }
419 break;
420
421 case TS_WAITING_SDTQ:
422 p_dtqcb = ((WINFO_SDTQ *)(p_tcb->p_winfo))->p_dtqcb;
423 if (!VALID_DTQCB(p_dtqcb)) {
424 return(E_SYS_LINENO);
425 }
426 if (!in_queue(&(p_dtqcb->swait_queue), &(p_tcb->task_queue))) {
427 return(E_SYS_LINENO);
428 }
429 break;
430
431 case TS_WAITING_RDTQ:
432 p_dtqcb = ((WINFO_RDTQ *)(p_tcb->p_winfo))->p_dtqcb;
433 if (!VALID_DTQCB(p_dtqcb)) {
434 return(E_SYS_LINENO);
435 }
436 if (!in_queue(&(p_dtqcb->rwait_queue), &(p_tcb->task_queue))) {
437 return(E_SYS_LINENO);
438 }
439 break;
440
441 case TS_WAITING_SPDQ:
442 p_pdqcb = ((WINFO_SPDQ *)(p_tcb->p_winfo))->p_pdqcb;
443 if (!VALID_PDQCB(p_pdqcb)) {
444 return(E_SYS_LINENO);
445 }
446 if (!in_queue(&(p_pdqcb->swait_queue), &(p_tcb->task_queue))) {
447 return(E_SYS_LINENO);
448 }
449 break;
450
451 case TS_WAITING_RPDQ:
452 p_pdqcb = ((WINFO_RPDQ *)(p_tcb->p_winfo))->p_pdqcb;
453 if (!VALID_PDQCB(p_pdqcb)) {
454 return(E_SYS_LINENO);
455 }
456 if (!in_queue(&(p_pdqcb->rwait_queue), &(p_tcb->task_queue))) {
457 return(E_SYS_LINENO);
458 }
459 break;
460
461 case TS_WAITING_MTX:
462 p_mtxcb = ((WINFO_MTX *)(p_tcb->p_winfo))->p_mtxcb;
463 if (!VALID_MTXCB(p_mtxcb)) {
464 return(E_SYS_LINENO);
465 }
466 if (!in_queue(&(p_mtxcb->wait_queue), &(p_tcb->task_queue))) {
467 return(E_SYS_LINENO);
468 }
469 break;
470
471 case TS_WAITING_MPF:
472 p_mpfcb = ((WINFO_MPF *)(p_tcb->p_winfo))->p_mpfcb;
473 if (!VALID_MPFCB(p_mpfcb)) {
474 return(E_SYS_LINENO);
475 }
476 if (!in_queue(&(p_mpfcb->wait_queue), &(p_tcb->task_queue))) {
477 return(E_SYS_LINENO);
478 }
479 break;
480
481 default:
482 return(E_SYS_LINENO);
483 break;
484 }
485 }
486
487 /*
488 * p_lastmtxの検査
489 */
490 if (p_tcb->p_lastmtx != NULL) {
491 if (!VALID_MTXCB(p_tcb->p_lastmtx)) {
492 return(E_SYS_LINENO);
493 }
494 }
495
496 /*
497 * tskctxbの検査
498 */
499 if (!TSTAT_DORMANT(tstat) && p_tcb != p_runtsk) {
500 /*
501 * ターゲット依存の検査
502 */
503#if 0
504 if (bit_tskctxb(&(p_tcb->tskctxb))) {
505 return(E_SYS_LINENO);
506 }
507#endif
508 }
509 return(E_OK);
510}
511
512/*
513 * セマフォ毎の整合性検査
514 */
515#define INDEX_SEM(semid) ((uint_t)((semid) - TMIN_SEMID))
516#define get_semcb(semid) (&(semcb_table[INDEX_SEM(semid)]))
517
518static ER
519bit_semaphore(ID semid)
520{
521 SEMCB *p_semcb;
522 const SEMINIB *p_seminib;
523 uint_t semcnt, pri;
524 QUEUE *p_queue;
525 TCB *p_tcb;
526
527 if (!VALID_SEMID(semid)) {
528 return(E_ID);
529 }
530 p_semcb = get_semcb(semid);
531 p_seminib = p_semcb->p_seminib;
532 semcnt = p_semcb->semcnt;
533
534 /*
535 * セマフォ初期化ブロックへのポインタの検査
536 */
537 if (p_seminib != &(seminib_table[INDEX_SEM(semid)])) {
538 return(E_SYS_LINENO);
539 }
540
541 /*
542 * semcntの検査
543 */
544 if (semcnt > p_seminib->maxsem) {
545 return(E_SYS_LINENO);
546 }
547
548 /*
549 * wait_queueの検査
550 */
551 if (semcnt == 0) {
552 p_queue = p_semcb->wait_queue.p_next;
553 pri = TMIN_TPRI;
554 while (p_queue != &(p_semcb->wait_queue)) {
555 p_tcb = (TCB *) p_queue;
556 if (!VALID_TCB(p_tcb)) {
557 return(E_SYS_LINENO);
558 }
559
560 /*
561 * キューがタスク優å…
562ˆåº¦é †ã«ãªã£ã¦ã„るかの検査
563 */
564 if ((p_seminib->sematr & TA_TPRI) != 0U) {
565 if (p_tcb->priority < pri) {
566 return(E_SYS_LINENO);
567 }
568 }
569 pri = p_tcb->priority;
570
571 /*
572 * タスク状æ…
573‹ã®æ¤œæŸ»
574 */
575 if (p_tcb->tstat != TS_WAITING_SEM) {
576 return(E_SYS_LINENO);
577 }
578 if (p_semcb != ((WINFO_SEM *)(p_tcb->p_winfo))->p_semcb) {
579 return(E_SYS_LINENO);
580 }
581 p_queue = p_queue->p_next;
582 }
583 }
584 else {
585 if (!queue_empty(&(p_semcb->wait_queue))) {
586 return(E_SYS_LINENO);
587 }
588 }
589 return(E_OK);
590}
591
592/*
593 * 整合性検査ルーチン本体
594 */
595ER
596bit_kernel(void)
597{
598 ID tskid;
599 ID semid;
600 ER ercd;
601
602 /*
603 * スケジューリングのためのデータ構造の検査
604 */
605 ercd = bit_schedcb();
606 if (ercd != E_OK) {
607 return(ercd);
608 }
609
610 /*
611 * タスク毎の検査
612 */
613 for (tskid = TMIN_TSKID; tskid <= tmax_tskid; tskid++) {
614 ercd = bit_task(tskid);
615 if (ercd != E_OK) {
616 return(ercd);
617 }
618 }
619
620 /*
621 * セマフォ毎の検査
622 */
623 for (semid = TMIN_SEMID; semid <= tmax_semid; semid++) {
624 ercd = bit_semaphore(semid);
625 if (ercd != E_OK) {
626 return(ercd);
627 }
628 }
629
630 return(E_OK);
631}
Note: See TracBrowser for help on using the repository browser.