source: azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/kernel.tf@ 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/plain;charset=UTF-8
File size: 50.8 KB
Line 
1$ ======================================================================
2$
3$ TOPPERS/ASP Kernel
4$ Toyohashi Open Platform for Embedded Real-Time Systems/
5$ Advanced Standard Profile Kernel
6$
7$ Copyright (C) 2007 by TAKAGI Nobuhisa
8$ Copyright (C) 2007-2015 by Embedded and Real-Time Systems Laboratory
9$ Graduate School of Information Science, Nagoya Univ., JAPAN
10$
11$ 上記著作権者は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
12$ ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
13$ 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
14$ (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
15$ 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
16$ スコード中に含まれていること.
17$ (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
18$ 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
19$ 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
20$ の無保証規定を掲載すること.
21$ (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
22$ 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
23$ と.
24$ (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
25$ 作権表示,この利用条件および下記の無保証規定を掲載すること.
26$ (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
27$ 報告すること.
28$ (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
29$ 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
30$ また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
31$ 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
32$ 免責すること.
33$
34$ 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
35$ よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
36$ に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
37$ アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
38$ の責任を負わない.
39$
40$ $Id$
41$
42$ =====================================================================
43
44$ =====================================================================
45$ AID_YYYの処理
46$ =====================================================================
47
48$num_atskid = 0$
49$FOREACH i ATSK.ORDER_LIST$
50$ // notskが負の場合(E_PAR)
51 $IF ATSK.NOTSK[i] < 0$
52 $ERROR ATSK.TEXT_LINE[i]$E_PAR: $FORMAT(_("illegal %1% `%2%\' in %3%"), "notsk", ATSK.NOTSK[i], "AID_TSK")$$END$
53 $END$
54 $num_atskid = num_atskid + ATSK.NOTSK[i]$
55$END$
56$num_tskid = LENGTH(TSK.ID_LIST) + num_atskid$
57
58$num_asemid = 0$
59$FOREACH i ASEM.ORDER_LIST$
60$ // nosemが負の場合(E_PAR)
61 $IF ASEM.NOSEM[i] < 0$
62 $ERROR ASEM.TEXT_LINE[i]$E_PAR: $FORMAT(_("illegal %1% `%2%\' in %3%"), "nosem", ASEM.NOSEM[i], "AID_SEM")$$END$
63 $END$
64 $num_asemid = num_asemid + ASEM.NOSEM[i]$
65$END$
66$num_semid = LENGTH(SEM.ID_LIST) + num_asemid$
67
68$num_aflgid = 0$
69$FOREACH i AFLG.ORDER_LIST$
70$ // noflgが負の場合(E_PAR)
71 $IF AFLG.NOFLG[i] < 0$
72 $ERROR AFLG.TEXT_LINE[i]$E_PAR: $FORMAT(_("illegal %1% `%2%\' in %3%"), "noflg", AFLG.NOFLG[i], "AID_FLG")$$END$
73 $END$
74 $num_aflgid = num_aflgid + AFLG.NOFLG[i]$
75$END$
76$num_flgid = LENGTH(FLG.ID_LIST) + num_aflgid$
77
78$num_adtqid = 0$
79$FOREACH i ADTQ.ORDER_LIST$
80$ // nodtqが負の場合(E_PAR)
81 $IF ADTQ.NODTQ[i] < 0$
82 $ERROR ADTQ.TEXT_LINE[i]$E_PAR: $FORMAT(_("illegal %1% `%2%\' in %3%"), "nodtq", ADTQ.NODTQ[i], "AID_DTQ")$$END$
83 $END$
84 $num_adtqid = num_adtqid + ADTQ.NODTQ[i]$
85$END$
86$num_dtqid = LENGTH(DTQ.ID_LIST) + num_adtqid$
87
88$num_apdqid = 0$
89$FOREACH i APDQ.ORDER_LIST$
90$ // nopdqが負の場合(E_PAR)
91 $IF APDQ.NOPDQ[i] < 0$
92 $ERROR APDQ.TEXT_LINE[i]$E_PAR: $FORMAT(_("illegal %1% `%2%\' in %3%"), "nopdq", APDQ.NOPDQ[i], "AID_PDQ")$$END$
93 $END$
94 $num_apdqid = num_apdqid + APDQ.NOPDQ[i]$
95$END$
96$num_pdqid = LENGTH(PDQ.ID_LIST) + num_apdqid$
97
98$num_ambxid = 0$
99$FOREACH i AMBX.ORDER_LIST$
100$ // nombxが負の場合(E_PAR)
101 $IF AMBX.NOMBX[i] < 0$
102 $ERROR AMBX.TEXT_LINE[i]$E_PAR: $FORMAT(_("illegal %1% `%2%\' in %3%"), "nombx", AMBX.NOMBX[i], "AID_MBX")$$END$
103 $END$
104 $num_ambxid = num_ambxid + AMBX.NOMBX[i]$
105$END$
106$num_mbxid = LENGTH(MBX.ID_LIST) + num_ambxid$
107
108$num_amtxid = 0$
109$FOREACH i AMTX.ORDER_LIST$
110$ // nomtxが負の場合(E_PAR)
111 $IF AMTX.NOMTX[i] < 0$
112 $ERROR AMTX.TEXT_LINE[i]$E_PAR: $FORMAT(_("illegal %1% `%2%\' in %3%"), "nomtx", AMTX.NOMTX[i], "AID_MTX")$$END$
113 $END$
114 $num_amtxid = num_amtxid + AMTX.NOMTX[i]$
115$END$
116$num_mtxid = LENGTH(MTX.ID_LIST) + num_amtxid$
117
118$num_ampfid = 0$
119$FOREACH i AMPF.ORDER_LIST$
120$ // nompfが負の場合(E_PAR)
121 $IF AMPF.NOMPF[i] < 0$
122 $ERROR AMPF.TEXT_LINE[i]$E_PAR: $FORMAT(_("illegal %1% `%2%\' in %3%"), "nompf", AMPF.NOMPF[i], "AID_MPF")$$END$
123 $END$
124 $num_ampfid = num_ampfid + AMPF.NOMPF[i]$
125$END$
126$num_mpfid = LENGTH(MPF.ID_LIST) + num_ampfid$
127
128$num_acycid = 0$
129$FOREACH i ACYC.ORDER_LIST$
130$ // nocycが負の場合(E_PAR)
131 $IF ACYC.NOCYC[i] < 0$
132 $ERROR ACYC.TEXT_LINE[i]$E_PAR: $FORMAT(_("illegal %1% `%2%\' in %3%"), "nocyc", ACYC.NOCYC[i], "AID_CYC")$$END$
133 $END$
134 $num_acycid = num_acycid + ACYC.NOCYC[i]$
135$END$
136$num_cycid = LENGTH(CYC.ID_LIST) + num_acycid$
137
138$num_aalmid = 0$
139$FOREACH i AALM.ORDER_LIST$
140$ // noalmが負の場合(E_PAR)
141 $IF AALM.NOALM[i] < 0$
142 $ERROR AALM.TEXT_LINE[i]$E_PAR: $FORMAT(_("illegal %1% `%2%\' in %3%"), "noalm", AALM.NOALM[i], "AID_ALM")$$END$
143 $END$
144 $num_aalmid = num_aalmid + AALM.NOALM[i]$
145$END$
146$num_almid = LENGTH(ALM.ID_LIST) + num_aalmid$
147
148$num_aisrid = 0$
149$FOREACH i AISR.ORDER_LIST$
150$ // noisrが負の場合(E_PAR)
151 $IF AISR.NOISR[i] < 0$
152 $ERROR AISR.TEXT_LINE[i]$E_PAR: $FORMAT(_("illegal %1% `%2%\' in %3%"), "noisr", AISR.NOISR[i], "AID_ISR")$$END$
153 $END$
154 $num_aisrid = num_aisrid + AISR.NOISR[i]$
155$END$
156$num_isrid = num_aisrid$
157$num_isr = LENGTH(ISR.ORDER_LIST) + num_aisrid$
158
159$ =====================================================================
160$ kernel_cfg.hの生成
161$ =====================================================================
162
163$FILE "kernel_cfg.h"$
164/* kernel_cfg.h */$NL$
165#ifndef TOPPERS_KERNEL_CFG_H$NL$
166#define TOPPERS_KERNEL_CFG_H$NL$
167$NL$
168#define TNUM_TSKID $num_tskid$$NL$
169#define TNUM_SEMID $num_semid$$NL$
170#define TNUM_FLGID $num_flgid$$NL$
171#define TNUM_DTQID $num_dtqid$$NL$
172#define TNUM_PDQID $num_pdqid$$NL$
173#define TNUM_MBXID $num_mbxid$$NL$
174#define TNUM_MTXID $num_mtxid$$NL$
175#define TNUM_MPFID $num_mpfid$$NL$
176#define TNUM_CYCID $num_cycid$$NL$
177#define TNUM_ALMID $num_almid$$NL$
178#define TNUM_ISRID $num_isrid$$NL$
179$NL$
180$FOREACH id TSK.ID_LIST$
181 #define $id$ $+id$$NL$
182$END$
183$FOREACH id SEM.ID_LIST$
184 #define $id$ $+id$$NL$
185$END$
186$FOREACH id FLG.ID_LIST$
187 #define $id$ $+id$$NL$
188$END$
189$FOREACH id DTQ.ID_LIST$
190 #define $id$ $+id$$NL$
191$END$
192$FOREACH id PDQ.ID_LIST$
193 #define $id$ $+id$$NL$
194$END$
195$FOREACH id MBX.ID_LIST$
196 #define $id$ $+id$$NL$
197$END$
198$FOREACH id MTX.ID_LIST$
199 #define $id$ $+id$$NL$
200$END$
201$FOREACH id MPF.ID_LIST$
202 #define $id$ $+id$$NL$
203$END$
204$FOREACH id CYC.ID_LIST$
205 #define $id$ $+id$$NL$
206$END$
207$FOREACH id ALM.ID_LIST$
208 #define $id$ $+id$$NL$
209$END$
210$NL$
211#endif /* TOPPERS_KERNEL_CFG_H */$NL$
212
213$ =====================================================================
214$ kernel_cfg.cの生成
215$ =====================================================================
216
217$FILE "kernel_cfg.c"$
218/* kernel_cfg.c */$NL$
219#include "kernel/kernel_int.h"$NL$
220#include "kernel_cfg.h"$NL$
221$NL$
222#if TKERNEL_PRID != 0x07u$NL$
223#error The kernel does not match this configuration file.$NL$
224#endif$NL$
225$NL$
226
227$
228$ インクルードディレクティブ(#include)
229$
230/*$NL$
231$SPC$* Include Directives (#include)$NL$
232$SPC$*/$NL$
233$NL$
234$INCLUDES$
235$NL$
236
237$
238$ オブジェクトのID番号を保持する変数
239$
240$IF USE_EXTERNAL_ID$
241 /*$NL$
242 $SPC$* Variables for Object ID$NL$
243 $SPC$*/$NL$
244 $NL$
245 $FOREACH id TSK.ID_LIST$
246 const ID $id$_id$SPC$=$SPC$$+id$;$NL$
247 $END$
248 $FOREACH id SEM.ID_LIST$
249 const ID $id$_id$SPC$=$SPC$$+id$;$NL$
250 $END$
251 $FOREACH id FLG.ID_LIST$
252 const ID $id$_id$SPC$=$SPC$$+id$;$NL$
253 $END$
254 $FOREACH id DTQ.ID_LIST$
255 const ID $id$_id$SPC$=$SPC$$+id$;$NL$
256 $END$
257 $FOREACH id PDQ.ID_LIST$
258 const ID $id$_id$SPC$=$SPC$$+id$;$NL$
259 $END$
260 $FOREACH id MBX.ID_LIST$
261 const ID $id$_id$SPC$=$SPC$$+id$;$NL$
262 $END$
263 $FOREACH id MTX.ID_LIST$
264 const ID $id$_id$SPC$=$SPC$$+id$;$NL$
265 $END$
266 $FOREACH id MPF.ID_LIST$
267 const ID $id$_id$SPC$=$SPC$$+id$;$NL$
268 $END$
269 $FOREACH id CYC.ID_LIST$
270 const ID $id$_id$SPC$=$SPC$$+id$;$NL$
271 $END$
272 $FOREACH id ALM.ID_LIST$
273 const ID $id$_id$SPC$=$SPC$$+id$;$NL$
274 $END$
275$END$
276
277$
278$ スタック領域の確保関数
279$
280$IF !ISFUNCTION("ALLOC_STACK")$
281$FUNCTION ALLOC_STACK$
282$ // 大きい方に丸めたサイズで確保する
283 static STK_T $ARGV[1]$[COUNT_STK_T($ARGV[2]$)];$NL$
284 $RESULT = FORMAT("ROUND_STK_T(%1%)", ARGV[2])$
285$END$
286$END$
287
288$
289$ タスク
290$
291/*$NL$
292$SPC$* Task Management Functions$NL$
293$SPC$*/$NL$
294$NL$
295
296$ 静的に生成されたタスクが1個以上存在することのチェック
297$IF !LENGTH(TSK.ID_LIST)$
298 $ERROR$$FORMAT(_("no task is registered"))$$END$
299$END$
300
301$ 静的に生成されたタスクの数
302#define TNUM_STSKID $LENGTH(TSK.ID_LIST)$$NL$
303$NL$
304
305$ タスクID番号の最大値
306const ID _kernel_tmax_tskid = (TMIN_TSKID + TNUM_TSKID - 1);$NL$
307const ID _kernel_tmax_stskid = (TMIN_TSKID + TNUM_STSKID - 1);$NL$
308$NL$
309
310$ エラーチェック
311$FOREACH tskid TSK.ID_LIST$
312$ // tskatrが([TA_ACT])でない場合(E_RSATR)
313 $IF (TSK.TSKATR[tskid] & ~(TA_ACT|TARGET_TSKATR)) != 0$
314 $ERROR TSK.TEXT_LINE[tskid]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "tskatr", TSK.TSKATR[tskid], tskid, "CRE_TSK")$$END$
315 $END$
316
317$ // (TMIN_TPRI <= itskpri && itskpri <= TMAX_TPRI)でない場合(E_PAR)
318 $IF !(TMIN_TPRI <= TSK.ITSKPRI[tskid] && TSK.ITSKPRI[tskid] <= TMAX_TPRI)$
319 $ERROR TSK.TEXT_LINE[tskid]$E_PAR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "itskpri", TSK.ITSKPRI[tskid], tskid, "CRE_TSK")$$END$
320 $END$
321
322$ // texatrが(TA_NULL)でない場合(E_RSATR)
323 $IF LENGTH(TSK.TEXATR[tskid]) && TSK.TEXATR[tskid] != 0$
324 $ERROR DEF_TEX.TEXT_LINE[tskid]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "texatr", TSK.TEXATR[tskid], tskid, "DEF_TEX")$$END$
325 $END$
326$END$
327
328$ スタック領域の生成とそれに関するエラーチェック
329$FOREACH tskid TSK.ID_LIST$
330$ // stkszが0以下か,ターゲット定義の最小値(TARGET_MIN_STKSZ)よりも
331$ // 小さい場合(E_PAR)
332 $IF TSK.STKSZ[tskid] <= 0 || (TARGET_MIN_STKSZ
333 && TSK.STKSZ[tskid] < TARGET_MIN_STKSZ)$
334 $ERROR TSK.TEXT_LINE[tskid]$E_PAR: $FORMAT(_("too small %1% `%2%\' of `%3%\' in %4%"), "stksz", TSK.STKSZ[tskid], tskid, "CRE_TSK")$$END$
335 $END$
336
337$ // stkszがスタック領域のサイズとして正しくない場合(E_PAR)
338 $IF !EQ(TSK.STK[tskid], "NULL") && CHECK_STKSZ_ALIGN
339 && (TSK.STKSZ[tskid] & (CHECK_STKSZ_ALIGN - 1))$
340 $ERROR TSK.TEXT_LINE[tskid]$E_PAR: $FORMAT(_("%1% `%2%\' of `%3%\' in %4% is not aligned"), "stksz", TSK.STKSZ[tskid], tskid, "CRE_TSK")$$END$
341 $END$
342
343 $IF EQ(TSK.STK[tskid],"NULL")$
344 $TSK.TINIB_STKSZ[tskid] = ALLOC_STACK(CONCAT("_kernel_stack_",
345 tskid), TSK.STKSZ[tskid])$
346 $TSK.TINIB_STK[tskid] = CONCAT("_kernel_stack_", tskid)$
347 $ELSE$
348 $TSK.TINIB_STKSZ[tskid] = FORMAT("(%1%)", TSK.STKSZ[tskid])$
349 $TSK.TINIB_STK[tskid] = FORMAT("(void *)(%1%)", TSK.STK[tskid])$
350 $END$
351$END$
352$NL$
353
354$ タスク初期化ブロックの生成(タスクは1個以上存在する)
355const TINIB _kernel_tinib_table[TNUM_STSKID] = {$NL$
356$JOINEACH tskid TSK.ID_LIST ",\n"$
357$ // タスク属性,拡張情報,起動番地,起動時優先度
358 $TAB${
359 $SPC$($TSK.TSKATR[tskid]$), (intptr_t)($TSK.EXINF[tskid]$),
360 $SPC$((TASK)($TSK.TASK[tskid]$)), INT_PRIORITY($TSK.ITSKPRI[tskid]$),
361
362$ // タスク初期化コンテキストブロック,スタック領域
363 $IF USE_TSKINICTXB$
364 $GENERATE_TSKINICTXB(tskid)$
365 $ELSE$
366 $SPC$$TSK.TINIB_STKSZ[tskid]$, $TSK.TINIB_STK[tskid]$,
367 $END$
368
369$ // タスク例外処理ルーチンの属性と起動番地
370 $SPC$($ALT(TSK.TEXATR[tskid],"TA_NULL")$), ($ALT(TSK.TEXRTN[tskid],"NULL")$) }
371$END$$NL$
372};$NL$
373$NL$
374
375$ 動的生成タスク用のタスク初期化ブロックの生成
376$IF num_atskid > 0$
377 TINIB _kernel_atinib_table[$num_atskid$];$NL$
378$ELSE$
379 TOPPERS_EMPTY_LABEL(TINIB, _kernel_atinib_table);$NL$
380$END$$NL$
381
382$ タスク管理ブロックの生成
383TCB _kernel_tcb_table[TNUM_TSKID];$NL$
384$NL$
385
386$ タスク生成順序テーブルの生成
387const ID _kernel_torder_table[TNUM_STSKID] = {$NL$
388$TAB$$JOINEACH tskid TSK.ORDER_LIST ", "$$tskid$$END$$NL$
389};$NL$
390$NL$
391
392$
393$ セマフォ
394$
395/*$NL$
396$SPC$* Semaphore Functions$NL$
397$SPC$*/$NL$
398$NL$
399
400$ 静的に生成されたセマフォの数
401#define TNUM_SSEMID $LENGTH(SEM.ID_LIST)$$NL$
402$NL$
403
404$ セマフォID番号の最大値
405const ID _kernel_tmax_semid = (TMIN_SEMID + TNUM_SEMID - 1);$NL$
406const ID _kernel_tmax_ssemid = (TMIN_SEMID + TNUM_SSEMID - 1);$NL$
407$NL$
408
409$ セマフォ初期化ブロックの生成
410$IF LENGTH(SEM.ID_LIST)$
411 const SEMINIB _kernel_seminib_table[TNUM_SSEMID] = {$NL$
412 $JOINEACH semid SEM.ID_LIST ",\n"$
413$ // sematrが([TA_TPRI])でない場合(E_RSATR)
414 $IF (SEM.SEMATR[semid] & ~TA_TPRI) != 0$
415 $ERROR SEM.TEXT_LINE[semid]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "sematr", SEM.SEMATR[semid], semid, "CRE_SEM")$$END$
416 $END$
417
418$ // (0 <= isemcnt && isemcnt <= maxsem)でない場合(E_PAR)
419 $IF !(0 <= SEM.ISEMCNT[semid] && SEM.ISEMCNT[semid] <= SEM.MAXSEM[semid])$
420 $ERROR SEM.TEXT_LINE[semid]$E_PAR: $FORMAT(_("too large %1% `%2%\' of `%3%\' in %4%"), "isemcnt", SEM.ISEMCNT[semid], semid, "CRE_SEM")$$END$
421 $END$
422
423$ // (1 <= maxsem && maxsem <= TMAX_MAXSEM)でない場合(E_PAR)
424 $IF !(1 <= SEM.MAXSEM[semid] && SEM.MAXSEM[semid] <= TMAX_MAXSEM)$
425 $ERROR SEM.TEXT_LINE[semid]$E_PAR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "maxsem", SEM.MAXSEM[semid], semid, "CRE_SEM")$$END$
426 $END$
427
428$ // セマフォ初期化ブロック
429 $TAB${ ($SEM.SEMATR[semid]$), ($SEM.ISEMCNT[semid]$), ($SEM.MAXSEM[semid]$) }
430 $END$$NL$
431 };$NL$
432$ELSE$
433 TOPPERS_EMPTY_LABEL(const SEMINIB, _kernel_seminib_table);$NL$
434$END$$NL$
435
436$ 動的生成セマフォ用のセマフォ初期化ブロックの生成
437$IF num_asemid > 0$
438 SEMINIB _kernel_aseminib_table[$num_asemid$];$NL$
439$ELSE$
440 TOPPERS_EMPTY_LABEL(SEMINIB, _kernel_aseminib_table);$NL$
441$END$$NL$
442
443$ セマフォ管理ブロックの生成
444$IF num_semid > 0$
445 SEMCB _kernel_semcb_table[TNUM_SEMID];$NL$
446$ELSE$
447 TOPPERS_EMPTY_LABEL(SEMCB, _kernel_semcb_table);$NL$
448$END$$NL$
449
450$
451$ イベントフラグ
452$
453/*$NL$
454$SPC$* Eventflag Functions$NL$
455$SPC$*/$NL$
456$NL$
457
458$ 静的に生成されたイベントフラグの数
459#define TNUM_SFLGID $LENGTH(FLG.ID_LIST)$$NL$
460$NL$
461
462$ イベントフラグID番号の最大値
463const ID _kernel_tmax_flgid = (TMIN_FLGID + TNUM_FLGID - 1);$NL$
464const ID _kernel_tmax_sflgid = (TMIN_FLGID + TNUM_SFLGID - 1);$NL$
465$NL$
466
467$ イベントフラグ初期化ブロックの生成
468$IF LENGTH(FLG.ID_LIST)$
469 const FLGINIB _kernel_flginib_table[TNUM_SFLGID] = {$NL$
470 $JOINEACH flgid FLG.ID_LIST ",\n"$
471$ // flgatrが([TA_TPRI]|[TA_WMUL]|[TA_CLR])でない場合(E_RSATR)
472 $IF (FLG.FLGATR[flgid] & ~(TA_TPRI|TA_WMUL|TA_CLR)) != 0$
473 $ERROR FLG.TEXT_LINE[flgid]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "flgatr", FLG.FLGATR[flgid], flgid, "CRE_FLG")$$END$
474 $END$
475
476$ // iflgptnがFLGPTNに格納できない場合(E_PAR)
477 $IF (FLG.IFLGPTN[flgid] & ~((1 << TBIT_FLGPTN) - 1)) != 0$
478 $ERROR FLG.TEXT_LINE[flgid]$E_PAR: $FORMAT(_("too large %1% `%2%\' of `%3%\' in %4%"), "iflgptn", FLG.IFLGPTN[flgid], flgid, "CRE_FLG")$$END$
479 $END$
480
481$ // イベントフラグ初期化ブロック
482 $TAB${ ($FLG.FLGATR[flgid]$), ($FLG.IFLGPTN[flgid]$) }
483 $END$$NL$
484 };$NL$
485$ELSE$
486 TOPPERS_EMPTY_LABEL(const FLGINIB, _kernel_flginib_table);$NL$
487$END$$NL$
488
489$ 動的生成イベントフラグ用のイベントフラグ初期化ブロックの生成
490$IF num_aflgid > 0$
491 FLGINIB _kernel_aflginib_table[$num_aflgid$];$NL$
492$ELSE$
493 TOPPERS_EMPTY_LABEL(FLGINIB, _kernel_aflginib_table);$NL$
494$END$$NL$
495
496$ イベントフラグ管理ブロックの生成
497$IF num_flgid > 0$
498 FLGCB _kernel_flgcb_table[TNUM_FLGID];$NL$
499$ELSE$
500 TOPPERS_EMPTY_LABEL(FLGCB, _kernel_flgcb_table);$NL$
501$END$$NL$
502
503$
504$ データキュー
505$
506/*$NL$
507$SPC$* Dataqueue Functions$NL$
508$SPC$*/$NL$
509$NL$
510
511$ 静的に生成されたデータキューの数
512#define TNUM_SDTQID $LENGTH(DTQ.ID_LIST)$$NL$
513$NL$
514
515$ データキューID番号の最大値
516const ID _kernel_tmax_dtqid = (TMIN_DTQID + TNUM_DTQID - 1);$NL$
517const ID _kernel_tmax_sdtqid = (TMIN_DTQID + TNUM_SDTQID - 1);$NL$
518$NL$
519
520$IF LENGTH(DTQ.ID_LIST)$
521 $FOREACH dtqid DTQ.ID_LIST$
522$ // dtqatrが([TA_TPRI])でない場合(E_RSATR)
523 $IF (DTQ.DTQATR[dtqid] & ~TA_TPRI) != 0$
524 $ERROR DTQ.TEXT_LINE[dtqid]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "dtqatr", DTQ.DTQATR[dtqid], dtqid, "CRE_DTQ")$$END$
525 $END$
526
527$ // dtqcntが負の場合(E_PAR)
528 $IF DTQ.DTQCNT[dtqid] < 0$
529 $ERROR DTQ.TEXT_LINE[dtqid]$E_PAR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "dtqcnt", DTQ.DTQCNT[dtqid], dtqid, "CRE_DTQ")$$END$
530 $END$
531
532$ // dtqmbがNULLでない場合(E_NOSPT)
533 $IF !EQ(DTQ.DTQMB[dtqid], "NULL")$
534 $ERROR DTQ.TEXT_LINE[dtqid]$E_NOSPT: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "dtqmb", DTQ.DTQMB[dtqid], dtqid, "CRE_DTQ")$$END$
535 $END$
536
537$ // データキュー管理領域
538 $IF DTQ.DTQCNT[dtqid]$
539 static DTQMB _kernel_dtqmb_$dtqid$[$DTQ.DTQCNT[dtqid]$];$NL$
540 $END$
541 $END$
542
543$ // データキュー初期化ブロックの生成
544 const DTQINIB _kernel_dtqinib_table[TNUM_SDTQID] = {$NL$
545 $JOINEACH dtqid DTQ.ID_LIST ",\n"$
546 $TAB${ ($DTQ.DTQATR[dtqid]$), ($DTQ.DTQCNT[dtqid]$), $IF DTQ.DTQCNT[dtqid]$(_kernel_dtqmb_$dtqid$)$ELSE$NULL$END$ }
547 $END$$NL$
548 };$NL$
549$ELSE$
550 TOPPERS_EMPTY_LABEL(const DTQINIB, _kernel_dtqinib_table);$NL$
551$END$$NL$
552
553$ 動的生成データキュー用のデータキュー初期化ブロックの生成
554$IF num_adtqid > 0$
555 DTQINIB _kernel_adtqinib_table[$num_adtqid$];$NL$
556$ELSE$
557 TOPPERS_EMPTY_LABEL(DTQINIB, _kernel_adtqinib_table);$NL$
558$END$$NL$
559
560$ データキュー管理ブロックの生成
561$IF num_dtqid > 0$
562 DTQCB _kernel_dtqcb_table[TNUM_DTQID];$NL$
563$ELSE$
564 TOPPERS_EMPTY_LABEL(DTQCB, _kernel_dtqcb_table);$NL$
565$END$$NL$
566
567$
568$ 優先度データキュー
569$
570/*$NL$
571$SPC$* Priority Dataqueue Functions$NL$
572$SPC$*/$NL$
573$NL$
574
575$ 静的に生成された優先度データキューの数
576#define TNUM_SPDQID $LENGTH(PDQ.ID_LIST)$$NL$
577$NL$
578
579$ 優先度データキューID番号の最大値
580const ID _kernel_tmax_pdqid = (TMIN_PDQID + TNUM_PDQID - 1);$NL$
581const ID _kernel_tmax_spdqid = (TMIN_PDQID + TNUM_SPDQID - 1);$NL$
582$NL$
583
584$IF LENGTH(PDQ.ID_LIST)$
585 $FOREACH pdqid PDQ.ID_LIST$
586$ // pdqatrが([TA_TPRI])でない場合(E_RSATR)
587 $IF (PDQ.PDQATR[pdqid] & ~TA_TPRI) != 0$
588 $ERROR PDQ.TEXT_LINE[pdqid]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "pdqatr", PDQ.PDQATR[pdqid], pdqid, "CRE_PDQ")$$END$
589 $END$
590
591$ // pdqcntが負の場合(E_PAR)
592 $IF PDQ.PDQCNT[pdqid] < 0$
593 $ERROR PDQ.TEXT_LINE[pdqid]$E_PAR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "pdqcnt", PDQ.PDQCNT[pdqid], pdqid, "CRE_PDQ")$$END$
594 $END$
595
596$ // (TMIN_DPRI <= maxdpri && maxdpri <= TMAX_DPRI)でない場合(E_PAR)
597 $IF !(TMIN_DPRI <= PDQ.MAXDPRI[pdqid] && PDQ.MAXDPRI[pdqid] <= TMAX_DPRI)$
598 $ERROR PDQ.TEXT_LINE[pdqid]$E_PAR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "maxdpri", PDQ.MAXDPRI[pdqid], pdqid, "CRE_PDQ")$$END$
599 $END$
600
601$ // pdqmbがNULLでない場合(E_NOSPT)
602 $IF !EQ(PDQ.PDQMB[pdqid], "NULL")$
603 $ERROR PDQ.TEXT_LINE[pdqid]$E_NOSPT: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "pdqmb", PDQ.PDQMB[pdqid], pdqid, "CRE_PDQ")$$END$
604 $END$
605
606$ // 優先度データキュー管理領域
607 $IF PDQ.PDQCNT[pdqid]$
608 static PDQMB _kernel_pdqmb_$pdqid$[$PDQ.PDQCNT[pdqid]$];$NL$
609 $END$
610 $END$
611
612$ // 優先度データキュー初期化ブロックの生成
613 const PDQINIB _kernel_pdqinib_table[TNUM_SPDQID] = {$NL$
614 $JOINEACH pdqid PDQ.ID_LIST ",\n"$
615 $TAB${ ($PDQ.PDQATR[pdqid]$), ($PDQ.PDQCNT[pdqid]$), ($PDQ.MAXDPRI[pdqid]$), $IF PDQ.PDQCNT[pdqid]$(_kernel_pdqmb_$pdqid$)$ELSE$NULL$END$ }
616 $END$$NL$
617 };$NL$
618$ELSE$
619 TOPPERS_EMPTY_LABEL(const PDQINIB, _kernel_pdqinib_table);$NL$
620$END$$NL$
621
622$ 動的生成優先度データキュー用の優先度データキュー初期化ブロックの生成
623$IF num_apdqid > 0$
624 PDQINIB _kernel_apdqinib_table[$num_apdqid$];$NL$
625$ELSE$
626 TOPPERS_EMPTY_LABEL(PDQINIB, _kernel_apdqinib_table);$NL$
627$END$$NL$
628
629$ 優先度データキュー管理ブロックの生成
630$IF num_pdqid > 0$
631 PDQCB _kernel_pdqcb_table[TNUM_PDQID];$NL$
632$ELSE$
633 TOPPERS_EMPTY_LABEL(PDQCB, _kernel_pdqcb_table);$NL$
634$END$$NL$
635
636$
637$ メールボックス
638$
639/*$NL$
640$SPC$* Mailbox Functions$NL$
641$SPC$*/$NL$
642$NL$
643
644$ 静的に生成されたメールボックスの数
645#define TNUM_SMBXID $LENGTH(MBX.ID_LIST)$$NL$
646$NL$
647
648$ メールボックスID番号の最大値
649const ID _kernel_tmax_mbxid = (TMIN_MBXID + TNUM_MBXID - 1);$NL$
650const ID _kernel_tmax_smbxid = (TMIN_MBXID + TNUM_SMBXID - 1);$NL$
651$NL$
652
653$ メールボックス初期化ブロックの生成
654$IF LENGTH(MBX.ID_LIST)$
655 const MBXINIB _kernel_mbxinib_table[TNUM_SMBXID] = {$NL$
656 $JOINEACH mbxid MBX.ID_LIST ",\n"$
657$ // mbxatrが([TA_TPRI]|[TA_MPRI])でない場合(E_RSATR)
658 $IF (MBX.MBXATR[mbxid] & ~(TA_TPRI|TA_MPRI)) != 0$
659 $ERROR MBX.TEXT_LINE[mbxid]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "mbxatr", MBX.MBXATR[mbxid], mbxid, "CRE_MBX")$$END$
660 $END$
661
662$ // (TMIN_MPRI <= maxmpri && maxmpri <= TMAX_MPRI)でない場合(E_PAR)
663 $IF !(TMIN_MPRI <= MBX.MAXMPRI[mbxid] && MBX.MAXMPRI[mbxid] <= TMAX_MPRI)$
664 $ERROR MBX.TEXT_LINE[mbxid]$E_PAR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "maxmpri", MBX.MAXMPRI[mbxid], mbxid, "CRE_MBX")$$END$
665 $END$
666
667$ // mprihdがNULLでない場合(E_NOSPT)
668 $IF !EQ(MBX.MPRIHD[mbxid], "NULL")$
669 $ERROR MBX.TEXT_LINE[mbxid]$E_NOSPT: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "mprihd", MBX.MPRIHD[mbxid], mbxid, "CRE_MBX")$$END$
670 $END$
671
672$ // メールボックス初期化ブロック
673 $TAB${ ($MBX.MBXATR[mbxid]$), ($MBX.MAXMPRI[mbxid]$) }
674 $END$$NL$
675 };$NL$
676$ELSE$
677 TOPPERS_EMPTY_LABEL(const MBXINIB, _kernel_mbxinib_table);$NL$
678$END$$NL$
679
680$ 動的生成メールボックス用のメールボックス初期化ブロックの生成
681$IF num_ambxid > 0$
682 MBXINIB _kernel_ambxinib_table[$num_ambxid$];$NL$
683$ELSE$
684 TOPPERS_EMPTY_LABEL(MBXINIB, _kernel_ambxinib_table);$NL$
685$END$$NL$
686
687$ メールボックス管理ブロックの生成
688$IF num_mbxid > 0$
689 MBXCB _kernel_mbxcb_table[TNUM_MBXID];$NL$
690$ELSE$
691 TOPPERS_EMPTY_LABEL(MBXCB, _kernel_mbxcb_table);$NL$
692$END$$NL$
693
694$
695$ ミューテックス
696$
697/*$NL$
698$SPC$* Mutex Functions$NL$
699$SPC$*/$NL$
700$NL$
701
702$ 静的に生成されたミューテックスの数
703#define TNUM_SMTXID $LENGTH(MTX.ID_LIST)$$NL$
704$NL$
705
706$ ミューテックスID番号の最大値
707const ID _kernel_tmax_mtxid = (TMIN_MTXID + TNUM_MTXID - 1);$NL$
708const ID _kernel_tmax_smtxid = (TMIN_MTXID + TNUM_SMTXID - 1);$NL$
709$NL$
710
711$ ミューテックス初期化ブロックの生成
712$IF LENGTH(MTX.ID_LIST)$
713 const MTXINIB _kernel_mtxinib_table[TNUM_SMTXID] = {$NL$
714 $JOINEACH mtxid MTX.ID_LIST ",\n"$
715$ // mtxatrが([TA_TPRI|TA_CEILING])でない場合(E_RSATR)
716 $IF !(MTX.MTXATR[mtxid] == 0 || MTX.MTXATR[mtxid] == TA_TPRI || MTX.MTXATR[mtxid] == TA_CEILING)$
717 $ERROR MTX.TEXT_LINE[mtxid]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "mtxatr", MTX.MTXATR[mtxid], mtxid, "CRE_MTX")$$END$
718 $END$
719
720$ // ceilpriが未指定の場合は0と見なす
721 $IF !LENGTH(MTX.CEILPRI[mtxid])$
722 $MTX.CEILPRI[mtxid] = 0$
723 $END$
724$ // (TMIN_TPRI <= ceilpri && ceilpri <= TMAX_TPRI)でない場合(E_PAR)
725 $IF MTX.MTXATR[mtxid] == TA_CEILING && (MTX.CEILPRI[mtxid] < TMIN_TPRI || TMAX_TPRI < MTX.CEILPRI[mtxid])$
726 $ERROR MTX.TEXT_LINE[mtxid]$E_PAR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "ceilpri", MTX.CEILPRI[mtxid], mtxid, "CRE_MTX")$$END$
727 $END$
728
729$ // ミューテックス初期化ブロック
730 $TAB${ ($MTX.MTXATR[mtxid]$), INT_PRIORITY($MTX.CEILPRI[mtxid]$) }
731 $END$$NL$
732 };$NL$
733$ELSE$
734 TOPPERS_EMPTY_LABEL(const MTXINIB, _kernel_mtxinib_table);$NL$
735$END$$NL$
736
737$ 動的生成ミューテックス用のミューテックス初期化ブロックの生成
738$IF num_amtxid > 0$
739 MTXINIB _kernel_amtxinib_table[$num_amtxid$];$NL$
740$ELSE$
741 TOPPERS_EMPTY_LABEL(MTXINIB, _kernel_amtxinib_table);$NL$
742$END$$NL$
743
744$ ミューテックス管理ブロックの生成
745$IF num_mtxid > 0$
746 MTXCB _kernel_mtxcb_table[TNUM_MTXID];$NL$
747$ELSE$
748 TOPPERS_EMPTY_LABEL(MTXCB, _kernel_mtxcb_table);$NL$
749$END$$NL$
750
751$
752$ 固定長メモリプール
753$
754/*$NL$
755$SPC$* Fixed-sized Memorypool Functions$NL$
756$SPC$*/$NL$
757$NL$
758
759$ 静的に生成された固定長メモリプールの数
760#define TNUM_SMPFID $LENGTH(MPF.ID_LIST)$$NL$
761$NL$
762
763$ 固定長メモリプールID番号の最大値
764const ID _kernel_tmax_mpfid = (TMIN_MPFID + TNUM_MPFID - 1);$NL$
765const ID _kernel_tmax_smpfid = (TMIN_MPFID + TNUM_SMPFID - 1);$NL$
766$NL$
767
768$IF LENGTH(MPF.ID_LIST)$
769 $FOREACH mpfid MPF.ID_LIST$
770$ // mpfatrが([TA_TPRI])でない場合(E_RSATR)
771 $IF (MPF.MPFATR[mpfid] & ~TA_TPRI) != 0$
772 $ERROR MPF.TEXT_LINE[mpfid]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "mpfatr", MPF.MPFATR[mpfid], mpfid, "CRE_MPF")$$END$
773 $END$
774
775$ // blkcntが0以下の場合(E_PAR)
776 $IF MPF.BLKCNT[mpfid] <= 0$
777 $ERROR MPF.TEXT_LINE[mpfid]$E_PAR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "blkcnt", MPF.BLKCNT[mpfid], mpfid, "CRE_MPF")$$END$
778 $END$
779
780$ // blkszが0以下の場合(E_PAR)
781 $IF MPF.BLKSZ[mpfid] <= 0$
782 $ERROR MPF.TEXT_LINE[mpfid]$E_PAR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "blksz", MPF.BLKSZ[mpfid], mpfid, "CRE_MPF")$$END$
783 $END$
784
785$ // 固定長メモリプール領域
786 $IF EQ(MPF.MPF[mpfid], "NULL")$
787 static MPF_T _kernel_mpf_$mpfid$[($MPF.BLKCNT[mpfid]$) * COUNT_MPF_T($MPF.BLKSZ[mpfid]$)];$NL$
788 $END$
789
790$ // mpfmbがNULLでない場合(E_NOSPT)
791 $IF !EQ(MPF.MPFMB[mpfid], "NULL")$
792 $ERROR MPF.TEXT_LINE[mpfid]$E_NOSPT: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "mpfmb", MPF.MPFMB[mpfid], mpfid, "CRE_MPF")$$END$
793 $END$
794
795$ // 固定長メモリプール管理領域
796 static MPFMB _kernel_mpfmb_$mpfid$[$MPF.BLKCNT[mpfid]$];$NL$
797 $END$
798
799$ // 固定長メモリプール初期化ブロックの生成
800 const MPFINIB _kernel_mpfinib_table[TNUM_SMPFID] = {$NL$
801 $JOINEACH mpfid MPF.ID_LIST ",\n"$
802 $TAB${ ($MPF.MPFATR[mpfid]$), ($MPF.BLKCNT[mpfid]$), ROUND_MPF_T($MPF.BLKSZ[mpfid]$), $IF EQ(MPF.MPF[mpfid],"NULL")$(_kernel_mpf_$mpfid$)$ELSE$(void *)($MPF.MPF[mpfid]$)$END$, (_kernel_mpfmb_$mpfid$) }
803 $END$$NL$
804 };$NL$
805$ELSE$
806 TOPPERS_EMPTY_LABEL(const MPFINIB, _kernel_mpfinib_table);$NL$
807$END$$NL$
808
809$ 動的生成固定長メモリプール用の固定長メモリプール初期化ブロックの生成
810$IF num_ampfid > 0$
811 MPFINIB _kernel_ampfinib_table[$num_ampfid$];$NL$
812$ELSE$
813 TOPPERS_EMPTY_LABEL(MPFINIB, _kernel_ampfinib_table);$NL$
814$END$$NL$
815
816$ 固定長メモリプール管理ブロックの生成
817$IF num_mpfid > 0$
818 MPFCB _kernel_mpfcb_table[TNUM_MPFID];$NL$
819$ELSE$
820 TOPPERS_EMPTY_LABEL(MPFCB, _kernel_mpfcb_table);$NL$
821$END$$NL$
822
823$
824$ 周期ハンドラ
825$
826/*$NL$
827$SPC$* Cyclic Handler Functions$NL$
828$SPC$*/$NL$
829$NL$
830
831$ 静的に生成された周期ハンドラの数
832#define TNUM_SCYCID $LENGTH(CYC.ID_LIST)$$NL$
833$NL$
834
835$ 周期ハンドラID番号の最大値
836const ID _kernel_tmax_cycid = (TMIN_CYCID + TNUM_CYCID - 1);$NL$
837const ID _kernel_tmax_scycid = (TMIN_CYCID + TNUM_SCYCID - 1);$NL$
838$NL$
839
840$ 周期ハンドラ初期化ブロックの生成
841$IF LENGTH(CYC.ID_LIST)$
842 const CYCINIB _kernel_cycinib_table[TNUM_SCYCID] = {$NL$
843 $JOINEACH cycid CYC.ID_LIST ",\n"$
844$ // cycatrが([TA_STA])でない場合(E_RSATR)
845 $IF (CYC.CYCATR[cycid] & ~TA_STA) != 0$
846 $ERROR CYC.TEXT_LINE[cycid]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "cycatr", CYC.CYCATR[cycid], cycid, "CRE_CYC")$$END$
847 $END$
848
849$ // (0 < cyctim && cyctim <= TMAX_RELTIM)でない場合(E_PAR)
850 $IF !(0 < CYC.CYCTIM[cycid] && CYC.CYCTIM[cycid] <= TMAX_RELTIM)$
851 $ERROR CYC.TEXT_LINE[cycid]$E_PAR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "cyctim", CYC.CYCTIM[cycid], cycid, "CRE_CYC")$$END$
852 $END$
853
854$ // (0 <= cycphs && cycphs <= TMAX_RELTIM)でない場合(E_PAR)
855 $IF !(0 <= CYC.CYCPHS[cycid] && CYC.CYCPHS[cycid] <= TMAX_RELTIM)$
856 $ERROR CYC.TEXT_LINE[cycid]$E_PAR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "cycphs", CYC.CYCPHS[cycid], cycid, "CRE_CYC")$$END$
857 $END$
858
859$ // 警告:cycatrにTA_STAが設定されていて,(cycphs == 0)の場合
860 $IF (CYC.CYCATR[cycid] & TA_STA) != 0 && CYC.CYCPHS[cycid] == 0$
861 $WARNING CYC.TEXT_LINE[cycid]$$FORMAT(_("%1% is not recommended when %2% is set to %3% in %4%"), "cycphs==0", "TA_STA", "cycatr", "CRE_CYC")$$END$
862 $END$
863
864$ // 周期ハンドラ初期化ブロック
865 $TAB${ ($CYC.CYCATR[cycid]$), (intptr_t)($CYC.EXINF[cycid]$), ($CYC.CYCHDR[cycid]$), ($CYC.CYCTIM[cycid]$), ($CYC.CYCPHS[cycid]$) }
866 $END$$NL$
867 };$NL$
868$ELSE$
869 TOPPERS_EMPTY_LABEL(const CYCINIB, _kernel_cycinib_table);$NL$
870$END$$NL$
871
872$ 動的生成周期ハンドラ用の周期ハンドラ初期化ブロックの生成
873$IF num_acycid > 0$
874 CYCINIB _kernel_acycinib_table[$num_acycid$];$NL$
875$ELSE$
876 TOPPERS_EMPTY_LABEL(CYCINIB, _kernel_acycinib_table);$NL$
877$END$$NL$
878
879$ 周期ハンドラ管理ブロックの生成
880$IF num_cycid > 0$
881 CYCCB _kernel_cyccb_table[TNUM_CYCID];$NL$
882$ELSE$
883 TOPPERS_EMPTY_LABEL(CYCCB, _kernel_cyccb_table);$NL$
884$END$$NL$
885
886$
887$ アラームハンドラ
888$
889/*$NL$
890$SPC$* Alarm Handler Functions$NL$
891$SPC$*/$NL$
892$NL$
893
894$ 静的に生成されたアラームハンドラの数
895#define TNUM_SALMID $LENGTH(ALM.ID_LIST)$$NL$
896$NL$
897
898$ アラームハンドラID番号の最大値
899const ID _kernel_tmax_almid = (TMIN_ALMID + TNUM_ALMID - 1);$NL$
900const ID _kernel_tmax_salmid = (TMIN_ALMID + TNUM_SALMID - 1);$NL$
901$NL$
902
903$ アラームハンドラ初期化ブロックの生成
904$IF LENGTH(ALM.ID_LIST)$
905 const ALMINIB _kernel_alminib_table[TNUM_SALMID] = {$NL$
906 $JOINEACH almid ALM.ID_LIST ",\n"$
907$ // almatrが(TA_NULL)でない場合(E_RSATR)
908 $IF ALM.ALMATR[almid] != 0$
909 $ERROR ALM.TEXT_LINE[almid]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "almatr", ALM.ALMATR[almid], almid, "CRE_ALM")$$END$
910 $END$
911
912$ // アラームハンドラ初期化ブロック
913 $TAB${ ($ALM.ALMATR[almid]$), (intptr_t)($ALM.EXINF[almid]$), ($ALM.ALMHDR[almid]$) }
914 $END$$NL$
915 };$NL$
916$ELSE$
917 TOPPERS_EMPTY_LABEL(const ALMINIB, _kernel_alminib_table);$NL$
918$END$$NL$
919
920$ 動的生成アラームハンドラ用のアラームハンドラ初期化ブロックの生成
921$IF num_aalmid > 0$
922 ALMINIB _kernel_aalminib_table[$num_aalmid$];$NL$
923$ELSE$
924 TOPPERS_EMPTY_LABEL(ALMINIB, _kernel_aalminib_table);$NL$
925$END$$NL$
926
927$ アラームハンドラ管理ブロックの生成
928$IF num_almid > 0$
929 ALMCB _kernel_almcb_table[TNUM_ALMID];$NL$
930$ELSE$
931 TOPPERS_EMPTY_LABEL(ALMCB, _kernel_almcb_table);$NL$
932$END$$NL$
933
934$
935$ 割込み管理機能
936$
937/*$NL$
938$SPC$* Interrupt Management Functions$NL$
939$SPC$*/$NL$
940$NL$
941
942$ 割込み番号と割込みハンドラ番号の変換テーブルの作成
943$IF LENGTH(INTNO_ATTISR_VALID) != LENGTH(INHNO_ATTISR_VALID)$
944 $ERROR$length of `INTNO_ATTISR_VALID' is different from length of `INHNO_ATTISR_VALID'$END$
945$END$
946$i = 0$
947$FOREACH intno INTNO_ATTISR_VALID$
948 $inhno = AT(INHNO_ATTISR_VALID, i)$
949 $INHNO[intno] = inhno$
950 $INTNO[inhno] = intno$
951 $i = i + 1$
952$END$
953
954$ 割込み要求ラインに関するエラーチェック
955$i = 0$
956$FOREACH intno INT.ORDER_LIST$
957$ // intnoがCFG_INTに対する割込み番号として正しくない場合(E_PAR)
958 $IF !LENGTH(FIND(INTNO_CFGINT_VALID, INT.INTNO[intno]))$
959 $ERROR INT.TEXT_LINE[intno]$E_PAR: $FORMAT(_("illegal %1% `%2%\' in %3%"), "intno", INT.INTNO[intno], "CFG_INT")$$END$
960 $END$
961
962$ // intnoがCFG_INTによって設定済みの場合(E_OBJ)
963 $j = 0$
964 $FOREACH intno2 INT.ORDER_LIST$
965 $IF j < i && INT.INTNO[intno] == INT.INTNO[intno2]$
966 $ERROR INT.TEXT_LINE[intno]$E_OBJ: $FORMAT(_("%1% `%2%\' in %3% is duplicated"), "intno", INT.INTNO[intno], "CFG_INT")$$END$
967 $END$
968 $j = j + 1$
969 $END$
970
971$ // intatrが([TA_ENAINT]|[TA_EDGE])でない場合(E_RSATR)
972 $IF (INT.INTATR[intno] & ~(TA_ENAINT|TA_EDGE|TARGET_INTATR)) != 0$
973 $ERROR INT.TEXT_LINE[intno]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of %3% `%4%\' in %5%"), "intatr", INT.INTATR[intno], "intno", INT.INTNO[intno], "CFG_INT")$$END$
974 $END$
975
976$ // intpriがCFG_INTに対する割込み優先度として正しくない場合(E_PAR)
977 $IF !LENGTH(FIND(INTPRI_CFGINT_VALID, INT.INTPRI[intno]))$
978 $ERROR INT.TEXT_LINE[intno]$E_PAR: $FORMAT(_("illegal %1% `%2%\' in %3%"), "intpri", INT.INTPRI[intno], "CFG_INT")$$END$
979 $END$
980
981$ // カーネル管理に固定されているintnoに対して,intpriにTMIN_INTPRI
982$ // よりも小さい値が指定された場合(E_OBJ)
983 $IF LENGTH(FIND(INTNO_FIX_KERNEL, intno))$
984 $IF INT.INTPRI[intno] < TMIN_INTPRI$
985 $ERROR INT.TEXT_LINE[intno]$E_OBJ: $FORMAT(_("%1% `%2%\' must not have higher priority than %3%"), "intno", INT.INTNO[intno], "TMIN_INTPRI")$$END$
986 $END$
987 $END$
988
989$ // カーネル管理外に固定されているintnoに対して,intpriにTMIN_INTPRI
990$ // よりも小さい値が指定されなかった場合(E_OBJ)
991 $IF LENGTH(FIND(INTNO_FIX_NONKERNEL, intno))$
992 $IF INT.INTPRI[intno] >= TMIN_INTPRI$
993 $ERROR INT.TEXT_LINE[intno]$E_OBJ: $FORMAT(_("%1% `%2%\' must have higher priority than %3%"), "intno", INT.INTNO[intno], "TMIN_INTPRI")$$END$
994 $END$
995 $END$
996 $i = i + 1$
997$END$
998
999$ 割込みハンドラに関するエラーチェック
1000$i = 0$
1001$FOREACH inhno INH.ORDER_LIST$
1002$ // inhnoがDEF_INHに対する割込みハンドラ番号として正しくない場合(E_PAR)
1003 $IF !LENGTH(FIND(INHNO_DEFINH_VALID, INH.INHNO[inhno]))$
1004 $ERROR INH.TEXT_LINE[inhno]$E_PAR: $FORMAT(_("illegal %1% `%2%\' in %3%"), "inhno", INH.INHNO[inhno], "DEF_INH")$$END$
1005 $END$
1006
1007$ // inhnoがDEF_INHによって設定済みの場合(E_OBJ)
1008 $j = 0$
1009 $FOREACH inhno2 INH.ORDER_LIST$
1010 $IF j < i && INH.INHNO[inhno] == INH.INHNO[inhno2]$
1011 $ERROR INH.TEXT_LINE[inhno]$E_OBJ: $FORMAT(_("%1% `%2%\' in %3% is duplicated"), "inhno", INH.INHNO[inhno], "DEF_INH")$$END$
1012 $END$
1013 $j = j + 1$
1014 $END$
1015
1016$ // inhatrが(TA_NULL)でない場合(E_RSATR)
1017 $IF (INH.INHATR[inhno] & ~TARGET_INHATR) != 0$
1018 $ERROR INH.TEXT_LINE[inhno]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of %3% `%4%\' in %5%"), "inhatr", INH.INHATR[inhno], "inhno", INH.INHNO[inhno], "DEF_INH")$$END$
1019 $END$
1020
1021$ // カーネル管理に固定されているinhnoに対して,inhatrにTA_NONKERNEL
1022$ // が指定されている場合(E_RSATR)
1023 $IF LENGTH(FIND(INHNO_FIX_KERNEL, inhno))$
1024 $IF (INH.INHATR[inhno] & TA_NONKERNEL) != 0$
1025 $ERROR INH.TEXT_LINE[inhno]$E_RSATR: $FORMAT(_("%1% `%2%\' must not be non-kernel interrupt"), "inhno", INH.INHNO[inhno])$$END$
1026 $END$
1027 $END$
1028
1029$ // カーネル管理外に固定されているinhnoに対して,inhatrにTA_NONKERNEL
1030$ // が指定されていない場合(E_RSATR)
1031 $IF LENGTH(FIND(INHNO_FIX_NONKERNEL, inhno))$
1032 $IF (INH.INHATR[inhno] & TA_NONKERNEL) == 0$
1033 $ERROR INH.TEXT_LINE[inhno]$E_RSATR: $FORMAT(_("%1% `%2%\' must be non-kernel interrupt"), "inhno", INH.INHNO[inhno])$$END$
1034 $END$
1035 $END$
1036
1037 $IF LENGTH(INTNO[INH.INHNO[inhno]])$
1038 $intno = INTNO[INH.INHNO[inhno]]$
1039$ // inhnoに対応するintnoに対するCFG_INTがない場合(E_OBJ)
1040 $IF !LENGTH(INT.INTNO[intno])$
1041 $ERROR INH.TEXT_LINE[inhno]$E_OBJ: $FORMAT(_("%1% `%2%\' corresponding to %3% `%4%\' is not configured with %5%"), "intno", intno, "inhno", INH.INHNO[inhno], "CFG_INT")$$END$
1042 $ELSE$
1043 $IF (INH.INHATR[inhno] & TA_NONKERNEL) == 0$
1044$ // inhatrにTA_NONKERNELが指定されておらず,inhnoに対応
1045$ // するintnoに対してCFG_INTで設定された割込み優先度が
1046$ // TMIN_INTPRIよりも小さい場合(E_OBJ)
1047 $IF INT.INTPRI[intno] < TMIN_INTPRI$
1048 $ERROR INT.TEXT_LINE[intno]$E_OBJ: $FORMAT(_("%1% `%2%\' configured for %3% `%4%\' is higher than %5%"), "intpri", INT.INTPRI[intno], "inhno", INH.INHNO[inhno], "TMIN_INTPRI")$$END$
1049 $END$
1050 $ELSE$
1051$ // inhatrにTA_NONKERNELが指定されており,inhnoに対応
1052$ // するintnoに対してCFG_INTで設定された割込み優先度が
1053$ // TMIN_INTPRI以上である場合(E_OBJ)
1054 $IF INT.INTPRI[intno] >= TMIN_INTPRI$
1055 $ERROR INT.TEXT_LINE[intno]$E_OBJ: $FORMAT(_("%1% `%2%\' configured for %3% `%4%\' is lower than or equal to %5%"), "intpri", INT.INTPRI[intno], "inhno", INH.INHNO[inhno], "TMIN_INTPRI")$$END$
1056 $END$
1057 $END$
1058 $END$
1059 $END$
1060 $i = i + 1$
1061$END$
1062
1063$ 割込みサービスルーチン(ISR)に関するエラーチェック
1064$FOREACH order ISR.ORDER_LIST$
1065$ // isratrが(TA_NULL)でない場合(E_RSATR)
1066 $IF (ISR.ISRATR[order] & ~TARGET_ISRATR) != 0$
1067 $ERROR ISR.TEXT_LINE[order]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' in %3%"), "isratr", ISR.ISRATR[order], "ATT_ISR")$$END$
1068 $END$
1069
1070$ // intnoがATT_ISRに対する割込み番号として正しくない場合(E_PAR)
1071 $IF !LENGTH(FIND(INTNO_ATTISR_VALID, ISR.INTNO[order]))$
1072 $ERROR ISR.TEXT_LINE[order]$E_PAR: $FORMAT(_("illegal %1% `%2%\' in %3%"), "intno", ISR.INTNO[order], "ATT_ISR")$$END$
1073 $END$
1074
1075$ // (TMIN_ISRPRI <= isrpri && isrpri <= TMAX_ISRPRI)でない場合(E_PAR)
1076 $IF !(TMIN_ISRPRI <= ISR.ISRPRI[order] && ISR.ISRPRI[order] <= TMAX_ISRPRI)$
1077 $ERROR ISR.TEXT_LINE[order]$E_PAR: $FORMAT(_("illegal %1% `%2%\' in %3%"), "isrpri", ISR.ISRPRI[order], "ATT_ISR")$$END$
1078 $END$
1079$END$
1080
1081$FOREACH intno INTNO_ATTISR_VALID$
1082 $inhno = INHNO[intno]$
1083
1084$ // 割込み番号intnoに対して登録されたISRのリストの作成
1085 $isr_order_list = {}$
1086 $FOREACH order ISR.ORDER_LIST$
1087 $IF ISR.INTNO[order] == intno$
1088 $isr_order_list = APPEND(isr_order_list, order)$
1089 $order_for_error = order$
1090 $END$
1091 $END$
1092
1093$ // 割込み番号intnoに対して登録されたISRが存在する場合
1094 $IF LENGTH(isr_order_list) > 0$
1095$ // intnoに対応するinhnoに対してDEF_INHがある場合(E_OBJ)
1096 $IF LENGTH(INH.INHNO[inhno])$
1097 $ERROR ISR.TEXT_LINE[order_for_error]$E_OBJ: $FORMAT(_("%1% `%2%\' in %3% is duplicated with %4% `%5%\'"), "intno", ISR.INTNO[order_for_error], "ATT_ISR", "inhno", INH.INHNO[inhno])$$END$
1098 $END$
1099
1100$ // intnoに対するCFG_INTがない場合(E_OBJ)
1101 $IF !LENGTH(INT.INTNO[intno])$
1102 $ERROR ISR.TEXT_LINE[order_for_error]$E_OBJ: $FORMAT(_("%1% `%2%\' is not configured with %3%"), "intno", ISR.INTNO[order_for_error], "CFG_INT")$$END$
1103 $ELSE$
1104$ // intnoに対してCFG_INTで設定された割込み優先度がTMIN_INTPRI
1105$ // よりも小さい場合(E_OBJ)
1106 $IF INT.INTPRI[intno] < TMIN_INTPRI$
1107 $ERROR INT.TEXT_LINE[intno]$E_OBJ: $FORMAT(_("%1% `%2%\' configured for %3% `%4%\' is higher than %5%"), "intpri", INT.INTPRI[intno], "intno", ISR.INTNO[order_for_error], "TMIN_INTPRI")$$END$
1108 $END$
1109 $END$
1110 $END$
1111$END$
1112
1113$ 割込みサービスルーチン(ISR)管理のデータ構造
1114$intno_isr_list = {}$
1115$FOREACH intno INTNO_ATTISR_VALID$
1116 $inhno = INHNO[intno]$
1117 $IF LENGTH(INT.INTNO[intno]) && !LENGTH(INH.INHNO[inhno])$
1118 $intno_isr_list = APPEND(intno_isr_list, intno)$
1119 $END$
1120$END$
1121
1122$INTNO_ISR = {}$
1123$i = 0$
1124$FOREACH intno SORT(intno_isr_list, "INT.INTNO")$
1125 $INTNO_ISR = APPEND(INTNO_ISR, intno)$
1126 $ISR_QUEUE_HEADER[intno] = FORMAT("&(_kernel_isr_queue_table[%d])", i)$
1127 $i = i + 1$
1128$END$
1129
1130const uint_t _kernel_tnum_isr_queue = $LENGTH(INTNO_ISR)$;$NL$
1131$NL$
1132
1133$IF LENGTH(INTNO_ISR)$
1134 const ISR_ENTRY _kernel_isr_queue_list[$LENGTH(INTNO_ISR)$] = {$NL$
1135 $JOINEACH intno INTNO_ISR ",\n"$
1136 $TAB${ $intno$, $ISR_QUEUE_HEADER[intno]$ }
1137 $END$$NL$
1138 };$NL$
1139$ELSE$
1140 TOPPERS_EMPTY_LABEL(QUEUE, _kernel_isr_queue_table);$NL$
1141$END$$NL$
1142
1143$IF LENGTH(INTNO_ISR)$
1144 QUEUE _kernel_isr_queue_table[$LENGTH(INTNO_ISR)$];$NL$
1145$ELSE$
1146 TOPPERS_EMPTY_LABEL(QUEUE, _kernel_isr_queue_table);$NL$
1147$END$$NL$
1148
1149$ 割込みサービスルーチン(ISR)呼出しのための割込みハンドラの生成
1150$FOREACH intno INTNO_ISR$
1151 $inhno = INHNO[intno]$
1152
1153$ // DEF_INH(inhno, { TA_NULL, _kernel_inthdr_<intno> } );
1154 $INH.INHNO[inhno] = inhno$
1155 $INH.INHATR[inhno] = VALUE("TA_NULL", 0)$
1156 $INH.INTHDR[inhno] = CONCAT("_kernel_inthdr_", intno)$
1157 $INH.ORDER_LIST = APPEND(INH.ORDER_LIST, inhno)$
1158
1159$ // ISR用の割込みハンドラ
1160 void$NL$
1161 _kernel_inthdr_$intno$(void)$NL$
1162 {$NL$
1163 $TAB$i_begin_int($intno$);$NL$
1164 $TAB$_kernel_call_isr($ISR_QUEUE_HEADER[intno]$);$NL$
1165 $TAB$i_end_int($intno$);$NL$
1166 }$NL$
1167 $NL$
1168$END$
1169
1170$ 割込みサービスルーチンの数
1171#define TNUM_SISR $LENGTH(ISR.ORDER_LIST)$$NL$
1172#define TNUM_ISR $LENGTH(ISR.ORDER_LIST) + num_aisrid$$NL$
1173$NL$
1174
1175$ 割込みサービスルーチンID番号の最大値
1176const ID _kernel_tmax_isrid = (TMIN_ISRID + TNUM_ISRID - 1);$NL$
1177const uint_t _kernel_tnum_sisr = TNUM_SISR;$NL$
1178$NL$
1179
1180$ 割込みサービスルーチン初期化ブロックの生成
1181$IF LENGTH(ISR.ORDER_LIST)$
1182 const ISRINIB _kernel_sisrinib_table[TNUM_SISR] = {$NL$
1183 $JOINEACH order ISR.ORDER_LIST ",\n"$
1184 $TAB${ ($ISR.ISRATR[order]$), (intptr_t)($ISR.EXINF[order]$), ($ISR.INTNO[order]$), ($ISR_QUEUE_HEADER[ISR.INTNO[order]]$), ($ISR.ISR[order]$), ($ISR.ISRPRI[order]$) }
1185 $END$$NL$
1186 };$NL$
1187$ELSE$
1188 TOPPERS_EMPTY_LABEL(const ISRINIB, _kernel_sisrinib_table);$NL$
1189$END$
1190$NL$
1191
1192$ 動的生成割込みサービスルーチン用の割込みサービスルーチン初期化ブロッ
1193$ クの生成
1194$IF num_aisrid > 0$
1195 ISRINIB _kernel_aisrinib_table[$num_aisrid$];$NL$
1196$ELSE$
1197 TOPPERS_EMPTY_LABEL(ISRINIB, _kernel_aisrinib_table);$NL$
1198$END$
1199$NL$
1200
1201$ 割込みサービスルーチン管理ブロックの生成
1202$IF num_isr > 0$
1203 ISRCB _kernel_isrcb_table[TNUM_ISR];$NL$
1204$ELSE$
1205 TOPPERS_EMPTY_LABEL(ISRCB, _kernel_isrcb_table);$NL$
1206$END$
1207$NL$
1208
1209$
1210$ 割込み管理機能のための標準的な初期化情報の生成
1211$
1212$ 割込みハンドラの初期化に必要な情報
1213$IF !OMIT_INITIALIZE_INTERRUPT || ALT(USE_INHINIB_TABLE,0)$
1214
1215$ 割込みハンドラ数
1216#define TNUM_INHNO $LENGTH(INH.ORDER_LIST)$$NL$
1217const uint_t _kernel_tnum_inhno = TNUM_INHNO;$NL$
1218$NL$
1219$FOREACH inhno INH.ORDER_LIST$
1220 $IF (INH.INHATR[inhno] & TA_NONKERNEL) == 0$
1221 INTHDR_ENTRY($INH.INHNO[inhno]$, $+INH.INHNO[inhno]$, $INH.INTHDR[inhno]$)$NL$
1222 $END$
1223$END$
1224$NL$
1225
1226$ 割込みハンドラ初期化ブロック
1227$IF LENGTH(INH.ORDER_LIST)$
1228 const INHINIB _kernel_inhinib_table[TNUM_INHNO] = {$NL$
1229 $JOINEACH inhno INH.ORDER_LIST ",\n"$
1230 $IF (INH.INHATR[inhno] & TA_NONKERNEL) == 0$
1231 $TAB${ ($INH.INHNO[inhno]$), ($INH.INHATR[inhno]$), (FP)(INT_ENTRY($INH.INHNO[inhno]$, $INH.INTHDR[inhno]$)) }
1232 $ELSE$
1233 $TAB${ ($INH.INHNO[inhno]$), ($INH.INHATR[inhno]$), (FP)($INH.INTHDR[inhno]$) }
1234 $END$
1235 $END$$NL$
1236 };$NL$
1237$ELSE$
1238 TOPPERS_EMPTY_LABEL(const INHINIB, _kernel_inhinib_table);$NL$
1239$END$$NL$
1240$END$
1241
1242$ 割込み要求ラインの初期化に必要な情報
1243$IF !OMIT_INITIALIZE_INTERRUPT || ALT(USE_INTINIB_TABLE,0)$
1244
1245$ 割込み要求ライン数
1246#define TNUM_INTNO $LENGTH(INT.ORDER_LIST)$$NL$
1247const uint_t _kernel_tnum_intno = TNUM_INTNO;$NL$
1248$NL$
1249
1250$ 割込み要求ライン初期化ブロック
1251$IF LENGTH(INT.ORDER_LIST)$
1252 const INTINIB _kernel_intinib_table[TNUM_INTNO] = {$NL$
1253 $JOINEACH intno INT.ORDER_LIST ",\n"$
1254 $TAB${ ($INT.INTNO[intno]$), ($INT.INTATR[intno]$), ($INT.INTPRI[intno]$) }
1255 $END$$NL$
1256 };$NL$
1257$ELSE$
1258 TOPPERS_EMPTY_LABEL(const INTINIB, _kernel_intinib_table);$NL$
1259$END$$NL$
1260$END$
1261
1262$
1263$ CPU例外管理機能
1264$
1265/*$NL$
1266$SPC$* CPU Exception Management Functions$NL$
1267$SPC$*/$NL$
1268$NL$
1269
1270$ CPU例外ハンドラに関するエラーチェック
1271$i = 0$
1272$FOREACH excno EXC.ORDER_LIST$
1273$ // excnoがDEF_EXCに対するCPU例外ハンドラ番号として正しくない場合(E_PAR)
1274 $IF !LENGTH(FIND(EXCNO_DEFEXC_VALID, EXC.EXCNO[excno]))$
1275 $ERROR EXC.TEXT_LINE[excno]$E_PAR: $FORMAT(_("illegal %1% `%2%\' in %3%"), "excno", EXC.EXCNO[excno], "DEF_EXC")$$END$
1276 $END$
1277
1278$ // excnoがDEF_EXCによって設定済みの場合(E_OBJ)
1279 $j = 0$
1280 $FOREACH excno2 EXC.ORDER_LIST$
1281 $IF j < i && EXC.EXCNO[excno] == EXC.EXCNO[excno2]$
1282 $ERROR EXC.TEXT_LINE[excno]$E_OBJ: $FORMAT(_("%1% `%2%\' in %3% is duplicated"), "excno", EXC.EXCNO[excno], "DEF_EXC")$$END$
1283 $END$
1284 $j = j + 1$
1285 $END$
1286
1287$ // excatrが(TA_NULL)でない場合(E_RSATR)
1288 $IF (EXC.EXCATR[excno] & ~TARGET_EXCATR) != 0$
1289 $ERROR EXC.TEXT_LINE[excno]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of %3% `%4%\' in %5%"), "excatr", EXC.EXCATR[excno], "excno", EXC.EXCNO[excno], "DEF_EXC")$$END$
1290 $END$
1291 $i = i + 1$
1292$END$
1293
1294$ CPU例外ハンドラのための標準的な初期化情報の生成
1295$IF !OMIT_INITIALIZE_EXCEPTION$
1296
1297$ CPU例外ハンドラ数
1298#define TNUM_EXCNO $LENGTH(EXC.ORDER_LIST)$$NL$
1299const uint_t _kernel_tnum_excno = TNUM_EXCNO;$NL$
1300$NL$
1301$FOREACH excno EXC.ORDER_LIST$
1302 EXCHDR_ENTRY($EXC.EXCNO[excno]$, $+EXC.EXCNO[excno]$, $EXC.EXCHDR[excno]$)$NL$
1303$END$
1304$NL$
1305
1306$ CPU例外ハンドラ初期化ブロック
1307$IF LENGTH(EXC.ORDER_LIST)$
1308 const EXCINIB _kernel_excinib_table[TNUM_EXCNO] = {$NL$
1309 $JOINEACH excno EXC.ORDER_LIST ",\n"$
1310 $TAB${ ($EXC.EXCNO[excno]$), ($EXC.EXCATR[excno]$), (FP)(EXC_ENTRY($EXC.EXCNO[excno]$, $EXC.EXCHDR[excno]$)) }
1311 $END$$NL$
1312 };$NL$
1313$ELSE$
1314 TOPPERS_EMPTY_LABEL(const EXCINIB, _kernel_excinib_table);$NL$
1315$END$$NL$
1316$END$
1317
1318$
1319$ 非タスクコンテキスト用のスタック領域
1320$
1321/*$NL$
1322$SPC$* Stack Area for Non-task Context$NL$
1323$SPC$*/$NL$
1324$NL$
1325
1326$IF !LENGTH(ICS.ORDER_LIST)$
1327$ // DEF_ICSがない場合のデフォルト値の設定
1328 #ifdef DEFAULT_ISTK$NL$
1329 $NL$
1330 #define TOPPERS_ISTKSZ DEFAULT_ISTKSZ$NL$
1331 #define TOPPERS_ISTK DEFAULT_ISTK$NL$
1332 $NL$
1333 #else /* DEAULT_ISTK */$NL$
1334 $NL$
1335 $istksz = ALLOC_STACK("_kernel_istack", "DEFAULT_ISTKSZ")$$NL$
1336 #define TOPPERS_ISTKSZ $istksz$$NL$
1337 #define TOPPERS_ISTK _kernel_istack$NL$
1338 $NL$
1339 #endif /* DEAULT_ISTK */$NL$
1340$ELSE$
1341
1342$ // 静的API「DEF_ICS」が複数ある(E_OBJ)
1343 $IF LENGTH(ICS.ORDER_LIST) > 1$
1344 $ERROR$E_OBJ: $FORMAT(_("too many %1%"), "DEF_ICS")$$END$
1345 $END$
1346
1347$ // istkszが0以下か,ターゲット定義の最小値(TARGET_MIN_ISTKSZ)よりも
1348$ // 小さい場合(E_PAR)
1349 $IF ICS.ISTKSZ[1] <= 0 || (TARGET_MIN_ISTKSZ
1350 && ICS.ISTKSZ[1] < TARGET_MIN_ISTKSZ)$
1351 $ERROR ICS.TEXT_LINE[1]$E_PAR: $FORMAT(_("too small %1% `%2%\' in %3%"), "istksz", ICS.ISTKSZ[1], "DEF_ICS")$$END$
1352 $END$
1353
1354$ // istkszがスタック領域のサイズとして正しくない場合(E_PAR)
1355 $IF !EQ(ICS.ISTK[1], "NULL") && CHECK_STKSZ_ALIGN
1356 && (ICS.ISTKSZ[1] & (CHECK_STKSZ_ALIGN - 1))$
1357 $ERROR ICS.TEXT_LINE[1]$E_PAR: $FORMAT(_("%1% `%2%\' in %3% is not aligned"), "istksz", ICS.ISTKSZ[1], "DEF_ICS")$$END$
1358 $END$
1359
1360 $IF EQ(ICS.ISTK[1], "NULL")$
1361$ // スタック領域の自動割付け
1362 $istksz = ALLOC_STACK("_kernel_istack", ICS.ISTKSZ[1])$$NL$
1363 #define TOPPERS_ISTKSZ $istksz$$NL$
1364 #define TOPPERS_ISTK _kernel_istack$NL$
1365 $ELSE$
1366 #define TOPPERS_ISTKSZ ($ICS.ISTKSZ[1]$)$NL$
1367 #define TOPPERS_ISTK (void *)($ICS.ISTK[1]$)$NL$
1368 $END$
1369$END$
1370$NL$
1371
1372$ 非タスクコンテキスト用のスタック領域
1373const SIZE _kernel_istksz = TOPPERS_ISTKSZ;$NL$
1374STK_T *const _kernel_istk = TOPPERS_ISTK;$NL$
1375$NL$
1376#ifdef TOPPERS_ISTKPT$NL$
1377STK_T *const _kernel_istkpt = TOPPERS_ISTKPT(TOPPERS_ISTK, TOPPERS_ISTKSZ);$NL$
1378#endif /* TOPPERS_ISTKPT */$NL$
1379$NL$
1380
1381$
1382$ カーネルが割り付けるメモリ領域
1383$
1384/*$NL$
1385$SPC$* Memory Area Allocated by Kernel$NL$
1386$SPC$*/$NL$
1387$NL$
1388
1389$IF !LENGTH(KMM.ORDER_LIST)$
1390$ // DEF_KMMがない場合のデフォルト値の設定
1391 #define TOPPERS_KMMSZ 0$NL$
1392 #define TOPPERS_KMM NULL$NL$
1393$ELSE$
1394$ // 静的API「DEF_KMM」が複数ある(E_OBJ)
1395 $IF LENGTH(KMM.ORDER_LIST) > 1$
1396 $ERROR$E_OBJ: $FORMAT(_("too many %1%"), "DEF_KMM")$$END$
1397 $END$
1398
1399$ // kmmszが0以下の場合(E_PAR)
1400 $IF KMM.KMMSZ[1] <= 0$
1401 $ERROR KMM.TEXT_LINE[1]$E_PAR: $FORMAT(_("%1% `%2%\' is zero in %3%"), "kmmsz", KMM.KMMSZ[1], "DEF_KMM")$$END$
1402 $END$
1403
1404$ // kmmszがカーネルが割り付けるメモリ領域のサイズとして正しくない場合(E_PAR)
1405 $IF !EQ(KMM.KMM[1], "NULL") && CHECK_MB_ALIGN
1406 && (KMM.KMMSZ[1] & (CHECK_MB_ALIGN - 1))$
1407 $ERROR KMM.TEXT_LINE[1]$E_PAR: $FORMAT(_("%1% `%2%\' in %3% is not aligned"), "kmmsz", KMM.KMMSZ[1], "DEF_KMM")$$END$
1408 $END$
1409
1410 $IF EQ(KMM.KMM[1], "NULL")$
1411$ // カーネルが割り付けるメモリ領域の自動割付け
1412 static MB_T _kernel_memory[TOPPERS_COUNT_SZ($KMM.KMMSZ[1]$, sizeof(MB_T))];$NL$
1413 #define TOPPERS_KMMSZ TOPPERS_ROUND_SZ($KMM.KMMSZ[1]$, sizeof(MB_T))$NL$
1414 #define TOPPERS_KMM _kernel_memory$NL$
1415 $ELSE$
1416 #define TOPPERS_KMMSZ ($KMM.KMMSZ[1]$)$NL$
1417 #define TOPPERS_KMM (void *)($KMM.KMM[1]$)$NL$
1418 $END$
1419$END$
1420$NL$
1421
1422$ カーネルが割り付けるメモリ領域
1423const SIZE _kernel_kmmsz = TOPPERS_KMMSZ;$NL$
1424MB_T *const _kernel_kmm = TOPPERS_KMM;$NL$
1425$NL$
1426
1427$
1428$ タイムイベント管理
1429$
1430/*$NL$
1431$SPC$* Time Event Management$NL$
1432$SPC$*/$NL$
1433$NL$
1434TMEVTN _kernel_tmevt_heap[TNUM_TSKID + TNUM_CYCID + TNUM_ALMID];$NL$
1435$NL$
1436
1437$
1438$ 各モジュールの初期化関数
1439$
1440/*$NL$
1441$SPC$* Module Initialization Function$NL$
1442$SPC$*/$NL$
1443$NL$
1444void$NL$
1445_kernel_initialize_object(void)$NL$
1446{$NL$
1447$TAB$_kernel_initialize_task();$NL$
1448$IF num_semid$$TAB$_kernel_initialize_semaphore();$NL$$END$
1449$IF num_flgid$$TAB$_kernel_initialize_eventflag();$NL$$END$
1450$IF num_dtqid$$TAB$_kernel_initialize_dataqueue();$NL$$END$
1451$IF num_pdqid$$TAB$_kernel_initialize_pridataq();$NL$$END$
1452$IF num_mbxid$$TAB$_kernel_initialize_mailbox();$NL$$END$
1453$IF num_mpfid$$TAB$_kernel_initialize_mempfix();$NL$$END$
1454$IF num_cycid$$TAB$_kernel_initialize_cyclic();$NL$$END$
1455$IF num_almid$$TAB$_kernel_initialize_alarm();$NL$$END$
1456$TAB$_kernel_initialize_interrupt();$NL$
1457$IF num_isr$$TAB$_kernel_initialize_isr();$NL$$END$
1458$TAB$_kernel_initialize_exception();$NL$
1459}$NL$
1460$NL$
1461
1462$
1463$ 初期化ルーチンの実行関数
1464$
1465/*$NL$
1466$SPC$* Initialization Routine$NL$
1467$SPC$*/$NL$
1468$NL$
1469void$NL$
1470_kernel_call_inirtn(void)$NL$
1471{$NL$
1472$FOREACH order INI.ORDER_LIST$
1473$ // iniatrが(TA_NULL)でない場合(E_RSATR)
1474 $IF INI.INIATR[order] != 0$
1475 $ERROR INI.TEXT_LINE[order]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of %3% `%4%\' in %5%"), "iniatr", INI.INIATR[order], "inirtn", INI.INIRTN[order], "ATT_INI")$$END$
1476 $END$
1477 $TAB$((INIRTN)($INI.INIRTN[order]$))((intptr_t)($INI.EXINF[order]$));$NL$
1478$END$
1479}$NL$
1480$NL$
1481
1482$
1483$ 終了処理ルーチンの実行関数
1484$
1485/*$NL$
1486$SPC$* Termination Routine$NL$
1487$SPC$*/$NL$
1488$NL$
1489void$NL$
1490_kernel_call_terrtn(void)$NL$
1491{$NL$
1492$FOREACH rorder TER.RORDER_LIST$
1493$ // teratrが(TA_NULL)でない場合(E_RSATR)
1494 $IF TER.TERATR[rorder] != 0$
1495 $ERROR TER.TEXT_LINE[rorder]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of %3% `%4%\' in %5%"), "teratr", TER.TERATR[rorder], "terrtn", TER.TERRTN[rorder], "ATT_TER")$$END$
1496 $END$
1497 $TAB$((TERRTN)($TER.TERRTN[rorder]$))((intptr_t)($TER.EXINF[rorder]$));$NL$
1498$END$
1499}$NL$
1500$NL$
Note: See TracBrowser for help on using the repository browser.