找回密码
 注册
关于网站域名变更的通知
查看: 402|回复: 1
打印 上一主题 下一主题

AMP架构双核应用程序开发和软中断处理(2)

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2020-12-3 13:21 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式

EDA365欢迎您登录!

您需要 登录 才可以下载或查看,没有帐号?注册

x

0 g- F" D& P, ~0 Q* M  v0,前言背景
% ]+ K1 q+ t) Q. ^这节课讲了中断。可能很多人和我一样不理解什么是中断。其实这个概念说起来很好理解,就是简单的停下来。可是又有什么用处?在系统设计中又处于什么样的一个地位呢?
2 a& Z5 I! t% r; i7 T; S这里引荐博文(不知道不翻墙能不能看)中断解析
% M4 \8 Z/ `, b3 b/ ~0 H- q( C这里先综合百度维基百科中的,加上我的理解,说说什么是中断。中断简单的来理解就是一种技术,这种技术可以显著提高计算机的工作效率。因此有比较重要的作用。这么重要,那么到底什么是中断???这里不用教科书中的定义(中断指当出现需要时,CPU暂时停止当前程序的执行转而执行处理新情况的程序和执行过程。即在程序运行过程中,系统出现了一个必须由CPU立即处理的情况,此时,CPU暂时中止程序的执行转而处理这个新的情况的过程就叫做中断。)。简单的打一个比方。假设我正在敲的博文是我正在执行的系统。那么我点击Ctrl + S就可以理解为一个中断。因为CSDN官方不可能随时每隔1us给我保存一次我的数据,而我的保存指令可以理解为一个中断,这个时候,系统就会将我的数据上传至服务器。而在我写博文没有点击保存的时间,服务器就可猥琐欲为的去做任何事情。这就是所谓的中断。下图就是博文中的图,用以借鉴。中断回调函数可以就是异常处理,而回调函数就是我们CPU响应中断所执行的内容。用前面那个例子,就是保存我的博文至服务器,就是我的中断回调函数。
! g: q8 w! m# r * P- l$ C3 ?+ ?* F
) y3 D" r" i" e5 q! _  v
1,中断详解与设计实现
: y8 j3 T9 q6 r+ U软中断,由CPU0或者CPU1发起,可以相互中断。0 y; W4 C7 }$ L% L
GIC(Generic Interrupt Controller)通用中断控制器。通关软终端进行控制核间的中断,控制出发那个CPU。
) }# ~! X) z9 B5 A- F; y 9 r  o! r/ c. H4 [
下面是老师总结的一般处理过程
2 f; A4 q) p! h& S' z3 S2 t 4 ~+ P; _3 f% C& `; j
中断回调函数是什么。由于外部请求触发的一个中断,而CPU中断的这段时间所做的事情,就是中断回调函数的执行的。中断也有其优先级,可以进行设置。
2 i' t/ N1 u, D: I7 P4 [7 C
) L9 m" d, P/ h- L8 y2 W/ N接下来就是代码分析首先定义一个初始化函数用于主函数调用。我们先看初始化函数
' [* c7 [) Z, H先看这个函数Xil_ExceptionInit();就是初始化,打开handler
5 j: X- ~& {( ~/ B4 L% @) e该函数是一个公共API,用于跨所有受支持的ARM处理器初始化异常处理程序。对于ARM Cortex-A53、Cortex-R5和Cortex-A9,异常处理程序正在被静态初始化,而这个函数什么也不做。但是,它仍然用于处理向后兼容性问题(在早期版本的bsp中,这个API用于初始化异常处理程序)。( F* r- e1 {0 o! I6 f
其次就和GPIO中的类似了。先得到期间地址,在初始化。
- w0 h$ a1 P& q, g% i+ F( @, f  d- l) H3 G6 C5 i
        status = XScuGic_CfgInitialize(&ScuGic,ScuGicCfgPtr,ScuGicCfgPtr->CpuBaseAddress);7 Q3 G* y+ R0 h* Q; s6 W
        if(status != XST_SUCCESS){
7 W6 v4 E  K4 h- J; E4 V7 J6 o2 F                return status;
4 j, Z! `3 T: _% E3 [        }
3 E7 e! F6 l& {+ ]8 P3 }5 z& s' o4 x* k1 P2 G( ^; o- @% l
一般这种写法是由于返回值是一个状态,我们定义一个变量,用于判断返回值是否正确,用于调试程序。
& m' ?. a3 F1 k  t. N: I1 I( f接下来是Xil_ExceptionRegisterHandler。异常注册管理器。(Xil_ExceptionHandler)XScuGic_InterruptHandler这是一个强制类型转换,其中的函数是用于设置中段优先级的。这里没有用到,因为只有一个中断。这里就将信息传回到CPU了。接下来就是连接软中断回调函数。XScuGic_Connect就是我们的连接函数。
; d# n# v2 `4 ~. g. d" x  m , l1 k  v7 [" d- h* z, F

+ j8 q9 z& R& m$ k9 I这是函数的说明。函数有返回值。我们使用同样的方式。方便调试。: {+ O: m9 N0 f3 u1 f- k3 }, M
接下来使能软中断。(连接之后,需要使能才能使用)传递进去参数就是连接的。首先是实例化的XScuGic的指针其次是中断ID。; |- K, o7 T4 h
最后是使能处理过程。
3 i% ?0 n8 j. g& t
6 }4 Z6 J8 _9 M1 |$ s    //initial gic & software intr
1 Y' ?7 p: S/ s+ w, J" P+ @4 j    int initSwIntr(){# S  R7 N& [* A1 U1 e3 ~; M5 @( w
            int status;
  f% v6 M) n% b0 ]/ t2 v            Xil_ExceptionInit();//打开系统异常
. T+ J, j1 A2 t' q& a5 h            ScuGicCfgPtr = XScuGic_LookupConfig(GIC_ID);
7 Y$ C" y; u! I4 q6 B, o4 a! ?            status = XScuGic_CfgInitialize(&ScuGic,ScuGicCfgPtr,ScuGicCfgPtr->CpuBaseAddress);
1 I; k3 k2 _4 E! R            if(status != XST_SUCCESS){3 H# G6 J% [2 ^8 J  J% L- w' f
                    return status;
3 N& u" y5 p% `6 v  V! y6 H, L            }
4 B( I# D. _: n* Z. @6 F8 K) _/ u            Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,(Xil_ExceptionHandler)XScuGic_InterruptHandler,&ScuGic);' D3 e1 g! U" P5 q6 i: O, `
            status = XScuGic_Connect(&ScuGic,CPU0_SW_INTR,(Xil_ExceptionHandler)cpu0IntrHandler,&ScuGic);& W! d+ Y% i" }: r/ ]# y/ X
            if(status != XST_SUCCESS){, J1 Z8 g1 F! e* x; R
                            return status;
3 Y. z" G, o6 i! X0 R$ f                    }% W7 _7 ^# y* n- a. K" T; z6 r
            XScuGic_Enable(&ScuGic,CPU0_SW_INTR);
9 p4 e% h' o' Z  m: Q# z- s  Z            Xil_ExceptionEnable();8 s/ Y6 H1 H5 ]+ g
            return XST_SUCCESS;! V6 c; p8 G' M" _
    }- Z  c. K! M, E, T- Z  ~& @

; s( S- }! c/ s. C接下来对回调函数内容进行编写。、
8 C, U: J! s# T, ]% L6 p. G. \1 k5 s( G0 b5 c
, K2 u  n7 T0 S  l' E    //callback function
) X2 ?/ f3 q2 S' ~3 Y. l5 A    void cpu0IntrHandler(void * Callbackref){
" I: Z7 g( _# X! v* Z+ o1 C1 K. ]            printf("cpu1 interrupt cpu0 success ! \n\r");
" R! ~- p0 A4 J0 u2 {    }: t+ c! ~' A' \. H1 e. P
: e1 c( v; X. X" ~' n. e8 _
接下来就是主函数8 N3 Z1 i. R' y# t
主函数进行初始化中断。然后就可以使用中断了。
6 p0 d5 L/ ]7 h; K6 C/ c( k9 I6 V4 p4 A: b, j. }% _
int main(). t2 l' p& A+ v8 k4 g& c
{
* a* ~  L, R5 o- E        COMM_VAL = 0;
: N" j: m* s) ?. w/ H% E        Xil_SetTlbAttributes(0xffff0000,0x14de2);
$ q7 J( R( o: u* U* l) w        int status;0 @- z& _) I+ |. [) d8 N
        status = initSwIntr();
/ V4 p% I% \* z  s4 R) M- a        if(status != XST_SUCCESS){
$ S' J) {6 U' n                return status;, O' K4 L$ H. H! E9 ^
        }
( x! T/ k0 A& h# _9 j        while(1) {. Y3 o2 _2 f/ X/ l$ a) n( Z
                print("Hello CPU0\n\r");, e0 C; ]  [9 J7 @: H9 ~) U2 i
                XScuGic_SoftwareIntr(&ScuGic,CPU1_SW_INTR,XSCUGIC_SPI_CPU1_MASK);
; I0 R: M. e$ S# G7 F                usleep(2000000);
" N3 q( k2 b5 R1 c                COMM_VAL = 1;
  f0 Q! [" P1 |% E" N! x        }* f  r. X8 W% o0 i8 x* |$ K
    return 0;
# f# ~: Q1 g. V+ `}0 p2 N% ^  s9 ^% Y. m( B0 e! r

5 @0 @4 Y# W) F- h这里的中断使用方式就是调用这个函数。XScuGic_SoftwareIntr
7 W* b3 _/ t# y% M6 [/ Q" h" Y结构体指针,初始化ID,CPUID。6 ~5 w  R/ @: z; C+ u5 I( T& |
这里的中断只是发起,至于执行什么,完全是由中断函数决定的
- `9 ]; |9 A  ?/ I% j
& ^! m- a; P! V4 c
+ T2 z: p0 q  P
" O$ u; s# B0 s; U7 E& O) T7 v4 t( j同样使用一样的代码。对CPU1进行中断的测试。- h# o8 w( S7 S( |1 _) U9 d
这里只有修改CPU1-CPU0即可。. }0 W% @8 I" ~* C

, o& j: j" B! X/ l* W$ x最后可以看到结果。两秒发送一次,使能中断成功!!!
! K2 i! D- |2 m7 ` 2 ]& Y+ b3 ]* p. t% w; I3 _

该用户从未签到

2#
发表于 2020-12-3 14:30 | 只看该作者
AMP架构双核应用程序开发和软中断处理
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

推荐内容上一条 /1 下一条

EDA365公众号

关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

GMT+8, 2025-11-25 00:36 , Processed in 0.203125 second(s), 27 queries , Gzip On.

深圳市墨知创新科技有限公司

地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

快速回复 返回顶部 返回列表