source: mypx/extension/dcre/kernel/interrupt.c @ 7

このファイルの 7 以降における最終更新内容7 で kominami が 2015/09/12 9:22:12 に更新しました

TOPPERS/ASP 1.9.1

ファイルサイズ: 10.1 KB
Rev 
[7]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$
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 */
詳しい使い方は TracBrowser を参照してください。