Smart210学习记录-----中断

发布者:JoyfulJourney最新更新时间:2025-01-20 来源: elecfans关键字:Smart210  学习记录  中断 手机看文章 扫描二维码
随时随地手机看文章

1. OVERVIEW OF VECTORED INTERRUPT CONTROLLER(概述向量中断控制器

  主要有4个VIC,4个TZIC还有一个很特殊的ARM PrimeCell PL192。主要的VIC和TZIC可以支持93个中断源。其中TZIC是为TrustZone技术所准备的,ARM TrustZone® 技术是系统范围的安全方法,针对高性能计算平台上的大量应用,包括安全支付、数字版权管理 (DRM)、企业服务和基于 Web 的服务(援引官方的介绍)。TZIC提供了安全控制的nFIQ中断并且使该这类中断从传统的不安全中断VIC中屏蔽掉,从而达到应用在数据传输时的安全性和保密性。

 

2,KEY FEATURES OF VECTORED INTERRUPT CONTROLLER


• Supports 93 vectored IRQ interrupts
• Fixed hardware interrupts priority levels (固定硬件中断优先级)
• Programmable interrupt priority levels (可编程中断优先级)
• Supports Hardware interrupt priority level masking (支持硬件中断优先级的屏蔽)
• Programmable interrupt priority level masking
• Generates IRQ and FIQ (产生IRQ和FIQ)
• Generates Software interrupt
• Test registers
• Raw interrupt status (原中断状态,就是设置使能,屏蔽寄存器之前的各中断状态)
• Interrupt request status
• Supports Privileged mode for restricted access(支持限制访问特权模式)

 

3.  When user clears interrupt pending, user must write 0 to all the VICADDRESS registers (VIC0ADDRESS,
VIC1ADDRESS, VIC2ADDRESS, and VIC3ADDRESS).

 

4.各中断寄存器请参考s5pv320用户手册。

中断参考程序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
.global _start
.global IRQ_handle
 
_start:
    // 关闭看门狗
    ldr r0, =0xE2700000        
    mov r1, #0
    str r1, [r0]
 
    // 设置栈,以便调用c函数
    ldr sp, =0x40000000    
 
    // 开中断
    mov r0, #0x53          
    msr CPSR_cxsf, r0  
 
    // 汇编初始化时钟     
    bl clock_init  
 
    // 调用main函数
    bl main
 
IRQ_handle:
    // 设置中断模式的栈
    ldr sp, =0xD0037F80
    // 保存现场
    sub lr, lr, #4             
    stmfd sp!, {r0-r12, lr}
    // 跳转到中断处理函数
    bl  irq_handler    
    // 恢复现场
    ldmfd sp!, {r0-r12, pc}^

  

首先,关闭看门狗,设置栈,开中断,设置时钟,,,当一个中断源(不是一个中断)发生时执行中断服务程序IRQ_handle,设置中断模式的栈, 保存现场,跳转到中断处理函(irq_handler),中断处理函数首先判断是哪个中断组发生中断,然后进入相应的中断处理子程序(irq_xxx),在事先我们要设置中断处理子程序irq_xxx(如irq_key)在地址VICxVECTADDRx中,,,当有中断发生时,硬件上会将当前中断的中断处理子程序从寄存器 VICxVECTADDxR 自动拷贝到寄存器VICADDR 中,所以我们在 irq_handler()函数里会调用保存在寄存器 VICDDR 里的中断处理函数即可。    

( 一个中断组有32个中断源,为什么我们可以直接运行中断组的VICxINTADDR指定的函数而无需知道是具体哪个中断源触发了中断呢?这是由于中断组内的中断源在触发中断后硬件会自动把对应中断源的处理函数入口地址赋给所属组的VICADDR,这样我们就能省去检索中断源再跳转到对应中断函数入口的时间了,当然,前提是我们要把【按键中断】的服务程序入口地址赋给某个对应的寄存器(假设是VIC0INTADDR12,所属组是VIC0组,所对应入口是VIC0INTADDR))。 

 

这一段真的有点难懂,需要花点时间

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include 'stdio.h'
#include 'int.h'
 
 
#define     GPH2CON     (*(volatile unsigned long *) 0xE0200C40)
#define     GPH2DAT     (*(volatile unsigned long *) 0xE0200C44)
 
#define     GPH2_0_EINT16   (0xf<<(0*4))
#define     GPH2_1_EINT17   (0xf<<(1*4))
#define     GPH2_2_EINT18   (0xf<<(2*4))
#define     GPH2_3_EINT19   (0xf<<(3*4))
 
#define     EXT_INT_0_CON           ( *((volatile unsigned long *)0xE0200E00) )
#define     EXT_INT_1_CON           ( *((volatile unsigned long *)0xE0200E04) )
#define     EXT_INT_2_CON           ( *((volatile unsigned long *)0xE0200E08) )
#define     EXT_INT_3_CON           ( *((volatile unsigned long *)0xE0200E0C) )
 
#define     EXT_INT_0_MASK          ( *((volatile unsigned long *)0xE0200F00) )
#define     EXT_INT_1_MASK          ( *((volatile unsigned long *)0xE0200F04) )
#define     EXT_INT_2_MASK          ( *((volatile unsigned long *)0xE0200F08) )
#define     EXT_INT_3_MASK          ( *((volatile unsigned long *)0xE0200F0C) )
 
#define     EXT_INT_0_PEND          ( *((volatile unsigned long *)0xE0200F40) )
#define     EXT_INT_1_PEND          ( *((volatile unsigned long *)0xE0200F44) )
#define     EXT_INT_2_PEND          ( *((volatile unsigned long *)0xE0200F48) )
#define     EXT_INT_3_PEND          ( *((volatile unsigned long *)0xE0200F4C) )
 
void uart_init();
 
 
void delay(unsigned long count)
{
    volatile unsigned long i = count;
    while (i--);
}
 
void isr_key(void)
{
    printf('we get company:EINT16_31rn');
     
    // clear VIC0ADDR
    intc_clearvectaddr();                  
    // clear pending bit   
    EXT_INT_2_PEND |= 1<<0;                  
}
 
int main(void)
{
    int c = 0;
 
    // 初始化串口
    uart_init();
 
    // 中断相关初始化
    system_initexception();                    
     
    printf('**************Int test *************** rn');
 
    // 外部中断相关的设置
    // 1111 = EXT_INT[16]
    GPH2CON |= 0xF;                        
    // 010 = Falling edge triggered
    EXT_INT_2_CON |= 1<<1;           
    // unmasked
    EXT_INT_2_MASK &= ~(1<<0);
     
    // 设置中断EINT16_31的处理函数
    intc_setvectaddr(NUM_EINT16_31, isr_key);  
    // 使能中断EINT16_31
    intc_enable(NUM_EINT16_31);
     
    while (1)
    {  
        printf('%drn',c++);
        delay(0x100000);
    }
}

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
#include 'int.h'
#include 'stdio.h'
 
//// Interrupt
#define VIC0_BASE                   (0xF2000000)
#define VIC1_BASE                   (0xF2100000)
#define VIC2_BASE                   (0xF2200000)
#define VIC3_BASE                   (0xF2300000)
 
// VIC0
#define     VIC0IRQSTATUS           ( *((volatile unsigned long *)(VIC0_BASE + 0x00)) )
#define     VIC0FIQSTATUS           ( *((volatile unsigned long *)(VIC0_BASE + 0x04)) )
#define     VIC0RAWINTR             ( *((volatile unsigned long *)(VIC0_BASE + 0x08)) )
#define     VIC0INTSELECT           ( *((volatile unsigned long *)(VIC0_BASE + 0x0c)) )
#define     VIC0INTENABLE           ( *((volatile unsigned long *)(VIC0_BASE + 0x10)) )
#define     VIC0INTENCLEAR          ( *((volatile unsigned long *)(VIC0_BASE + 0x14)) )
#define     VIC0SOFTINT             ( *((volatile unsigned long *)(VIC0_BASE + 0x18)) )
#define     VIC0SOFTINTCLEAR        ( *((volatile unsigned long *)(VIC0_BASE + 0x1c)) )
#define     VIC0PROTECTION          ( *((volatile unsigned long *)(VIC0_BASE + 0x20)) )
#define     VIC0SWPRIORITYMASK      ( *((volatile unsigned long *)(VIC0_BASE + 0x24)) )
#define     VIC0PRIORITYDAISY       ( *((volatile unsigned long *)(VIC0_BASE + 0x28)) )
#define     VIC0VECTADDR            (VIC0_BASE + 0x100)
#define     VIC0VECPRIORITY         ( *((volatile unsigned long *)(VIC0_BASE + 0x200)) )
#define     VIC0ADDR                ( *((volatile unsigned long *)(VIC0_BASE + 0xf00)) )
#define     VIC0PERID0              ( *((volatile unsigned long *)(VIC0_BASE + 0xfe0)) )
#define     VIC0PERID1              ( *((volatile unsigned long *)(VIC0_BASE + 0xfe4)) )
#define     VIC0PERID2              ( *((volatile unsigned long *)(VIC0_BASE + 0xfe8)) )
#define     VIC0PERID3              ( *((volatile unsigned long *)(VIC0_BASE + 0xfec)) )
#define     VIC0PCELLID0            ( *((volatile unsigned long *)(VIC0_BASE + 0xff0)) )
#define     VIC0PCELLID1            ( *((volatile unsigned long *)(VIC0_BASE + 0xff4)) )
#define     VIC0PCELLID2            ( *((volatile unsigned long *)(VIC0_BASE + 0xff8)) )
#define     VIC0PCELLID3            ( *((volatile unsigned long *)(VIC0_BASE + 0xffc)) )
 
// VIC1
#define     VIC1IRQSTATUS           ( *((volatile unsigned long *)(VIC1_BASE + 0x00)) )
#define     VIC1FIQSTATUS           ( *((volatile unsigned long *)(VIC1_BASE + 0x04)) )
#define     VIC1RAWINTR             ( *((volatile unsigned long *)(VIC1_BASE + 0x08)) )
#define     VIC1INTSELECT           ( *((volatile unsigned long *)(VIC1_BASE + 0x0c)) )
#define     VIC1INTENABLE           ( *((volatile unsigned long *)(VIC1_BASE + 0x10)) )
#define     VIC1INTENCLEAR          ( *((volatile unsigned long *)(VIC1_BASE + 0x14)) )
#define     VIC1SOFTINT             ( *((volatile unsigned long *)(VIC1_BASE + 0x18)) )
#define     VIC1SOFTINTCLEAR        ( *((volatile unsigned long *)(VIC1_BASE + 0x1c)) )
#define     VIC1PROTECTION          ( *((volatile unsigned long *)(VIC1_BASE + 0x20)) )
#define     VIC1SWPRIORITYMASK      ( *((volatile unsigned long *)(VIC1_BASE + 0x24)) )
#define     VIC1PRIORITYDAISY       ( *((volatile unsigned long *)(VIC1_BASE + 0x28)) )
#define     VIC1VECTADDR            (VIC1_BASE + 0x100)
#define     VIC1VECPRIORITY         ( *((volatile unsigned long *)(VIC1_BASE + 0x200)) )
#define     VIC1ADDR                ( *((volatile unsigned long *)(VIC1_BASE + 0xf00)) )
#define     VIC1PERID0              ( *((volatile unsigned long *)(VIC1_BASE + 0xfe0)) )
#define     VIC1PERID1              ( *((volatile unsigned long *)(VIC1_BASE + 0xfe4)) )
#define     VIC1PERID2              ( *((volatile unsigned long *)(VIC1_BASE + 0xfe8)) )
#define     VIC1PERID3              ( *((volatile unsigned long *)(VIC1_BASE + 0xfec)) )
#define     VIC1PCELLID0                ( *((volatile unsigned long *)(VIC1_BASE + 0xff0)) )
#define     VIC1PCELLID1                ( *((volatile unsigned long *)(VIC1_BASE + 0xff4)) )
#define     VIC1PCELLID2                ( *((volatile unsigned long *)(VIC1_BASE + 0xff8)) )
#define     VIC1PCELLID3                ( *((volatile unsigned long *)(VIC1_BASE + 0xffc)) )
 
// VIC2
#define     VIC2IRQSTATUS           ( *((volatile unsigned long *)(VIC2_BASE + 0x00)) )
#define     VIC2FIQSTATUS           ( *((volatile unsigned long *)(VIC2_BASE + 0x04)) )
#define     VIC2RAWINTR             ( *((volatile unsigned long *)(VIC2_BASE + 0x08)) )
#define     VIC2INTSELECT           ( *((volatile unsigned long *)(VIC2_BASE + 0x0c)) )
#define     VIC2INTENABLE           ( *((volatile unsigned long *)(VIC2_BASE + 0x10)) )
#define     VIC2INTENCLEAR          ( *((volatile unsigned long *)(VIC2_BASE + 0x14)) )
#define     VIC2SOFTINT             ( *((volatile unsigned long *)(VIC2_BASE + 0x18)) )
#define     VIC2SOFTINTCLEAR        ( *((volatile unsigned long *)(VIC2_BASE + 0x1c)) )
#define     VIC2PROTECTION          ( *((volatile unsigned long *)(VIC2_BASE + 0x20)) )
#define     VIC2SWPRIORITYMASK      ( *((volatile unsigned long *)(VIC2_BASE + 0x24)) )
#define     VIC2PRIORITYDAISY       ( *((volatile unsigned long *)(VIC2_BASE + 0x28)) )
#define         VIC2VECTADDR            (VIC2_BASE + 0x100)
#define         VIC2VECPRIORITY         ( *((volatile unsigned long *)(VIC2_BASE + 0x200)) )
#define         VIC2ADDR                ( *((volatile unsigned long *)(VIC2_BASE + 0xf00)) )
#define         VIC2PERID0              ( *((volatile unsigned long *)(VIC2_BASE + 0xfe0)) )
#define         VIC2PERID1              ( *((volatile unsigned long *)(VIC2_BASE + 0xfe4)) )
#define         VIC2PERID2              ( *((volatile unsigned long *)(VIC2_BASE + 0xfe8)) )
#define         VIC2PERID3              ( *((volatile unsigned long *)(VIC2_BASE + 0xfec)) )
#define         VIC2PCELLID0                ( *((volatile unsigned long *)(VIC2_BASE + 0xff0)) )
#define         VIC2PCELLID1                ( *((volatile unsigned long *)(VIC2_BASE + 0xff4)) )
#define         VIC2PCELLID2                ( *((volatile unsigned long *)(VIC2_BASE + 0xff8)) )
#define         VIC2PCELLID3                ( *((volatile unsigned long *)(VIC2_BASE + 0xffc)) )
 
// VIC3
#define     VIC3IRQSTATUS           ( *((volatile unsigned long *)(VIC3_BASE + 0x00)) )
#define     VIC3FIQSTATUS           ( *((volatile unsigned long *)(VIC3_BASE + 0x04)) )
#define     VIC3RAWINTR             ( *((volatile unsigned long *)(VIC3_BASE + 0x08)) )
#define     VIC3INTSELECT           ( *((volatile unsigned long *)(VIC3_BASE + 0x0c)) )
#define     VIC3INTENABLE           ( *((volatile unsigned long *)(VIC3_BASE + 0x10)) )
#define     VIC3INTENCLEAR          ( *((volatile unsigned long *)(VIC3_BASE + 0x14)) )
#define     VIC3SOFTINT             ( *((volatile unsigned long *)(VIC3_BASE + 0x18)) )
#define     VIC3SOFTINTCLEAR        ( *((volatile unsigned long *)(VIC3_BASE + 0x1c)) )
#define     VIC3PROTECTION          ( *((volatile unsigned long *)(VIC3_BASE + 0x20)) )
#define     VIC3SWPRIORITYMASK      ( *((volatile unsigned long *)(VIC3_BASE + 0x24)) )
#define     VIC3PRIORITYDAISY       ( *((volatile unsigned long *)(VIC3_BASE + 0x28)) )
#define         VIC3VECTADDR            (VIC3_BASE + 0x100)
#define         VIC3VECPRIORITY         ( *((volatile unsigned long *)(VIC3_BASE + 0x200)) )
#define         VIC3ADDR                ( *((volatile unsigned long *)(VIC3_BASE + 0xf00)) )
#define         VIC3PERID0              ( *((volatile unsigned long *)(VIC3_BASE + 0xfe0)) )
#define         VIC3PERID1              ( *((volatile unsigned long *)(VIC3_BASE + 0xfe4)) )
#define         VIC3PERID2              ( *((volatile unsigned long *)(VIC3_BASE + 0xfe8)) )
#define         VIC3PERID3              ( *((volatile unsigned long *)(VIC3_BASE + 0xfec)) )
#define         VIC3PCELLID0                ( *((volatile unsigned long *)(VIC3_BASE + 0xff0)) )
#define         VIC3PCELLID1                ( *((volatile unsigned long *)(VIC3_BASE + 0xff4)) )
#define         VIC3PCELLID2                ( *((volatile unsigned long *)(VIC3_BASE + 0xff8)) )
#define         VIC3PCELLID3                ( *((volatile unsigned long *)(VIC3_BASE + 0xffc)) )
 
#define     _Exception_Vector           0xD0037400
#define      pExceptionRESET            ( *((volatile unsigned long *)(_Exception_Vector + 0x0)) )
#define      pExceptionUNDEF            ( *((volatile unsigned long *)(_Exception_Vector + 0x4)) )
#define      pExceptionSWI          ( *((volatile unsigned long *)(_Exception_Vector + 0x8)) )
#define         pExceptionPABORT            ( *((volatile unsigned long *)(_Exception_Vector + 0xc)) )
#define         pExceptionDABORT            ( *((volatile unsigned long *)(_Exception_Vector + 0x10)) )
#define      pExceptionRESERVED     ( *((volatile unsigned long *)(_Exception_Vector + 0x14)) )
#define         pExceptionIRQ               ( *((volatile unsigned long *)(_Exception_Vector + 0x18)) )
#define         pExceptionFIQ               ( *((volatile unsigned long *)(_Exception_Vector + 0x1c)) )
 
 
void exceptionundef(void)
{
    printf('undefined instruction exception.n');
    while(1);
}
 
void exceptionswi(void)
{
    printf('swi exception.n');
    while(1);
}
 
void exceptionpabort(void)
{
    printf('pabort exception.n');
    while(1);
}
 
void exceptiondabort(void)
{
 
    printf('dabort exception.n');
    while(1);
}
 
// 中断相关初始化
void system_initexception( void)
{
    // 设置中断向量表
    pExceptionUNDEF   = (unsigned long)exceptionundef;
    pExceptionSWI     = (unsigned long)exceptionswi;
    pExceptionPABORT  = (unsigned long)exceptionpabort;
    pExceptionDABORT  = (unsigned long)exceptiondabort;
    pExceptionIRQ     = (unsigned long)IRQ_handle;
    pExceptionFIQ     = (unsigned long)IRQ_handle;
 
    // 初始化中断控制器
    intc_init();
 
}
 
 
 
// 初始化中断控制器
void intc_init(void)
{
    // 禁止所有中断
    VIC0INTENCLEAR = 0xffffffff;
    VIC1INTENCLEAR = 0xffffffff;
    VIC2INTENCLEAR = 0xffffffff;
    VIC3INTENCLEAR = 0xffffffff;
 
    // 选择中断类型为IRQ
    VIC0INTSELECT = 0x0;
    VIC1INTSELECT = 0x0;
    VIC2INTSELECT = 0x0;
    VIC3INTSELECT = 0x0;
 
    // 清VICxADDR
    intc_clearvectaddr();
 
}
 
// 保存需要处理的中断的中断处理函数的地址
void intc_setvectaddr(unsigned long intnum, void (*handler)(void))
{
    //VIC0
    if(intnum<32)
    {
        *( (volatile unsigned long *)(VIC0VECTADDR + 4*intnum) ) = (unsigned)handler;
    }
    //VIC1
    else if(intnum<64)
    {
        *( (volatile unsigned long *)(VIC1VECTADDR + 4*(intnum-32)) ) = (unsigned)handler;
    }
    //VIC2
    else if(intnum<96)
    {
        *( (volatile unsigned long *)(VIC2VECTADDR + 4*(intnum-64)) ) = (unsigned)handler;
    }
    //VIC3
    else
    {
        *( (volatile unsigned long *)(VIC3VECTADDR + 4*(intnum-96)) ) = (unsigned)handler;
    }
    return;
}
 
// 清除需要处理的中断的中断处理函数的地址
void intc_clearvectaddr(void)
{
    // VICxADDR:当前正在处理的中断的中断处理函数的地址
    VIC0ADDR = 0;
    VIC1ADDR = 0;
    VIC2ADDR = 0;
    VIC3ADDR = 0;
}
 
// 使能中断
void intc_enable(unsigned long intnum)
{
    unsigned long temp;
    if(intnum<32)
    {
        temp = VIC0INTENABLE;
        temp |= (1<
        VIC0INTENABLE = temp;
    }
    else if(intnum<64)
    {
        temp = VIC1INTENABLE;
        temp |= (1<<(intnum-32));
        VIC1INTENABLE = temp;
    }
    else if(intnum<96)
    {
        temp = VIC2INTENABLE;
        temp |= (1<<(intnum-64));
        VIC2INTENABLE = temp;
    }
    else if(intnum
    {
        temp = VIC3INTENABLE;
        temp |= (1<<(intnum-96));
        VIC3INTENABLE = temp;
    }
    // NUM_ALL : enable all interrupt
    else
    {
        VIC0INTENABLE = 0xFFFFFFFF;
        VIC1INTENABLE = 0xFFFFFFFF;
        VIC2INTENABLE = 0xFFFFFFFF;
        VIC3INTENABLE = 0xFFFFFFFF;
    }
 
}
 
// 禁止中断
void intc_disable(unsigned long intnum)
{
    unsigned long temp;
 
    if(intnum<32)
    {
        temp = VIC0INTENCLEAR;
        temp |= (1<
        VIC0INTENCLEAR = temp;
    }
    else if(intnum<64)
    {
        temp = VIC1INTENCLEAR;
        temp |= (1<<(intnum-32));
        VIC1INTENCLEAR = temp;
    }
    else if(intnum<96)
    {
        temp = VIC2INTENCLEAR;
        temp |= (1<<(intnum-64));
        VIC2INTENCLEAR = temp;
    }
    else if(intnum
    {
        temp = VIC3INTENCLEAR;
        temp |= (1<<(intnum-96));
        VIC3INTENCLEAR = temp;
    }
    // NUM_ALL : disable all interrupt
    else
    {
        VIC0INTENCLEAR = 0xFFFFFFFF;
        VIC1INTENCLEAR = 0xFFFFFFFF;
        VIC2INTENCLEAR = 0xFFFFFFFF;
        VIC3INTENCLEAR = 0xFFFFFFFF;
    }
 
    return;
}
 
 
// 读中断状态
unsigned long intc_getvicirqstatus(unsigned long ucontroller)
{
    if(ucontroller == 0)
        return  VIC0IRQSTATUS;
    else if(ucontroller == 1)
        return  VIC1IRQSTATUS;
    else if(ucontroller == 2)
        return  VIC2IRQSTATUS;
    else if(ucontroller == 3)
        return  VIC3IRQSTATUS;
    else
    {}
    return 0;
}
 
// 通用中断处理函数
void irq_handler(void)
{
    unsigned long vicaddr[4] = {VIC0ADDR,VIC1ADDR,VIC2ADDR,VIC3ADDR};
    int i=0;
    void (*isr)(void) = NULL;
 
    for(; i<4; i++)
    {
        if(intc_getvicirqstatus(i) != 0)
        {
            isr = (void (*)(void)) vicaddr[i];
            break;
        }
    }
    (*isr)();
}


[1] [1]
关键字:Smart210  学习记录  中断 引用地址:Smart210学习记录-----中断

上一篇:Smart20学习记录----异步通知
下一篇:Smart210学习记录----beep linux字符设备驱动

推荐阅读最新更新时间:2026-03-13 18:48

Smart210学习记录-------文件操作
一.linux文件操作(只能在linux系统上用) 创建: int creat(const char* filename, mode_t mode) filename 表示要创建的文件名,mode表示对该文件的读写权限 int umask(int newmask) 调用将 umask 设置为 newmask,然后返回旧的 umask,它只影响读、写和执行权限 S_IRUSR 用户可以读 S_IWUSR 用户可以写 S_IXUSR 用户可以执行 。。。等等 除了可以通过上述宏进行“或”逻辑产生标志以外,我们也可以自己用数字来表示,Linux 用 5 个数字来表示文件的各种权限:第一位表示设置用户 ID;第二位表示设置组 ID;第三位
[单片机]
Smart210学习记录----nand flash驱动
当读写文件请求到来的时候,流程如下   1.通过vfs进入文件系统,   2.文件系统把文件读写转换为块设备读写,其中有运用算法对读写操作进行合并,排序等,最后把块设备读写放进队列   3.循环从队列中取出读写要求,然后用处理函数(blk_init_queue设置)进行处理。    这个函数就是连接上层(IO调度)跟底层(硬件操作)的桥梁,当我们调用add_mtd_partitions的时候,就建立了上下层的联系。   4.对不同的处理要求,调用不同的nand的底层处理函数 nand flash驱动代码: #include linux/module.h #include linux/types.h #in
[单片机]
<font color='red'>Smart210</font><font color='red'>学习</font><font color='red'>记录</font>----nand flash驱动
[smart210] s5pv210的中断体系
平台:smart210 CPU:s5pv210 目标:学习s5pv210的中断体系,从一个子中断的使能等设置的流程中体会完整的中断过程。 知识储备:向量中断控制器的介绍 主要有4个VIC,4个TZIC还有一个很特殊的ARM PrimeCell PL192。主要的VIC和TZIC可以支持93个中断源。其中TZIC是为TrustZone技术所准备的,ARM TrustZone® 技术是系统范围的安全方法,针对高性能计算平台上的大量应用,包括 安全支付 、数字版权管理 (DRM)、企业服务和基于 Web 的服务(援引官方的介绍)。TZIC提供了安全控制的nFIQ中断并且使该这类中断从传统的不安全中断VIC中屏蔽掉,从而达到应用在数据
[单片机]
[<font color='red'>smart210</font>] s5pv210的<font color='red'>中断</font>体系
STM32按键中断学习记录
习惯了调程序遇到问题就在网上各种搜罗,常常能从大牛的记录或者回复中得到启发,没想到有一天自己也开始写博客记录下学习的点滴。 学习STM32的这一个月颇有点闭门造车的意思,因为周围没有学习这个开发板的朋友,遇到问题要么远程求助要么自己琢磨,感觉略苦逼,也容易造成不自信。。。最近一直断断续续得学习STM32里的中断实验,遇到了很多问题,今天总算是把程序调了出来,趁着现在内心扑腾的小火苗还在燃烧,先把按键中断实验记录下来。 我使用的开发板是淘宝购置的STM32奋斗板V3,是从朋友处得到的,因为我从来没有接触过硬件开发,导致这一个月里有近四分之一的时间是花在琢磨如何使用JTAG,让开发板和软件连接好上了,一开始甚至连短接线是啥都不知道
[单片机]
STM32学习记录7:定时器中断
配置流程: 1:系统时钟初始化,包括系统时钟和要开放的IO口或者功能的时钟配置。 2:IO口初始化,包括引脚,速率,输入输出模式等。 3:NVIC 中断向量配置 ,中断向量基地址和优先级的配置。 4:TIM3初始化:包括自动重装值,分频值,计数模式,使能TIM中断,使能TIM3外设 5:中断处理函数:注意清除TIMx的中断待处理位 注意: 1:RCC初始化要使能或者失能 APB1 外设时钟。 2:中断处理函数:注意清除TIMx的中断待处理位 TIMx_SR寄存器 3:关于时钟:初始化RCC时使用SystemInit()函数时默认的是AHB不分频,即HCLK等于SYSHCLK,APB2不分频,APB1为HCLK 2分频而定时器3
[单片机]
[smart210] 定时器与PWM
平台:smart210 CPU:s5pv210 目标:学习如何配置定时器timer,实现PWM输出功能以及利用定时器产生中断 知识储备:s5pv210有5个定时器,其中定时器0,1,2,3具有PWM输出功能,均有专门的引脚作为输出。而定时器4是内部定时器,不具备输出引脚。 该CPU的定时器,所需要配置的寄存器并不多,主要有TCON(Timer Control),TCFG0(Timer Configuration 0),TCFG1(Timer Configuration 1),TCNTBn(Timer n Counter Buffer),TCMPB(Timer n Compare Buffer),TCNTOn(Timer n Cou
[单片机]
[<font color='red'>smart210</font>] 定时器与PWM
【STM32F429学习记录】HAL库版——ADC+DMA双缓冲采样和软件滤波例程
本次移植参考了安富莱V7的ADC+DMA双缓冲例程,双缓冲编程的核心就是利用DMA传输一半和传输完成的标志位进行搞事情,将弱定义的DMAx_Streamy_IRQHandler()函数重新定义一下,要注意修改DMAx_Streamy_IRQHandler()中断函数中DMAx- LISR的传输一半和传输完成寄存器的值,要和你自己使用的DMA通道对应上,我自己刚开始学习DMA移植的时候忽略的这一点导致程序卡死不能运行,剩下的部分根据F429的例子进行了小修改,欢迎大家提出补充意见。 下载地址:https://www.lanzous.com/iaisahi /* *********************************
[单片机]
【STM32学习记录】1、点亮LED
我用的硬件是STM32F407最小系统板,其实它和F103差别不大,只是它的处理速度要快一点吧。(STM32F1 基础性 主频72M &STM32F4 高性能 主频168M)这个开发板是从某宝上买的,价格也不贵,四五十块钱适合学生党。 贴上图片 我用的开发板 STM32F407VET6 用的是标准库,话不多说直接上代码 1、LED相关配置函数bsp_led.c #include bsp_led.h void LED_GPIO_Config() { /*开GPIO的时钟*/ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); //使能GPIOA时钟 /*定
[单片机]
小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2026 EEWORLD.com.cn, Inc. All rights reserved