source: asp3_wo_tecs/trunk/extension/messagebuf/test/bit_kernel.c@ 302

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

TECSレスのASP3の開発のため以下のtrunkからコピー
http://dev.toppers.jp/svn/asp3/branches/WO_TECS-3.C.0

File size: 12.2 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-2014 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 53 2014-04-26 18:58:00Z 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/messagebuf.h"
69#include "kernel/mempfix.h"
70#include "kernel/time_event.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_MBFCB(p_mbfcb) \
105 ((((char *) p_mbfcb) - ((char *) mbfcb_table)) % sizeof(MBFCB) == 0 \
106 && TMIN_MBFID <= MBFID(p_mbfcb) && MBFID(p_mbfcb) <= tmax_mbfid)
107
108#define VALID_MPFCB(p_mpfcb) \
109 ((((char *) p_mpfcb) - ((char *) mpfcb_table)) % sizeof(MPFCB) == 0 \
110 && TMIN_MPFID <= MPFID(p_mpfcb) && MPFID(p_mpfcb) <= tmax_mpfid)
111
112/*
113 * キューのチェックのための関数
114 *
115 * p_queueにp_entryが含まれているかを調べる.含まれていればtrue,含ま
116 * れていない場合にはfalseを返す.ダブルリンクの不整合の場合にも,
117 * falseを返す.
118 */
119static bool_t
120in_queue(QUEUE *p_queue, QUEUE *p_entry)
121{
122 QUEUE *p_current, *p_next;
123
124 p_current = p_queue->p_next;
125 if (p_current->p_prev != p_queue) {
126 return(false); /* ダブルリンクの不整合 */
127 }
128 while (p_current != p_queue) {
129 if (p_current == p_entry) {
130 return(true); /* p_entryが含まれていた */
131 }
132
133 /*
134 * キューの次の要素に進む
135 */
136 p_next = p_current->p_next;
137 if (p_next->p_prev != p_current) {
138 return(false); /* ダブルリンクの不整合 */
139 }
140 p_current = p_next;
141 }
142 return(false);
143}
144
145/*
146 * スタック上を指しているかの検査
147 */
148static bool_t
149on_stack(void *addr, const TINIB *p_tinib)
150{
151 if (p_tinib->stk <= addr
152 && addr < (void *)((char *)(p_tinib->stk) + p_tinib->stksz)) {
153 return(true);
154 }
155 return(false);
156}
157
158/*
159 * タスク毎の整合性検査
160 */
161static ER
162bit_task(ID tskid)
163{
164 TCB *p_tcb;
165 const TINIB *p_tinib;
166 uint_t tstat, pri;
167 TMEVTB *p_tmevtb;
168 SEMCB *p_semcb;
169 FLGCB *p_flgcb;
170 DTQCB *p_dtqcb;
171 PDQCB *p_pdqcb;
172 MTXCB *p_mtxcb;
173 MBFCB *p_mbfcb;
174 MPFCB *p_mpfcb;
175
176 if (!(TMIN_TSKID <= (tskid) && (tskid) <= tmax_tskid)) {
177 return(E_ID);
178 }
179 p_tcb = get_tcb(tskid);
180 p_tinib = p_tcb->p_tinib;
181 tstat = p_tcb->tstat;
182 pri = p_tcb->priority;
183
184 /*
185 * 初期化ブロックへのポインタの検査
186 */
187 if (p_tinib != &(tinib_table[INDEX_TSK(tskid)])) {
188 return(E_SYS_LINENO);
189 }
190
191 /*
192 * tstatの検査
193 */
194 if (TSTAT_DORMANT(tstat)) {
195 if (tstat != TS_DORMANT) {
196 return(E_SYS_LINENO);
197 }
198 }
199 else if (TSTAT_WAITING(tstat)) {
200 if ((tstat & ~(TS_WAITING_MASK | TS_SUSPENDED)) != 0U) {
201 return(E_SYS_LINENO);
202 }
203 }
204 else if (TSTAT_SUSPENDED(tstat)) {
205 if (tstat != TS_SUSPENDED) {
206 return(E_SYS_LINENO);
207 }
208 }
209 else {
210 if (tstat != TS_RUNNABLE) {
211 return(E_SYS_LINENO);
212 }
213 }
214
215 /*
216 * actqueの検査
217 */
218 if (TSTAT_DORMANT(tstat) && p_tcb->actque) {
219 return(E_SYS_LINENO);
220 }
221
222 /*
223 * タスク優å…
224ˆåº¦ã®æ¤œæŸ»
225 */
226 if (pri >= TNUM_TPRI) {
227 return(E_SYS_LINENO);
228 }
229
230 /*
231 * rasterと他の状æ…
232‹ã®æ•´åˆæ€§ã®æ¤œæŸ»
233 */
234 if (p_tcb->raster && (p_tcb->enater || TSTAT_WAITING(tstat))) {
235 return(E_SYS_LINENO);
236 }
237
238 /*
239 * 休止状æ…
240‹ã«ãŠã‘るチェック
241 */
242 if (TSTAT_DORMANT(tstat)) {
243 if (!(pri == p_tinib->ipriority)
244 && (p_tcb->wupque == false)
245 && (p_tcb->raster == false)
246 && (p_tcb->enater == true)) {
247 return(E_SYS_LINENO);
248 }
249 }
250
251 /*
252 * 実行できる状æ…
253‹ã«ãŠã‘るチェック
254 */
255 if (TSTAT_RUNNABLE(tstat)) {
256 if (!in_queue(&ready_queue[pri], &(p_tcb->task_queue))) {
257 return(E_SYS_LINENO);
258 }
259 }
260
261 /*
262 * 待
263ち状æ…
264‹ã«ãŠã‘るチェック
265 */
266 if (TSTAT_WAITING(tstat)) {
267 if (!on_stack(p_tcb->p_winfo, p_tinib)) {
268 return(E_SYS_LINENO);
269 }
270 p_tmevtb = p_tcb->p_winfo->p_tmevtb;
271 if (p_tmevtb != NULL) {
272 if (!on_stack(p_tmevtb, p_tinib)) {
273 return(E_SYS_LINENO);
274 }
275 /*
276 * (*p_tmevtb)の検査(未完成)
277 */
278 }
279
280 switch (tstat & TS_WAITING_MASK) {
281 case TS_WAITING_SLP:
282 if (p_tcb->wupque == true) {
283 return(E_SYS_LINENO);
284 }
285 break;
286
287 case TS_WAITING_DLY:
288 if (p_tmevtb == NULL) {
289 return(E_SYS_LINENO);
290 }
291 break;
292
293 case TS_WAITING_SEM:
294 p_semcb = ((WINFO_SEM *)(p_tcb->p_winfo))->p_semcb;
295 if (!VALID_SEMCB(p_semcb)) {
296 return(E_SYS_LINENO);
297 }
298 if (!in_queue(&(p_semcb->wait_queue), &(p_tcb->task_queue))) {
299 return(E_SYS_LINENO);
300 }
301 break;
302
303 case TS_WAITING_FLG:
304 p_flgcb = ((WINFO_FLG *)(p_tcb->p_winfo))->p_flgcb;
305 if (!VALID_FLGCB(p_flgcb)) {
306 return(E_SYS_LINENO);
307 }
308 if (!in_queue(&(p_flgcb->wait_queue), &(p_tcb->task_queue))) {
309 return(E_SYS_LINENO);
310 }
311 break;
312
313 case TS_WAITING_SDTQ:
314 p_dtqcb = ((WINFO_SDTQ *)(p_tcb->p_winfo))->p_dtqcb;
315 if (!VALID_DTQCB(p_dtqcb)) {
316 return(E_SYS_LINENO);
317 }
318 if (!in_queue(&(p_dtqcb->swait_queue), &(p_tcb->task_queue))) {
319 return(E_SYS_LINENO);
320 }
321 break;
322
323 case TS_WAITING_RDTQ:
324 p_dtqcb = ((WINFO_RDTQ *)(p_tcb->p_winfo))->p_dtqcb;
325 if (!VALID_DTQCB(p_dtqcb)) {
326 return(E_SYS_LINENO);
327 }
328 if (!in_queue(&(p_dtqcb->rwait_queue), &(p_tcb->task_queue))) {
329 return(E_SYS_LINENO);
330 }
331 break;
332
333 case TS_WAITING_SPDQ:
334 p_pdqcb = ((WINFO_SPDQ *)(p_tcb->p_winfo))->p_pdqcb;
335 if (!VALID_PDQCB(p_pdqcb)) {
336 return(E_SYS_LINENO);
337 }
338 if (!in_queue(&(p_pdqcb->swait_queue), &(p_tcb->task_queue))) {
339 return(E_SYS_LINENO);
340 }
341 break;
342
343 case TS_WAITING_RPDQ:
344 p_pdqcb = ((WINFO_RPDQ *)(p_tcb->p_winfo))->p_pdqcb;
345 if (!VALID_PDQCB(p_pdqcb)) {
346 return(E_SYS_LINENO);
347 }
348 if (!in_queue(&(p_pdqcb->rwait_queue), &(p_tcb->task_queue))) {
349 return(E_SYS_LINENO);
350 }
351 break;
352
353 case TS_WAITING_MTX:
354 p_mtxcb = ((WINFO_MTX *)(p_tcb->p_winfo))->p_mtxcb;
355 if (!VALID_MTXCB(p_mtxcb)) {
356 return(E_SYS_LINENO);
357 }
358 if (!in_queue(&(p_mtxcb->wait_queue), &(p_tcb->task_queue))) {
359 return(E_SYS_LINENO);
360 }
361 break;
362
363 case TS_WAITING_SMBF:
364 p_mbfcb = ((WINFO_SMBF *)(p_tcb->p_winfo))->p_mbfcb;
365 if (!VALID_MBFCB(p_mbfcb)) {
366 return(E_SYS_LINENO);
367 }
368 if (!in_queue(&(p_mbfcb->swait_queue), &(p_tcb->task_queue))) {
369 return(E_SYS_LINENO);
370 }
371 break;
372
373 case TS_WAITING_RMBF:
374 p_mbfcb = ((WINFO_RMBF *)(p_tcb->p_winfo))->p_mbfcb;
375 if (!VALID_MBFCB(p_mbfcb)) {
376 return(E_SYS_LINENO);
377 }
378 if (!in_queue(&(p_mbfcb->rwait_queue), &(p_tcb->task_queue))) {
379 return(E_SYS_LINENO);
380 }
381 break;
382
383 case TS_WAITING_MPF:
384 p_mpfcb = ((WINFO_MPF *)(p_tcb->p_winfo))->p_mpfcb;
385 if (!VALID_MPFCB(p_mpfcb)) {
386 return(E_SYS_LINENO);
387 }
388 if (!in_queue(&(p_mpfcb->wait_queue), &(p_tcb->task_queue))) {
389 return(E_SYS_LINENO);
390 }
391 break;
392
393 default:
394 return(E_SYS_LINENO);
395 break;
396 }
397 }
398
399 /*
400 * tskctxbの検査
401 */
402 if (!TSTAT_DORMANT(tstat) && p_tcb != p_runtsk) {
403 /*
404 * ターゲット依存の検査
405 */
406#if 0
407 if (bit_tskctxb(&(p_tcb->tskctxb))) {
408 return(E_SYS_LINENO);
409 }
410#endif
411 }
412 return(E_OK);
413}
414
415/*
416 * セマフォ毎の整合性検査
417 */
418#define INDEX_SEM(semid) ((uint_t)((semid) - TMIN_SEMID))
419#define get_semcb(semid) (&(semcb_table[INDEX_SEM(semid)]))
420
421static ER
422bit_semaphore(ID semid)
423{
424 SEMCB *p_semcb;
425 const SEMINIB *p_seminib;
426 uint_t semcnt;
427 QUEUE *p_queue;
428 TCB *p_tcb;
429
430 if (!(TMIN_SEMID <= (semid) && (semid) <= tmax_semid)) {
431 return(E_ID);
432 }
433 p_semcb = get_semcb(semid);
434 p_seminib = p_semcb->p_seminib;
435 semcnt = p_semcb->semcnt;
436
437 /*
438 * 初期化ブロックへのポインタの検査
439 */
440 if (p_seminib != &(seminib_table[INDEX_SEM(semid)])) {
441 return(E_SYS_LINENO);
442 }
443
444 /*
445 * semcntの検査
446 */
447 if (semcnt > p_seminib->maxsem) {
448 return(E_SYS_LINENO);
449 }
450
451 /*
452 * wait_queueの検査
453 */
454 if (semcnt == 0) {
455 p_queue = p_semcb->wait_queue.p_next;
456 while (p_queue != &(p_semcb->wait_queue)) {
457 p_tcb = (TCB *) p_queue;
458 p_queue = p_queue->p_next;
459 if (!VALID_TCB(p_tcb)) {
460 return(E_SYS_LINENO);
461 }
462 if (p_tcb->tstat != TS_WAITING_SEM) {
463 return(E_SYS_LINENO);
464 }
465 if (p_semcb != ((WINFO_SEM *)(p_tcb->p_winfo))->p_semcb) {
466 return(E_SYS_LINENO);
467 }
468 }
469 }
470 else {
471 if (!queue_empty(&(p_semcb->wait_queue))) {
472 return(E_SYS_LINENO);
473 }
474 }
475 return(E_OK);
476}
477
478/*
479 * 整合性検査ルーチン本体
480 */
481ER
482bit_kernel(void)
483{
484 ID tskid;
485 ID semid;
486 ER ercd;
487
488 /*
489 * タスク毎の検査
490 */
491 for (tskid = TMIN_TSKID; tskid <= tmax_tskid; tskid++) {
492 ercd = bit_task(tskid);
493 if (ercd != E_OK) {
494 return(ercd);
495 }
496 }
497
498 /*
499 * セマフォ毎の検査
500 */
501 for (semid = TMIN_SEMID; semid <= tmax_semid; semid++) {
502 ercd = bit_semaphore(semid);
503 if (ercd != E_OK) {
504 return(ercd);
505 }
506 }
507
508 return(E_OK);
509}
Note: See TracBrowser for help on using the repository browser.