BaseFramework_TC49xN_Scr 工程详细分析


文档信息

项目
内容
工程名
BaseFramework_TC49xN_Scr
芯片型号
TC49xN
iLLD 版本
2.5.1
关键特性
SCR + TriCore 多核协作

1. 工程目录结构概览

BaseFramework_TC49xN_Scr/
├── 0_Src/
│   ├── AppSw/
│   │   ├── CpuGeneric/
│   │   │   └── Config/
│   │   │       ├── Ifx_Cfg.h
│   │   │       ├── Ifx_InterfaceConst.c   ← 共享数据/接口常数
│   │   │       └── MainPage.h
│   │   ├── Tricore/
│   │   │   ├── Cfg_Ssw/
│   │   │   │   ├── Ifx_Cfg_Ssw.c/h
│   │   │   │   └── Ifx_Cfg_SswBmhd.c
│   │   │   ├── Main/
│   │   │   │   ├── Cpu0_Main.c ← TriCore 主程序
│   │   │   │   ├── Cpu1_Main.c
│   │   │   │   ├── Cpu2_Main.c
│   │   │   │   ├── Cpu3_Main.c
│   │   │   │   └── Cpu4_Main.c
│   │   │   └── ScrCArray/
│   │   │       └── CompileScrArray.mk    ← SCR 转换构建脚本
│   │   └── i51/
│   │       └── main.c                      ← SCR 主程序
│   └── Libraries/
├── 1_ToolEnv/
│   └── 0_Build/
│       ├── 0_Utilities/
│       │   └── iHex2Array.exe            ← SCR 程序转换工具
│       └── 1_Config/
│           ├── Config_i51_Tasking/       ← SCR Tasking 编译配置
│           │   ├── Lcf_Tasking_i51_Scr.lsl ← SCR 链接脚本
│           │   └── arch_scr.lsl
│           └── Config_Tricore_Tasking/   ← TriCore Tasking 配置
│               └── Lcf_Tasking_Tricore_Tc.lsl
└── Makefile

2. 系统架构简介

2.1 SCR 是什么?

SCR  tricore里面的异构核心,主要做休眠唤醒使用的。近期有三个客户试用这个功能,基于英飞凌illd的demo一起分析学习的笔记分享出来了,欢迎大家一起学习批评指正。

TC49xN 芯片包含:

2.2 系统框图

    ┌─────────────────────────────────────────────────────────┐
    │                    TC49xN 芯片                           │
    ├─────────────────────────────────────────────────────────┤
    │                                                           │
    │   ┌─────────────────────────────────────────────────┐   │
    │   │              TriCore 子系统                      │   │
    │   │    ┌───────┐   ┌───────┐   ┌───────┐            │   │
    │   │    │ Cpu0  │   │ Cpu1  │   │ Cpu2  │            │   │
    │   │    └───┬───┘   └───┬───┘   └───┬───┘            │   │
    │   │        │           │           │                │   │
    │   │    ┌───┴───┐   ┌───┴───┐   ┌───┴───┐            │   │
    │   │    │ PMS   │   │ DSPRAM│   │ PFlash│            │   │
    │   │    │(控制SCR│   │       │   │       │            │   │
    │   │    │配置)  │   │       │   │       │            │   │
    │   │    └───────┘   └───────┘   └───────┘            │   │
    │   └─────────────────────────────────────────────────┘   │
    │                          │                                │
    │        ┌─────────────────┼─────────────────┐            │
    │        │                 │                 │            │
    │        │   ┌───────────────────────────────┐│            │
    │        │   │           SCR 子系统          ││            │
    │        │   │    ┌─────────────────────┐  ││            │
    │        │   │    │    8051 CPU        │  ││            │
    │        │   │    │  (1T, 8bit, 16bit) │  ││            │
    │        │   │    └─────────────────────┘  ││            │
    │        │   │              │              ││            │
    │        │   │    ┌──────────────────────┐ ││            │
    │        │   │    │  SCR XRAM (64KB)   │ ││            │
    │        │   │    │  (代码+数据)        │ ││            │
    │        │   │    └──────────────────────┘ ││            │
    │        │   │              │              ││            │
    │        │   │    ┌──────────────────────┐ ││            │
    │        │   │    │  SCR 外设 (RTC等)   │ ││            │
    │        │   │    └──────────────────────┘ ││            │
    │        │   └───────────────────────────────┘│            │
    │        │                                    │            │
    │        └────────────────────────────────────┘            │
    │                                                           │
    └─────────────────────────────────────────────────────────┘

2.3 SCR 的典型应用


3. 启动流程详解

3.1 整体启动流程

上电复位
    │
    ├─→ SSW 启动软件初始化 TriCore
    │
    ├─→ TriCore Cpu0 启动
    │       │
    │       ├─→ [1] 禁用看门狗
    │       ├─→ [2] 使能全局中断
    │       ├─→ [3] 配置引脚功能(分配给 SCR)
    │       ├─→ [4] 初始化并加载 SCR 程序
    │       │       │
    │       │       ├─→ 清空 XRAM
    │       │       ├─→ 将 SCR 二进制程序拷贝到 XRAM
    │       │       └─→ 配置 SCR 启动模式
    │       │
    │       ├─→ [5] 发送握手信号 0xAA 给 SCR
    │       ├─→ [6] 等待 SCR 回复 0xBB
    │       │
    │       └─→ [7] TriCore 进入主循环
    │
    └─→ SCR 启动
            │
            ├─→ [1] SCR 启动运行
            ├─→ [2] 发送 0xEE 给 TriCore(可选)
            ├─→ [3] 等待 TriCore 的 0xAA
            ├─→ [4] 回复 TriCore 0xBB
            ├─→ [5] SCR 初始化外设(RTC 等)
            └─→ [6] SCR 进入主循环(可与 TriCore 通信)

3.2 TriCore 侧启动代码分析

文件位置0_Src/AppSw/Tricore/Main/Cpu0_Main.c

void core0_main (void)
{
    uint32 *addrPtr;

    // [1] 禁用看门狗(演示用,实际产品建议启用)

    IfxWtu_disableCpuWatchdog(IfxWtu_getCpuWatchdogPassword());
    IfxWtu_disableSystemWatchdog(IfxWtu_getSystemWatchdogPassword());

    // [2] 使能全局中断

    IfxCpu_enableInterrupts();

    // [3] 配置引脚(分配给 SCR 使用)

    {
        P32_PCSRSEL.U = 0x000000F4;  // Port32 配置
        P33_PCSRSEL.U = 0x0000FFFE;  // Port33 配置
        P34_PCSRSEL.U = 0x0000003E;  // Port34 配置
    }

    // [4] SCR 初始化

    {
        // 指向 SCR 的 XRAM

        addrPtr = PMS_XRAM;

        // 清空 XRAM 内存

        while
((uint32)addrPtr <= (uint32)0xF0247FFF)
        {
            *addrPtr = 0u;
            addrPtr++;
        }

        // SCR 程序加载配置

        IfxPmsPm_MemoryConfig memCfg = {
            &scrProgram,        // SCR 二进制程序
            PMS_XRAM,           // 加载地址
            scrProgramSize      // 程序大小
        };

        // 初始化 SCR(用户模式)

        IfxPmsPm_initScr(
            IfxPmsPm_ScrBootMode_userMode,  // 启动模式
            FALSE,                          // 是否使用安全模式
            &memCfg                         // 内存配置
        );

        // 复位 SCR(使其开始运行)

        IfxPmsPm_resetScr(&MODULE_PMS);
    }

    // [5] TriCore 向 SCR 发送握手消息 0xAA

    IfxPmsPm_sendMessageToScr(&MODULE_PMS, 0xAA);

    // [6] 等待 SCR 回复 0xBB

    while
(0xBB != IfxPmsPm_readMessageFromScr(&MODULE_PMS));

    // [7] TriCore 主循环

    while
 (1)
    {
        counter0++;
    }
}

3.3 SCR 侧启动代码分析

文件位置0_Src/AppSw/i51/main.c

void main(void)
{
    uint8 i = 0;
    IfxScrRtc_Config Rtc_Config;

    // [1] SCR 发送 0xEE 给 TriCore(可选)

    IfxScrCpuIrq_sendMessageToTricore(0xEE);

    // [2] 禁用位保护方案

    IfxScrScu_disableBitProtectionScheme();

    // [3] 使能全局中断

    IfxScrCpuIrq_enableGlobalInterrupt();

    // [4] 等待 TriCore 的握手消息 0xAA

    while
(IfxScrCpuIrq_readMessageFromTricore() != 0xAA);

    // [5] 回复 TriCore 0xBB

    IfxScrCpuIrq_sendMessageToTricore(0xBB);

    // [6] 配置 SCR 引脚

    {
        // 使能 SCR_P0.0 (P33.0)

        IfxScrPort_enablePortPad(PORT0, PIN1);

        // 配置为推挽输出

        IfxScrPort_configurePortControl(
            PORT0,
            PIN1,
            IfxScrPort_IoControl_output_pushpullGpio
        );
    }

    // [7] 配置 RTC(实时时钟)

    {
        // 使能 RTC 模块

        IfxScrScu_enableModule(IfxScrScu_Module_rtc);

        // 使能 RTC 中断

        IfxScrCpuIrq_enableInterruptNode(IfxScrCpuIrq_InterruptNode_rtc);

        // 配置 RTC

        Rtc_Config.clockSource = IfxScrRtc_ClockSel_pclk;
        Rtc_Config.bypassPrescaler = 0x1;
        Rtc_Config.enableInterruptOnCompare = 0x1;
        Rtc_Config.initialCountValue = 0x00000000;
        Rtc_Config.compareValue = 0x114E20;  // 比较值
        IfxScrRtc_initModule(&Rtc_Config);

        // 启动 RTC

        IfxScrRtc_enableRtc();
    }

    // [8] SCR 主循环

    while
(1)
    {
        // 持续向 TriCore 发送递增数据

        IfxScrCpuIrq_sendMessageToTricore(i++);
    }
}

// RTC 中断服务程序

void
 __interrupt(__INTNO(13)) rtc_interrupt(void)
{
    // 翻转引脚状态 (P33.0)

    IfxScrPort_togglePinState(PORT0, PIN1);
    rtc_flag++;
}

4. SCR 和 TriCore 的交互机制

4.1 交互方式

方式
描述
代码位置
消息邮箱
8位 消息寄存器,TriCore ↔ SCR 双向通信
PMS 模块
共享内存
SCR XRAM,TriCore 也可以访问
0xF024 0000-0xF024 7FFF
引脚控制
部分引脚可配置给 SCR 直接控制
Port32/33/34

4.2 消息邮箱 API

TriCore 侧(发送给 SCR)

// TriCore 向 SCR 发送消息
IfxPmsPm_sendMessageToScr(
    &MODULE_PMS,  // PMS 模块
    0xAA
         // 8位数据
);

// TriCore 从 SCR 读取消息

uint8 data = IfxPmsPm_readMessageFromScr(&MODULE_PMS);

SCR 侧(发送给 TriCore)

// SCR 向 TriCore 发送消息
IfxScrCpuIrq_sendMessageToTricore(0xBB);

// SCR 从 TriCore 读取消息

uint8 data = IfxScrCpuIrq_readMessageFromTricore();

4.3 握手时序

TriCore                    SCR
│                        │
│ sendMessage(0xAA) ────│
│                        │
│ wait for 0xBB         │
│                        │
│                    readMessage()
│                        │
│                    sendMessage(0xBB) ────┐
│                                        │
│ readMessage()  ←───────────────────────┘

│ (握手完成)

4.4 XRAM 共享内存

XRAM 地址范围:0xF024 0000 - 0xF024 7FFF (64KB)

// TriCore 侧访问 XRAM
uint32 *xramPtr = PMS_XRAM;
*xramPtr = data;  // 写入 XRAM
data = *xramPtr;  // 从 XRAM 读取

// SCR 侧访问 XRAM

__xdata unsigned char *xramPtr = ...;
*xramPtr = data;

5. SCR 程序加载流程

5.1 构建流程概览

这是一个两阶段构建系统:

SCR 源代码 (i51/main.c)
        │
        ├─→ [1] SCR 工具链编译
        │        │
        │        ├─→ .hex 文件
        │        │
        │        ├─→ [2] iHex2Array.exe 转换
        │        │        │
        │        │        └─→ CArray.c (数组格式的 SCR 程序)
        │        │
        │        └─→ [3] TriCore 工具链编译
        │
        └─→ [4] 链接进 TriCore ELF

5.2 编译脚本分析

文件位置0_Src/AppSw/Tricore/ScrCArray/CompileScrArray.mk

# 将转换后的 SCR C数组 链接进 TriCore
B_GEN_CUSTOBJS_TRICORE_TC += $(B_GEN_OUT_FOLDER_I51)/CArray.o
B_GEN_CUSTOBJS_TRICORE_TC0 += $(B_GEN_OUT_FOLDER_I51)/CArray.o

# Tasking 编译器示例

ifeq
 ($(B_GEN_TOOLCHAIN_PRIMARY_TRICORE),Tasking)
$(B_GEN_OUT_FOLDER_I51)
/CArray.o: \
    $(B_GEN_OUT_FOLDER_I51)
/CArray.c \
    $(B_GEN_CONFIG_TRICORE_TASKING)
 \
    $(B_CONFIG_FILES_FOLDER)
/Config.xml
    
    @echo Compiling $< ! for Tasking Tricore
    
    $(B_GEN_TRICORE_TASKING_CC)
 \
        -o $@ \
        $<
 \
        -c $(B_TASKING_TRICORE_CC_OPTIONS)
endif

5.3 CArray.c 格式

转换后的 SCR 程序在 TriCore 代码中的呈现:

// 在 CArray.c 中(自动生成)
extern
 const unsigned int scrProgramSize;
extern
 const unsigned char scrProgram[];

// SCR 二进制程序数组

const
 unsigned char scrProgram[] = {
    0x02
, 0x10, ...  // SCR 的机器码
    ...
};

const
 unsigned int scrProgramSize = sizeof(scrProgram);

5.4 加载步骤

// TriCore 代码中的加载
IfxPmsPm_MemoryConfig memCfg = {
    &scrProgram,        // SCR 二进制数组(来自 CArray.o)
    PMS_XRAM,           // XRAM 地址 0xF024 0000
    scrProgramSize      // 程序大小
};

// 初始化 SCR,将程序从 TriCore Flash 拷贝到 SCR XRAM

IfxPmsPm_initScr(
    IfxPmsPm_ScrBootMode_userMode,
    FALSE,
    &memCfg
);

// 复位 SCR,开始运行

IfxPmsPm_resetScr(&MODULE_PMS);

6. LSL 链接脚本详解

6.1 TriCore 侧 LSL

文件位置1_ToolEnv/0_Build/1_Config/Config_Tricore_Tasking/Lcf_Tasking_Tricore_Tc.lsl

LSL 关键配置

// CSA (上下文保存区) 和堆栈配置
#define LCF_CSA0_SIZE     8k
#define LCF_USTACK0_SIZE  2k
#define LCF_ISTACK0_SIZE  1k

#define LCF_CSA1_SIZE     8k
#define LCF_USTACK1_SIZE  2k
#define LCF_ISTACK1_SIZE  1k
...

// DSPRAM 地址配置

#define LCF_DSPR4_START  0x30000000  // Cpu4
#define LCF_DSPR4_SIZE   112K

#define LCF_DSPR3_START  0x40000000  // Cpu3
#define LCF_DSPR3_SIZE   112K

#define LCF_DSPR2_START  0x50000000  // Cpu2
#define LCF_DSPR2_SIZE   240K

#define LCF_DSPR1_START  0x60000000  // Cpu1
#define LCF_DSPR1_SIZE   240K

#define LCF_DSPR0_START  0x70000000  // Cpu0
#define LCF_DSPR0_SIZE   240K

// 中断向量表地址

#define LCF_INTVEC0_START 0x803FE000
#define LCF_INTVEC1_START 0x807FE000
...

// 陷阱向量表地址

#define LCF_TRAPVEC0_START 0x80000100
...

// 程序启动地址

#define LCF_STARTPTR_CPU0 0x80000000   // Cpu0 缓存 Flash
#define LCF_STARTPTR_NC_CPU0 0xA0000000  // Cpu0 非缓存
...

// 默认核配置

#define LCF_DEFAULT_HOST LCF_CPU0

6.2 SCR 侧 LSL

文件位置1_ToolEnv/0_Build/1_Config/Config_i51_Tasking/Lcf_Tasking_i51_Scr.lsl

// 包含通用 SCR 架构描述
#include "arch_scr3g.lsl"

////////////////////////////////////////////////////////////////////////////

//

// memory definitions

//


// IRAM (内部 RAM,256字节)

memory iram
{
    mau = 8;
    type = ram;
    size = 256;
    map (dest=bus:scr3g:idata_bus, src_offset=0x0, dest_offset=0x0, size=256);
}

// XRAM (扩展 RAM,64KB)

memory xram
{
    mau = 8;
    type = ram;
    size = 64k;
    map (dest=bus:scr3g:xdata_bus, src_offset=0x0, dest_offset=0x0, size=64k);
}

// XROM (程序 ROM,64KB)

memory xrom
{
    mau = 8;
    type = rom;
    size = 64k;
    map (dest=bus:scr3g:code_bus, src_offset=0x0, dest_offset=0x0, size=64k);
}

//

// 预留 xdata 的首末字节

// 防止空指针和溢出检查

//

section_setup scr3g:scr3g:xdata
{
    reserved (tag="prevent xdata NULL pointer") 0x0 .. 0x1;
    reserved (tag="allow xdata overflow check") 0xffff .. 0x10000;
}

6.3 SCR 内存映射

地址范围
用途
说明
0x0000-0x00FF
IRAM (256B)
内部寄存器/快速内存
0x0000-0xFFFF
XRAM (64KB)
扩展内存(代码+数据)
0x0000-0xFFFF
XROM (64KB)
程序 ROM(虚拟)
// SCR 代码中的 XRAM 变量定义
volatile
 __xdata unsigned char rtc_flag __at(0x700C);

7. 常见修改和配置

7.1 修改 SCR 程序

步骤

  1. 1. 修改 0_Src/AppSw/i51/main.c
  2. 2. 重新编译工程(自动触发 SCR 编译 → 转换 → 链接)
  3. 3. 下载到芯片

7.2 修改消息握手

TriCore 侧

// 发送不同的消息
IfxPmsPm_sendMessageToScr(&MODULE_PMS, 0x11);  // 改为 0x11

// 等待不同的回复

while
(0x22 != IfxPmsPm_readMessageFromScr(&MODULE_PMS));

SCR 侧

// 发送不同的消息
IfxScrCpuIrq_sendMessageToTricore(0x22);

// 等待不同的消息

while
(IfxScrCpuIrq_readMessageFromTricore() != 0x11);

7.3 修改引脚配置

TriCore 侧(分配给 SCR)

P32_PCSRSEL.U = 0x000000F4;  // 修改 P32 配置
P33_PCSRSEL.U = 0x0000FFFE;  // 修改 P33 配置
P34_PCSRSEL.U = 0x0000003E;  // 修改 P34 配置

SCR 侧(使用引脚)

// 使能引脚
IfxScrPort_enablePortPad(PORT0, PIN1);

// 配置为输出

IfxScrPort_configurePortControl(
    PORT0,
    PIN1,
    IfxScrPort_IoControl_output_pushpullGpio
);

// 翻转引脚

IfxScrPort_togglePinState(PORT0, PIN1);

7.4 修改 RTC 配置

// RTC 配置
Rtc_Config.clockSource = IfxScrRtc_ClockSel_pclk;  // 时钟源
Rtc_Config.bypassPrescaler = 0x1;                  // 预分频器
Rtc_Config.enableInterruptOnCompare = 0x1;         // 比较中断
Rtc_Config.initialCountValue = 0x00000000;         // 初始计数值
Rtc_Config.compareValue = 0x114E20;                // 比较值(时间间隔)

IfxScrRtc_initModule(&Rtc_Config);
IfxScrRtc_enableRtc();  // 启动 RTC

8. 调试技巧

8.1 调试 SCR 的方法

方法
说明
消息打印
SCR 发送数字给 TriCore,TriCore 打印
引脚翻转
SCR 翻转引脚,示波器/逻辑分析仪观察
共享内存
SCR 写入 XRAM,TriCore 读取
RTC 中断
固定间隔翻转引脚,检查时序

8.2 示例:调试 SCR 消息

// SCR 侧
while
(1)
{
    // 发送递增数据

    IfxScrCpuIrq_sendMessageToTricore(i++);
}

// TriCore 侧

while
(1)
{
    // 读取 SCR 消息并打印

    uint8 msg = IfxPmsPm_readMessageFromScr(&MODULE_PMS);
    printf
("SCR says: 0x%X ", msg);
}

9. 完整示例:双向通信

9.1 TriCore 侧

volatile uint8 tx_data = 0;
volatile
 uint8 rx_data = 0;

void
 core0_main(void)
{
    // 初始化 SCR...


    // 握手...

    IfxPmsPm_sendMessageToScr(&MODULE_PMS, 0xAA);
    while
(0xBB != IfxPmsPm_readMessageFromScr(&MODULE_PMS));

    while
(1)
    {
        // 发送数据给 SCR

        IfxPmsPm_sendMessageToScr(&MODULE_PMS, tx_data++);

        // 读取 SCR 数据

        rx_data = IfxPmsPm_readMessageFromScr(&MODULE_PMS);
    }
}

9.2 SCR 侧

volatile uint8 tx_data = 0;
volatile
 uint8 rx_data = 0;

void
 main(void)
{
    // 握手...

    while
(IfxScrCpuIrq_readMessageFromTricore() != 0xAA);
    IfxScrCpuIrq_sendMessageToTricore(0xBB);

    while
(1)
    {
        // 读取 TriCore 数据

        rx_data = IfxScrCpuIrq_readMessageFromTricore();

        // 发送数据给 TriCore

        IfxScrCpuIrq_sendMessageToTricore(tx_data++);
    }
}

10. 注意事项

注意点
说明
看门狗
演示工程禁用了看门狗,实际产品建议启用
XRAM 大小
SCR XRAM 是 64KB,注意程序大小
引脚配置
部分引脚可分配给 SCR,需正确配置
消息处理
消息邮箱是单字的,注意发送/读取的时序
中断优先级
SCR 有自己的中断控制器

11. 总结

11.1 关键要点回顾

  1. 1. SCR 启动加载
  2. 2. SCR-TriCore 通信
  3. 3. 典型应用场景

希望这份文档对您有帮助!

如果你在编译tc4xx 遇到问题 请联系我们:
support@softor.com.cn
tianpengbo@softor.com.cn

作者与交流

作者:tianpengbo / 田朋博。大家如果在项目中遇到相关技术问题,欢迎联系我交流。
support@softor.com.cn
tianpengbo@softor.com.cn

作者与交流

作者:tianpengbo / 田朋博。大家如果在项目中遇到相关技术问题,欢迎联系我交流。
support@softor.com.cn
tianpengbo@softor.com.cn

在线留言