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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
0,前言
. Q" G" p' ~/ [, \这节课主要讲裸机使用两个CPU跑不同的应用程序。总体来说难度不是很大。使用共享内存时两个CPU进行交互。后面将其烧写进SD卡。
) p' D  W, n7 N6 n3 M
, l3 z2 f4 h1 p5 p- E) S: R1,搭建工程(BD)3 L& ?9 w/ y5 i/ p$ M6 ]
这里只使用了uart,后面用到了SD卡。因此这里只需要将这两个勾选。设定好DDR3的类型,去掉PL端的时钟,即可生成顶层文件。这里在前面的章节已经有总结过。不再赘述。7 X6 c$ F4 l  {
这里提出来一种可以节约时间的方法。使用的时候可以不先将BIT文件导入到SDK工程中。而是直接launch SDK工程后在导入比特流文件。可以节省一定的时间。
. `+ V2 _0 P, @1 c" y. ?  X9 x
2 c5 H  Y* f$ X7 c- {2,知识储备) D2 Q7 G* W8 r! X
2.1AMP架构+ d* W' ]" O# U8 W9 e! y7 T) V+ Q6 x
AMP就是非对称多处理器。这种模式是在有多个处理器的情况下,CPU0跑一个程序,CPU1跑一个程序。然后两个通过共享内存进行数据交互。对应的有SMP 对称处理器架构
( U- z. _4 P! N/ ^5 d9 j" m. c4 {1 p5 o# x
2.2地址空间的分配
* q# H% V7 d8 Q% B1 ^) m2 [下面是提供的ZYNQ地址空间的分配,在UG585中可以找到。我们在运行程序是需要对两个运行地址进行重新分配。) R6 P5 C0 v7 Z6 O' @+ d' M
# Z" m4 ~9 P2 z" z" I6 `' V

4 z0 j  G0 Q: ]0 W5 Z" H2 u3 r3,代码分析
( D8 c8 o" m1 R4 Y; @  L  ~首先建立一个工程命名为CPU0。建立一个共享内存。就是前面的OCM3。: F4 O0 R) k# M- O0 x; |

2 T, j4 F. D) U( @' _/ U7 Y4 @    #include <stdio.h>
0 g; r* j; J. @6 {+ Z2 e+ C( J    #define COMM_VAL        (*(volatile unsigned long *)(0xffff0000))5 ~& I$ Q1 x" `, Q! f
    //首先进行定义共享内存地址。因为我们需要访问其数据,因此加个*访问其寄存器中的地址+ D4 [9 X! L! f' p. t
    int main()3 L. g* m- [! F8 U" k) z9 X
    {% p. R" L4 C& k
            COMM_VAL = 0;
2 S( U+ F' L+ s8 c3 B1 q. [            Xil_SetTlbAttributes(0xffff0000,0x14de2);
# K4 K, I5 }  d; ~            //这个函数用于关闭1MB的cache
) D. k% E3 o$ O* [            while(1) {0 X8 u0 c# O9 k8 f. J# }  G
                    while(COMM_VAL == 1){
( A# }+ g: h8 u1 L9 K                    }
  x; \# K" x4 Y                    print("Hello CPU0\n\r");
$ R9 y8 V# V& M2 @( j& G2 ^                    usleep(2000000);
6 v7 }7 B" W  Z7 h* O6 W5 c                    COMM_VAL = 1;( a- L9 U, a6 h. ^$ [
            }6 V/ K+ C2 V. ^* P- x; f
        return 0;4 B& _% i/ j: A1 z: Q0 W
    }8 X0 [, {# r9 Y
+ E1 h0 G$ f) ~0 H

- c" k( f' a8 a下面是关键字的定义。用于直接不想被优化的数据的定义。引荐博文C语言中volatile关键字的作用
2 ^3 v9 ]6 [2 |9 [9 `  F: g, w很简单的,建立一个工程,然后写入代码。主要是对共享内存数据进行处理即可。然后检测数据是不是1.若是1.则进入死循环,不是1,就输出Hello CPU0后将其延时2秒赋值为1。这里是为了和CPU1同时进行的。代码如下。两个合起来看会很容易的理解。
! t; Q/ F2 m4 V9 \4 Y9 A% e
0 R/ U3 M* q* B( X9 _3 Y#include <stdio.h>5 ]. v( ?0 |0 J- @2 |0 `1 ]- d
#define COMM_VAL        (*(volatile unsigned long *)(0xffff0000))
7 s3 Q$ ~% Z0 Tint main()# ]) l* ^3 d& H8 Y, Q3 r
{6 ?' j6 j7 O% i" b# Z
        Xil_SetTlbAttributes(0xffff0000,0x14de2);6 m/ ?# V" S$ n9 e5 a8 b
        while(1) {
! M1 u. D: X& F( G* G                while(COMM_VAL == 0){
2 G: `( w0 @: t6 C! S                }# d+ O) T* r$ g- @  ~& O
                print("Hello CPU1\n\r");/ O/ ^, ~* @- G$ W
                usleep(2000000);
. s4 M# Y2 ]6 \7 e7 n, G                COMM_VAL = 0;& u& ^1 l' \* C6 g
        }
6 |5 R0 t$ y& Z, |3 J* P# b; H7 p! L! y    return 0;) Z$ a/ R6 J% w2 R
}
" A* w- H0 ?, ~, R5 C7 I' d4 c+ ~  n5 \9 L4 n

- m* B, a  `' ]8 T4 z! @这里需要进行的是地址空间的分配以及配置应用程序时候的设置。# P( x+ P6 f" h$ W
地址空间的设置如下。这是CPU0地址空间的设置。% ^, f$ Q2 B0 N; \. N9 v

. X# X* O, r! z( z% v$ a这是CPU1地址空间的设置。
/ b/ }- ]- w  t; e( e1 L$ x9 o 6 _  e6 l/ t/ [: `5 @$ U* B
这里在写CPU1的应用程序时候,需要进行的设置是$ z- @1 }7 U* I; u* U

8 i0 }2 k+ O6 ~* o同时在debug的时候,下面的两个都要勾选上。3 X/ p0 y0 ], h; n2 W4 n6 S

  l( Z' @% c  Y! ~& n% p5 G/ e8 i然后点击调试即可,这里调试的时候必须点击CPU1,他才会运转,要是你直接运行的话就可以直接看到现象。我们会发现。串口打印的数据两秒变化一次。
# h$ B' ]  s/ U6 t2 t( P0 h & y, h5 I1 u! u' ~- t& f+ s4 a
可以看到结果完全正确。
* T' g  d& D% p8 e2 [0 N( M$ r
2 H$ ~3 E2 i2 a# P2 I- J7 {* u4,烧写进入SD卡
3 v" f  O' P3 h* U# N9 Q- {6 x  |这里烧写进sd卡时候由于是需要两个CPU同时工作。因此在生成fsbl的时候要进行简单的设置。
* l' V$ B# F6 M$ Y# X. U7 E修改Main函数为了启动core1,需要两个步骤,第一个把CPU1应用程序地址写入到0xfffffff0地址中,然后执行SEV指令启动加载CPU1应用程序。参考UG585的启动代码章节。
$ @, M% V  p% h7 ]2 Q在main函数之上加入如下代码
% I2 {  \/ r; y1 J) V5 |8 _, J8 o# D9 a7 R9 g# c+ W% z
#define sev() __asm__("sev")( C. z6 s  ?1 w: K, U- b
#define CPU1STARTADR 0xFFFFFFF0$ N; W4 E7 z7 E+ e8 |
#define CPU1STARTMEM 0x2000000
: F( i$ i1 G4 }' l/ T8 Z7 Ovoid StartCpu1(void)
+ [0 \# t; V) q  a0 v8 {2 G+ K{
) n0 R/ E7 T$ v$ @$ K; @6 _$ l    #if 1& o, ~% g; E2 E) i- t* W1 a
    fsbl_printf(DEBUG_GENERAL,"FSBL: Write the address of the application for CPU 1 to 0xFFFFFFF0\n\r");5 K  M& T7 B) H- X. G$ ?, \
    Xil_Out32(CPU1STARTADR, CPU1STARTMEM);$ ?# M1 _4 T  @8 K5 x# b6 V7 l4 r& K- o
    dmb(); //waits until write has finished9 O* \2 a9 X2 K
    fsbl_printf(DEBUG_GENERAL,"FSBL: Execute the SEV instruction to cause CPU 1 to wake up and jump to the application\n\r");! n$ @" e# g& o% s( i
    sev();
9 ], b3 n; Z  Q) k    #endif5 E/ P1 s" a0 L% \. j
}
  e4 l% f/ g4 a在load 镜像位置加入如图代码:StartCpu1();! Q( z* l- k' j# D  @2 Q

. U$ {  a& j" y/ L% d
% e. P0 \$ J5 G' _% ~5 j7 ~& w将代码随意粘贴到主函数前面即可。然后在load 调用后打开CPU1即可。
6 C4 N" ^' |5 }* f
5 m2 f/ e2 C! t9 I; B) @& |( T接着直接生成即可。将BOOT.bin文件加载如sd卡,启动即可。% d; M; [, p4 Y1 L0 [* {

该用户从未签到

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

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-11-24 21:47 , Processed in 0.171875 second(s), 26 queries , Gzip On.

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

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

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