【ARM系列】ARM Development Studio 2021 FVP调试Startup代码

前言

ARM Development Studio 2021是一款集开发、调试、性能追踪等功能的高性能IDE,这款IDE可以配合DStream仿真器对arm嵌入式平台进行高效开发。其中,ARM FVP是arm提供的一个固定虚拟平台,在没有RTL EMU的情况下可以快速调试软件,加快软件的开发进度。在我们安装DS2021的时候已经自带了一部分FVP,如果你需要使用其他的FVP,可以去ARM官网购买下载。

本文主要介绍使用FVP_Base_Neoverse-N1x4来调试Neoverse N1 Multi-core Startup Code的流程。Startup程序由汇编和C语言实现,同时采用Arm Compiler 6工具链进行编译链接。Startup代码包含vector table,reset handler,cache/mmu configuration,interrupt contorller(GICv3) initialization ,NEON support。并通过一个多核-素数生成器程序来进行说明。

导入工程

在安装ARM Development Studio 2021软件时,自带了一些工程用例,此处通过import将bare-metal工程startup_Neoverse_N1导入到软件中。下图是工程文件导入界面和编译后工程文件介绍。
在这里插入图片描述

代码分析

此处只对代码流程做简单分析,后续会单独出一篇文章对Startup代码做详细配置分析。

1.所有4个core默认启动状态是AArch64 EL3,这段Startup代码在EL3等级会进行一些基础初始化配置操作:设置VBAR,各EL等级的系统寄存器配置,每个core的EL3_STACK空间分配,GIC的配置,EL等级的切换(EL3->EL1N)。
2.切换到EL1后会进行App_STACK分配,使能floating point,无效掉EL1的cache/TLB,设置Translation Table Base的地址,内存属性等。
3.上面两段公共程序执行完成后,会根据CPU ID进行分支选择。

  • CPU1/2/3会执行el1_secondary代码:完成SGI中断初始化配置,并执行“wfi”进入低功耗状态,直至CPU0使用中断将它们唤醒,被唤醒后配置mmu和cache的使能,然后跳转到MainApp。
  • CPU 0作为主核会执行el1_primary代码,包括MMU的配置,__main中完成C语言run_time环境(scatterloading)的初始化,向main()的跳转,并在main中发出SGI-15去唤醒CPU1/2/3和timer的初始化操作,最后跳转到MainApp()。
  • 进入MainApp后,程序通过一个多核素数生成程序,完成核的调度并行仿真。

Run工程

通过Run—>Debug Configurations…进行工程配置
1.在Generic Arm C/C++ Application中选中startup_Neoverse_N1x4,在右侧Connection界面,选择Neoverse N1x4 SMP,表示进行4核调试。
在这里插入图片描述
2.在Files窗口,选用默认路径文件,该文件是通过编译后生成的可执行文件。
在这里插入图片描述
3.在Debugger窗口,选择Debug from entry point
在这里插入图片描述

Core的运行

1.第一条指令

按照上述步骤配置完成后点击Debug后,程序会自动跳转到下图中的第一条指令,可以通过F6通过逐步执行的方式观察CPU的运行步骤,过程中可以通过查看对应的寄存器的值的变化进行沉浸式体验。
![在这里插入图片描述](https://img-blog.csdnimg.cn/76a8d5f674f64e6084110114eceb7ee4.png

2.EL等级切换

可以通过设置断点的方式,观察el等级的切换过程以及CPU状态的变化。将断点设置在drop_to_el1处,然后采用单步执行的方式继续向下执行,会观测到CPU的状态从EL3h切换到了EL1h
在这里插入图片描述

3.el1_primaryd分支:

CPU0进入el1_primaryd分支执行,配置完成mmu页表的配置并跳转到__main,执行 __scatterload和rt_entry,然后进入main()中初始化Primes并配置产生SGI中断唤醒CPU1/2/3,完成timer的初始化,最后进入MainApp程序。
在这里插入图片描述

4.el1_secondary分支

CPU1/2/3会进入el1_secondary分支,完成GIC相关配置后通过wfi进入低功耗模式,等待CPU0通过SGI中断被唤醒。
在这里插入图片描述
CPU1/2/3等待中断被唤醒后,会使能MMU和Cache,然后进入MainApp中执行C函数
在这里插入图片描述

5.MainApp的执行

在这里插入图片描述

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
局部有源忆阻一阶周期电路是一种基本的电路,由一个有源电阻器和一个电容器组成。其中,有源电阻器是一种特殊的电阻器,它可以通过电压控制电阻值,从而实现电路的记忆功能。这种电路可以用于周期信号的滤波和延迟等应用。 下图是局部有源忆阻一阶周期电路的电路图: ![image](https://user-images.githubusercontent.com/44451116/114691829-9d5a8b00-9d48-11eb-9fda-6e45a8a9e7c6.png) 其中,R是有源电阻器的电阻值,C是电容器的电容值,Vin是输入信号,Vout是输出信号。有源电阻器的电阻值可以表示为: ``` R = Ro * (1 + β * Vout) ``` 其中,Ro是有源电阻器的基准电阻值,β是电阻器的控制系数,Vout是输出信号的电压。 根据基尔霍夫电压定律,可以得到: ``` Vin = Vout + L * dI/dt ``` 其中,L是电路中的电感值,I是电路中的电流。假设输入信号为周期信号,频率为f,则可以将输入信号表示为: ``` Vin = Vp * sin(2πft) ``` 其中,Vp是输入信号的幅值,t是时间。 将上述两个公式代入基尔霍夫电压定律的式子中,可以得到: ``` Vp * sin(2πft) = Vout + L * dI/dt ``` 对上式两边同时求导数,可以得到: ``` 2πfVp * cos(2πft) = dVout/dt + L * d^2I/dt^2 ``` 将有源电阻器的电阻值代入电流的表达式中,可以得到: ``` I = Vout / (Ro * (1 + β * Vout)) ``` 将上式代入上式的左边,可以得到: ``` 2πfVp * cos(2πft) = dVout/dt + L * dVout/dt * β / (Ro * (1 + β * Vout))^2 + L * Vout / (Ro * (1 + β * Vout))^2 * dVout/dt ``` 将上式整理,可以得到: ``` dVout/dt + R1 * Vout = R2 * cos(2πft) ``` 其中,R1和R2是一些常数,可以表示为: ``` R1 = L / (Ro * (1 + β * Vout)) R2 = 2πfLβVp / (Ro * (1 + β * Vout))^2 ``` 这个式子是局部有源忆阻一阶周期电路的微分方程,可以用来描述电路的行为。该电路的特点是具有记忆功能,输出信号的电阻值是由输入信号和输出信号的电压值共同决定的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值