source: rubycfg_asp/trunk/asp_dcre/kernel/interrupt.c@ 313

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

ソースを追加

  • 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.1 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-2012 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 313 2017-07-23 04:50:32Z 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(intno)
72#endif /* LOG_ISR_ENTER */
73
74#ifndef LOG_ISR_LEAVE
75#define LOG_ISR_LEAVE(intno)
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, intpri)
124#endif /* LOG_GET_IPM_LEAVE */
125
126/*
127 * 割込みサービスルーチンの数
128 */
129#define tnum_isr ((uint_t)(tmax_isrid - TMIN_ISRID + 1) + tnum_sisr)
130
131/*
132 * 割込みサービスルーチンIDから割込みサービスルーチン管理ブロックを取
133 * り出すためのマクロ
134 */
135#define INDEX_ISR(isrid) ((uint_t)((isrid) - TMIN_ISRID) + tnum_sisr)
136#define get_isrcb(isrid) (&(isrcb_table[INDEX_ISR(isrid)]))
137
138/*
139 * 割込みサービスルーチンキューへの登録
140 */
141Inline void
142enqueue_isr(QUEUE *p_isr_queue, ISRCB *p_isrcb)
143{
144 QUEUE *p_entry;
145 PRI isrpri = p_isrcb->p_isrinib->isrpri;
146
147 for (p_entry = p_isr_queue->p_next; p_entry != p_isr_queue;
148 p_entry = p_entry->p_next) {
149 if (isrpri < ((ISRCB *) p_entry)->p_isrinib->isrpri) {
150 break;
151 }
152 }
153 queue_insert_prev(p_entry, &(p_isrcb->isr_queue));
154}
155
156#ifdef TOPPERS_isrini
157
158/*
159 * 使用していない割込みサービスルーチン管理ブロックのリスト
160 */
161QUEUE free_isrcb;
162
163/*
164 * 割込みサービスルーチン機能の初期化
165 */
166void
167initialize_isr(void)
168{
169 uint_t i, j;
170 ISRCB *p_isrcb;
171 ISRINIB *p_isrinib;
172
173 for (i = 0; i < tnum_isr_queue; i++) {
174 queue_initialize(&(isr_queue_table[i]));
175 }
176 for (i = 0; i < tnum_sisr; i++) {
177 p_isrcb = &(isrcb_table[i]);
178 p_isrcb->p_isrinib = &(sisrinib_table[i]);
179 enqueue_isr(p_isrcb->p_isrinib->p_isr_queue, p_isrcb);
180 }
181 queue_initialize(&free_isrcb);
182 for (j = 0; i < tnum_isr; i++, j++) {
183 p_isrcb = &(isrcb_table[i]);
184 p_isrinib = &(aisrinib_table[j]);
185 p_isrinib->isratr = TA_NOEXS;
186 p_isrcb->p_isrinib = ((const ISRINIB *) p_isrinib);
187 queue_insert_prev(&free_isrcb, &(p_isrcb->isr_queue));
188 }
189}
190
191#endif /* TOPPERS_isrini */
192
193/*
194 * 割込みサービスルーチンの呼出し
195 */
196#ifdef TOPPERS_isrcal
197
198void
199call_isr(QUEUE *p_isr_queue)
200{
201 QUEUE *p_queue;
202 ISRINIB *p_isrinib;
203 PRI saved_ipm;
204
205 saved_ipm = i_get_ipm();
206 for (p_queue = p_isr_queue->p_next; p_queue != p_isr_queue;
207 p_queue = p_queue->p_next) {
208 p_isrinib = (ISRINIB *)(((ISRCB *) p_queue)->p_isrinib);
209 LOG_ISR_ENTER(p_isrinib->intno);
210 (*(p_isrinib->isr))(p_isrinib->exinf);
211 LOG_ISR_LEAVE(p_isrinib->intno);
212
213 if (p_queue->p_next != p_isr_queue) {
214 /* ISRの呼出し前の状æ…
215‹ã«æˆ»ã™ */
216 if (i_sense_lock()) {
217 i_unlock_cpu();
218 }
219 i_set_ipm(saved_ipm);
220 }
221 }
222}
223
224#endif /* TOPPERS_isrcal */
225
226/*
227 * 割込みサービスルーチン呼出しキューの検索
228 */
229Inline QUEUE *
230search_isr_queue(INTNO intno)
231{
232 int_t left, right, i;
233
234 if (tnum_isr_queue == 0) {
235 return(NULL);
236 }
237
238 left = 0;
239 right = tnum_isr_queue - 1;
240 while (left < right) {
241 i = (left + right + 1) / 2;
242 if (intno < isr_queue_list[i].intno) {
243 right = i - 1;
244 }
245 else {
246 left = i;
247 }
248 }
249 if (isr_queue_list[left].intno == intno) {
250 return(isr_queue_list[left].p_isr_queue);
251 }
252 else {
253 return(NULL);
254 }
255}
256
257/*
258 * 割込みサービスルーチンの生成
259 */
260#ifdef TOPPERS_acre_isr
261
262ER_UINT
263acre_isr(const T_CISR *pk_cisr)
264{
265 ISRCB *p_isrcb;
266 ISRINIB *p_isrinib;
267 QUEUE *p_isr_queue;
268 ER ercd;
269
270 LOG_ACRE_ISR_ENTER(pk_cisr);
271 CHECK_TSKCTX_UNL();
272 CHECK_RSATR(pk_cisr->isratr, TARGET_ISRATR);
273 CHECK_INTNO_CREISR(pk_cisr->intno);
274 CHECK_ALIGN_FUNC(pk_cisr->isr);
275 CHECK_NONNULL_FUNC(pk_cisr->isr);
276 CHECK_ISRPRI(pk_cisr->isrpri);
277
278 p_isr_queue = search_isr_queue(pk_cisr->intno);
279 CHECK_OBJ(p_isr_queue != NULL);
280
281 t_lock_cpu();
282 if (tnum_isr == 0 || queue_empty(&free_isrcb)) {
283 ercd = E_NOID;
284 }
285 else {
286 p_isrcb = ((ISRCB *) queue_delete_next(&free_isrcb));
287 p_isrinib = (ISRINIB *)(p_isrcb->p_isrinib);
288 p_isrinib->isratr = pk_cisr->isratr;
289 p_isrinib->exinf = pk_cisr->exinf;
290 p_isrinib->intno = pk_cisr->intno;
291 p_isrinib->p_isr_queue = p_isr_queue;
292 p_isrinib->isr = pk_cisr->isr;
293 p_isrinib->isrpri = pk_cisr->isrpri;
294 enqueue_isr(p_isr_queue, p_isrcb);
295 ercd = ISRID(p_isrcb);
296 }
297 t_unlock_cpu();
298
299 error_exit:
300 LOG_ACRE_ISR_LEAVE(ercd);
301 return(ercd);
302}
303
304#endif /* TOPPERS_acre_isr */
305
306/*
307 * 割込みサービスルーチンの削除
308 */
309#ifdef TOPPERS_del_isr
310
311ER
312del_isr(ID isrid)
313{
314 ISRCB *p_isrcb;
315 ISRINIB *p_isrinib;
316 ER ercd;
317
318 LOG_DEL_ISR_ENTER(isrid);
319 CHECK_TSKCTX_UNL();
320 CHECK_ISRID(isrid);
321 p_isrcb = get_isrcb(isrid);
322
323 t_lock_cpu();
324 if (p_isrcb->p_isrinib->isratr == TA_NOEXS) {
325 ercd = E_NOEXS;
326 }
327 else {
328 queue_delete(&(p_isrcb->isr_queue));
329 p_isrinib = (ISRINIB *)(p_isrcb->p_isrinib);
330 p_isrinib->isratr = TA_NOEXS;
331 queue_insert_prev(&free_isrcb, &(p_isrcb->isr_queue));
332 ercd = E_OK;
333 }
334 t_unlock_cpu();
335
336 error_exit:
337 LOG_DEL_ISR_LEAVE(ercd);
338 return(ercd);
339}
340
341#endif /* TOPPERS_del_isr */
342
343/*
344 * 割込み管理機能の初期化
345 */
346#ifdef TOPPERS_intini
347#ifndef OMIT_INITIALIZE_INTERRUPT
348
349void
350initialize_interrupt(void)
351{
352 uint_t i;
353 const INHINIB *p_inhinib;
354 const INTINIB *p_intinib;
355
356 for (i = 0; i < tnum_inhno; i++) {
357 p_inhinib = &(inhinib_table[i]);
358 x_define_inh(p_inhinib->inhno, p_inhinib->int_entry);
359 }
360 for (i = 0; i < tnum_intno; i++) {
361 p_intinib = &(intinib_table[i]);
362 x_config_int(p_intinib->intno, p_intinib->intatr, p_intinib->intpri);
363 }
364}
365
366#endif /* OMIT_INITIALIZE_INTERRUPT */
367#endif /* TOPPERS_intini */
368
369/*
370 * 割込みの禁止
371 */
372#ifdef TOPPERS_dis_int
373#ifdef TOPPERS_SUPPORT_DIS_INT
374
375ER
376dis_int(INTNO intno)
377{
378 bool_t locked;
379 ER ercd;
380
381 LOG_DIS_INT_ENTER(intno);
382 CHECK_TSKCTX();
383 CHECK_INTNO_DISINT(intno);
384
385 locked = t_sense_lock();
386 if (!locked) {
387 t_lock_cpu();
388 }
389 if (t_disable_int(intno)) {
390 ercd = E_OK;
391 }
392 else {
393 ercd = E_OBJ;
394 }
395 if (!locked) {
396 t_unlock_cpu();
397 }
398
399 error_exit:
400 LOG_DIS_INT_LEAVE(ercd);
401 return(ercd);
402}
403
404#endif /* TOPPERS_SUPPORT_DIS_INT */
405#endif /* TOPPERS_dis_int */
406
407/*
408 * 割込みの許可
409 */
410#ifdef TOPPERS_ena_int
411#ifdef TOPPERS_SUPPORT_ENA_INT
412
413ER
414ena_int(INTNO intno)
415{
416 bool_t locked;
417 ER ercd;
418
419 LOG_ENA_INT_ENTER(intno);
420 CHECK_TSKCTX();
421 CHECK_INTNO_DISINT(intno);
422
423 locked = t_sense_lock();
424 if (!locked) {
425 t_lock_cpu();
426 }
427 if (t_enable_int(intno)) {
428 ercd = E_OK;
429 }
430 else {
431 ercd = E_OBJ;
432 }
433 if (!locked) {
434 t_unlock_cpu();
435 }
436
437 error_exit:
438 LOG_ENA_INT_LEAVE(ercd);
439 return(ercd);
440}
441
442#endif /* TOPPERS_SUPPORT_ENA_INT */
443#endif /* TOPPERS_ena_int */
444
445/*
446 * 割込み優å…
447ˆåº¦ãƒžã‚¹ã‚¯ã®å¤‰æ›´
448 */
449#ifdef TOPPERS_chg_ipm
450
451ER
452chg_ipm(PRI intpri)
453{
454 ER ercd;
455
456 LOG_CHG_IPM_ENTER(intpri);
457 CHECK_TSKCTX_UNL();
458 CHECK_INTPRI_CHGIPM(intpri);
459
460 t_lock_cpu();
461 t_set_ipm(intpri);
462 if (intpri == TIPM_ENAALL) {
463 ipmflg = true;
464 if (!disdsp) {
465 dspflg = true;
466 if (p_runtsk != p_schedtsk) {
467 dispatch();
468 }
469 }
470 if (p_runtsk->enatex && p_runtsk->texptn != 0U) {
471 call_texrtn();
472 }
473 }
474 else {
475 ipmflg = false;
476 dspflg = false;
477 }
478 ercd = E_OK;
479 t_unlock_cpu();
480
481 error_exit:
482 LOG_CHG_IPM_LEAVE(ercd);
483 return(ercd);
484}
485
486#endif /* TOPPERS_chg_ipm */
487
488/*
489 * 割込み優å…
490ˆåº¦ãƒžã‚¹ã‚¯ã®å‚ç…
491§
492 */
493#ifdef TOPPERS_get_ipm
494
495ER
496get_ipm(PRI *p_intpri)
497{
498 ER ercd;
499
500 LOG_GET_IPM_ENTER(p_intpri);
501 CHECK_TSKCTX_UNL();
502
503 t_lock_cpu();
504 *p_intpri = t_get_ipm();
505 ercd = E_OK;
506 t_unlock_cpu();
507
508 error_exit:
509 LOG_GET_IPM_LEAVE(ercd, *p_intpri);
510 return(ercd);
511}
512
513#endif /* TOPPERS_get_ipm */
Note: See TracBrowser for help on using the repository browser.