source: asp3_wo_tecs/trunk/extension/dcre/kernel/interrupt.c@ 302

Last change on this file since 302 was 302, checked in by ertl-honda, 7 years ago

TECSレスのASP3の開発のため以下のtrunkからコピー
http://dev.toppers.jp/svn/asp3/branches/WO_TECS-3.C.0

File size: 11.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-2014 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 275 2014-11-03 14:26:05Z ertl-hiro $
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 p_isrcb = &(isrcb_table[i]);
179 p_isrcb->p_isrinib = &(isrinib_table[i]);
180 enqueue_isr(p_isrcb->p_isrinib->p_isr_queue, p_isrcb);
181 }
182 queue_initialize(&free_isrcb);
183 for (j = 0; i < tnum_isr; i++, j++) {
184 p_isrcb = &(isrcb_table[i]);
185 p_isrinib = &(aisrinib_table[j]);
186 p_isrinib->isratr = TA_NOEXS;
187 p_isrcb->p_isrinib = ((const ISRINIB *) p_isrinib);
188 queue_insert_prev(&free_isrcb, &(p_isrcb->isr_queue));
189 }
190}
191
192#endif /* TOPPERS_isrini */
193
194/*
195 * 割込みサービスルーチンの呼出し
196 */
197#ifdef TOPPERS_isrcal
198
199void
200call_isr(QUEUE *p_isr_queue)
201{
202 QUEUE *p_queue;
203 ISRCB *p_isrcb;
204
205 for (p_queue = p_isr_queue->p_next; p_queue != p_isr_queue;
206 p_queue = p_queue->p_next) {
207 p_isrcb = (ISRCB *) p_queue;
208 LOG_ISR_ENTER(ISRID(p_isrcb));
209 (*(p_isrcb->p_isrinib->isr))(p_isrcb->p_isrinib->exinf);
210 LOG_ISR_LEAVE(ISRID(p_isrcb));
211
212 if (p_queue->p_next != p_isr_queue) {
213 /* ISRの呼出し前の状æ…
214‹ã«æˆ»ã™ */
215 if (sense_lock()) {
216 unlock_cpu();
217 }
218 }
219 }
220}
221
222#endif /* TOPPERS_isrcal */
223
224/*
225 * 割込みサービスルーチン呼出しキューの検索
226 */
227Inline QUEUE *
228search_isr_queue(INTNO intno)
229{
230 int_t left, right, i;
231
232 if (tnum_isr_queue == 0) {
233 return(NULL);
234 }
235
236 left = 0;
237 right = tnum_isr_queue - 1;
238 while (left < right) {
239 i = (left + right + 1) / 2;
240 if (intno < isr_queue_list[i].intno) {
241 right = i - 1;
242 }
243 else {
244 left = i;
245 }
246 }
247 if (isr_queue_list[left].intno == intno) {
248 return(isr_queue_list[left].p_isr_queue);
249 }
250 else {
251 return(NULL);
252 }
253}
254
255/*
256 * 割込みサービスルーチンの生成
257 */
258#ifdef TOPPERS_acre_isr
259
260ER_UINT
261acre_isr(const T_CISR *pk_cisr)
262{
263 ISRCB *p_isrcb;
264 ISRINIB *p_isrinib;
265 QUEUE *p_isr_queue;
266 ER ercd;
267
268 LOG_ACRE_ISR_ENTER(pk_cisr);
269 CHECK_TSKCTX_UNL();
270 CHECK_RSATR(pk_cisr->isratr, TARGET_ISRATR);
271 CHECK_PAR(VALID_INTNO_CREISR(pk_cisr->intno));
272 CHECK_PAR(FUNC_ALIGN(pk_cisr->isr));
273 CHECK_PAR(FUNC_NONNULL(pk_cisr->isr));
274 CHECK_PAR(VALID_ISRPRI(pk_cisr->isrpri));
275
276 p_isr_queue = search_isr_queue(pk_cisr->intno);
277 CHECK_OBJ(p_isr_queue != NULL);
278
279 lock_cpu();
280 if (tnum_isr == 0 || queue_empty(&free_isrcb)) {
281 ercd = E_NOID;
282 }
283 else {
284 p_isrcb = ((ISRCB *) queue_delete_next(&free_isrcb));
285 p_isrinib = (ISRINIB *)(p_isrcb->p_isrinib);
286 p_isrinib->isratr = pk_cisr->isratr;
287 p_isrinib->exinf = pk_cisr->exinf;
288 p_isrinib->p_isr_queue = p_isr_queue;
289 p_isrinib->isr = pk_cisr->isr;
290 p_isrinib->isrpri = pk_cisr->isrpri;
291 enqueue_isr(p_isr_queue, p_isrcb);
292 ercd = ISRID(p_isrcb);
293 }
294 unlock_cpu();
295
296 error_exit:
297 LOG_ACRE_ISR_LEAVE(ercd);
298 return(ercd);
299}
300
301#endif /* TOPPERS_acre_isr */
302
303/*
304 * 割込みサービスルーチンの削除
305 */
306#ifdef TOPPERS_del_isr
307
308ER
309del_isr(ID isrid)
310{
311 ISRCB *p_isrcb;
312 ISRINIB *p_isrinib;
313 ER ercd;
314
315 LOG_DEL_ISR_ENTER(isrid);
316 CHECK_TSKCTX_UNL();
317 CHECK_ID(VALID_ISRID(isrid));
318 p_isrcb = get_isrcb(isrid);
319
320 lock_cpu();
321 if (p_isrcb->p_isrinib->isratr == TA_NOEXS) {
322 ercd = E_NOEXS;
323 }
324 else if (isrid <= tmax_sisrid) {
325 ercd = E_OBJ;
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 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_def_inhno; i++) {
357 p_inhinib = &(inhinib_table[i]);
358 define_inh(p_inhinib->inhno, p_inhinib->int_entry);
359 }
360 for (i = 0; i < tnum_cfg_intno; i++) {
361 p_intinib = &(intinib_table[i]);
362 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 * 割込みの禁止[NGKI3555]
371 */
372#ifdef TOPPERS_dis_int
373#ifdef TOPPERS_SUPPORT_DIS_INT /*ï¼»NGKI3093ï¼½*/
374
375ER
376dis_int(INTNO intno)
377{
378 bool_t locked;
379 ER ercd;
380
381 LOG_DIS_INT_ENTER(intno);
382 CHECK_PAR(VALID_INTNO_DISINT(intno)); /*[NGKI3083][NGKI3087]*/
383
384 locked = sense_lock();
385 if (!locked) {
386 lock_cpu();
387 }
388 if (disable_int(intno)) { /*ï¼»NGKI3086ï¼½*/
389 ercd = E_OK;
390 }
391 else {
392 ercd = E_OBJ; /*ï¼»NGKI3085ï¼½*/
393 }
394 if (!locked) {
395 unlock_cpu();
396 }
397
398 error_exit:
399 LOG_DIS_INT_LEAVE(ercd);
400 return(ercd);
401}
402
403#endif /* TOPPERS_SUPPORT_DIS_INT */
404#endif /* TOPPERS_dis_int */
405
406/*
407 * 割込みの許可[NGKI3556]
408 */
409#ifdef TOPPERS_ena_int
410#ifdef TOPPERS_SUPPORT_ENA_INT /*ï¼»NGKI3106ï¼½*/
411
412ER
413ena_int(INTNO intno)
414{
415 bool_t locked;
416 ER ercd;
417
418 LOG_ENA_INT_ENTER(intno);
419 CHECK_PAR(VALID_INTNO_DISINT(intno)); /*[NGKI3096][NGKI3100]*/
420
421 locked = sense_lock();
422 if (!locked) {
423 lock_cpu();
424 }
425 if (enable_int(intno)) { /*ï¼»NGKI3099ï¼½*/
426 ercd = E_OK;
427 }
428 else {
429 ercd = E_OBJ; /*ï¼»NGKI3098ï¼½*/
430 }
431 if (!locked) {
432 unlock_cpu();
433 }
434
435 error_exit:
436 LOG_ENA_INT_LEAVE(ercd);
437 return(ercd);
438}
439
440#endif /* TOPPERS_SUPPORT_ENA_INT */
441#endif /* TOPPERS_ena_int */
442
443/*
444 * 割込み優å…
445ˆåº¦ãƒžã‚¹ã‚¯ã®å¤‰æ›´ï¼»NGKI3107ï¼½
446 */
447#ifdef TOPPERS_chg_ipm
448
449ER
450chg_ipm(PRI intpri)
451{
452 ER ercd;
453
454 LOG_CHG_IPM_ENTER(intpri);
455 CHECK_TSKCTX_UNL(); /*[NGKI3108][NGKI3109]*/
456 CHECK_PAR(VALID_INTPRI_CHGIPM(intpri)); /*[NGKI3113][NGKI3114]*/
457
458 lock_cpu();
459 t_set_ipm(intpri); /*ï¼»NGKI3111ï¼½*/
460 if (intpri == TIPM_ENAALL && enadsp) {
461 dspflg = true;
462 p_schedtsk = search_schedtsk();
463 if (p_runtsk->raster && p_runtsk->enater) {
464 task_terminate(p_runtsk);
465 exit_and_dispatch();
466 ercd = E_SYS;
467 }
468 else {
469 if (p_runtsk != p_schedtsk) {
470 dispatch();
471 }
472 ercd = E_OK;
473 }
474 }
475 else {
476 dspflg = false;
477 ercd = E_OK;
478 }
479 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§ï¼»NGKI3115ï¼½
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(); /*[NGKI3116][NGKI3117]*/
502
503 lock_cpu();
504 *p_intpri = t_get_ipm(); /*ï¼»NGKI3120ï¼½*/
505 ercd = E_OK;
506 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.