source: asp3_gr_sakura/trunk/kernel/interrupt.c@ 318

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

プロパティの文字コードにUTF-8を追加、キーワードを削除

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc; charset=UTF-8
File size: 15.4 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) 2000-2003 by Embedded and Real-Time Systems Laboratory
7 * Toyohashi Univ. of Technology, JAPAN
8 * Copyright (C) 2005-2017 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 */
46
47#include "kernel_impl.h"
48#include "check.h"
49#include "task.h"
50#include "interrupt.h"
51#include "overrun.h"
52
53/*
54 * トレースログマクロのデフォルト定義
55 */
56#ifndef LOG_ISR_ENTER
57#define LOG_ISR_ENTER(isrid)
58#endif /* LOG_ISR_ENTER */
59
60#ifndef LOG_ISR_LEAVE
61#define LOG_ISR_LEAVE(isrid)
62#endif /* LOG_ISR_LEAVE */
63
64#ifndef LOG_ACRE_ISR_ENTER
65#define LOG_ACRE_ISR_ENTER(pk_cisr)
66#endif /* LOG_ACRE_ISR_ENTER */
67
68#ifndef LOG_ACRE_ISR_LEAVE
69#define LOG_ACRE_ISR_LEAVE(ercd)
70#endif /* LOG_ACRE_ISR_LEAVE */
71
72#ifndef LOG_DEL_ISR_ENTER
73#define LOG_DEL_ISR_ENTER(isrid)
74#endif /* LOG_DEL_ISR_ENTER */
75
76#ifndef LOG_DEL_ISR_LEAVE
77#define LOG_DEL_ISR_LEAVE(ercd)
78#endif /* LOG_DEL_ISR_LEAVE */
79
80#ifndef LOG_DIS_INT_ENTER
81#define LOG_DIS_INT_ENTER(intno)
82#endif /* LOG_DIS_INT_ENTER */
83
84#ifndef LOG_DIS_INT_LEAVE
85#define LOG_DIS_INT_LEAVE(ercd)
86#endif /* LOG_DIS_INT_LEAVE */
87
88#ifndef LOG_ENA_INT_ENTER
89#define LOG_ENA_INT_ENTER(intno)
90#endif /* LOG_ENA_INT_ENTER */
91
92#ifndef LOG_ENA_INT_LEAVE
93#define LOG_ENA_INT_LEAVE(ercd)
94#endif /* LOG_ENA_INT_LEAVE */
95
96#ifndef LOG_CLR_INT_ENTER
97#define LOG_CLR_INT_ENTER(intno)
98#endif /* LOG_CLR_INT_ENTER */
99
100#ifndef LOG_CLR_INT_LEAVE
101#define LOG_CLR_INT_LEAVE(ercd)
102#endif /* LOG_CLR_INT_LEAVE */
103
104#ifndef LOG_RAS_INT_ENTER
105#define LOG_RAS_INT_ENTER(intno)
106#endif /* LOG_RAS_INT_ENTER */
107
108#ifndef LOG_RAS_INT_LEAVE
109#define LOG_RAS_INT_LEAVE(ercd)
110#endif /* LOG_RAS_INT_LEAVE */
111
112#ifndef LOG_PRB_INT_ENTER
113#define LOG_PRB_INT_ENTER(intno)
114#endif /* LOG_PRB_INT_ENTER */
115
116#ifndef LOG_PRB_INT_LEAVE
117#define LOG_PRB_INT_LEAVE(ercd)
118#endif /* LOG_PRB_INT_LEAVE */
119
120#ifndef LOG_CHG_IPM_ENTER
121#define LOG_CHG_IPM_ENTER(intpri)
122#endif /* LOG_CHG_IPM_ENTER */
123
124#ifndef LOG_CHG_IPM_LEAVE
125#define LOG_CHG_IPM_LEAVE(ercd)
126#endif /* LOG_CHG_IPM_LEAVE */
127
128#ifndef LOG_GET_IPM_ENTER
129#define LOG_GET_IPM_ENTER(p_intpri)
130#endif /* LOG_GET_IPM_ENTER */
131
132#ifndef LOG_GET_IPM_LEAVE
133#define LOG_GET_IPM_LEAVE(ercd, p_intpri)
134#endif /* LOG_GET_IPM_LEAVE */
135
136/*
137 * 割込み番号の範囲の判定
138 */
139#ifndef VALID_INTNO_DISINT
140#define VALID_INTNO_DISINT(intno) VALID_INTNO(intno)
141#endif /* VALID_INTNO_DISINT */
142
143#ifndef VALID_INTNO_CLRINT
144#define VALID_INTNO_CLRINT(intno) VALID_INTNO(intno)
145#endif /* VALID_INTNO_CLRINT */
146
147#ifndef VALID_INTNO_RASINT
148#define VALID_INTNO_RASINT(intno) VALID_INTNO(intno)
149#endif /* VALID_INTNO_RASINT */
150
151#ifndef VALID_INTNO_PRBINT
152#define VALID_INTNO_PRBINT(intno) VALID_INTNO(intno)
153#endif /* VALID_INTNO_PRBINT */
154
155#ifndef VALID_INTNO_CREISR
156#define VALID_INTNO_CREISR(intno) VALID_INTNO(intno)
157#endif /* VALID_INTNO_CREISR */
158
159/*
160 * 割込み優先度の範囲の判定
161 */
162#ifndef VALID_INTPRI_CHGIPM
163#define VALID_INTPRI_CHGIPM(intpri) \
164 (TMIN_INTPRI <= (intpri) && (intpri) <= TIPM_ENAALL)
165#endif /* VALID_INTPRI_CHGIPM */
166
167/*
168 * 割込みサービスルーチンの数
169 */
170#define tnum_isr ((uint_t)(tmax_isrid - TMIN_ISRID + 1))
171#define tnum_sisr ((uint_t)(tmax_sisrid - TMIN_ISRID + 1))
172
173/*
174 * 割込みサービスルーチンIDから割込みサービスルーチン管理ブロックを取
175 * り出すためのマクロ
176 */
177#define INDEX_ISR(isrid) ((uint_t)((isrid) - TMIN_ISRID))
178#define get_isrcb(isrid) (&(isrcb_table[INDEX_ISR(isrid)]))
179
180/*
181 * 割込みサービスルーチンキューへの登録
182 */
183Inline void
184enqueue_isr(QUEUE *p_isr_queue, ISRCB *p_isrcb)
185{
186 QUEUE *p_entry;
187 PRI isrpri = p_isrcb->p_isrinib->isrpri;
188
189 for (p_entry = p_isr_queue->p_next; p_entry != p_isr_queue;
190 p_entry = p_entry->p_next) {
191 if (isrpri < ((ISRCB *) p_entry)->p_isrinib->isrpri) {
192 break;
193 }
194 }
195 queue_insert_prev(p_entry, &(p_isrcb->isr_queue));
196}
197
198#ifdef TOPPERS_isrini
199
200/*
201 * 使用していない割込みサービスルーチン管理ブロックのリスト
202 */
203QUEUE free_isrcb;
204
205/*
206 * 割込みサービスルーチン機能の初期化
207 */
208void
209initialize_isr(void)
210{
211 uint_t i, j;
212 ISRCB *p_isrcb;
213 ISRINIB *p_isrinib;
214
215 for (i = 0; i < tnum_isr_queue; i++) {
216 queue_initialize(&(isr_queue_table[i]));
217 }
218 for (i = 0; i < tnum_sisr; i++) {
219 j = INDEX_ISR(isrorder_table[i]);
220 p_isrcb = &(isrcb_table[j]);
221 p_isrcb->p_isrinib = &(isrinib_table[j]);
222 enqueue_isr(p_isrcb->p_isrinib->p_isr_queue, p_isrcb);
223 }
224 queue_initialize(&free_isrcb);
225 for (j = 0; i < tnum_isr; i++, j++) {
226 p_isrcb = &(isrcb_table[i]);
227 p_isrinib = &(aisrinib_table[j]);
228 p_isrinib->isratr = TA_NOEXS;
229 p_isrcb->p_isrinib = ((const ISRINIB *) p_isrinib);
230 queue_insert_prev(&free_isrcb, &(p_isrcb->isr_queue));
231 }
232}
233
234#endif /* TOPPERS_isrini */
235
236/*
237 * 割込みサービスルーチンの呼出し
238 */
239#ifdef TOPPERS_isrcal
240
241void
242call_isr(QUEUE *p_isr_queue)
243{
244 QUEUE *p_queue;
245 ISRCB *p_isrcb;
246
247 for (p_queue = p_isr_queue->p_next; p_queue != p_isr_queue;
248 p_queue = p_queue->p_next) {
249 p_isrcb = (ISRCB *) p_queue;
250 LOG_ISR_ENTER(ISRID(p_isrcb));
251 (*(p_isrcb->p_isrinib->isr))(p_isrcb->p_isrinib->exinf);
252 LOG_ISR_LEAVE(ISRID(p_isrcb));
253
254 if (p_queue->p_next != p_isr_queue) {
255 /* ISRの呼出し前の状態に戻す */
256 if (sense_lock()) {
257 unlock_cpu();
258 }
259 }
260 }
261}
262
263#endif /* TOPPERS_isrcal */
264
265/*
266 * 割込みサービスルーチン呼出しキューの検索
267 */
268Inline QUEUE *
269search_isr_queue(INTNO intno)
270{
271 int_t left, right, i;
272
273 if (tnum_isr_queue == 0) {
274 return(NULL);
275 }
276
277 left = 0;
278 right = tnum_isr_queue - 1;
279 while (left < right) {
280 i = (left + right + 1) / 2;
281 if (intno < isr_queue_list[i].intno) {
282 right = i - 1;
283 }
284 else {
285 left = i;
286 }
287 }
288 if (isr_queue_list[left].intno == intno) {
289 return(isr_queue_list[left].p_isr_queue);
290 }
291 else {
292 return(NULL);
293 }
294}
295
296/*
297 * 割込みサービスルーチンの生成
298 *
299 * pk_cisr->exinfは,エラーチェックをせず,一度しか参照しないため,ロー
300 * カル変数にコピーする必要がない(途中で書き換わっても支障がない).
301 */
302#ifdef TOPPERS_acre_isr
303
304ER_UINT
305acre_isr(const T_CISR *pk_cisr)
306{
307 ISRCB *p_isrcb;
308 ISRINIB *p_isrinib;
309 QUEUE *p_isr_queue;
310 ATR isratr;
311 INTNO intno;
312 ISR isr;
313 PRI isrpri;
314 ER ercd;
315
316 LOG_ACRE_ISR_ENTER(pk_cisr);
317 CHECK_TSKCTX_UNL();
318
319 isratr = pk_cisr->isratr;
320 intno = pk_cisr->intno;
321 isr = pk_cisr->isr;
322 isrpri = pk_cisr->isrpri;
323
324 CHECK_RSATR(isratr, TARGET_ISRATR);
325 CHECK_PAR(VALID_INTNO_CREISR(intno));
326 CHECK_PAR(FUNC_ALIGN(isr));
327 CHECK_PAR(FUNC_NONNULL(isr));
328 CHECK_PAR(VALID_ISRPRI(isrpri));
329
330 p_isr_queue = search_isr_queue(intno);
331 CHECK_OBJ(p_isr_queue != NULL);
332
333 lock_cpu();
334 if (tnum_isr == 0 || queue_empty(&free_isrcb)) {
335 ercd = E_NOID;
336 }
337 else {
338 p_isrcb = ((ISRCB *) queue_delete_next(&free_isrcb));
339 p_isrinib = (ISRINIB *)(p_isrcb->p_isrinib);
340 p_isrinib->isratr = isratr;
341 p_isrinib->exinf = pk_cisr->exinf;
342 p_isrinib->p_isr_queue = p_isr_queue;
343 p_isrinib->isr = isr;
344 p_isrinib->isrpri = isrpri;
345 enqueue_isr(p_isr_queue, p_isrcb);
346 ercd = ISRID(p_isrcb);
347 }
348 unlock_cpu();
349
350 error_exit:
351 LOG_ACRE_ISR_LEAVE(ercd);
352 return(ercd);
353}
354
355#endif /* TOPPERS_acre_isr */
356
357/*
358 * 割込みサービスルーチンの削除
359 */
360#ifdef TOPPERS_del_isr
361
362ER
363del_isr(ID isrid)
364{
365 ISRCB *p_isrcb;
366 ISRINIB *p_isrinib;
367 ER ercd;
368
369 LOG_DEL_ISR_ENTER(isrid);
370 CHECK_TSKCTX_UNL();
371 CHECK_ID(VALID_ISRID(isrid));
372 p_isrcb = get_isrcb(isrid);
373
374 lock_cpu();
375 if (p_isrcb->p_isrinib->isratr == TA_NOEXS) {
376 ercd = E_NOEXS;
377 }
378 else if (isrid <= tmax_sisrid) {
379 ercd = E_OBJ;
380 }
381 else {
382 queue_delete(&(p_isrcb->isr_queue));
383 p_isrinib = (ISRINIB *)(p_isrcb->p_isrinib);
384 p_isrinib->isratr = TA_NOEXS;
385 queue_insert_prev(&free_isrcb, &(p_isrcb->isr_queue));
386 ercd = E_OK;
387 }
388 unlock_cpu();
389
390 error_exit:
391 LOG_DEL_ISR_LEAVE(ercd);
392 return(ercd);
393}
394
395#endif /* TOPPERS_del_isr */
396
397/*
398 * 割込み管理機能の初期化
399 */
400#ifdef TOPPERS_intini
401#ifndef OMIT_INITIALIZE_INTERRUPT
402
403void
404initialize_interrupt(void)
405{
406 uint_t i;
407 const INHINIB *p_inhinib;
408 const INTINIB *p_intinib;
409
410 for (i = 0; i < tnum_def_inhno; i++) {
411 p_inhinib = &(inhinib_table[i]);
412 define_inh(p_inhinib->inhno, p_inhinib->int_entry);
413 }
414 for (i = 0; i < tnum_cfg_intno; i++) {
415 p_intinib = &(intinib_table[i]);
416 config_int(p_intinib->intno, p_intinib->intatr, p_intinib->intpri);
417 }
418}
419
420#endif /* OMIT_INITIALIZE_INTERRUPT */
421#endif /* TOPPERS_intini */
422
423/*
424 * 割込みの禁止[NGKI3555]
425 */
426#ifdef TOPPERS_dis_int
427#ifdef TOPPERS_SUPPORT_DIS_INT /*[NGKI3093]*/
428
429ER
430dis_int(INTNO intno)
431{
432 bool_t locked;
433 ER ercd;
434
435 LOG_DIS_INT_ENTER(intno);
436 CHECK_PAR(VALID_INTNO_DISINT(intno)); /*[NGKI3083][NGKI3087]*/
437
438 locked = sense_lock();
439 if (!locked) {
440 lock_cpu();
441 }
442 if (check_intno_cfg(intno)) {
443 disable_int(intno); /*[NGKI3086]*/
444 ercd = E_OK;
445 }
446 else {
447 ercd = E_OBJ; /*[NGKI3085]*/
448 }
449 if (!locked) {
450 unlock_cpu();
451 }
452
453 error_exit:
454 LOG_DIS_INT_LEAVE(ercd);
455 return(ercd);
456}
457
458#endif /* TOPPERS_SUPPORT_DIS_INT */
459#endif /* TOPPERS_dis_int */
460
461/*
462 * 割込みの許可[NGKI3556]
463 */
464#ifdef TOPPERS_ena_int
465#ifdef TOPPERS_SUPPORT_ENA_INT /*[NGKI3106]*/
466
467ER
468ena_int(INTNO intno)
469{
470 bool_t locked;
471 ER ercd;
472
473 LOG_ENA_INT_ENTER(intno);
474 CHECK_PAR(VALID_INTNO_DISINT(intno)); /*[NGKI3096][NGKI3100]*/
475
476 locked = sense_lock();
477 if (!locked) {
478 lock_cpu();
479 }
480 if (check_intno_cfg(intno)) {
481 enable_int(intno); /*[NGKI3099]*/
482 ercd = E_OK;
483 }
484 else {
485 ercd = E_OBJ; /*[NGKI3098]*/
486 }
487 if (!locked) {
488 unlock_cpu();
489 }
490
491 error_exit:
492 LOG_ENA_INT_LEAVE(ercd);
493 return(ercd);
494}
495
496#endif /* TOPPERS_SUPPORT_ENA_INT */
497#endif /* TOPPERS_ena_int */
498
499/*
500 * 割込み要求のクリア[NGKI3920]
501 */
502#ifdef TOPPERS_clr_int
503#ifdef TOPPERS_SUPPORT_CLR_INT /*[NGKI3927]*/
504
505ER
506clr_int(INTNO intno)
507{
508 bool_t locked;
509 ER ercd;
510
511 LOG_CLR_INT_ENTER(intno);
512 CHECK_PAR(VALID_INTNO_CLRINT(intno)); /*[NGKI3921][NGKI3930]*/
513
514 locked = sense_lock();
515 if (!locked) {
516 lock_cpu();
517 }
518 if (check_intno_cfg(intno) && check_intno_clear(intno)) {
519 clear_int(intno); /*[NGKI3924]*/
520 ercd = E_OK;
521 }
522 else {
523 ercd = E_OBJ; /*[NGKI3923][NGKI3929]*/
524 }
525 if (!locked) {
526 unlock_cpu();
527 }
528
529 error_exit:
530 LOG_CLR_INT_LEAVE(ercd);
531 return(ercd);
532}
533
534#endif /* TOPPERS_SUPPORT_CLR_INT */
535#endif /* TOPPERS_clr_int */
536
537/*
538 * 割込みの要求[NGKI3932]
539 */
540#ifdef TOPPERS_ras_int
541#ifdef TOPPERS_SUPPORT_RAS_INT /*[NGKI3939]*/
542
543ER
544ras_int(INTNO intno)
545{
546 bool_t locked;
547 ER ercd;
548
549 LOG_RAS_INT_ENTER(intno);
550 CHECK_PAR(VALID_INTNO_RASINT(intno)); /*[NGKI3933][NGKI3942]*/
551
552 locked = sense_lock();
553 if (!locked) {
554 lock_cpu();
555 }
556 if (check_intno_cfg(intno) && check_intno_raise(intno)) {
557 raise_int(intno); /*[NGKI3936]*/
558 ercd = E_OK;
559 }
560 else {
561 ercd = E_OBJ; /*[NGKI3935][NGKI3941]*/
562 }
563 if (!locked) {
564 unlock_cpu();
565 }
566
567 error_exit:
568 LOG_RAS_INT_LEAVE(ercd);
569 return(ercd);
570}
571
572#endif /* TOPPERS_SUPPORT_RAS_INT */
573#endif /* TOPPERS_ras_int */
574
575/*
576 * 割込み要求のチェック[NGKI3944]
577 */
578#ifdef TOPPERS_prb_int
579#ifdef TOPPERS_SUPPORT_PRB_INT /*[NGKI3951]*/
580
581ER_BOOL
582prb_int(INTNO intno)
583{
584 bool_t locked;
585 ER ercd;
586
587 LOG_PRB_INT_ENTER(intno);
588 CHECK_PAR(VALID_INTNO_PRBINT(intno)); /*[NGKI3945][NGKI3952]*/
589
590 locked = sense_lock();
591 if (!locked) {
592 lock_cpu();
593 }
594 if (check_intno_cfg(intno)) {
595 ercd = (ER_BOOL) probe_int(intno); /*[NGKI3948]*/
596 }
597 else {
598 ercd = E_OBJ; /*[NGKI3947]*/
599 }
600 if (!locked) {
601 unlock_cpu();
602 }
603
604 error_exit:
605 LOG_PRB_INT_LEAVE(ercd);
606 return(ercd);
607}
608
609#endif /* TOPPERS_SUPPORT_PRB_INT */
610#endif /* TOPPERS_prb_int */
611
612/*
613 * 割込み優先度マスクの変更[NGKI3107]
614 */
615#ifdef TOPPERS_chg_ipm
616
617ER
618chg_ipm(PRI intpri)
619{
620 ER ercd;
621
622 LOG_CHG_IPM_ENTER(intpri);
623 CHECK_TSKCTX_UNL(); /*[NGKI3108][NGKI3109]*/
624 CHECK_PAR(VALID_INTPRI_CHGIPM(intpri)); /*[NGKI3113][NGKI3114]*/
625
626 lock_cpu();
627 t_set_ipm(intpri); /*[NGKI3111]*/
628 if (intpri == TIPM_ENAALL && enadsp) {
629 dspflg = true;
630 p_schedtsk = search_schedtsk();
631 if (p_runtsk->raster && p_runtsk->enater) {
632#ifdef TOPPERS_SUPPORT_OVRHDR
633 if (p_runtsk->staovr) {
634 (void) target_ovrtimer_stop(INTNO_DUMMY_TIMER);
635 ovrtimer_flag = false;
636 }
637#endif /* TOPPERS_SUPPORT_OVRHDR */
638 task_terminate(p_runtsk);
639 exit_and_dispatch();
640 ercd = E_SYS;
641 }
642 else {
643 if (p_runtsk != p_schedtsk) {
644 dispatch();
645 }
646 ercd = E_OK;
647 }
648 }
649 else {
650 dspflg = false;
651 ercd = E_OK;
652 }
653 unlock_cpu();
654
655 error_exit:
656 LOG_CHG_IPM_LEAVE(ercd);
657 return(ercd);
658}
659
660#endif /* TOPPERS_chg_ipm */
661
662/*
663 * 割込み優先度マスクの参照[NGKI3115]
664 */
665#ifdef TOPPERS_get_ipm
666
667ER
668get_ipm(PRI *p_intpri)
669{
670 ER ercd;
671
672 LOG_GET_IPM_ENTER(p_intpri);
673 CHECK_TSKCTX_UNL(); /*[NGKI3116][NGKI3117]*/
674
675 lock_cpu();
676 *p_intpri = t_get_ipm(); /*[NGKI3120]*/
677 ercd = E_OK;
678 unlock_cpu();
679
680 error_exit:
681 LOG_GET_IPM_LEAVE(ercd, p_intpri);
682 return(ercd);
683}
684
685#endif /* TOPPERS_get_ipm */
Note: See TracBrowser for help on using the repository browser.