source: rtos_arduino/trunk/asp_1.9.2/test/bit_kernel.c@ 136

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

ライブラリとOS及びベーシックなサンプルの追加.

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 * 上記著作権者
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 2128 2011-06-26 01:21:05Z 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/mailbox.h"
68#include "kernel/mempfix.h"
69#include "kernel/time_event.h"
70
71/*
72 * エラーコードの定義
73 */
74#define E_SYS_LINENO ERCD(E_SYS, -(__LINE__))
75
76/*
77 * 管理ブロックのアドレスの正当性のチェック
78 */
79#define VALID_TCB(p_tcb) \
80 ((((char *) p_tcb) - ((char *) tcb_table)) % sizeof(TCB) == 0 \
81 && TMIN_TSKID <= TSKID(p_tcb) && TSKID(p_tcb) <= tmax_tskid)
82
83#define VALID_SEMCB(p_semcb) \
84 ((((char *) p_semcb) - ((char *) semcb_table)) % sizeof(SEMCB) == 0 \
85 && TMIN_SEMID <= SEMID(p_semcb) && SEMID(p_semcb) <= tmax_semid)
86
87#define VALID_FLGCB(p_flgcb) \
88 ((((char *) p_flgcb) - ((char *) flgcb_table)) % sizeof(FLGCB) == 0 \
89 && TMIN_FLGID <= FLGID(p_flgcb) && FLGID(p_flgcb) <= tmax_flgid)
90
91#define VALID_DTQCB(p_dtqcb) \
92 ((((char *) p_dtqcb) - ((char *) dtqcb_table)) % sizeof(DTQCB) == 0 \
93 && TMIN_DTQID <= DTQID(p_dtqcb) && DTQID(p_dtqcb) <= tmax_dtqid)
94
95#define VALID_PDQCB(p_pdqcb) \
96 ((((char *) p_pdqcb) - ((char *) pdqcb_table)) % sizeof(PDQCB) == 0 \
97 && TMIN_PDQID <= PDQID(p_pdqcb) && PDQID(p_pdqcb) <= tmax_pdqid)
98
99#define VALID_MBXCB(p_mbxcb) \
100 ((((char *) p_mbxcb) - ((char *) mbxcb_table)) % sizeof(MBXCB) == 0 \
101 && TMIN_MBXID <= MBXID(p_mbxcb) && MBXID(p_mbxcb) <= tmax_mbxid)
102
103#define VALID_MPFCB(p_mpfcb) \
104 ((((char *) p_mpfcb) - ((char *) mpfcb_table)) % sizeof(MPFCB) == 0 \
105 && TMIN_MPFID <= MPFID(p_mpfcb) && MPFID(p_mpfcb) <= tmax_mpfid)
106
107/*
108 * キューのチェックのための関数
109 *
110 * p_queueにp_entryが含まれているかを調べる.含まれていればtrue,含ま
111 * れていない場合にはfalseを返す.ダブルリンクの不整合の場合にも,
112 * falseを返す.
113 */
114static bool_t
115in_queue(QUEUE *p_queue, QUEUE *p_entry)
116{
117 QUEUE *p_current, *p_next;
118
119 p_current = p_queue->p_next;
120 if (p_current->p_prev != p_queue) {
121 return(false); /* ダブルリンクの不整合 */
122 }
123 while (p_current != p_queue) {
124 if (p_current == p_entry) {
125 return(true); /* p_entryが含まれていた */
126 }
127
128 /*
129 * キューの次の要素に進む
130 */
131 p_next = p_current->p_next;
132 if (p_next->p_prev != p_current) {
133 return(false); /* ダブルリンクの不整合 */
134 }
135 p_current = p_next;
136 }
137 return(false);
138}
139
140/*
141 * スタック上を指しているかの検査
142 */
143static bool_t
144on_stack(void *addr, const TINIB *p_tinib)
145{
146 if (p_tinib->stk <= addr
147 && addr < (void *)((char *)(p_tinib->stk) + p_tinib->stksz)) {
148 return(true);
149 }
150 return(false);
151}
152
153/*
154 * タスク毎の整合性検査
155 */
156static ER
157bit_task(ID tskid)
158{
159 TCB *p_tcb;
160 const TINIB *p_tinib;
161 uint_t tstat, tstat_wait, pri;
162 TMEVTB *p_tmevtb;
163 SEMCB *p_semcb;
164 FLGCB *p_flgcb;
165 DTQCB *p_dtqcb;
166 PDQCB *p_pdqcb;
167 MBXCB *p_mbxcb;
168 MPFCB *p_mpfcb;
169
170 if (!(TMIN_TSKID <= (tskid) && (tskid) <= tmax_tskid)) {
171 return(E_ID);
172 }
173 p_tcb = get_tcb(tskid);
174 p_tinib = p_tcb->p_tinib;
175 tstat = p_tcb->tstat;
176 tstat_wait = (tstat & TS_WAIT_MASK);
177 pri = p_tcb->priority;
178
179 /*
180 * 初期化ブロックへのポインタの検査
181 */
182 if (p_tinib != &(tinib_table[INDEX_TSK(tskid)])) {
183 return(E_SYS_LINENO);
184 }
185
186 /*
187 * tstatの検査
188 */
189 switch (tstat & (TS_RUNNABLE | TS_WAITING | TS_SUSPENDED)) {
190 case TS_DORMANT:
191 if (tstat != TS_DORMANT) {
192 return(E_SYS_LINENO);
193 }
194 break;
195 case TS_RUNNABLE:
196 if (tstat != TS_RUNNABLE) {
197 return(E_SYS_LINENO);
198 }
199 break;
200 case TS_WAITING:
201 case (TS_WAITING | TS_SUSPENDED):
202 if (!(TS_WAIT_DLY <= tstat_wait && tstat_wait <= TS_WAIT_MPF)) {
203 return(E_SYS_LINENO);
204 }
205 if ((tstat & ~(TS_WAIT_MASK | TS_RUNNABLE | TS_WAITING | TS_SUSPENDED))
206 != 0U) {
207 return(E_SYS_LINENO);
208 }
209 break;
210 case TS_SUSPENDED:
211 if (tstat != TS_SUSPENDED) {
212 return(E_SYS_LINENO);
213 }
214 break;
215 default:
216 return(E_SYS_LINENO);
217 }
218
219 /*
220 * actqueの検査
221 */
222 if (TSTAT_DORMANT(tstat) && p_tcb->actque) {
223 return(E_SYS_LINENO);
224 }
225
226 /*
227 * タスク優å…
228ˆåº¦ã®æ¤œæŸ»
229 */
230 if (pri >= TNUM_TPRI) {
231 return(E_SYS_LINENO);
232 }
233
234 /*
235 * texptnの検査
236 */
237 if (p_tcb->p_tinib->texrtn == NULL && p_tcb->texptn != 0U) {
238 return(E_SYS_LINENO);
239 }
240
241 /*
242 * 休止状æ…
243‹ã«ãŠã‘るチェック
244 */
245 if (TSTAT_DORMANT(tstat)) {
246 if (!(pri == p_tinib->ipriority)
247 && (p_tcb->wupque == false)
248 && (p_tcb->enatex == false)
249 && (p_tcb->texptn == 0U)) {
250 return(E_SYS_LINENO);
251 }
252 }
253
254 /*
255 * 実行できる状æ…
256‹ã«ãŠã‘るチェック
257 */
258 if (TSTAT_RUNNABLE(tstat)) {
259 if (!in_queue(&ready_queue[pri], &(p_tcb->task_queue))) {
260 return(E_SYS_LINENO);
261 }
262 }
263
264 /*
265 * 待
266ち状æ…
267‹ã«ãŠã‘るチェック
268 */
269 if (TSTAT_WAITING(tstat)) {
270 if (!on_stack(p_tcb->p_winfo, p_tinib)) {
271 return(E_SYS_LINENO);
272 }
273 p_tmevtb = p_tcb->p_winfo->p_tmevtb;
274 if (p_tmevtb != NULL) {
275 if (!on_stack(p_tmevtb, p_tinib)) {
276 return(E_SYS_LINENO);
277 }
278 /*
279 * (*p_tmevtb)の検査(未完成)
280 */
281 }
282
283 switch (tstat & TS_WAIT_MASK) {
284 case TS_WAIT_SLP:
285 if (p_tcb->wupque == true) {
286 return(E_SYS_LINENO);
287 }
288 break;
289
290 case TS_WAIT_DLY:
291 if (p_tmevtb == NULL) {
292 return(E_SYS_LINENO);
293 }
294 break;
295
296 case TS_WAIT_SEM:
297 p_semcb = ((WINFO_SEM *)(p_tcb->p_winfo))->p_semcb;
298 if (!VALID_SEMCB(p_semcb)) {
299 return(E_SYS_LINENO);
300 }
301 if (!in_queue(&(p_semcb->wait_queue), &(p_tcb->task_queue))) {
302 return(E_SYS_LINENO);
303 }
304 break;
305
306 case TS_WAIT_FLG:
307 p_flgcb = ((WINFO_FLG *)(p_tcb->p_winfo))->p_flgcb;
308 if (!VALID_FLGCB(p_flgcb)) {
309 return(E_SYS_LINENO);
310 }
311 if (!in_queue(&(p_flgcb->wait_queue), &(p_tcb->task_queue))) {
312 return(E_SYS_LINENO);
313 }
314 break;
315
316 case TS_WAIT_SDTQ:
317 p_dtqcb = ((WINFO_DTQ *)(p_tcb->p_winfo))->p_dtqcb;
318 if (!VALID_DTQCB(p_dtqcb)) {
319 return(E_SYS_LINENO);
320 }
321 if (!in_queue(&(p_dtqcb->swait_queue), &(p_tcb->task_queue))) {
322 return(E_SYS_LINENO);
323 }
324 break;
325
326 case TS_WAIT_RDTQ:
327 p_dtqcb = ((WINFO_DTQ *)(p_tcb->p_winfo))->p_dtqcb;
328 if (!VALID_DTQCB(p_dtqcb)) {
329 return(E_SYS_LINENO);
330 }
331 if (!in_queue(&(p_dtqcb->rwait_queue), &(p_tcb->task_queue))) {
332 return(E_SYS_LINENO);
333 }
334 break;
335
336 case TS_WAIT_SPDQ:
337 p_pdqcb = ((WINFO_PDQ *)(p_tcb->p_winfo))->p_pdqcb;
338 if (!VALID_PDQCB(p_pdqcb)) {
339 return(E_SYS_LINENO);
340 }
341 if (!in_queue(&(p_pdqcb->swait_queue), &(p_tcb->task_queue))) {
342 return(E_SYS_LINENO);
343 }
344 break;
345
346 case TS_WAIT_RPDQ:
347 p_pdqcb = ((WINFO_PDQ *)(p_tcb->p_winfo))->p_pdqcb;
348 if (!VALID_PDQCB(p_pdqcb)) {
349 return(E_SYS_LINENO);
350 }
351 if (!in_queue(&(p_pdqcb->rwait_queue), &(p_tcb->task_queue))) {
352 return(E_SYS_LINENO);
353 }
354 break;
355
356 case TS_WAIT_MBX:
357 p_mbxcb = ((WINFO_MBX *)(p_tcb->p_winfo))->p_mbxcb;
358 if (!VALID_MBXCB(p_mbxcb)) {
359 return(E_SYS_LINENO);
360 }
361 if (!in_queue(&(p_mbxcb->wait_queue), &(p_tcb->task_queue))) {
362 return(E_SYS_LINENO);
363 }
364 break;
365
366 case TS_WAIT_MPF:
367 p_mpfcb = ((WINFO_MPF *)(p_tcb->p_winfo))->p_mpfcb;
368 if (!VALID_MPFCB(p_mpfcb)) {
369 return(E_SYS_LINENO);
370 }
371 if (!in_queue(&(p_mpfcb->wait_queue), &(p_tcb->task_queue))) {
372 return(E_SYS_LINENO);
373 }
374 break;
375 }
376 }
377
378 /*
379 * tskctxbの検査
380 */
381 if (!TSTAT_DORMANT(tstat) && p_tcb != p_runtsk) {
382 /*
383 * ターゲット依存の検査
384 */
385#if 0
386 if (bit_tskctxb(&(p_tcb->tskctxb))) {
387 return(E_SYS_LINENO);
388 }
389#endif
390 }
391 return(E_OK);
392}
393
394/*
395 * セマフォ毎の整合性検査
396 */
397#define INDEX_SEM(semid) ((uint_t)((semid) - TMIN_SEMID))
398#define get_semcb(semid) (&(semcb_table[INDEX_SEM(semid)]))
399
400static ER
401bit_semaphore(ID semid)
402{
403 SEMCB *p_semcb;
404 const SEMINIB *p_seminib;
405 uint_t semcnt;
406 QUEUE *p_queue;
407 TCB *p_tcb;
408
409 if (!(TMIN_SEMID <= (semid) && (semid) <= tmax_semid)) {
410 return(E_ID);
411 }
412 p_semcb = get_semcb(semid);
413 p_seminib = p_semcb->p_seminib;
414 semcnt = p_semcb->semcnt;
415
416 /*
417 * 初期化ブロックへのポインタの検査
418 */
419 if (p_seminib != &(seminib_table[INDEX_SEM(semid)])) {
420 return(E_SYS_LINENO);
421 }
422
423 /*
424 * semcntの検査
425 */
426 if (semcnt > p_seminib->maxsem) {
427 return(E_SYS_LINENO);
428 }
429
430 /*
431 * wait_queueの検査
432 */
433 if (semcnt == 0) {
434 p_queue = p_semcb->wait_queue.p_next;
435 while (p_queue != &(p_semcb->wait_queue)) {
436 p_tcb = (TCB *) p_queue;
437 p_queue = p_queue->p_next;
438 if (!VALID_TCB(p_tcb)) {
439 return(E_SYS_LINENO);
440 }
441 if (p_tcb->tstat != (TS_WAITING | TS_WAIT_SEM)) {
442 return(E_SYS_LINENO);
443 }
444 if (p_semcb != ((WINFO_SEM *)(p_tcb->p_winfo))->p_semcb) {
445 return(E_SYS_LINENO);
446 }
447 }
448 }
449 else {
450 if (!queue_empty(&(p_semcb->wait_queue))) {
451 return(E_SYS_LINENO);
452 }
453 }
454 return(E_OK);
455}
456
457/*
458 * 整合性検査ルーチン本体
459 */
460ER
461bit_kernel(void)
462{
463 ID tskid;
464 ID semid;
465 ER ercd;
466
467 /*
468 * タスク毎の検査
469 */
470 for (tskid = TMIN_TSKID; tskid <= tmax_tskid; tskid++) {
471 ercd = bit_task(tskid);
472 if (ercd != E_OK) {
473 return(ercd);
474 }
475 }
476
477 /*
478 * セマフォ毎の検査
479 */
480 for (semid = TMIN_SEMID; semid <= tmax_semid; semid++) {
481 ercd = bit_semaphore(semid);
482 if (ercd != E_OK) {
483 return(ercd);
484 }
485 }
486
487 return(E_OK);
488}
Note: See TracBrowser for help on using the repository browser.