source: EcnlProtoTool/trunk/asp3_dcre/kernel/interrupt.c@ 270

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

mruby版ECNLプロトタイピング・ツールを追加

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-csrc
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) 2000-2003 by Embedded and Real-Time Systems Laboratory
7 * Toyohashi Univ. of Technology, JAPAN
8 * Copyright (C) 2005-2016 by Embedded and Real-Time Systems Laboratory
9 * Graduate School of Information Science, Nagoya Univ., JAPAN
10 *
11 * 上記著作権者
12は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
13 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
14 * 変・再é…
15å¸ƒï¼ˆä»¥ä¸‹ï¼Œåˆ©ç”¨ã¨å‘¼ã¶ï¼‰ã™ã‚‹ã“とを無償で許諾する.
16 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
17 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
18 * スコード中に含まれていること.
19 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
20 * 用できる形で再é…
21å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œå†é…
22å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨
23 * 者
24マニュアルなど)に,上記の著作権表示,この利用条件および下記
25 * の無保証規定を掲載すること.
26 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
27 * 用できない形で再é…
28å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œæ¬¡ã®ã„ずれかの条件を満たすこ
29 * と.
30 * (a) 再é…
31å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨è€…
32マニュアルなど)に,上記の著
33 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
34 * (b) 再é…
35å¸ƒã®å½¢æ…
36‹ã‚’,別に定める方法によって,TOPPERSプロジェクトに
37 * 報告すること.
38 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
39 * 害からも,上記著作権者
40およびTOPPERSプロジェクトをå…
41è²¬ã™ã‚‹ã“と.
42 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
43 * 由に基づく請求からも,上記著作権者
44およびTOPPERSプロジェクトを
45 * å…
46è²¬ã™ã‚‹ã“と.
47 *
48 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者
49お
50 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
51 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
52 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
53 * の責任を負わない.
54 *
55 * $Id: interrupt.c 270 2017-02-09 04:03:47Z coas-nagasima $
56 */
57
58/*
59 * 割込み管理機能
60 */
61
62#include "kernel_impl.h"
63#include "check.h"
64#include "task.h"
65#include "interrupt.h"
66
67/*
68 * トレースログマクロのデフォルト定義
69 */
70#ifndef LOG_ISR_ENTER
71#define LOG_ISR_ENTER(isrid)
72#endif /* LOG_ISR_ENTER */
73
74#ifndef LOG_ISR_LEAVE
75#define LOG_ISR_LEAVE(isrid)
76#endif /* LOG_ISR_LEAVE */
77
78#ifndef LOG_ACRE_ISR_ENTER
79#define LOG_ACRE_ISR_ENTER(pk_cisr)
80#endif /* LOG_ACRE_ISR_ENTER */
81
82#ifndef LOG_ACRE_ISR_LEAVE
83#define LOG_ACRE_ISR_LEAVE(ercd)
84#endif /* LOG_ACRE_ISR_LEAVE */
85
86#ifndef LOG_DEL_ISR_ENTER
87#define LOG_DEL_ISR_ENTER(isrid)
88#endif /* LOG_DEL_ISR_ENTER */
89
90#ifndef LOG_DEL_ISR_LEAVE
91#define LOG_DEL_ISR_LEAVE(ercd)
92#endif /* LOG_DEL_ISR_LEAVE */
93
94#ifndef LOG_DIS_INT_ENTER
95#define LOG_DIS_INT_ENTER(intno)
96#endif /* LOG_DIS_INT_ENTER */
97
98#ifndef LOG_DIS_INT_LEAVE
99#define LOG_DIS_INT_LEAVE(ercd)
100#endif /* LOG_DIS_INT_LEAVE */
101
102#ifndef LOG_ENA_INT_ENTER
103#define LOG_ENA_INT_ENTER(intno)
104#endif /* LOG_ENA_INT_ENTER */
105
106#ifndef LOG_ENA_INT_LEAVE
107#define LOG_ENA_INT_LEAVE(ercd)
108#endif /* LOG_ENA_INT_LEAVE */
109
110#ifndef LOG_CHG_IPM_ENTER
111#define LOG_CHG_IPM_ENTER(intpri)
112#endif /* LOG_CHG_IPM_ENTER */
113
114#ifndef LOG_CHG_IPM_LEAVE
115#define LOG_CHG_IPM_LEAVE(ercd)
116#endif /* LOG_CHG_IPM_LEAVE */
117
118#ifndef LOG_GET_IPM_ENTER
119#define LOG_GET_IPM_ENTER(p_intpri)
120#endif /* LOG_GET_IPM_ENTER */
121
122#ifndef LOG_GET_IPM_LEAVE
123#define LOG_GET_IPM_LEAVE(ercd, p_intpri)
124#endif /* LOG_GET_IPM_LEAVE */
125
126/*
127 * 割込みサービスルーチンの数
128 */
129#define tnum_isr ((uint_t)(tmax_isrid - TMIN_ISRID + 1))
130#define tnum_sisr ((uint_t)(tmax_sisrid - TMIN_ISRID + 1))
131
132/*
133 * 割込みサービスルーチンIDから割込みサービスルーチン管理ブロックを取
134 * り出すためのマクロ
135 */
136#define INDEX_ISR(isrid) ((uint_t)((isrid) - TMIN_ISRID))
137#define get_isrcb(isrid) (&(isrcb_table[INDEX_ISR(isrid)]))
138
139/*
140 * 割込みサービスルーチンキューへの登録
141 */
142Inline void
143enqueue_isr(QUEUE *p_isr_queue, ISRCB *p_isrcb)
144{
145 QUEUE *p_entry;
146 PRI isrpri = p_isrcb->p_isrinib->isrpri;
147
148 for (p_entry = p_isr_queue->p_next; p_entry != p_isr_queue;
149 p_entry = p_entry->p_next) {
150 if (isrpri < ((ISRCB *) p_entry)->p_isrinib->isrpri) {
151 break;
152 }
153 }
154 queue_insert_prev(p_entry, &(p_isrcb->isr_queue));
155}
156
157#ifdef TOPPERS_isrini
158
159/*
160 * 使用していない割込みサービスルーチン管理ブロックのリスト
161 */
162QUEUE free_isrcb;
163
164/*
165 * 割込みサービスルーチン機能の初期化
166 */
167void
168initialize_isr(void)
169{
170 uint_t i, j;
171 ISRCB *p_isrcb;
172 ISRINIB *p_isrinib;
173
174 for (i = 0; i < tnum_isr_queue; i++) {
175 queue_initialize(&(isr_queue_table[i]));
176 }
177 for (i = 0; i < tnum_sisr; i++) {
178 j = INDEX_ISR(isrorder_table[i]);
179 p_isrcb = &(isrcb_table[j]);
180 p_isrcb->p_isrinib = &(isrinib_table[j]);
181 enqueue_isr(p_isrcb->p_isrinib->p_isr_queue, p_isrcb);
182 }
183 queue_initialize(&free_isrcb);
184 for (j = 0; i < tnum_isr; i++, j++) {
185 p_isrcb = &(isrcb_table[i]);
186 p_isrinib = &(aisrinib_table[j]);
187 p_isrinib->isratr = TA_NOEXS;
188 p_isrcb->p_isrinib = ((const ISRINIB *) p_isrinib);
189 queue_insert_prev(&free_isrcb, &(p_isrcb->isr_queue));
190 }
191}
192
193#endif /* TOPPERS_isrini */
194
195/*
196 * 割込みサービスルーチンの呼出し
197 */
198#ifdef TOPPERS_isrcal
199
200void
201call_isr(QUEUE *p_isr_queue)
202{
203 QUEUE *p_queue;
204 ISRCB *p_isrcb;
205
206 for (p_queue = p_isr_queue->p_next; p_queue != p_isr_queue;
207 p_queue = p_queue->p_next) {
208 p_isrcb = (ISRCB *) p_queue;
209 LOG_ISR_ENTER(ISRID(p_isrcb));
210 (*(p_isrcb->p_isrinib->isr))(p_isrcb->p_isrinib->exinf);
211 LOG_ISR_LEAVE(ISRID(p_isrcb));
212
213 if (p_queue->p_next != p_isr_queue) {
214 /* ISRの呼出し前の状æ…
215‹ã«æˆ»ã™ */
216 if (sense_lock()) {
217 unlock_cpu();
218 }
219 }
220 }
221}
222
223#endif /* TOPPERS_isrcal */
224
225/*
226 * 割込みサービスルーチン呼出しキューの検索
227 */
228Inline QUEUE *
229search_isr_queue(INTNO intno)
230{
231 int_t left, right, i;
232
233 if (tnum_isr_queue == 0) {
234 return(NULL);
235 }
236
237 left = 0;
238 right = tnum_isr_queue - 1;
239 while (left < right) {
240 i = (left + right + 1) / 2;
241 if (intno < isr_queue_list[i].intno) {
242 right = i - 1;
243 }
244 else {
245 left = i;
246 }
247 }
248 if (isr_queue_list[left].intno == intno) {
249 return(isr_queue_list[left].p_isr_queue);
250 }
251 else {
252 return(NULL);
253 }
254}
255
256/*
257 * 割込みサービスルーチンの生成
258 *
259 * pk_cisr->exinfは,エラーチェックをせず,一度しか参ç…
260§ã—ないため,ロー
261 * カル変数にコピーする必
262要がない(途中で書き換わっても支障がない).
263 */
264#ifdef TOPPERS_acre_isr
265
266ER_UINT
267acre_isr(const T_CISR *pk_cisr)
268{
269 ISRCB *p_isrcb;
270 ISRINIB *p_isrinib;
271 QUEUE *p_isr_queue;
272 ATR isratr;
273 INTNO intno;
274 ISR isr;
275 PRI isrpri;
276 ER ercd;
277
278 LOG_ACRE_ISR_ENTER(pk_cisr);
279 CHECK_TSKCTX_UNL();
280
281 isratr = pk_cisr->isratr;
282 intno = pk_cisr->intno;
283 isr = pk_cisr->isr;
284 isrpri = pk_cisr->isrpri;
285
286 CHECK_RSATR(isratr, TARGET_ISRATR);
287 CHECK_PAR(VALID_INTNO_CREISR(intno));
288 CHECK_PAR(FUNC_ALIGN(isr));
289 CHECK_PAR(FUNC_NONNULL(isr));
290 CHECK_PAR(VALID_ISRPRI(isrpri));
291
292 p_isr_queue = search_isr_queue(intno);
293 CHECK_OBJ(p_isr_queue != NULL);
294
295 lock_cpu();
296 if (tnum_isr == 0 || queue_empty(&free_isrcb)) {
297 ercd = E_NOID;
298 }
299 else {
300 p_isrcb = ((ISRCB *) queue_delete_next(&free_isrcb));
301 p_isrinib = (ISRINIB *)(p_isrcb->p_isrinib);
302 p_isrinib->isratr = isratr;
303 p_isrinib->exinf = pk_cisr->exinf;
304 p_isrinib->p_isr_queue = p_isr_queue;
305 p_isrinib->isr = isr;
306 p_isrinib->isrpri = isrpri;
307 enqueue_isr(p_isr_queue, p_isrcb);
308 ercd = ISRID(p_isrcb);
309 }
310 unlock_cpu();
311
312 error_exit:
313 LOG_ACRE_ISR_LEAVE(ercd);
314 return(ercd);
315}
316
317#endif /* TOPPERS_acre_isr */
318
319/*
320 * 割込みサービスルーチンの削除
321 */
322#ifdef TOPPERS_del_isr
323
324ER
325del_isr(ID isrid)
326{
327 ISRCB *p_isrcb;
328 ISRINIB *p_isrinib;
329 ER ercd;
330
331 LOG_DEL_ISR_ENTER(isrid);
332 CHECK_TSKCTX_UNL();
333 CHECK_ID(VALID_ISRID(isrid));
334 p_isrcb = get_isrcb(isrid);
335
336 lock_cpu();
337 if (p_isrcb->p_isrinib->isratr == TA_NOEXS) {
338 ercd = E_NOEXS;
339 }
340 else if (isrid <= tmax_sisrid) {
341 ercd = E_OBJ;
342 }
343 else {
344 queue_delete(&(p_isrcb->isr_queue));
345 p_isrinib = (ISRINIB *)(p_isrcb->p_isrinib);
346 p_isrinib->isratr = TA_NOEXS;
347 queue_insert_prev(&free_isrcb, &(p_isrcb->isr_queue));
348 ercd = E_OK;
349 }
350 unlock_cpu();
351
352 error_exit:
353 LOG_DEL_ISR_LEAVE(ercd);
354 return(ercd);
355}
356
357#endif /* TOPPERS_del_isr */
358
359/*
360 * 割込み管理機能の初期化
361 */
362#ifdef TOPPERS_intini
363#ifndef OMIT_INITIALIZE_INTERRUPT
364
365void
366initialize_interrupt(void)
367{
368 uint_t i;
369 const INHINIB *p_inhinib;
370 const INTINIB *p_intinib;
371
372 for (i = 0; i < tnum_def_inhno; i++) {
373 p_inhinib = &(inhinib_table[i]);
374 define_inh(p_inhinib->inhno, p_inhinib->int_entry);
375 }
376 for (i = 0; i < tnum_cfg_intno; i++) {
377 p_intinib = &(intinib_table[i]);
378 config_int(p_intinib->intno, p_intinib->intatr, p_intinib->intpri);
379 }
380}
381
382#endif /* OMIT_INITIALIZE_INTERRUPT */
383#endif /* TOPPERS_intini */
384
385/*
386 * 割込みの禁止[NGKI3555]
387 */
388#ifdef TOPPERS_dis_int
389#ifdef TOPPERS_SUPPORT_DIS_INT /*ï¼»NGKI3093ï¼½*/
390
391ER
392dis_int(INTNO intno)
393{
394 bool_t locked;
395 ER ercd;
396
397 LOG_DIS_INT_ENTER(intno);
398 CHECK_PAR(VALID_INTNO_DISINT(intno)); /*[NGKI3083][NGKI3087]*/
399
400 locked = sense_lock();
401 if (!locked) {
402 lock_cpu();
403 }
404 if (disable_int(intno)) { /*ï¼»NGKI3086ï¼½*/
405 ercd = E_OK;
406 }
407 else {
408 ercd = E_OBJ; /*ï¼»NGKI3085ï¼½*/
409 }
410 if (!locked) {
411 unlock_cpu();
412 }
413
414 error_exit:
415 LOG_DIS_INT_LEAVE(ercd);
416 return(ercd);
417}
418
419#endif /* TOPPERS_SUPPORT_DIS_INT */
420#endif /* TOPPERS_dis_int */
421
422/*
423 * 割込みの許可[NGKI3556]
424 */
425#ifdef TOPPERS_ena_int
426#ifdef TOPPERS_SUPPORT_ENA_INT /*ï¼»NGKI3106ï¼½*/
427
428ER
429ena_int(INTNO intno)
430{
431 bool_t locked;
432 ER ercd;
433
434 LOG_ENA_INT_ENTER(intno);
435 CHECK_PAR(VALID_INTNO_DISINT(intno)); /*[NGKI3096][NGKI3100]*/
436
437 locked = sense_lock();
438 if (!locked) {
439 lock_cpu();
440 }
441 if (enable_int(intno)) { /*ï¼»NGKI3099ï¼½*/
442 ercd = E_OK;
443 }
444 else {
445 ercd = E_OBJ; /*ï¼»NGKI3098ï¼½*/
446 }
447 if (!locked) {
448 unlock_cpu();
449 }
450
451 error_exit:
452 LOG_ENA_INT_LEAVE(ercd);
453 return(ercd);
454}
455
456#endif /* TOPPERS_SUPPORT_ENA_INT */
457#endif /* TOPPERS_ena_int */
458
459/*
460 * 割込み優å…
461ˆåº¦ãƒžã‚¹ã‚¯ã®å¤‰æ›´ï¼»NGKI3107ï¼½
462 */
463#ifdef TOPPERS_chg_ipm
464
465ER
466chg_ipm(PRI intpri)
467{
468 ER ercd;
469
470 LOG_CHG_IPM_ENTER(intpri);
471 CHECK_TSKCTX_UNL(); /*[NGKI3108][NGKI3109]*/
472 CHECK_PAR(VALID_INTPRI_CHGIPM(intpri)); /*[NGKI3113][NGKI3114]*/
473
474 lock_cpu();
475 t_set_ipm(intpri); /*ï¼»NGKI3111ï¼½*/
476 if (intpri == TIPM_ENAALL && enadsp) {
477 dspflg = true;
478 p_schedtsk = search_schedtsk();
479 if (p_runtsk->raster && p_runtsk->enater) {
480 task_terminate(p_runtsk);
481 exit_and_dispatch();
482 ercd = E_SYS;
483 }
484 else {
485 if (p_runtsk != p_schedtsk) {
486 dispatch();
487 }
488 ercd = E_OK;
489 }
490 }
491 else {
492 dspflg = false;
493 ercd = E_OK;
494 }
495 unlock_cpu();
496
497 error_exit:
498 LOG_CHG_IPM_LEAVE(ercd);
499 return(ercd);
500}
501
502#endif /* TOPPERS_chg_ipm */
503
504/*
505 * 割込み優å…
506ˆåº¦ãƒžã‚¹ã‚¯ã®å‚ç…
507§ï¼»NGKI3115ï¼½
508 */
509#ifdef TOPPERS_get_ipm
510
511ER
512get_ipm(PRI *p_intpri)
513{
514 ER ercd;
515
516 LOG_GET_IPM_ENTER(p_intpri);
517 CHECK_TSKCTX_UNL(); /*[NGKI3116][NGKI3117]*/
518
519 lock_cpu();
520 *p_intpri = t_get_ipm(); /*ï¼»NGKI3120ï¼½*/
521 ercd = E_OK;
522 unlock_cpu();
523
524 error_exit:
525 LOG_GET_IPM_LEAVE(ercd, p_intpri);
526 return(ercd);
527}
528
529#endif /* TOPPERS_get_ipm */
Note: See TracBrowser for help on using the repository browser.