source: UsbWattMeter/trunk/asp_dcre/kernel/interrupt.c

Last change on this file was 167, checked in by coas-nagasima, 8 years ago

MIMEにSJISを設定

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