source: azure_iot_hub_f767zi/trunk/asp_baseplatform/test/bit_kernel.c@ 457

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

ファイルを追加

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