source: azure_iot_hub/trunk/asp3_dcre/kernel/interrupt.c@ 389

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

ビルドが通るよう更新

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