
参考AURIX™ System Architecture 和 Multicore_1 for KIT_AURIX_TC397_TFT:
CPU架构;
TC1.6.2P实现:
这一部分手册的内容直接机翻了. 至于怎么用, 这节先不管, 有个概念即可.
AURIX™ TC3xx平台具有三个独立的片上连接资源:
SRI Fabric将TriCore CPU, DMA模块和其他高带宽请求者连接到高带宽存储器和其他资源用于指令提取和数据访问.
SPB将TriCore CPU, DMA模块和其他SPB主设备连接到中低带宽外设, SPB主服务器不会直接连接到SRI Fabric,而是将通过SRI_F2S桥访问SRI附加的资源.
BBB将TriCore CPU, DMA模块和SPB主站与ADAS资源相连. 主SRI不直接连接到BBB, 但通过SFI_S2F桥接器访问BBB连接的资源.
SRI连接TriCore CPU和高性能模块如DMA等. 结构的关键组件是SRI交叉开关, 它将所有代理(agent)连接到一个SRI域. SRI交叉开关承载域的SRI主站和SRI从站之间的事务. SRI交叉开关支持不同SRI主代理和SRI从代理之间的并行事务. 除了并发请求的并行性, 它还支持从SRI主设备到SRI从设备的流水线请求. SRI功能概述:
与以前的基于AURIX™的产品相比,AURIX连接性的主要差异:
上图的解释:
上图的解释:
名词的解释:
| Term | Description |
|---|---|
| Agent 代理,媒介 | An SRI agent is any master or slave device which is connected to the SRI Fabric. |
| Master 主 | An SRI master device is an SRI agent which is able to initiate transactions on the SRI Fabric. |
| Slave 从 | An SRI slave device is an SRI agent which is not able to initiate transactions on the SRI. It is only able to respond to transactions operations that are directed to it by the SRI Fabric. |
| SRI crossbar 交叉开关 | The SRI crossbar provides the interconnects between Masters and Slaves in the same domain. The SRI crossbar includes arbitration mechanisms and error capture capabilities. |
| MCI 主连接接口 | Each Master is connected via one Master Connection Interface. The SRI Fabric contains control and status registers which affect MCI priority and provide related error information. |
| SCI 从连接接口 | Each Slave is connected via one Slave Connection Interface. The SRI Fabric contains control and status registers which include control and error informations related to the SCI. |
| Domain 域 | An SRI domain consists of those agents which are connected to a specific SRI crossbar. There will be at least one Master (or S2S bridge acting as a Master) and at least one Slave (or S2S bridge acting as a Slave), and an instance of a crossbarproviding full or partial connectivity between all the agents in the domain. |
| Arbiter 仲裁 | If two (or more) Masters attempt to access the same Slave, the arbiter provides the decisions as to the order in which Masters gain access. The order is determined by the two-level round-robin mechanism implemented in the arbiter and the configuration programmed by the user. |
拍脑袋能想出来的一般多核注意事项:
英飞凌多和单片机应用技术一书中, 以TC2x举例:
CPU0外的其它CPU上电后会保持在HALT暂停状态, 需要通过CPU0设置它们的PC程序指针寄存器, 设置HALT相应的位, 从HALT状态切换到RUN状态.
新工程我们打开 AURIX Development Studio, File -> New -> New AURIX Project, 新建的空工程默认就有6个Main.c文件对应6个CPU:
Cpu0_Main.c 内容默认为:
#include "Ifx_Types.h"
#include "IfxCpu.h"
#include "IfxScuWdt.h"
IFX_ALIGN(4) IfxCpu_syncEvent g_cpuSyncEvent = 0;
void core0_main(void)
{
IfxCpu_enableInterrupts();
IfxScuWdt_disableCpuWatchdog(IfxScuWdt_getCpuWatchdogPassword());
IfxScuWdt_disableSafetyWatchdog(IfxScuWdt_getSafetyWatchdogPassword());
IfxCpu_emitEvent(&g_cpuSyncEvent);
IfxCpu_waitEvent(&g_cpuSyncEvent, 1);
while(1)
{
}
}
Cpu1_Main.c 内容默认为:
#include "Ifx_Types.h"
#include "IfxCpu.h"
#include "IfxScuWdt.h"
extern IfxCpu_syncEvent g_cpuSyncEvent;
void core1_main(void)
{
IfxCpu_enableInterrupts();
IfxScuWdt_disableCpuWatchdog(IfxScuWdt_getCpuWatchdogPassword());
IfxCpu_emitEvent(&g_cpuSyncEvent);
IfxCpu_waitEvent(&g_cpuSyncEvent, 1);
while(1)
{
}
}
其中:
点灯为例, 如果一个核操作一个LED翻转, 互不干涉, 直接在各个Cpux_Main.c初始化延时翻转即可, 不存在冲突. 官方给的这个例子是3个核控制一个LED:
Cpu0_Main.c 内容(注意LED初始化放到其它CPU初始化之前):
#include "Ifx_Types.h"
#include "IfxCpu.h"
#include "IfxScuWdt.h"
IFX_ALIGN(4) IfxCpu_syncEvent g_cpuSyncEvent = 0;
#define LED &MODULE_P13, 0
uint16 g_turnLEDon = FALSE;
void core0_main(void)
{
IfxCpu_enableInterrupts();
IfxScuWdt_disableCpuWatchdog(IfxScuWdt_getCpuWatchdogPassword());
IfxScuWdt_disableSafetyWatchdog(IfxScuWdt_getSafetyWatchdogPassword());
//initLED
IfxPort_setPinHigh(LED);
IfxPort_setPinMode(LED, IfxPort_Mode_outputPushPullGeneral);
//Initialize the time constants
initTime();
IfxCpu_emitEvent(&g_cpuSyncEvent);
IfxCpu_waitEvent(&g_cpuSyncEvent, 1);
while(1)
{
if(g_turnLEDon == TRUE)
{
IfxPort_setPinLow(LED);
}
}
}
Cpu1_Main.c 内容:
#include "Ifx_Types.h"
#include "IfxCpu.h"
#include "IfxScuWdt.h"
extern IfxCpu_syncEvent g_cpuSyncEvent;
#ifndef LED
#define LED &MODULE_P13, 0
#endif
extern uint16 g_turnLEDon;
void core1_main(void)
{
IfxCpu_enableInterrupts();
IfxScuWdt_disableCpuWatchdog(IfxScuWdt_getCpuWatchdogPassword());
IfxCpu_emitEvent(&g_cpuSyncEvent);
IfxCpu_waitEvent(&g_cpuSyncEvent, 1);
while(1)
{
if(g_turnLEDon == FALSE)
{
IfxPort_setPinHigh(LED);
}
}
}
Cpu2_Main.c 内容:
#include "Ifx_Types.h"
#include "IfxCpu.h"
#include "IfxScuWdt.h"
extern IfxCpu_syncEvent g_cpuSyncEvent;
#include "Bsp.h"
#ifndef LED
#define LED &MODULE_P13, 0
#endif
extern uint16 g_turnLEDon;
void core2_main(void)
{
IfxCpu_enableInterrupts();
IfxScuWdt_disableCpuWatchdog(IfxScuWdt_getCpuWatchdogPassword());
IfxCpu_emitEvent(&g_cpuSyncEvent);
IfxCpu_waitEvent(&g_cpuSyncEvent, 1);
while(1)
{
g_turnLEDon = !g_turnLEDon;
wait(TimeConst_1s);
}
}
当然, define或者全局变量的extern可以放到一个公共的头文件如Multicore.h中, 然后所有.c包含即可.
编译运行, LED每s翻转一次状态.
微信公众号欢迎扫描关注我的微信公众号, 及时获取最新文章: