|
|
|
|---|---|
| 工程名 |
|
| 芯片型号 |
|
| iLLD 版本 |
|
| 关键特性 |
|
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
SCR tricore里面的异构核心,主要做休眠唤醒使用的。近期有三个客户试用这个功能,基于英飞凌illd的demo一起分析学习的笔记分享出来了,欢迎大家一起学习批评指正。
TC49xN 芯片包含:
┌─────────────────────────────────────────────────────────┐
│ TC49xN 芯片 │
├─────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ TriCore 子系统 │ │
│ │ ┌───────┐ ┌───────┐ ┌───────┐ │ │
│ │ │ Cpu0 │ │ Cpu1 │ │ Cpu2 │ │ │
│ │ └───┬───┘ └───┬───┘ └───┬───┘ │ │
│ │ │ │ │ │ │
│ │ ┌───┴───┐ ┌───┴───┐ ┌───┴───┐ │ │
│ │ │ PMS │ │ DSPRAM│ │ PFlash│ │ │
│ │ │(控制SCR│ │ │ │ │ │ │
│ │ │配置) │ │ │ │ │ │ │
│ │ └───────┘ └───────┘ └───────┘ │ │
│ └─────────────────────────────────────────────────┘ │
│ │ │
│ ┌─────────────────┼─────────────────┐ │
│ │ │ │ │
│ │ ┌───────────────────────────────┐│ │
│ │ │ SCR 子系统 ││ │
│ │ │ ┌─────────────────────┐ ││ │
│ │ │ │ 8051 CPU │ ││ │
│ │ │ │ (1T, 8bit, 16bit) │ ││ │
│ │ │ └─────────────────────┘ ││ │
│ │ │ │ ││ │
│ │ │ ┌──────────────────────┐ ││ │
│ │ │ │ SCR XRAM (64KB) │ ││ │
│ │ │ │ (代码+数据) │ ││ │
│ │ │ └──────────────────────┘ ││ │
│ │ │ │ ││ │
│ │ │ ┌──────────────────────┐ ││ │
│ │ │ │ SCR 外设 (RTC等) │ ││ │
│ │ │ └──────────────────────┘ ││ │
│ │ └───────────────────────────────┘│ │
│ │ │ │
│ └────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────┘
上电复位
│
├─→ 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 通信)
文件位置: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++;
}
}
文件位置: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++;
}
|
|
|
|
|---|---|---|
| 消息邮箱 |
|
|
| 共享内存 |
|
|
| 引脚控制 |
|
|
// TriCore 向 SCR 发送消息
IfxPmsPm_sendMessageToScr(
&MODULE_PMS, // PMS 模块
0xAA // 8位数据
);
// TriCore 从 SCR 读取消息
uint8 data = IfxPmsPm_readMessageFromScr(&MODULE_PMS);
// SCR 向 TriCore 发送消息
IfxScrCpuIrq_sendMessageToTricore(0xBB);
// SCR 从 TriCore 读取消息
uint8 data = IfxScrCpuIrq_readMessageFromTricore();
TriCore SCR
│ │
│ sendMessage(0xAA) ────│
│ │
│ wait for 0xBB │
│ │
│ readMessage()
│ │
│ sendMessage(0xBB) ────┐
│ │
│ readMessage() ←───────────────────────┘
│
│ (握手完成)
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;
这是一个两阶段构建系统:
SCR 源代码 (i51/main.c)
│
├─→ [1] SCR 工具链编译
│ │
│ ├─→ .hex 文件
│ │
│ ├─→ [2] iHex2Array.exe 转换
│ │ │
│ │ └─→ CArray.c (数组格式的 SCR 程序)
│ │
│ └─→ [3] TriCore 工具链编译
│
└─→ [4] 链接进 TriCore ELF
文件位置: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
转换后的 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);
// 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);
文件位置:1_ToolEnv/0_Build/1_Config/Config_Tricore_Tasking/Lcf_Tasking_Tricore_Tc.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
文件位置: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;
}
|
|
|
|
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
// SCR 代码中的 XRAM 变量定义
volatile __xdata unsigned char rtc_flag __at(0x700C);
步骤:
0_Src/AppSw/i51/main.c// 发送不同的消息
IfxPmsPm_sendMessageToScr(&MODULE_PMS, 0x11); // 改为 0x11
// 等待不同的回复
while(0x22 != IfxPmsPm_readMessageFromScr(&MODULE_PMS));
// 发送不同的消息
IfxScrCpuIrq_sendMessageToTricore(0x22);
// 等待不同的消息
while(IfxScrCpuIrq_readMessageFromTricore() != 0x11);
P32_PCSRSEL.U = 0x000000F4; // 修改 P32 配置
P33_PCSRSEL.U = 0x0000FFFE; // 修改 P33 配置
P34_PCSRSEL.U = 0x0000003E; // 修改 P34 配置
// 使能引脚
IfxScrPort_enablePortPad(PORT0, PIN1);
// 配置为输出
IfxScrPort_configurePortControl(
PORT0,
PIN1,
IfxScrPort_IoControl_output_pushpullGpio
);
// 翻转引脚
IfxScrPort_togglePinState(PORT0, PIN1);
// 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
|
|
|
|---|---|
| 消息打印 |
|
| 引脚翻转 |
|
| 共享内存 |
|
| RTC 中断 |
|
// SCR 侧
while(1)
{
// 发送递增数据
IfxScrCpuIrq_sendMessageToTricore(i++);
}
// TriCore 侧
while(1)
{
// 读取 SCR 消息并打印
uint8 msg = IfxPmsPm_readMessageFromScr(&MODULE_PMS);
printf("SCR says: 0x%X
", msg);
}
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);
}
}
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++);
}
}
|
|
|
|---|---|
| 看门狗 |
|
| XRAM 大小 |
|
| 引脚配置 |
|
| 消息处理 |
|
| 中断优先级 |
|
希望这份文档对您有帮助!
作者:tianpengbo / 田朋博。大家如果在项目中遇到相关技术问题,欢迎联系我交流。
support@softor.com.cn
tianpengbo@softor.com.cn
作者:tianpengbo / 田朋博。大家如果在项目中遇到相关技术问题,欢迎联系我交流。
support@softor.com.cn
tianpengbo@softor.com.cn