zynq双核AMP实验之cpu1唤醒代码

本文详细介绍了Zynq平台下多核CPU的运行模式,包括AMP、SMP和BMP,重点讲解了如何通过特定函数唤醒闲置的CPU1,以及为维护多核间缓存一致性而采取的措施。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一·多核CPU的运行模式
    从软件的角度看,多核处理器的运行模式有 AMP(非对称多处理)、SMP(对称多处理)和 BMP(受约束多处理)三种运行模式。
    AMP 运行模式指多个内核相对独立的运行不同的任务,每个内核相互隔离,可以运行不同的操作系统(OS)或裸机应用程序。
    SMP 运行模式指多个处理器运行一个操作系统,这个操作系统同等的管理多个内核,如 PC 电脑。
    BMP 运行模式与 SMP 类似,但开发者可以指定将某个任务仅在某个指定内核上执行。
    
二.唤醒CPU1
    zynq中有两个Cortex-A9核,上电启动后,如果不经过配置,代码都是CPU0上执行,并且CPU1同时执行一个等待的命令。如果要在两个核上运行代码,需要人为进行配置。很简单,只要在cpu0中的main函数中执行下面的startcpu1函数。

#define CPU1STARTADR 0xFFFFFFF0
#define CPU1STARTMEM 0x2000000
#define sev() asm(“sev”)
void StartCpu1(void)
{
Xil_Out32(CPU1STARTADR, CPU1STARTMEM);
dmb(); //waits until write has finished
sev();
}

上面的代码中CPU1STARTADR表示的是cpu1的开始地址,这个是固定的,由厂家决定的。
    然后CPU1STARTMEM表示的是CPU1程序开始的地址(一般是用户分配给CPU1的DDR内存的基地址的),CPU1STARTMEM是可以根据ddr的地址,看情况给的,也就是由用户设置的,可以改变的。
    Xil_Out32(CPU1STARTADR, CPU1STARTMEM);这个代码表示把CPU1STARTMEM写入地址CPU1STARTADR中去。这样做的目的是:cpu1被唤醒以后,会读取CPU1STARTADR中的值,也就是CPU1STARTMEM,然后跳转到CPU1STARTMEM这个内存地址上去运行应用程序。(提示:Xil_Out32()这个函数被定义在xil_io.h,作用就是把32位的值写入到对应的地址上去。与其对应的还有Xil_In32(),表示从指定的地址读取32的值)。
    sev()就是唤醒CPU1的指令。
三.缓存一致性
    缓存一致性的意思就是多核cpu访问共享内存时,可以不冲突。所以为了防止zynq的两个核访问共享变量的时候不冲突,需要禁用L1 Cache 缓存,让两个处理器直接跟共享内存进行数据交换,防止数据经过缓存导致数据的冲突和不同步。所以要在两个核上main函数上都要加上Xil_SetTlbAttributes(INTPTR Addr, u32 attrib)函数禁用 Cache 缓存,以维护两个 CPU 访问 共享内存 一致性的问题。第一个参数为共享内存的基地址,第二个参数为设置内存的参数,包括是否禁用 Cache 等(第二个参数一般是0x14de2,我暂时不知道为什么,有兴趣的可以去研究一下)。
四.cpu1工程建立
    写CPU1的代码的时候,只要新建一个NEW PROJECT,只要进行下图那样更改
在这里插入图片描述


### 关于Zynq双核调试方法的详细介绍 #### 调试环境准备 为了成功完成Zynq双核调试,首先需要准备好必要的硬件和软件环境。这包括但不限于Xilinx SDK、Vivado工具链以及目标板的支持文件[^3]。具体来说,用户可以通过以下方式设置开发环境: 1. **安装必要工具** 使用Xilinx Vivado设计套件来配置PS(Processor System)部分,并生成相应的比特流文件。随后利用SDK加载应用程序到ARM Cortex-A9内核。 2. **参考官方文档** 官方手册`ug585-Zynq-7000-TRM.pdf`第6.1.10章节提供了详细的启动流程指导,而应用笔记`xapp1078-amp-linux-bare-metal.pdf`则进一步解释了如何构建可引导解决方案及其调试技巧[^1]。 #### 启动与初始化过程 在实际操作过程中,确保两颗CPU能够按照预期顺序正常工作至关重要。以下是几个关键点: - **FSBL定制化修改** 文件系统引导加载程序(FSBL)扮演着至关重要的角色。通过编辑其源代码中的`main.c`文件,增加特定指令以唤醒第二个CPU。例如定义宏命令`sev()`并通过写入寄存器地址触发事件通知机制让CPU1进入预设位置开始执行任务[^4]。 ```c #define sev() __asm__("sev") #define CPU1STARTADR 0xFFFFFFF0 #define CPU1STARTMEM 0x10000000 void StartCpu1(void) { fsbl_printf(DEBUG_GENERAL,"FSBL: Write the address of the application for CPU 1 to 0xFFFFFFF0\n\r"); Xil_Out32(CPU1STARTADR, CPU1STARTMEM); dmb(); // waits until write has finished fsbl_printf(DEBUG_GENERAL,"FSBL: Execute the SEV instruction to cause CPU 1 to wake up and jump to the application\n\r"); sev(); } ``` 此段代码片段展示了如何向指定内存区域发送信号从而激活次级处理器单元。 - **AMP架构下的分工协作** 非对称多处理模式下,主控核心负责协调其他辅助节点的行为逻辑。因此,在规划整体框架时需考虑清楚哪些功能模块应该分配给哪个具体的计算引擎承担负荷[^5]。 #### 实际案例分享 针对初学者而言,可以从开源社区寻找现成实例作为起点。比如链接至GitCode平台上的项目仓库包含了完整的样例工程结构以及详尽的文字解说材料[^3]。这些资源可以帮助快速熟悉基本概念并积累实践经验。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值