source: asp_wo_cfg/trunk/kernel/interrupt.c@ 50

Last change on this file since 50 was 50, checked in by ertl-hiro, 12 years ago

ターゲット依存のエラーチェックコードを追加。

  • Property svn:keywords set to Id
File size: 10.6 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 * 上記著作権者は,以下の(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: interrupt.c 50 2012-09-07 03:47:18Z ertl-hiro $
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(intno)
57#endif /* LOG_ISR_ENTER */
58
59#ifndef LOG_ISR_LEAVE
60#define LOG_ISR_LEAVE(intno)
61#endif /* LOG_ISR_LEAVE */
62
63#ifndef LOG_CFG_INT_ENTER
64#define LOG_CFG_INT_ENTER(intno, pk_cint)
65#endif /* LOG_CFG_INT_ENTER */
66
67#ifndef LOG_CFG_INT_LEAVE
68#define LOG_CFG_INT_LEAVE(ercd)
69#endif /* LOG_CFG_INT_LEAVE */
70
71#ifndef LOG_ATT_ISR_ENTER
72#define LOG_ATT_ISR_ENTER(pk_cisr)
73#endif /* LOG_ATT_ISR_ENTER */
74
75#ifndef LOG_ATT_ISR_LEAVE
76#define LOG_ATT_ISR_LEAVE(ercd)
77#endif /* LOG_ATT_ISR_LEAVE */
78
79#ifndef LOG_DEF_INH_ENTER
80#define LOG_DEF_INH_ENTER(inhno, pk_dinh)
81#endif /* LOG_DEF_INH_ENTER */
82
83#ifndef LOG_DEF_INH_LEAVE
84#define LOG_DEF_INH_LEAVE(ercd)
85#endif /* LOG_DEF_INH_LEAVE */
86
87#ifndef LOG_DIS_INT_ENTER
88#define LOG_DIS_INT_ENTER(intno)
89#endif /* LOG_DIS_INT_ENTER */
90
91#ifndef LOG_DIS_INT_LEAVE
92#define LOG_DIS_INT_LEAVE(ercd)
93#endif /* LOG_DIS_INT_LEAVE */
94
95#ifndef LOG_ENA_INT_ENTER
96#define LOG_ENA_INT_ENTER(intno)
97#endif /* LOG_ENA_INT_ENTER */
98
99#ifndef LOG_ENA_INT_LEAVE
100#define LOG_ENA_INT_LEAVE(ercd)
101#endif /* LOG_ENA_INT_LEAVE */
102
103#ifndef LOG_CHG_IPM_ENTER
104#define LOG_CHG_IPM_ENTER(intpri)
105#endif /* LOG_CHG_IPM_ENTER */
106
107#ifndef LOG_CHG_IPM_LEAVE
108#define LOG_CHG_IPM_LEAVE(ercd)
109#endif /* LOG_CHG_IPM_LEAVE */
110
111#ifndef LOG_GET_IPM_ENTER
112#define LOG_GET_IPM_ENTER(p_intpri)
113#endif /* LOG_GET_IPM_ENTER */
114
115#ifndef LOG_GET_IPM_LEAVE
116#define LOG_GET_IPM_LEAVE(ercd, intpri)
117#endif /* LOG_GET_IPM_LEAVE */
118
119/*
120 * 割込みサービスルーチンの数
121 */
122#define tnum_isr ((uint_t)(tmax_isrid - TMIN_SEMID + 1))
123
124/*
125 * 割込みサービスルーチンキューへの登録
126 */
127Inline void
128enqueue_isr(QUEUE *p_isr_queue, ISRCB *p_isrcb)
129{
130 QUEUE *p_entry;
131 PRI isrpri = p_isrcb->p_isrinib->isrpri;
132
133 for (p_entry = p_isr_queue->p_next; p_entry != p_isr_queue;
134 p_entry = p_entry->p_next) {
135 if (isrpri < ((ISRCB *) p_entry)->p_isrinib->isrpri) {
136 break;
137 }
138 }
139 queue_insert_prev(p_entry, &(p_isrcb->isr_queue));
140}
141
142#ifdef TOPPERS_isrini
143
144/*
145 * 割込みサービスルーチンキューのエリア
146 */
147QUEUE isr_queue_table[TNUM_INTNO];
148
149/*
150 * 使用していない割込みサービスルーチン管理ブロックのリスト
151 */
152QUEUE free_isrcb;
153
154/*
155 * 割込みサービスルーチン機能の初期化
156 */
157void
158initialize_isr(void)
159{
160 uint_t i;
161 ISRCB *p_isrcb;
162 ISRINIB *p_isrinib;
163
164 for (i = 0; i < TNUM_INTNO; i++) {
165 queue_initialize(&(isr_queue_table[i]));
166 }
167 queue_initialize(&free_isrcb);
168 for (i = 0; i < tnum_isr; i++) {
169 p_isrcb = &(isrcb_table[i]);
170 p_isrinib = &(isrinib_table[i]);
171 p_isrinib->isratr = TA_NOEXS;
172 p_isrcb->p_isrinib = ((const ISRINIB *) p_isrinib);
173 queue_insert_prev(&free_isrcb, &(p_isrcb->isr_queue));
174 }
175}
176
177#endif /* TOPPERS_isrini */
178
179/*
180 * 割込みサービスルーチンの呼出し
181 */
182#ifdef TOPPERS_isrcal
183
184void
185inthdr_call_isr(INTNO intno)
186{
187 QUEUE *p_isr_queue, *p_queue;
188 ISRINIB *p_isrinib;
189 PRI saved_ipm;
190
191 i_begin_int(intno);
192 saved_ipm = i_get_ipm();
193 p_isr_queue = &isr_queue_table[INDEX_INTNO(intno)];
194 for (p_queue = p_isr_queue->p_next; p_queue != p_isr_queue;
195 p_queue = p_queue->p_next) {
196 p_isrinib = (ISRINIB *)(((ISRCB *) p_queue)->p_isrinib);
197 LOG_ISR_ENTER(p_isrinib->intno);
198 (*(p_isrinib->isr))(p_isrinib->exinf);
199 LOG_ISR_LEAVE(p_isrinib->intno);
200
201 if (p_queue->p_next != p_isr_queue) {
202 /* ISRの呼出し前の状態に戻す */
203 if (i_sense_lock()) {
204 i_unlock_cpu();
205 }
206 i_set_ipm(saved_ipm);
207 }
208 }
209 i_end_int(intno);
210}
211
212#endif /* TOPPERS_isrcal */
213
214/*
215 * 割込みサービスルーチンの生成
216 */
217#ifdef TOPPERS_att_isr
218
219ER
220att_isr(const T_CISR *pk_cisr)
221{
222 ISRCB *p_isrcb;
223 ISRINIB *p_isrinib;
224 QUEUE *p_isr_queue;
225 INHINIB *p_inhinib;
226 ER ercd;
227
228 LOG_ATT_ISR_ENTER(pk_cisr);
229 CHECK_INIRTN();
230 CHECK_RSATR(pk_cisr->isratr, TARGET_ISRATR);
231 CHECK_INTNO_CREISR(pk_cisr->intno);
232 CHECK_ALIGN_FUNC(pk_cisr->isr);
233 CHECK_NONNULL_FUNC(pk_cisr->isr);
234 CHECK_ISRPRI(pk_cisr->isrpri);
235
236 p_inhinib = get_inhinib(INHNO_INTNO(pk_cisr->intno));
237 if (get_intinib(pk_cisr->intno)->intatr == TA_NOEXS
238 || (p_inhinib->inhatr != TA_NOEXS
239 && p_inhinib->inthdr != inthdr_call_isr)) {
240 ercd = E_OBJ;
241 }
242 else if (tnum_isr == 0 || queue_empty(&free_isrcb)) {
243 ercd = E_NOID;
244 }
245 else {
246 if (p_inhinib->inhatr == TA_NOEXS) {
247 p_inhinib->inhatr = TA_NULL;
248 p_inhinib->inthdr = inthdr_call_isr;
249 }
250 p_isr_queue = &isr_queue_table[INDEX_INTNO(pk_cisr->intno)];
251 p_isrcb = ((ISRCB *) queue_delete_next(&free_isrcb));
252 p_isrinib = (ISRINIB *)(p_isrcb->p_isrinib);
253 p_isrinib->isratr = pk_cisr->isratr;
254 p_isrinib->exinf = pk_cisr->exinf;
255 p_isrinib->intno = pk_cisr->intno;
256 p_isrinib->p_isr_queue = p_isr_queue;
257 p_isrinib->isr = pk_cisr->isr;
258 p_isrinib->isrpri = pk_cisr->isrpri;
259 enqueue_isr(p_isr_queue, p_isrcb);
260 ercd = E_OK;
261 }
262
263 error_exit:
264 LOG_ATT_ISR_LEAVE(ercd);
265 return(ercd);
266}
267
268#endif /* TOPPERS_att_isr */
269
270#ifdef TOPPERS_intini
271
272/*
273 * 割込みハンドラ初期化ブロックのエリア
274 */
275INHINIB inhinib_table[TNUM_INHNO];
276
277/*
278 * 割込み要求ライン初期化ブロックのエリア
279 */
280INTINIB intinib_table[TNUM_INTNO];
281
282/*
283 * 割込み管理機能の初期化
284 */
285void
286initialize_interrupt(void)
287{
288 uint_t i;
289
290 for (i = 0; i < TNUM_INHNO; i++) {
291 inhinib_table[i].inhatr = TA_NOEXS;
292 }
293 for (i = 0; i < TNUM_INTNO; i++) {
294 intinib_table[i].intatr = TA_NOEXS;
295 }
296}
297
298#endif /* TOPPERS_intini */
299
300/*
301 * 割込み要求ラインの属性の設定
302 */
303#ifdef TOPPERS_cfg_int
304
305ER
306cfg_int(INTNO intno, const T_CINT *pk_cint)
307{
308 INTINIB *p_intinib;
309 ER ercd;
310
311 LOG_CFG_INT_ENTER(intno, pk_cint);
312 CHECK_INIRTN();
313 CHECK_PAR(VALID_INTNO_CFGINT(intno));
314 CHECK_RSATR(pk_cint->intatr, TA_ENAINT|TA_EDGE|TARGET_INTATR);
315 CHECK_PAR(VALID_INTPRI_CFGINT(pk_cint->intpri));
316 p_intinib = get_intinib(intno);
317
318 if ((ercd = target_check_cint(intno, pk_cint)) == E_OK) {
319 p_intinib->intatr = pk_cint->intatr;
320 p_intinib->intpri = pk_cint->intpri;
321 }
322
323 error_exit:
324 LOG_CFG_INT_LEAVE(ercd);
325 return(ercd);
326}
327
328#endif /* TOPPERS_cfg_int */
329
330/*
331 * 割込みハンドラの定義
332 */
333#ifdef TOPPERS_def_inh
334
335ER
336def_inh(INHNO inhno, const T_DINH *pk_dinh)
337{
338 INHINIB *p_inhinib;
339 ER ercd;
340
341 LOG_DEF_INH_ENTER(inhno, pk_dinh);
342 CHECK_INIRTN();
343 CHECK_PAR(VALID_INHNO_DEFINH(inhno));
344 CHECK_RSATR(pk_dinh->inhatr, TARGET_INHATR);
345 CHECK_NOSPT(pk_dinh->inthdr != NULL);
346 CHECK_ALIGN_FUNC(pk_dinh->inthdr);
347 CHECK_NONNULL_FUNC(pk_dinh->inthdr);
348 p_inhinib = get_inhinib(inhno);
349
350 if (get_intinib(INTNO_INHNO(inhno))->intatr == TA_NOEXS
351 || p_inhinib->inhatr != TA_NOEXS) {
352 ercd = E_OBJ;
353 }
354 else if ((ercd = target_check_dinh(inhno, pk_dinh)) == E_OK) {
355 p_inhinib->inhatr = pk_dinh->inhatr;
356 p_inhinib->inthdr = (IINTHDR)(pk_dinh->inthdr);
357 }
358
359 error_exit:
360 LOG_DEF_INH_LEAVE(ercd);
361 return(ercd);
362}
363
364#endif /* TOPPERS_def_inh */
365
366/*
367 * 割込みの禁止
368 */
369#ifdef TOPPERS_dis_int
370#ifdef TOPPERS_SUPPORT_DIS_INT
371
372ER
373dis_int(INTNO intno)
374{
375 bool_t locked;
376 ER ercd;
377
378 LOG_DIS_INT_ENTER(intno);
379 CHECK_TSKCTX();
380 CHECK_INTNO_DISINT(intno);
381
382 locked = t_sense_lock();
383 if (!locked) {
384 t_lock_cpu();
385 }
386 if (t_disable_int(intno)) {
387 ercd = E_OK;
388 }
389 else {
390 ercd = E_OBJ;
391 }
392 if (!locked) {
393 t_unlock_cpu();
394 }
395
396 error_exit:
397 LOG_DIS_INT_LEAVE(ercd);
398 return(ercd);
399}
400
401#endif /* TOPPERS_SUPPORT_DIS_INT */
402#endif /* TOPPERS_dis_int */
403
404/*
405 * 割込みの許可
406 */
407#ifdef TOPPERS_ena_int
408#ifdef TOPPERS_SUPPORT_ENA_INT
409
410ER
411ena_int(INTNO intno)
412{
413 bool_t locked;
414 ER ercd;
415
416 LOG_ENA_INT_ENTER(intno);
417 CHECK_TSKCTX();
418 CHECK_INTNO_DISINT(intno);
419
420 locked = t_sense_lock();
421 if (!locked) {
422 t_lock_cpu();
423 }
424 if (t_enable_int(intno)) {
425 ercd = E_OK;
426 }
427 else {
428 ercd = E_OBJ;
429 }
430 if (!locked) {
431 t_unlock_cpu();
432 }
433
434 error_exit:
435 LOG_ENA_INT_LEAVE(ercd);
436 return(ercd);
437}
438
439#endif /* TOPPERS_SUPPORT_ENA_INT */
440#endif /* TOPPERS_ena_int */
441
442/*
443 * 割込み優先度マスクの変更
444 */
445#ifdef TOPPERS_chg_ipm
446
447ER
448chg_ipm(PRI intpri)
449{
450 ER ercd;
451
452 LOG_CHG_IPM_ENTER(intpri);
453 CHECK_TSKCTX_UNL();
454 CHECK_INTPRI_CHGIPM(intpri);
455
456 t_lock_cpu();
457 t_set_ipm(intpri);
458 if (intpri == TIPM_ENAALL) {
459 ipmflg = true;
460 if (!disdsp) {
461 dspflg = true;
462 if (p_runtsk != p_schedtsk) {
463 dispatch();
464 }
465 }
466 if (p_runtsk->enatex && p_runtsk->texptn != 0U) {
467 call_texrtn();
468 }
469 }
470 else {
471 ipmflg = false;
472 dspflg = false;
473 }
474 ercd = E_OK;
475 t_unlock_cpu();
476
477 error_exit:
478 LOG_CHG_IPM_LEAVE(ercd);
479 return(ercd);
480}
481
482#endif /* TOPPERS_chg_ipm */
483
484/*
485 * 割込み優先度マスクの参照
486 */
487#ifdef TOPPERS_get_ipm
488
489ER
490get_ipm(PRI *p_intpri)
491{
492 ER ercd;
493
494 LOG_GET_IPM_ENTER(p_intpri);
495 CHECK_TSKCTX_UNL();
496
497 t_lock_cpu();
498 *p_intpri = t_get_ipm();
499 ercd = E_OK;
500 t_unlock_cpu();
501
502 error_exit:
503 LOG_GET_IPM_LEAVE(ercd, *p_intpri);
504 return(ercd);
505}
506
507#endif /* TOPPERS_get_ipm */
Note: See TracBrowser for help on using the repository browser.