3. AURIX多核启动与CPU同步控制
任务目标
在AURIX TC3xx上完成三核启动:CPU0完成基础初始化后,依次唤醒CPU1、CPU2;三核通过共享同步标志会合,全部就绪后同时进入各自主循环。核心是"启动顺序 + 同步屏障"两件事。
关键机制
- 启动顺序:复位后仅CPU0运行,CPU1/CPU2处于halt状态,需由CPU0写各自CPU的启动地址并置位启动请求。
- 同步屏障:用共享内存中的计数器实现。每个核到达屏障时原子自增,CPU0等待计数达到3后置"放行"标志,其余核自旋等待该标志。
- 可见性:共享变量用
volatile,跨核访问前用内存屏障保证顺序。
完整实现
以下代码基于iLLD(Infineon Low Level Driver)。CPU1/CPU2的入口函数地址写入各自CPU的启动配置寄存器,再触发启动。同步用共享结构体完成。
#include "IfxCpu.h"
#include "IfxCpu_reg.h"
#include "IfxScu_reg.h"
/* 共享同步结构:放在非缓存或一致访问的段,这里用普通全局并加volatile */
typedef struct {
volatile unsigned int arrived; /* 已到达屏障的核数 */
volatile unsigned int release; /* 放行标志 */
} SyncBarrier;
static SyncBarrier g_sync = { 0u, 0u };
/* 三核主循环入口 */
static void core_main(unsigned int cpuId)
{
/* 到达屏障:原子自增 */
IfxCpu_disableInterrupts();
unsigned int prev = __atomic_fetch_add(&g_sync.arrived, 1u, __ATOMIC_SEQ_CST);
IfxCpu_enableInterrupts();
if (cpuId == 0u) {
/* CPU0负责判定:等齐3个核后放行 */
while (g_sync.arrived < 3u) { }
__atomic_store_n(&g_sync.release, 1u, __ATOMIC_SEQ_CST);
} else {
/* CPU1/CPU2自旋等待放行 */
while (__atomic_load_n(&g_sync.release, __ATOMIC_SEQ_CST) == 0u) { }
}
/* 三核在此刻之后同时进入主循环 */
for (;;) {
/* 各核主循环任务,此处以空转示意 */
__asm("nop");
}
}
/* CPU1入口 */
void core1_entry(void) { core_main(1u); }
/* CPU2入口 */
void core2_entry(void) { core_main(2u); }
/* 唤醒指定CPU:写启动地址并置启动请求位 */
static void start_cpu(IfxCpu_ResourceCpu cpu, void (*entry)(void))
{
IfxCpu_setCoreStartAddress(cpu, (void *)entry);
IfxCpu_startCore(cpu);
}
int core0_main(void)
{
/* CPU0基础初始化(时钟、看门狗等由iLLD初始化代码完成) */
IfxCpu_enableInterrupts();
/* 依次唤醒CPU1、CPU2 */
start_cpu(IfxCpu_ResourceCpu_1, core1_entry);
start_cpu(IfxCpu_ResourceCpu_2, core2_entry);
/* CPU0也进入同步与主循环 */
core_main(0u);
return 0;
}
运行与验证
- 用AURIX Development Studio或Tasking编译,链接脚本确保
g_sync位于所有核可访问的共享RAM段(默认全局段即可)。 - 烧录后复位运行,在调试器中给
core_main的for(;;)处下断点。 - 通过条件:三个核都停在主循环,且
g_sync.arrived == 3、g_sync.release == 1。若某核未到达,检查其启动地址是否正确、该核是否被看门狗复位。
常见问题
- CPU1/CPU2未启动:确认
IfxCpu_startCore调用前已使能对应核的时钟,且入口函数地址对齐。 - 同步卡死:
g_sync若被编译器优化或放在各核私有缓存,会导致可见性问题,务必用volatile+原子操作。 - 看门狗复位:多核等待期间需喂狗或先关闭看门狗,否则屏障等待可能超时。