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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
0,前言
3 B, h" n- z& J- a* \* P这节课主要讲裸机使用两个CPU跑不同的应用程序。总体来说难度不是很大。使用共享内存时两个CPU进行交互。后面将其烧写进SD卡。
8 _1 n! ^' y3 ^" P. f  |; V5 D  V- i+ Q7 \9 d, V/ z2 M; j
1,搭建工程(BD)
3 b5 P7 y" S' D8 ]& K这里只使用了uart,后面用到了SD卡。因此这里只需要将这两个勾选。设定好DDR3的类型,去掉PL端的时钟,即可生成顶层文件。这里在前面的章节已经有总结过。不再赘述。: f& E6 o. i$ v* K% s8 J
这里提出来一种可以节约时间的方法。使用的时候可以不先将BIT文件导入到SDK工程中。而是直接launch SDK工程后在导入比特流文件。可以节省一定的时间。7 J" |7 q) N, Z/ }; \) c" h

4 L: c  t8 r4 H2,知识储备2 M3 Y( S. A: T4 r$ T7 y0 _4 i
2.1AMP架构& ?9 \* b7 ~+ b, B
AMP就是非对称多处理器。这种模式是在有多个处理器的情况下,CPU0跑一个程序,CPU1跑一个程序。然后两个通过共享内存进行数据交互。对应的有SMP 对称处理器架构$ y& B& i# W! V3 o

: u6 G: {" o" i2.2地址空间的分配! |1 T2 A6 x! u- b
下面是提供的ZYNQ地址空间的分配,在UG585中可以找到。我们在运行程序是需要对两个运行地址进行重新分配。
7 m4 j- \! @. Y4 U! t
. g: E1 q; v  m; p) I$ z; l, n3 K! D( n  I
3,代码分析8 q8 a4 z3 K) J$ r
首先建立一个工程命名为CPU0。建立一个共享内存。就是前面的OCM3。' I5 w) r% {' l& D  u" C
1 o) m. V7 u0 L4 w- e5 B6 p
    #include <stdio.h>  P* R3 }4 Q" q7 Z+ K
    #define COMM_VAL        (*(volatile unsigned long *)(0xffff0000))
; N7 K( D  S9 D1 ~    //首先进行定义共享内存地址。因为我们需要访问其数据,因此加个*访问其寄存器中的地址! c9 |4 X3 |! F2 c6 @
    int main()
4 F' K% E5 t) O    {, J3 @- e& e7 {; d' |
            COMM_VAL = 0;2 Q6 y7 x7 T9 ^" N& x. R6 M! a! y
            Xil_SetTlbAttributes(0xffff0000,0x14de2);4 U/ y; q/ I8 a2 f' l! E# X9 k
            //这个函数用于关闭1MB的cache% n! v! o% u* D
            while(1) {# S( L" S- @4 ^! |: `* U& r
                    while(COMM_VAL == 1){
% p( P9 y* ^0 R                    }
8 Q, J9 {9 H9 S0 w                    print("Hello CPU0\n\r");* T" F: x5 o/ W- T6 N0 I
                    usleep(2000000);2 y" V  u, @: z3 {  U  D( r# q' o
                    COMM_VAL = 1;
9 O# _! _" r! Q            }
6 |; k2 Y% Z: f: H4 b2 x# ~        return 0;
/ q+ X+ `; v2 z" w' Y+ E* D+ r1 `    }8 g% P0 o) u0 G- X

, s# I8 y; a0 s0 \) |
! R2 S! B8 h, e/ m- I. v9 }' A) T# \8 F; Y% u下面是关键字的定义。用于直接不想被优化的数据的定义。引荐博文C语言中volatile关键字的作用
4 A( W  e8 y6 B; Z1 m+ E很简单的,建立一个工程,然后写入代码。主要是对共享内存数据进行处理即可。然后检测数据是不是1.若是1.则进入死循环,不是1,就输出Hello CPU0后将其延时2秒赋值为1。这里是为了和CPU1同时进行的。代码如下。两个合起来看会很容易的理解。
- s4 F& `/ M1 L$ C0 v) d$ v4 ^5 _. c9 X/ B) m) j! B1 ]$ N& E
#include <stdio.h>0 G: s2 y2 s: B( g
#define COMM_VAL        (*(volatile unsigned long *)(0xffff0000))4 Q' R: [! s! n6 m$ d4 W5 b
int main()1 s& Y0 |8 H3 b  ?5 z' F* @
{
  Q* c) G( A, [7 U( s3 b. ]        Xil_SetTlbAttributes(0xffff0000,0x14de2);0 z: u+ ]5 f: ~
        while(1) {$ ]: Y) W) H* E# ]# z$ R- T
                while(COMM_VAL == 0){
6 a1 h6 H& [6 l                }" N# F! z# O) A4 V% C
                print("Hello CPU1\n\r");/ [! Y# l/ b% Q  z  |& b3 f1 e
                usleep(2000000);( F5 P; J) t/ N- U. @
                COMM_VAL = 0;0 c2 y- `: b. R* o3 c8 X. A& l
        }
/ l% t2 _- c) ^4 w) f' D$ N2 C# o    return 0;2 k) ~  |4 L: t4 y; Z
}' E' ~, u1 k) L5 L3 l

* x8 i7 f8 d3 l: T1 H3 C
5 {: X3 N  p" v9 u; ]这里需要进行的是地址空间的分配以及配置应用程序时候的设置。
% F1 ]5 J+ x" d+ g! F6 V地址空间的设置如下。这是CPU0地址空间的设置。+ |7 A, W& v  A8 E
  T$ ~! e+ d' N/ D
这是CPU1地址空间的设置。+ o' b+ z( X$ i' {; e- y

* F7 Z& f5 K( l* `7 A2 H) N) V这里在写CPU1的应用程序时候,需要进行的设置是
0 j* V4 [' D/ y5 ~5 A; A5 e
' X2 r4 h* _% M7 z+ @3 f( P同时在debug的时候,下面的两个都要勾选上。: t" [* v/ z: G, u( c
4 m* u' r3 b  f: ]; J6 M+ l
然后点击调试即可,这里调试的时候必须点击CPU1,他才会运转,要是你直接运行的话就可以直接看到现象。我们会发现。串口打印的数据两秒变化一次。- _1 I" b% M# E* t! _
9 W0 V( w7 P1 @! q! A
可以看到结果完全正确。+ B+ `0 l( {6 x! Q2 z

6 V3 k0 V5 ]6 L/ j; |4,烧写进入SD卡+ `' _; t$ _9 A2 I4 g
这里烧写进sd卡时候由于是需要两个CPU同时工作。因此在生成fsbl的时候要进行简单的设置。
1 E" u8 {" v/ f$ O1 _7 z* y修改Main函数为了启动core1,需要两个步骤,第一个把CPU1应用程序地址写入到0xfffffff0地址中,然后执行SEV指令启动加载CPU1应用程序。参考UG585的启动代码章节。6 D( A9 b* {/ s3 p* w6 ^
在main函数之上加入如下代码- T2 t- J  \4 O1 l/ C; q( ~
3 {- @( r0 n/ U6 ^: O8 C" h* y" u8 n
#define sev() __asm__("sev")4 s* j: t* i$ r: D7 v
#define CPU1STARTADR 0xFFFFFFF0; L  r' ?3 _- U" ]
#define CPU1STARTMEM 0x2000000
- _/ q3 J- }+ Jvoid StartCpu1(void)
) E% a6 V9 P. M% q( ?; N{
, _7 h* J2 g  V" d; a" t    #if 18 w3 U2 Z, O" y4 {
    fsbl_printf(DEBUG_GENERAL,"FSBL: Write the address of the application for CPU 1 to 0xFFFFFFF0\n\r");& {) ^' e' X/ s! E
    Xil_Out32(CPU1STARTADR, CPU1STARTMEM);' l& h* C" n- \
    dmb(); //waits until write has finished
$ M8 V3 O& ^) V* W) l; G) D/ N    fsbl_printf(DEBUG_GENERAL,"FSBL: Execute the SEV instruction to cause CPU 1 to wake up and jump to the application\n\r");4 b8 G* [0 l$ Y% h& {: M
    sev();2 K; I4 B' i0 i
    #endif4 Q: m- A2 j5 l+ h
}
' s9 e  L6 H* P, l3 ~在load 镜像位置加入如图代码:StartCpu1();
$ A  p& z+ v% f* E% w* @4 B1 I; U4 S8 R& z& v4 X6 n
* j# O! K; W5 N) [
将代码随意粘贴到主函数前面即可。然后在load 调用后打开CPU1即可。
: \# h/ D% ~( \' h
* A: G5 L2 D  N5 J! w接着直接生成即可。将BOOT.bin文件加载如sd卡,启动即可。
' X5 B8 ]6 ~* V# i0 ~4 S

该用户从未签到

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

本版积分规则

关闭

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

EDA365公众号

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

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

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

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

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