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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
0,前言
4 t9 Z! E: x$ H0 g! j这节课主要讲裸机使用两个CPU跑不同的应用程序。总体来说难度不是很大。使用共享内存时两个CPU进行交互。后面将其烧写进SD卡。. Z. C: H+ f' c, v/ a8 L$ q: T% M' z* r, D
$ j4 h0 W; O+ [8 h4 _$ ^
1,搭建工程(BD)9 S+ p7 |0 c! h* d: n0 V9 x! w  ^: F
这里只使用了uart,后面用到了SD卡。因此这里只需要将这两个勾选。设定好DDR3的类型,去掉PL端的时钟,即可生成顶层文件。这里在前面的章节已经有总结过。不再赘述。/ x2 f6 X- V& B( G
这里提出来一种可以节约时间的方法。使用的时候可以不先将BIT文件导入到SDK工程中。而是直接launch SDK工程后在导入比特流文件。可以节省一定的时间。
/ s, [4 l$ o1 \: @8 M6 H/ k* h% h  }; A: r# K
2,知识储备
8 m8 ]' H; n: ~  Y1 p! J2.1AMP架构; }4 v. g$ n2 g+ }' q2 `/ }
AMP就是非对称多处理器。这种模式是在有多个处理器的情况下,CPU0跑一个程序,CPU1跑一个程序。然后两个通过共享内存进行数据交互。对应的有SMP 对称处理器架构9 S# o1 _0 @" I4 W
9 Q2 I% Z" ~0 R9 v" {
2.2地址空间的分配
9 [) a/ e# F" A, t$ K8 _+ u# y3 w; h2 {下面是提供的ZYNQ地址空间的分配,在UG585中可以找到。我们在运行程序是需要对两个运行地址进行重新分配。: v% z+ B/ B, I6 j, e
2 o  _* a) s# n  n9 C

- O1 S7 `5 O9 F4 }3 f3 b3,代码分析
% j" Z0 g5 t5 y首先建立一个工程命名为CPU0。建立一个共享内存。就是前面的OCM3。' l0 W, @* |' m6 G

7 f, g% u4 C$ g9 R+ ^0 q: l    #include <stdio.h>: [  z) @  R3 T! E8 b# F
    #define COMM_VAL        (*(volatile unsigned long *)(0xffff0000)), [3 l2 V0 J) V* a. [+ _
    //首先进行定义共享内存地址。因为我们需要访问其数据,因此加个*访问其寄存器中的地址0 n1 |& _, X. N3 v! }
    int main()
+ I2 H& b: W$ i0 V2 H* K. L    {
- a3 z( E" {) c            COMM_VAL = 0;5 k/ ?, q0 M9 B1 }, W( Q& k( o: w0 @
            Xil_SetTlbAttributes(0xffff0000,0x14de2);; c0 x8 M& m) \
            //这个函数用于关闭1MB的cache
: [1 Y2 ?0 X$ X' K, b, N, p0 O            while(1) {
' y3 U: a/ B3 G                    while(COMM_VAL == 1){
4 t0 ~5 v1 `- l! X3 f' ~, V                    }
, a3 A9 Q$ u5 t/ T( W  H                    print("Hello CPU0\n\r");
1 Y* p( V4 U+ a' ~7 \& s; Q                    usleep(2000000);
$ S/ u- C& J, Z  ~4 ^* F                    COMM_VAL = 1;5 J! x2 i/ x# }( f
            }" R, h3 [& n/ Z8 m. ^1 M
        return 0;
  B% \4 i# D" r/ X    }' d7 k$ ~: m& A. C9 I
7 J9 W, E3 N& l* O' Q: T
# K! [8 d+ Y& o- p6 i. |6 V! L
下面是关键字的定义。用于直接不想被优化的数据的定义。引荐博文C语言中volatile关键字的作用. f$ }# @( D+ U# G$ ~) p7 t6 l8 E
很简单的,建立一个工程,然后写入代码。主要是对共享内存数据进行处理即可。然后检测数据是不是1.若是1.则进入死循环,不是1,就输出Hello CPU0后将其延时2秒赋值为1。这里是为了和CPU1同时进行的。代码如下。两个合起来看会很容易的理解。
: G+ _* |" H& _- P4 V  \
- l$ X2 N' L( q; Z3 n, ?1 L#include <stdio.h>
9 d1 A- d9 i  Q2 [' I#define COMM_VAL        (*(volatile unsigned long *)(0xffff0000))) J) g5 a: b# ~4 {
int main()
! C* l2 u( ]2 C! y5 o" H{
/ F) C. O; ], X. o% s, D        Xil_SetTlbAttributes(0xffff0000,0x14de2);3 S7 m7 z  v6 O+ u' M
        while(1) {
* a4 e% h" e: V3 z# I/ R3 C* T3 s7 U                while(COMM_VAL == 0){
* _9 J. n0 r% L5 O2 [                }
2 V, v1 t' w8 b9 ]7 S                print("Hello CPU1\n\r");& ~! T% d4 b2 W8 a) {0 Y
                usleep(2000000);0 Y: _  c4 s) q( ]0 h
                COMM_VAL = 0;
7 I- b9 @& ]/ m0 b; z* j9 o: \        }
. ^; \) |) J+ J! K7 R) T7 G* g    return 0;
- d" o; e. m- M- [. u}
% Q9 u% ^" z4 l/ U8 z0 x. s0 U- s
* c1 C! I" n8 I; N- G1 I) m+ l$ B. M4 {+ ~
这里需要进行的是地址空间的分配以及配置应用程序时候的设置。0 W4 D# w2 ]" t  Q8 w
地址空间的设置如下。这是CPU0地址空间的设置。
7 W+ ~. [! {2 n1 b! }
3 M/ M4 J& h4 [& [% _  _9 ^这是CPU1地址空间的设置。
$ U4 d" ?6 F/ U8 L# o
$ u; R6 }( O" O. _) J这里在写CPU1的应用程序时候,需要进行的设置是
9 O6 K- N6 h, d  e
, C: p, R% }4 ]& S* ^5 O- Q7 U8 j0 M同时在debug的时候,下面的两个都要勾选上。# r2 X9 M1 k% [, I( {$ f

5 a9 v. E3 J  o1 p( e) K; P然后点击调试即可,这里调试的时候必须点击CPU1,他才会运转,要是你直接运行的话就可以直接看到现象。我们会发现。串口打印的数据两秒变化一次。: D5 a% U. K# }! S& ~
  A) U4 D  g2 ^$ }2 S3 J
可以看到结果完全正确。! S2 g9 `0 x( J3 L: m8 k1 R: a+ N! B
! B2 o- p/ \) T! L" \
4,烧写进入SD卡5 n4 w- e* [3 l% @$ O" I/ V
这里烧写进sd卡时候由于是需要两个CPU同时工作。因此在生成fsbl的时候要进行简单的设置。
6 C" T, H# F3 Y0 M! }/ B修改Main函数为了启动core1,需要两个步骤,第一个把CPU1应用程序地址写入到0xfffffff0地址中,然后执行SEV指令启动加载CPU1应用程序。参考UG585的启动代码章节。
" ]1 @6 n3 t6 L! ?. w在main函数之上加入如下代码
  i: J6 `$ ~) g$ ]) g3 C+ f% g) h
#define sev() __asm__("sev")& p. w/ j. U4 ~6 N7 _& U7 w
#define CPU1STARTADR 0xFFFFFFF0
2 u& I) I+ Y0 _, z( N#define CPU1STARTMEM 0x2000000
) p; e. {, M2 X) vvoid StartCpu1(void)9 ~! A7 Z. V  c" R! _# k
{1 L. ^3 V( M$ t$ ?
    #if 1; t9 J8 d5 w$ q0 t! W) j
    fsbl_printf(DEBUG_GENERAL,"FSBL: Write the address of the application for CPU 1 to 0xFFFFFFF0\n\r");
9 y, }; h2 f: }' V+ r. H- C9 w    Xil_Out32(CPU1STARTADR, CPU1STARTMEM);
# w0 r' O' r9 D, ]9 _3 i    dmb(); //waits until write has finished
7 ]0 y4 A! z+ v! u    fsbl_printf(DEBUG_GENERAL,"FSBL: Execute the SEV instruction to cause CPU 1 to wake up and jump to the application\n\r");
! p* r8 F  b0 d# f; T4 t    sev();: f. r7 a" H9 P, O* I: _
    #endif
4 b4 R* S3 L  K0 ?2 y% o}
7 t6 d, x& I5 {6 r  Y+ ~% p/ e6 N在load 镜像位置加入如图代码:StartCpu1();
7 \# ?6 I  a7 m% |  n3 d' _; w% U) U7 P' S6 w8 r
4 F, h# E# K- y! X5 ~
将代码随意粘贴到主函数前面即可。然后在load 调用后打开CPU1即可。5 W# D( J8 r+ h2 G. p! v, ]$ |
, m, [3 I/ E8 h) t
接着直接生成即可。将BOOT.bin文件加载如sd卡,启动即可。
# E' i7 l% }# J' r3 X

该用户从未签到

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

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-11-24 20:23 , Processed in 0.187500 second(s), 26 queries , Gzip On.

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

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

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