TMS320C6678 多核学习 中断分析 实例+解析

TMS320C6678 多核学习 中断分析 实例+解析

  • TMS320C6678
    • 了解c66x内核
      • C66x corepac的位置
      • 内部架构
    • 中断
      • 事件
      • 中断控制器
    • 中断例程
      • 环境
      • 预期结果
      • 运行结果
      • 分析

TMS320C6678

了解c66x内核

C66x corepac的位置

TMS320C6678 多核学习 中断分析 实例+解析_第1张图片

内部架构

TMS320C6678 多核学习 中断分析 实例+解析_第2张图片
可以看到66x corepac的组成模块

  • 一.首当其冲就是C66x DSP,这块的知识可以了解一下C66x DSP的结构图
    TMS320C6678 多核学习 中断分析 实例+解析_第3张图片
    ========================= 66x dsp结构图==============================
    1).两组寄存器文件组(A和B)
    2)…L,.S,.M,.D功能单元
    3).两个写入内存的数据通路 ST
    4).两个数据地址通路DA
    5).两个内存转载数据的数据通路LD
    6).寄存器交叉通道1X,2X
  • 二.L1程序存储器控制器 (提供dsp与l1p内存之间的存储通道)L1 数据存储器控制器 (提供DSP与L1D内存的接口)
  • 三.L2 存储器控制器
  • 四.DMA (进行内部与外部数据的迁移)
  • 五.EMC(外部内存控制器)提供与与其他设备的桥接,CFG(访问所有映射在memory的寄存器不能访问dsp或corepac的内部控制器)和sdma 与其他核之间的数据传输
  • 六.XMC (扩展存储器控制器)与MSMC的管理
  • 七.BWM (带宽管理)
  • 八.中断控制器
  • 九.存储器保护架构
  • 十.下电控制器

这就是CorePac的组成

中断

事件

在文档中关于中断是这样描述的
TMS320C6678 多核学习 中断分析 实例+解析_第4张图片
大意就是C6678设备上的CPU中断是通过中断控制来控制的也就是所谓的INTC(上面的corepac可以看到)。中断控制器允许将最多128个系统事件编程为12个CPU中断输入(CPUINT4-CPUINT15)、也就是每个核中的中断控制器最对处理128个系统事件
.
什么是系统事件,就是核上产生的事件和片级产生的事件。这128个系统事件由内部生成的事件(在CorePac内)和芯片级事件组成。

额外的系统事件被路由到每个 C66x CorePac,以提供不需要作为 CPU 中断/异常的芯片级事件作为仿真事件路由到中断控制器。 此外,错误类事件或不经常使用的事件也通过系统事件路由器路由,以卸载 C66x CorePac 中断选择器。 这是通过芯片中断控制器 (CIC) 块实现的。

这里涉及到了CIC(片级中断控制器),看了上面的解释还是有点懵,那就上图
TMS320C6678 多核学习 中断分析 实例+解析_第5张图片
可以看到这里面有四个CIC(0-4),这里主要讨论一下CIC0和1,根据上面的解释最起码明确了一点,一个中断控制器最多接受128个系统事件,那就得知道128个系统事件是谁给他的,这就是CIC的作用。根据图来看一个core会接受 98 + 17 + 5 +8 =128个事件。其中的17和8就是CIC分给他的.
在这里插入图片描述

上面解释了core是如何得到这128个系统事件的
接下来分析如何处理这128个系统事件

中断控制器

这128个系统事件最后都是要路由到合适的DSP中断中去的,所以接下来有一个过程就是如和从事件到中断
记住2个概念 interrupt SelectorEvent Combiner

Event Combiner:负责事件打包组合
TMS320C6678 多核学习 中断分析 实例+解析_第6张图片
将4-127的事件通过上图的方法(也可以自己进行配置使用mask和flag)分成组合,然后通过MASK和FLAG生成新的事件0 - 3最终形成128事件

interrupt Selector:负责路由
DSP有12个可屏蔽的中断,可以将128个事件路由到任意一个中断上。当然为了方便我们肯定是在事件打包之后进行路由

TMS320C6678 多核学习 中断分析 实例+解析_第7张图片
路径映射之后,就得设置中断触发源,可以通过设置中断选择寄存器设置。三个复用寄存器正好可以对应12个中断每个寄存器的(0-6,8-14,16-22,24-30)对应要生成的中断。

TMS320C6678 多核学习 中断分析 实例+解析_第8张图片

中断例程

了解了中断的大致原理,就可以上代码了。
我使用的板子是6678里面有8个核,所以用了一个核间通信(IPC)的例子来分析一下中断。

环境

CCS5.5
6678板卡
seed xds200仿真器
win 7

预期结果

core 0给core 1发送信息16,core 1收到后发送给 core 2 ,依次类推

运行结果

TMS320C6678 多核学习 中断分析 实例+解析_第9张图片

分析

main.c
#include 
#include 
#include 
#include 
#include 

#include 
#include 
#include 

#include "ipc_interrupt.h"

void main()
{
	uint32_t i;
	// 获取内核号
	uint32_t coreID = CSL_chipReadReg (CSL_CHIP_DNUM);

	TSCL = 0;
	//初始化
	intcInit();  //init the intc CSL global data structures, enable global ISR
	//注册
	registerInterrupt(); //register the Host interrupt with the event

	for (i=0; i<1000; i++)
		asm (" NOP 5");
	
	//core 0开始发送信息给下一个核
	if (0 == coreID)
	{
		IssueInterruptToNextCore();
	}

	while(1)
	{
		asm(" NOP 9");
	};
}
ipc_interrupt.c
#include 
#include 
#include 
#include 

#include 
#include 
#include 

#include "ipc_interrupt.h"

CSL_IntcGlobalEnableState state;    //使能
CSL_IntcContext context;     //上下文
CSL_IntcEventHandlerRecord Record[CSL_INTC_EVENTID_CNT]; //128个事件句柄
CSL_IntcEventHandlerRecord  EventRecord; //当前事件句柄
uint32_t        coreVector[MAX_CORE_NUM]; //内核表
CSL_IntcObj     intcObj[16]; //中断控制器对象
CSL_IntcHandle  hintc[16]; //中断控制器句柄
volatile Uint32 interruptNumber=0;

/* IPCGR Info */
int32_t iIPCGRInfo[CORENUM] = {
								IPCGR0,
								IPCGR1,
								IPCGR2,
								IPCGR3,
								IPCGR4,
								IPCGR5,
								IPCGR6,
								IPCGR7
							 };
/* IPCAR Info */
int32_t iIPCARInfo[CORENUM] = {
								IPCAR0,
								IPCAR1,
								IPCAR2,
								IPCAR3,
								IPCAR4,
								IPCAR5,
								IPCAR6,
								IPCAR7
							 };

interruptCfg intInfo[MAX_SYSTEM_VECTOR] =
{
	/* core   event   vector*/
	{  0,     91,     CSL_INTC_VECTID_4, &IPC_ISR},
	{  1,     91,     CSL_INTC_VECTID_4, &IPC_ISR},
	{  2,     91,     CSL_INTC_VECTID_4, &IPC_ISR},
	{  3,     91,     CSL_INTC_VECTID_4, &IPC_ISR},
	{  4,     91,     CSL_INTC_VECTID_4, &IPC_ISR},
	{  5,     91,     CSL_INTC_VECTID_4, &IPC_ISR},
	{  6,     91,     CSL_INTC_VECTID_4, &IPC_ISR},
	{  7,     91,     CSL_INTC_VECTID_4, &IPC_ISR},
};

int32_t intcInit()
{
	//初始化上下文环境
    /* INTC module initialization */
    context.eventhandlerRecord = Record;
    context.numEvtEntries      = CSL_INTC_EVENTID_CNT;
    if (CSL_intcInit (&context) != CSL_SOK)
        return -1;

    /* Enable NMIs */
    if (CSL_intcGlobalNmiEnable () != CSL_SOK)
        return -1;

    /* Enable global interrupts */
    if (CSL_intcGlobalEnable (&state) != CSL_SOK)
        return -1;

    /* INTC has been initialized successfully. */
    return 0;
}

//注册中断
int32_t registerInterrupt()
{
	uint32_t i;
	uint32_t event;
	uint32_t vector;
	uint32_t core;
	uint32_t coreID = CSL_chipReadReg (CSL_CHIP_DNUM);
	CSL_IntcEventHandler isr;

	for (i=0; i

如果各位需要源码的话可以私聊我…

你可能感兴趣的:(DSP,随笔,dsp,内核)